LoginSignup
7
7

More than 5 years have passed since last update.

StackEditで相互参照をするExtension

Last updated at Posted at 2014-12-16

[追記あり]

まずはStackEditの紹介から。StackEditはブラウザで動作するMarkdownエディタです。非常によく出来ていて、僕が知る中では最高のMarkdownエディタです。

StackEdit

StackEditはextensionとして各自自由に機能を追加することが出来ます。ExtensionはJavaScriptで記述します。

GitHubのドキュメントに開発者向けの記述があります。

Developer guide

とまあ読んでもらえればわかると思いますがただのextensionだけでなくStackEdit本体のコードをいじって更なる機能追加もできるようです。ですが今回はとりあえず標準で行えるExtensionだけで機能を追加します。

本題に入ります。今回やりたいのは図表番号の相互参照です。TeXやWordにはある機能ですがMarkdownには存在しません。そのため相互参照をしたければ独自に拡張するしかありません。ちょっとしたレポートをMarkdownでささっと書けたら便利に違いないと思いなんとか実装してみたというわけです。

とりあえずコードはこんな感じになりました。

userCustom.onPagedownConfigure = function(editor) {
    var converter = editor.getConverter();
    var figStack = [];

    converter.hooks.chain("preConversion", function(text) {
        figStack.length = 0;
        return text.replace(/\\label\[(.*?)\]/g, function(wholeMatch, m1) {
            figStack.push(m1)
            return '';
        });
    });
    converter.hooks.chain("preConversion", function(text) {
        return text.replace(/\\ref\[(.*?)\]/g, function(wholeMatch, m1) {
            return figStack.indexOf(m1) + 1;
        });
    });
};

これをStackEditの左上にある#を押してカラムを出し、その中にあるSettings -> Extensionsとたどります。Extensionsの一番下にUserCustom extensionがあるので、テキストボックスの中にコードを貼り付ければ動きます。

現状できるのは

\label[tag]

でラベルを設定し、

\ref[tag]

で参照です。\labelは本文に出てきた順に1,2,3,...と割り振られます。\label[tag]はプレビューには表示されません。\ref[tag]とすると割り振られた数字がプレビューに表示されます。

\label[id]

図\ref[id]は…

と言った感じで使えます。

とりあえず最低限動くことを確認したかったのでまだ荒削りです。図と表などをそれぞれ別に番号を振るようにしたりなどもう少し使いやすく拡張する予定です。

また自分のためにもコードの解説を書いておきたい…。


追記です。

TeXは\label{fig:fig1}\label{table:t1}などのように図や表に別の通し番号を振れます。この機能が無いと相互参照の意味が無いのでさっそく実装しました。

userCustom.onPagedownConfigure = function(editor) {
    var converter = editor.getConverter();
    var index = [];
    var stack = [];

    converter.hooks.chain("preConversion", function(text) {
        index.length = 0;
        stack.length = 0;
        return text.replace(/\\label\[(.*?):(.*?)\]/g, function(wholeMatch, m1, m2) {
            var i = index.indexOf(m1);
            if (i < 0) {
                index.push(m1);
                stack.push([]);
                stack[ index.indexOf(m1) ].push(m2);
            } else {
                stack[i].push(m2);
            }
            return '';
        });
    });
    converter.hooks.chain("preConversion", function(text) {
        return text.replace(/\\ref\[(.*?):(.*?)\]/g, function(wholeMatch, m1, m2) {
            i = index.indexOf(m1);
            if (i < 0) {
                return i;
            } else {
                return stack[ i ].indexOf(m2) + 1;
            }
        });
    });
};

これで\label[tag:name]とすれば\ref[tag:name]で番号を参照できます。

7
7
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
7
7