「タグでシンタックスハイライト」を実装して、執筆専用ブラウザを文章エディタに

WorkFlowyでシンタックスハイライトを実現させるために、いろいろと調べました。
もっとぼくにプログラミングの知識があれば、ほんまもんのシンタックスハイライトを実装できたのかもしれませんが、そこまではわからずで。
最終的に、「タグ」によってハイライトする方法で、文章の見出しやリストの文字色を変えることにしました。
例えば、見出しのh2にしたいところには、「#h2」というタグをつける。すると、そのトピックの文字色が変化する、というような感じです。
マークダウンであれば「##」をつけてh2の見出しにするところを、「#h2」というタグをつけることで見出しにするわけです。
特定のタグに対して、そのトピックのスタイルを自由に定めることができるって機能なので、ただ単に文字の色を変えるだけでもいいですし、スタイルをがらっと変えてしまったりもできます。

HandyFlowyとFireFoxでの実装

「特定のタグをつけたトピックの文字を装飾する」機能は、こちらの記事を参考にさせてもらいまくりました。
#HandyFlowy タグでトピックのスタイルを変える – #WorkFlowy 関連のメモ ( #sorashima )

HandyFlowyバージョン

まず、HandyFlowy用のスクリプトはこんな感じ。

// ==UserScript==
// @name                     WorkflowyStylableTags
// @description        Gives each tag it's own css style, so you can style them with Stylish. I use Blank Canvas to manage my userscripts in Chrome.
// @author                 Nigel Thorne and LukeMT
// @include                http*://*workflowy.com/*
// @version                1.1
// ==/UserScript==



/*タグ装飾を可能にする*/
String.prototype.endsWith = function(suffix) {
suffix.length) !== -1;
};

var customClasses = function(index, old){
        var classes = old.split(" ");
        var custom = [];
        for( i = 0; i < classes.length; i++){
                if(classes[i].endsWith("-proj")){ custom.push(classes[i]);};
        };
        return custom.join(" ");
}

var StylableTagsCounter = 1;
setInterval(function(){
        StylableTagsCounter ++;
        if( StylableTagsCounter >= 3){
                $('.project').removeClass(customClasses);
                $('.pageContainer').removeClass(customClasses);
                StylableTagsCounter = 0;
        }
        $('span > .contentTagText').map( function(){
                var x = $(this).text();
                $(this).parent('.contentTag').parent().parent().parent().addClass(x+"-proj");}
        );
},1000);


/*装飾可能にするタグを指定し、どんな装飾をほどこすのかを定める。着脱式になってます。*/
\";position: absolute;left: 0px;width: 40px;color:#31B404;height: 0;line-height: 1.0;padding-top:1.5px;font-size:16px;}.contentTag[title=\"Filter #l\"]{font-size:10px;font-weight:100;background-color:white;color:white;}.contentTag[title=\"Filter @l\"]{font-size:10px;font-weight:100;background-color:white;color:white;}.project.o-proj>.name>.content {color: #AEB404;}.project.o-proj>.name>.content :before{content: \"1. \";position: absolute;left: 0px;width: 40px;color:#AEB404;height: 0;line-height: 1.0;padding-top:3px;font-size:16px;}.contentTag[title=\"Filter #o\"]{font-size:10px;font-weight:100;background-color:white;color:white;}.contentTag[title=\"Filter @o\"]{font-size:10px;font-weight:100;background-color:white;color:white;}.project.b-proj>.name>.content {color: #A4A4A4;}.project.b-proj>.name>.content :before{content: \"> \";position: absolute;left: 0px;width: 40px;color:#A4A4A4;height: 0;line-height: 1.0;padding-top:1.5px;font-size:16px;}.contentTag[title=\"Filter #b\"]{font-size:10px;font-weight:100;background-color:white;color:white;}.contentTag[title=\"Filter @b\"]{font-size:10px;font-weight:100;background-color:white;color:white;}";document.body.appendChild(e);}"

このスクリプトは、大きく分けて二段階になっています。
前半部分が、「タグ装飾を可能にする」ためのもの。後半部分が、「装飾可能にするタグを指定し、どんな装飾をほどこすのかを定める」ためのもの。
後半部分をいじってもらえれば、自分の好きなスタイルを作ることが可能です。
例えば、「#h2」タグをつけたトピックの装飾を決めているのが、コード内の以下の部分。
.project.h2-proj>.name>.content {color: blue;font-weight: bold;font-size: 20px;padding-left:0px;}
これは、
.project.タグ名-proj>.name>.content {どんな装飾をほどこすか}
という形式になっています。
つまり、「「#h2」タグがついているトピックの文字の色を青にし(color: blue;)、文字を太くし(font-weight: bold;)、文字の大きさを20pxにし(font-size: 20px;)、左の余白を0にする(padding-left:0px;)」という指示になります。
ってな感じで、「見出し」「リスト」「番号付きリスト」「引用」のためのタグを設定しています。
以下のような指示のコードを書いています。

  • 各種見出し
    • 「#h2」「#h3」「#h4」をつければ青色に装飾&文頭に「##」をつける&タグの色を白にして見えないように
  • リスト
    • 「#l」をつければ緑色に装飾&文頭に「- 」をつける&タグの色を白にして見えないように
  • 番号付き見出し
    • 「#o」をつければ緑色に装飾&文頭に「1. 」をつける&タグの色を白にして見えないように
  • 引用
    • 「#b」をつければ灰色に装飾&文頭に「> 」をつける&タグの色を白にして見えないように

その結果、こんな見かけになります。

推敲するときはブログの表示に似せたスタイルを適用します。上記拡張スクリプトとは別途、作成しました。スタイルを切り替えて適用するだけで、見かけはこんな風に変わります。

スタイル切り替えるだけでいける、ってところがうれしい。

FireFoxバージョン

PCでは、少し手間がかかります。
FireFoxのアドオンとして、「Stylish」に加えて「Tampermonkey • Firefox」というのをインストールする必要があるからです。
どちらも、拡張機能から入手可能です。
TemperMonkeyが「タグ装飾を可能に」してくれて、Stylishによって「装飾可能にするタグを指定し、どんな装飾をほどこすのかを定める」わけなのです。

TemperMonkeyをインストールしてもらって、「新規スクリプトを追加」を選び、以下のコードをコピペしていただければオッケーです。ただ、あくまでも自己責任でお願いします。

// ==UserScript==
// @name                     WorkflowyStylableTags2
// @description        Gives each tag it's own css style, so you can style them with Stylish. I use Blank Canvas to manage my userscripts in Chrome.
// @author                 Nigel Thorne and LukeMT
// @include                http*://*workflowy.com/*
// @version                1.1
// ==/UserScript==



String.prototype.endsWith = function(suffix) {
suffix.length) !== -1;
};

var customClasses = function(index, old){
        var classes = old.split(" ");
        var custom = [];
        for( i = 0; i < classes.length; i++){
                if(classes[i].endsWith("-proj")){ custom.push(classes[i]);}
        }
        return custom.join(" ");
};

var StylableTagsCounter = 1;
setInterval(function(){
        StylableTagsCounter ++;
        if( StylableTagsCounter >= 3){
                $('.project').removeClass(customClasses);
                $('.pageContainer').removeClass(customClasses);
                StylableTagsCounter = 0;
        }
        $('span > .contentTagText').map( function(){
                var x = $(this).text();
                $(this).parent('.contentTag').parent().parent().parent().addClass(x+"-proj");}
        );
},1000);

で、Stylishにて、タグを指定してそのトピックのスタイルを書き換えます。書き換えのコードは、HandyFlowyのときに説明したようにすると、自分の好きなように装飾することができます。
少し長くなりますが、全容を載せます。

/*h1の見出しのスタイルを調整*/
.project.h1-proj>.name>.content {
        color: black;
        font-weight: bold;
        font-size: 23px;
        /*padding-left:20px;*/
}

/*h1タグのスタイル*/
.contentTag[title="Filter #h1"]{
        font-size:10px;
        font-weight:100;
        background-color:#BDBDBD;
        color:white;
}
.contentTag[title="Filter @h1"]{
        font-size:10px;
        font-weight:100;
        background-color:#BDBDBD;
        color:white;
}


/*h2の見出しのスタイルを調整*/
.project.h2-proj>.name>.content {
        color: blue;
        //font-weight: bold;
        //font-size: 20px;
        padding-left:0px;
}
.project.h2-proj>.name>.content :before{
        content: "##";
        position: absolute;
        left: 0px;
        width: 40px;
        height: 0;
        font-size: 16px;
        //font-weight:bold;
        line-height: 1.0;
        color: blue;
        padding-top:2px;

}

/*h2タグのスタイル*/
.contentTag[title="Filter #h2"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @h2"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}

/*h3の見出しのスタイルを調整*/
.project.h3-proj>.name>.content {
        color: royalblue;
        //font-weight: bold;
        font-size: 16px;
        //padding-left:10px;
}
.project.h3-proj>.name>.content :before{
        content: "###";
        position: absolute;
        left: 0px;
        width: 40px;
        height: 0;
        font-size: 16px;
        line-height: 1.0;
        color: royalblue;
        padding-top:2px;
        //font-weight:bold;
}
/*h3のタグのスタイルを調整*/
.contentTag[title="Filter #h3"]{
        font-size:16px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @h3"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
/*h4の見出しのスタイルを調整*/
.project.h4-proj>.name>.content {
        //font-weight: bold;
        color: cornflowerblue;
        //padding-left:38px;
}
.project.h4-proj>.name>.content :before{
        content: "####";
        position: absolute;
        left: 0px;
        width: 40px;
        color:cornflowerblue;
        height: 0;
        line-height: 1.0;
        padding-top:2px;
        font-size:16px;
        //font-weight:bold;
        padding-top:2px;
}
/*h4のタグのスタイルを調整*/
.contentTag[title="Filter #h4"]{
        font-size:20px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @h4"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}

/*リストの見出しのスタイルを調整*/
.project.l-proj>.name>.content {
        color: #31B404;
        //padding-left:13px;
}
.project.l-proj>.name>.content :before{
";
        position: absolute;
        left: 0px;
        width: 40px;
        color:#31B404;
        height: 0;
        line-height: 1.0;
        padding-top:1.5px;
        font-size:16px;
}
.contentTag[title="Filter #l"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @l"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}

/*リスト(番号)のスタイルを調整*/
.project.o-proj>.name>.content {
        color: #AEB404;
        //padding-left:13px;
}
.project.o-proj>.name>.content :before{
        content: "1. ";
        position: absolute;
        left: 0px;
        width: 40px;
        color:#AEB404;
        height: 0;
        line-height: 1.0;
        padding-top:3px;
        font-size:16px;
}
.contentTag[title="Filter #o"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @o"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}

/*引用のスタイルを調整*/
.project.b-proj>.name>.content {
        color: #A4A4A4;
        //padding-left:13px;
}
.project.b-proj>.name>.content :before{
        content: "> ";
        position: absolute;
        left: 0px;
        width: 40px;
        color:#A4A4A4;
        height: 0;
        line-height: 1.0;
        padding-top:1.5px;
        font-size:16px;
}
.contentTag[title="Filter #b"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.contentTag[title="Filter @b"]{
        font-size:10px;
        font-weight:100;
        //background-color:#BDBDBD;
        background-color:white;
        color:white;
}
.bullet{background-image:none;}

.bullet{background-image:none;}
    .project.open>.name>.bullet{border:1px silver solid;border-radius:3px;}
    .bullet,#bulletBucket .bulletBucketBullet{background:silver;border-radius:3px;}

これで、書くとき用のシンプルなシンタックスハイライトが実装されます。

タグのルールは上記HandyFlowyと一緒です。
で、自分用には推敲用のブログの見かけと同一になる装飾のスタイルも作成しちゃいました。

FireFoxでも、両方を切り替えながら書くことができ、とても、とてもいい感じです。
重ね重ね言いますが、どうか自己責任でお願いします。

このルールで色を変えることができるのは、「タグをつけたトピックを装飾する」という性質上、「見出し」と「リスト」と「番号付きリスト」と「引用」のみ。文章中の一部を「太字」や「イタリック」に装飾し、そこだけ色を変える、なんてことはできません。
また、タグを書く位置は、文頭に。じゃないと表示がうまくいかないようになってます。
文中ならどこでもいいっちゃいいのですが、あとあとのエクスポートのときを考えているのと、マークダウンは基本文頭に記号を書くこと。また、WorkFlowyでは、カーソルを移動させてる時にトピックをまたぐと、カーソルはかならず文頭に行く、ってことから、文頭に書くというルールにしました。

おわりに

公開しているのはシンプルなシンタックスハイライトのほうだけですが、自分用にはPCとHandyFlowyの両方に、執筆用と推敲用の二つのスタイルを作りました。これで、PCでもiPhoneでも書けるし、推敲できるようになったわけです。
一応どっちも用意してるだけで、基本的な流れは、PCにて「執筆用」で書き始め、書き進め、マークダウンタグで見出しとか定め、仕上げに近いところまでもっていきます。
そしてPCかiPhoneのどっちかの「推敲用」で、ブログと同じ見かけに表示させて、読み返し、細かい修正を加える、という感じ。
ブログにアップするためには、WorkFlowyでつけた「#h2」とかのタグを、「##」やら「<h2>」やらに書き換えなければいけないのですが、そのへんをスムーズにいくようにするのが、今後の課題です。

おそらく、技術的な部分では説明不足なエントリとなってしまったかもしれませんが、自分自身コードを書く技術に乏しいので、勘弁してやってください。

では、お読みいただきありがとうございました。