はじめに
今回の投稿はScrapboxのUserScriptテンプレートまとめに引き続き、Scrapboxネタです。(よっぽど好きだということです)
まずは以下のリンク先ページをご覧ください。
Scrapboxにコードを書いて実行する
なんとっ Scrapbox上に書いたJavaScriptのコードが実行されてるじゃないですか! すごい。UserScriptととはまた違ったことやってる!
自分もやりたいぃってことで、どうやって実現しているのか調べてみました。
※ Vue.js
タグにさせてもらいましたが、Vue.js
自体は実演で使わせてもらっただけで、チュートリアルの域を出ていないです。ご注意ください。
知れること・知れないこと
知れること
- Scrapbox上にコード記法で記載したJavaScriptのコードを実行して表示させる方法
知れないこと
- Scrapbox上に書いたJavaScript以外(コンパイルが必要になるような言語)を実行させる方法
- Scrapbox上に実行結果を埋め込む方法
仕組み
どうやって実現させているか紐解く鍵は、下のコードを実行
のリンクの中身にあります。
遷移した後のURLを見るのでも構いませんが、
https://[アカウント名].github.io/[リポジトリ名]/?code=[ほにゃらら]/[ほにゃらら].js
となっているはずです。
Tip1 : CDN
(他にもやりようはあるかとは思いますが)各種プログラムを実行するために、お馴染みのCDN(Contents Delivery Network)を利用します。
Tip2 : GitHub Pages
urlを見てもらったら分かるように、github.io
の静的ホスティングサービスであるGitHub Pagesを利用します。
(実際は静的ホスティングサービスであれば、何であっても構わないと思うのですが、今回は参考元のやり方のGitHub Pagesで説明させてもらいます)
Tip3 : ScrapboxのAPI
公式で大々的に説明があるAPIではありませんが、コード記法で書いた内容にアクセスできるAPIがあります。
形式 : https://scrapbox.io/api/code/[プロジェクト名]/[ページ名]/[付けたファイル名]
普段は上記のようにコード記法
で書いたコードをコピーするために利用されます。
(APIのURLにアクセスすればブラウザ上にコードの中身が表示されます)
「Scrapboxにコードを書いて実行する」の仕組みを、一言で(ざっくり)言うなら
静的ホスティングしたサイトにScrapboxで書いたコードを返却するAPIを渡して、コード記法で書かれた該当のコードを書き込み、CDNを利用して実行する
となります。
実装方法〜〜ユースケースとともに〜〜
本家Scrapboxにコードを書いて実行するのように、動きのあるコードの方が、面白味があるとは思いますが、今回はVue.js
のチュートリアルのコードを実行してみます。
GitHub Pagesの準備(簡易説明)
- Github上にリポジトリを作成する。
-
index.html
ファイルを作成する。 - branch :
gh-pages
を作成する - 後はrepositoryのURLにアクセスで
index.html
の内容が表示される!
コードの全容
私が今回説明で使っているソースはこちらです。
フォルダ構成
├── index.html
└── index.js
Github上に置くファイルはGithub Pagesで準備したindex.html
とindex.js
だけ!!(簡単)
※README.md
ファイルは省略して記載しています。
index.js (ScrapboxのAPIのURLをGetパラメータから取得して、画面に読み込ませる)
ここが一番肝要なところですが、
本家様のコードをほぼほぼ流用しています。基本、本家様のコードを参照でお願いします。
本家様コード
ちなみにgh-pages
ブランチとmaster
ブランチで内容が違っていたので、見比べて勉強させてもらいました。(jsだけでなくstyle読み込んだりなどなど)
今回Vue.js
のコードを動かしたい関係で、jQueryありきの部分については少し変更を加えています。
今回のindex.js
// jQueryお馴染みの「$」の部分
$(function(){
↓
// 純粋なJavaScriptに変更
window.addEventListener('DOMContentLoaded', function(){
コードを見てもらったらわかりますが、JavaScriptでアクセスしたURLを解析して、
?code=
の=以降の値(Getパラメータの値)を読み取って、その値をscriptタグとして追加する実装になっています。
(実行する際は?code=[ScrapboxのAPIのURL]
としてアクセスしてください)
index.html (必要なCDNの読み込みや簡易のレイアウト記載)
今回はこんなかんじ。
<!DOCTYPE html>
<html>
<head>
<title>Scrapboxでプログラミングの勉強をする</title>
<!-- bulma -->
<link href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css" rel="stylesheet">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<div id="app">
<app-template></app-template>
</div>
<!-- vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="./index.js"></script>
</html>
基本CDN
と先ほどのindex.js
を読み込んでいるだけ!
CDN
はここで自分の利用したいものをカスタマイズしましょう。
今回はVue.jsと表示の調整でBulmaを書きました。
ここまでで下準備は完了!
Scrapboxにコードを書いて実行
では、Scrapboxでコードを書いて実際に実行してみましょう。
コードはVue.jsのチュートリアルを参考に書いています。
Githubに挙げているコードは変更しない方向で、<app-template></app-template>
をカスタム要素として利用した書き方に調整しています。
コード記法は拡張子「js」でファイル名書くようにしてください。
- Hello World
const Messages = {
template:
`<div class="hero">` +
'<div class="hero-body has-text-centered">{{ message }}</div>' +
'</div>',
data: function() {
return {
message: 'Hello World!!',
}
}
}
new Vue({
el: '#app',
components: {
'app-template': Messages
}
})
実行の様子。上部は切り取っていますが、実行すると新規タブが開きます。
※押しているボタンについてはおまけで後述します。やってることはhttps://[アカウント名].github.io/[リポジトリ名]/?code=[ScrapboxのAPIのURL]
にアクセスするだけです。
Scrapboxのコードを実行しているだけなので、Scrapboxのコードを書き換えると、当然結果も変わります。
他の例も用意したので、載せておきます。
- v-for
const BlogPost = {
template:
`<div class="hero">` +
'<div class="hero-body has-text-centered">' +
'<div v-for="post in posts" v-bind:key="post.id">' +
'{{post.title}}' +
'</div>' +
'</div>' +
'</div>',
data: function () {
return {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
}
}
new Vue({
el: '#app',
components: {
'app-template': BlogPost
}
})
- ボタン
Vue.component('app-template',{
data: function(){
return {
count1: 0,
count2: 0
}
},
template:
'<div class="hero">'
+ '<div class="hero-body has-text-centered">'
+ '<button v-on:click="count1++">You clicked me {{count1}} times.</button>'
+ '<br>'
+ '<button v-on:click="count2++">You clicked me {{count2}} times.</button>'
+ '</div>'
+ '</div>'
})
new Vue({ el: '#app' })
アクセスするたびに同じ画面だけど違う結果が出てくる
というのはなかなかに面白いものです。
上記の3つのコードを続け様で実行した場合↓
どういった時に使える?
本家にも書いてありますが「プログラミング体験」として抜群です。
自分で勉強するにしても人に教えるにしても、文面と実行できるコードを共存して管理できるというのは、利点が多いのではないでしょうか。(いろいろな使い方ができそうです)
注意
言わずもがな、自分のコードは自分のGitHub Pages(あるいは別の静的ホスティングサービス)にアクセス・実行するようお願いします。
といっても他人のページだとCDN
のカスタマイズもできないですし、自分で用意した方がいろいろ可能性が広がって楽しいと思います。
おまけ
開いているページ(前回はカードと書いていた)上のコード記法にアクセスするAPIを抽出して、https://[アカウント名].github.io/[リポジトリ名]/?code=[ScrapboxのAPIのURL]
を開くUserScript作っているので、参考で載せておきます。
(今までのgif画像でも使っていました)
ScrapboxのUserScriptの詳しい説明については前回記事ScrapboxのUserScriptテンプレートまとめやScrapboxのヘルプ参照ください。
下準備
前回記事の番外テンプレート(1)を作成するために、画像を用意して1つページを作ります。
UserScript
UserScriptとはこんな感じ。
const GITHUB_REPOSITORY = 'https://[githubユーザ名].github.io/[リポジトリ名]';
const SCRAPBOX_URL = 'https://scrapbox.io';
const $appRoot = $('#app-container');
$appRoot.on('click', 'img[class="icon"]', e => {
const $icon = $(e.target).closest('img[class="icon"]');
const iconName = $icon.attr('title');
// 「programming」アイコンの場合に処理を実行
if (iconName === 'programming') {
let codeUrl;
$('a').each(function (index, atag) {
let hrefStr = String($(atag).attr('href'));
// getパラメータの作成
if (hrefStr.startsWith('/api/code') && hrefStr.endsWith('js')) {
codeUrl = (codeUrl == null) ?
'code=' + SCRAPBOX_URL + hrefStr
: codeUrl + '&code=' + SCRAPBOX_URL + hrefStr;
}
})
console.log('呼び出し先コードのURL :' + codeUrl);
window.open(GITHUB_REPOSITORY + '?' + codeUrl);
return false;
}
});
これで、Scrapboxの[programming.icon]
(アイコン記法)と書かれた場所をクリックすれば、プログラムの実行(条件を満たした状態でGitHub Pagesにアクセス)できます!!
※ScrapboxのUserScriptは自分にしか効かない(Scrapboxのヘルプ参照)ので、Publicで公開しているプロジェクトにおいて、閲覧者に実行してもらいたい場合等は、リンクをScrapbox上に書くようにしてください。
おわりの余談
前回のブログを書いていた頃含め、1年以上Scrapboxを書いてきたわけですが、アドベントカレンダーやろう! ってなったときも、内容考えるのすごく楽でした。
Scrapboxは項目と項目をつなげることで新たな発想が生まれたり、思考がクリアになったりと、使うほどにいろんな効果があるような気がしています。(個人の感想)
ちなみに……
Scrapboxでアウトプットするというのも一つですが、私個人として「Scrapboxの内容をまとめてブログに書く」使い方はこれからもしていくと思います。(私にとってScrapboxはネタ帳の色合いが濃いです)
以上です!