LoginSignup
15
13

More than 1 year has passed since last update.

「Scrapboxにコードを書いて実行する」を説明してみる

Last updated at Posted at 2020-03-16

はじめに

今回の投稿は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/[プロジェクト名]/[ページ名]/[付けたファイル名]
画面収録 2020-03-13 22.15.03.mov.gif
普段は上記のようにコード記法で書いたコードをコピーするために利用されます。
(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.htmlindex.jsだけ!!(簡単)
README.mdファイルは省略して記載しています。

index.js (ScrapboxのAPIのURLをGetパラメータから取得して、画面に読み込ませる)

ここが一番肝要なところですが、
本家様のコードをほぼほぼ流用しています。基本、本家様のコードを参照でお願いします。:bow:

本家様コード
ちなみにgh-pagesブランチとmasterブランチで内容が違っていたので、見比べて勉強させてもらいました。(jsだけでなくstyle読み込んだりなどなど)

今回Vue.jsのコードを動かしたい関係で、jQueryありきの部分については少し変更を加えています。
今回のindex.js

index.js
// jQueryお馴染みの「$」の部分
$(function(){

// 純粋なJavaScriptに変更
window.addEventListener('DOMContentLoaded', function(){

コードを見てもらったらわかりますが、JavaScriptでアクセスしたURLを解析して、
?code=の=以降の値(Getパラメータの値)を読み取って、その値をscriptタグとして追加する実装になっています。
(実行する際は?code=[ScrapboxのAPIのURL]としてアクセスしてください)

index.html (必要なCDNの読み込みや簡易のレイアウト記載)

今回はこんなかんじ。

index.html
<!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
   }
 })

実行の様子。上部は切り取っていますが、実行すると新規タブが開きます。
画面収録 2020-03-14 21.33.44.mov.gif

※押しているボタンについてはおまけで後述します。やってることはhttps://[アカウント名].github.io/[リポジトリ名]/?code=[ScrapboxのAPIのURL]にアクセスするだけです。

Scrapboxのコードを実行しているだけなので、Scrapboxのコードを書き換えると、当然結果も変わります。
画面収録 2020-03-14 21.55.59.mov.gif

他の例も用意したので、載せておきます。

  • 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
    }
})

画面収録 2020-03-14 22.26.39.mov.gif

  • ボタン
 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' })

画面収録 2020-03-14 22.28.26.mov.gif

アクセスするたびに同じ画面だけど違う結果が出てくる
というのはなかなかに面白いものです。
上記の3つのコードを続け様で実行した場合↓
画面収録 2020-03-15 0.32.54.mov.gif

どういった時に使える?

本家にも書いてありますが「プログラミング体験」として抜群です。
自分で勉強するにしても人に教えるにしても、文面と実行できるコードを共存して管理できるというのは、利点が多いのではないでしょうか。(いろいろな使い方ができそうです)

注意

言わずもがな、自分のコードは自分のGitHub Pages(あるいは別の静的ホスティングサービス)にアクセス・実行するようお願いします。

といっても他人のページだとCDNのカスタマイズもできないですし、自分で用意した方がいろいろ可能性が広がって楽しいと思います。

おまけ

開いているページ(前回はカードと書いていた)上のコード記法にアクセスするAPIを抽出して、https://[アカウント名].github.io/[リポジトリ名]/?code=[ScrapboxのAPIのURL]を開くUserScript作っているので、参考で載せておきます。
(今までのgif画像でも使っていました)

ScrapboxのUserScriptの詳しい説明については前回記事ScrapboxのUserScriptテンプレートまとめScrapboxのヘルプ参照ください。

下準備

前回記事の番外テンプレート(1)を作成するために、画像を用意して1つページを作ります。
スクリーンショット 2020-03-15 1.20.05.png

UserScript

UserScriptとはこんな感じ。

script.js
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はネタ帳の色合いが濃いです)

以上です!

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13