2014年5月30日金曜日

TiddlyWikiのMarkdownプラグイン

PluginMarkdown

TiddlyWiki ClassicMarkdown記法が使えるプラグインを作りました。

( 追記:Dec 22, 2014
  現在は最新版の TiddlyWiki5 と区別するため、 TiddlyWiki Classic と呼ばれています。
  http://classic.tiddlywiki.com/ )


特長

  • Markdownパーサに、GitHub Flavored Markdownに対応したMarked.jsを使用。
  • コードブロックのシンタックスハイライト機能。(google-code-prettify
  • オンライン使用ならば、このプラグインのインストールだけですぐに使えます。もちろんオフライン使用も可能です。


インストール

http://babooshka.tiddlyspot.com/からインポートできない場合は手動でプラグインtiddlerを作成してください。

プラグインtiddlerの作成手順

新規tiddlerを以下の内容で作成します。

tiddlerタイトル

PluginMarkdown

tiddler本文

ここに、文末のcode:PluginMarkdownの内容をコピーして貼り付けます。

tiddlerタグ

systemConfig

tiddlerを保存して、ブラウザのページを再読み込みすればインストール完了です。



使い方

Markdown記法で書くときは本文を<md>...</md>タグで囲むだけです。

このように書くと

<md>
This is an h1 header
====================

Unordered list
--------------

* Item one 
* Item two
  * Item A
  * Item B

code blocks
-----------

```
loadStylesheet : function(src) {
    var MdStyleSheet = document.createElement( 'link' );
    MdStyleSheet.type = 'text/css';
    MdStyleSheet.rel = 'stylesheet';
    MdStyleSheet.href = src;
    document.getElementsByTagName( 'head' )[0].appendChild( MdStyleSheet );
},
```

teble
-----

|Left align  |Center align  |Right align
|:-----------|:------------:|-------------:
|0001        |apple         |1234
|0002        |`Strawberry`  |56789

</md>

このように表示されます。



tiddlyspot.comで確認できます

http://babooshka.tiddlyspot.com/#Pluginsの「Markdown sample text」にMarkdownサンプルを用意しましたのでご覧ください。

追記:Jul 07, 2016
その後の改良版は icm7216.github.io/MyTiddlyWiki/#PluginMarkdown に置いています。 Markdown 内の TiddlyLink に対応しました。 icm7216.github.io/MyTiddlyWiki/ - TiddlyLink



オフライン使用の場合

TiddlyWikiはオフラインで使えるWikiです。もちろんこのプラグインもオフラインで使用できます。

オフラインで使用するには次の3つのファイルが必要になります。marked.js prettify.js prettify.css


setp1

以下のリンクから marked と google-code-prettify をダウンロードして展開します。展開には7-ZipLhaplusなどを使用します。

marked.js

prettify.js, prettify.css

これらのファイルを 使用するTiddlyWikiの直下のフォルダに展開してください

TiddlyWiki/
    memo.html           <== your TiddlyWiki file
    marked-master/
        lib/
            marked.js
    google-code-prettify/
        prettify.js
        prettify.css

step2

PluginMarkdownのコードを修正してローカルファイルのフォルダを指定します。

Code内の「online use」項目をコメントアウトし、「offline use」項目のコメントを取り除きます。

このように変更します

// ## Online use ##
//scriptMarked : "https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js",
//scriptPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.js",
//cssPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css",

// ## Offline use ##
scriptMarked : "marked-master/lib/marked.js",
scriptPrettify : "google-code-prettify/prettify.js",
cssPrettify : "google-code-prettify/prettify.css",

step3

TiddlyWikiを保存後に、ページを再読み込みすれば完了です。



code:PluginMarkdown

動作確認はWindows7 Firefox 29.0.1 で行いましたが、その他の環境では未確認です。

/***
|''Name''|PluginMarkdown|
|''Description''|Allows to use MarkDown syntax and syntax highlight in a tiddler|
|''Author''|babooshka|
|''Version''|1.0.6|
|''date''|Aug 27, 2014|
|''Requires''|https://raw.github.com/chjj/marked/master/lib/marked.js <br> https://google-code-prettify.googlecode.com/svn/loader/prettify.js|
|''License''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion''|2.8.1|
|''Type''|plugin|

!! 変更履歴
!!! 1.0.6 Aug 27, 2014
* font-sizeを調整。
!!! 1.0.5 May 22, 2014
* シンタックスハイライトをhighlightのコールバックで行うため、prettyPrintOneに変更。これに合わせてcssを修正。Marked.jsのCDNJSを0.3.2に変更。
!!! 1.0.4 Apr 06, 2014
* Marked.jsのCDNJSを0.3.1に変更。
!!! 1.0.3 Dec 01, 2013
* prettify.jsをCDNJS[[prettify - cdnjs|http://cdnjs.com/libraries/prettify/]]に変更。 
!!! 1.0.2 Nov 22, 2013
* headerのstyleを修正。
!!! 1.0.1 Nov 07, 2013
* Marked.jsをCDNJSに変更。[[marked - cdnjs|http://cdnjs.com/libraries/marked/]]
!!! 1.0.0 Nov 07, 2013
* オリジナルの[[ShowDown|http://showdown.tiddlyspace.com/]]を元に作成。
  オリジナルからの変更内容
    MarkdownのパーサーをGFMに対応できる[[marked.js|https://github.com/chjj/marked/tree/master/]]へ変更。
    シンタックスハイライト[[google-code-prettify|http://code.google.com/p/google-code-prettify/downloads/list]]を追加。

プラグイン内にMarkdown用cssを含んでいるため、Markdown用のスタイルシートtiddlerを個別に作らなくて済みます。 オンライン使用の場合は、このプラグインをインストールするだけで使えます。

ここに、参考にしたオリジナルのクレジットを記載します。
<<<
credit of original author
|''Name''|ShowDown|
|''Description''|Allows to use MarkDown syntax in a tiddler|
|''Documentation''|http://tobibeer.tiddlyspace.com/#ShowDown|
|''Author''|Tobias Beer|
|''Contributions''|Mario Pietsch, Paul Downey|
|''Version''|0.9.1|
|''Requires''|https://raw.github.com/tobibeer/TiddlyWikiPlugins/master/resources/ShowDown/ShowDown.js|
|''Source''|https://raw.github.com/tobibeer/TiddlyWikiPlugins/master/plugins/ShowDown.js|
|''License''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion''|2.5.3|
|''Type''|plugin|
<<<


-----


!Description
* allows to write in the [[GFM|https://help.github.com/articles/github-flavored-markdown]] notation.
* allows to [[syntax highlighting|http://code.google.com/p/google-code-prettify/]] of source code snippets for {{{<pre>}}} code blocks.<br>This plugin adds a new formatter for {{{<pre class='prettyprint linenums'>}}} within the Markdown contents. 

!Usage
* [[Markdown|http://daringfireball.net/projects/markdown/syntax]] contents wrapped in a {{{<md>...</md>}}} tag. These contents are converted into a tiddler text wrapped in a {{{<html>-</html>}}} tag.

For example
{{{
<md>
This is an h1 header
====================

Unordered list
--------------

* Item one 
* Item two
  * Item A
  * Item B

code blocks
-----------

```
loadStylesheet : function(src) {
    var MdStyleSheet = document.createElement( 'link' );
    MdStyleSheet.type = 'text/css';
    MdStyleSheet.rel = 'stylesheet';
    MdStyleSheet.href = src;
    document.getElementsByTagName( 'head' )[0].appendChild( MdStyleSheet );
},
```

teble
-----

|Left align  |Center align  |Right align
|:-----------|:------------:|-------------:
|0001        |apple         |1234
|0002        |`Strawberry`  |56789

</md>
}}}

Displays as:
<md>
This is an h1 header
====================

Unordered list
--------------

* Item one 
* Item two
  * Item A
  * Item B

code blocks
-----------

```
loadStylesheet : function(src) {
    var MdStyleSheet = document.createElement( 'link' );
    MdStyleSheet.type = 'text/css';
    MdStyleSheet.rel = 'stylesheet';
    MdStyleSheet.href = src;
    document.getElementsByTagName( 'head' )[0].appendChild( MdStyleSheet );
},
```

teble
-----

|Left align  |Center align  |Right align
|:-----------|:------------:|-------------:
|0001        |apple         |1234
|0002        |`Strawberry`  |56789

</md>


!When using local installation.
If you want to offline use. You need to install "marked.js" and "prettify.js", "prettify.css" in your PC.

!!How to local installation

setp1.
Download and install marked and google-code-prettify zip files. and then extract files using any extract tool. For example, [[7-Zip|http://www.7-zip.org/]], [[Lhaplus|http://www.forest.impress.co.jp/library/software/lhaplus/]], etc.

Download marked.js from here
* [[marked-master.zip|https://github.com/chjj/marked/tree/master/]]

Download prettify.js and prettify.css from here
* [[prettify-small-4-Mar-2013.tar.bz2|http://code.google.com/p/google-code-prettify/downloads/list]]

These files should be installed under the directory of TiddlyWiki.

like this
{{{
TiddlyWiki/
    memo.html           <== your TiddlyWiki file
    marked-master/
        lib/
            marked.js
    google-code-prettify/
        prettify.js
        prettify.css
}}}


step2.
Edit the code to specify the local file directory.
* Add comment mark {{{"//"}}} within an "online use" section.
* Remove comment mark {{{"//"}}} within an "offline use" section.
Fix this part of the code. like this
{{{
// ## Online use ##
//scriptMarked : "https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js",
//scriptPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.js",
//cssPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css",

// ## Offline use ##
scriptMarked : "marked-master/lib/marked.js",
scriptPrettify : "google-code-prettify/prettify.js",
cssPrettify : "google-code-prettify/prettify.css",
}}}


step3.
Save the TiddlyWiki. Reload the TiddlyWiki browser window.





!Code
***/
//{{{
if(!version.extensions.PluginMarkdown) {
    version.extensions.PluginMarkdown = { installed: true };

    config.extensions.PluginMarkdown = {

        // ## Online use ##
        scriptMarked : "https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js",
        scriptPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.js",
        cssPrettify : "https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css",

        // ## Offline use ##
        //scriptMarked : "marked-master/lib/marked.js",
        //scriptPrettify : "google-code-prettify/prettify.js",
        //cssPrettify : "google-code-prettify/prettify.css",

        // ## custom StyleSheet ##
        MyStyleSheet : { text:
                      '/*{{{*/\n'
                      +'.viewer .MarkdownBody {\n'
                      +'    background-color : rgb(251, 251, 251);\n'
                      +'    border: 1px solid rgb(200, 200, 200);\n'
                      +'    padding : 1em;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody h1,\n'
                      +'.viewer .MarkdownBody h2,\n'
                      +'.viewer .MarkdownBody h3,\n'
                      +'.viewer .MarkdownBody h4,\n'
                      +'.viewer .MarkdownBody h5,\n'
                      +'.viewer .MarkdownBody h6 {\n'
                      +'    font-weight: normal;\n'
                      +'    line-height: 1;\n'
                      +'    font-weight: bold;\n'
                      +'    color: rgb(20, 20, 20);\n'
                      +'    margin: 2em 0em 1em 0em;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody h1,\n'
                      +'.viewer .MarkdownBody h2,\n'
                      +'.viewer .MarkdownBody h3 {\n'
                      +'    border-bottom:1px solid rgb(190, 190, 190);\n'
                      +'}\n'
                      +'.viewer .MarkdownBody h1 { font-size: 2.5em; }\n'
                      +'.viewer .MarkdownBody h2 { font-size: 2.0em; }\n'
                      +'.viewer .MarkdownBody h3 { font-size: 1.5em; }\n'
                      +'.viewer .MarkdownBody h4 { font-size: 1.2em; }\n'
                      +'.viewer .MarkdownBody h5 { font-size: 1.0em; }\n'
                      +'.viewer .MarkdownBody h6 { font-size: 0.9em; }\n'
                      +'.viewer .MarkdownBody pre.prettyprint {\n'
                      +'    border-radius: 3px;\n'
                      +'    border: 1px solid rgb(200, 200, 200);\n'
                      +'    background-color: rgb(245, 245, 245);\n'
                      +'    padding: 0px;\n'
                      +'    margin: 1em;\n'
                      +'}\n'                      
                      +'.viewer .MarkdownBody code {\n'
                      +'    border-radius: 3px;\n'
                      +'    border: 1px solid rgb(180, 180, 180);\n'
                      +'    background-color: rgb(240, 240, 240);\n'
                      +'    margin: 0px 2px;\n'
                      +'    padding: 0px 5px;\n'
                      +'    color: rgb(10, 10, 10);\n'
                      +'    font-size: 0.9em;\n'
                      +'    line-height: 1.4em;\n'
                      +'    display: inline-block;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody code.prettyprint {\n'
                      +'    border-radius: 0px;\n'
                      +'    border: none;\n'
                      +'    background-color: rgb(245, 245, 245);\n'
                      +'    box-shadow: 38px 0px 0px rgb(251, 251, 251) inset, 40px 0px 0px rgb(230, 230, 230) inset;\n'
                      +'    display: block;\n'
                      +'    margin: 0px 0px 0px 0px;\n'
                      +'    padding: 0px 0px 0px 0px;\n'
                      +'    font-family: Consolas, "DejaVu Sans Mono", "メイリオ", verdana, monospace;\n'
                      +'    font-size: 0.9em;\n'
                      +'    line-height: 1.4em;\n'
                      +'    white-space:pre;\n'
                      +'    word-wrap: normal;\n'
                      +'    overflow: auto;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody ol.linenums {\n'
                      +'    background-color: transparent;\n'
                      +'    color: rgb(160, 160, 160);\n'
                      +'    margin: 5px 0px -10px 0px;\n'
                      +'    padding: 0px 0px 0px 40px;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody ol.linenums li {\n'
                      +'    list-style-type: decimal;\n'
                      +'    padding-left: 5px;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody table {\n'
                      +'    border: 1px solid rgb(220, 220, 220);\n'
                      +'    border-collapse: collapse;\n'
                      +'    border-spacing: 0px;\n'
                      +'}\n'
                      +'.viewer .MarkdownBody table tr {\n'
                      +'    background-color: rgb(255, 255, 255);\n'
                      +'}\n'
                      +'.viewer .MarkdownBody table tr:nth-child(2n+1) {\n'
                      +'    background-color: rgb(245, 245, 245);\n'
                      +'}\n'
                      +'.viewer .MarkdownBody table th,\n'
                      +'.viewer .MarkdownBody table td {\n'
                      +'    border: 1px solid rgb(220, 220, 220);\n'
                      +'    padding: 0.1em 1em;\n'
                      +'    color: rgb(0, 0, 0);\n'
                      +'}\n'
                      +'.viewer .MarkdownBody table th {\n'
                      +'    background-color: rgb(255, 255, 255);\n'
                      +'    font-weight: bold;\n'
                      +'}\n'
                      +'/*}}}*/\n'
        },

        loadScript: function(src, callback) {
            var elem = document.createElement('script');
            elem.type = 'text/javascript';
            elem.src = src;
            document.getElementsByTagName('head')[0].appendChild(elem);

            if ( callback && typeof(callback) === 'function' ) {
                if ( document.addEventListener ) { 
                    elem.addEventListener('load', callback, false);
                } else {
                    elem.onreadystatechange = function() { //IE8
                        if ( elem.readyState in {complete: 1, loaded: 1 }) {
                            elem.onreadystatechange = null;
                            callback();
                        }
                    };
                }
            }
        },

        install: function() {
            var _PluginMarkdown = config.extensions.PluginMarkdown;

            // ## load marked and Options settings ##
            _PluginMarkdown.loadScript( _PluginMarkdown.scriptMarked, function() {
                marked.setOptions({
                    gfm: true,
                    tables: true,
                    breaks: false,
                    pedantic: false,
                    sanitize: false,
                    smartLists: true,
                    smartypants: false,
                    langPrefix: 'lang-',

                    // ## highlighting with google-code-prettify ##
                    highlight: function(code, lang) {
                        var htmltext = String(code)
                            .replace(/&/g, '&amp;')
                            .replace(/</g, '&lt;')
                            .replace(/>/g, '&gt;')
                            .replace(/"/g, '&quot;')
                            .replace(/'/g, '&#39;');
                        return prettyPrintOne(htmltext, lang, true)
                    }
                });
            });

            // ## load Prettify script and css ##
            _PluginMarkdown.loadScript( _PluginMarkdown.scriptPrettify );
            var elecss = document.createElement( 'link' );
            elecss.type = 'text/css';
            elecss.rel = 'stylesheet';
            elecss.href = _PluginMarkdown.cssPrettify;
            document.getElementsByTagName( 'head' )[0].appendChild( elecss );

            // ## set custom css ##
            setStylesheet( _PluginMarkdown.MyStyleSheet.text, 'PluginMarkdown' );
        }
    };

    config.formatters.push({

        name: "PluginMarkdown",
        match: "<[Mm][Dd]>",
        lookaheadRegExp: /<[Mm][Dd]>((?:.|\n)*?)<\/[Mm][Dd]>/mg,

        handler: function(w) {
            this.lookaheadRegExp.lastIndex = w.matchStart;
            var match = this.lookaheadRegExp.exec( w.source );

            if ( match && match.index == w.matchStart ) {
                var t = marked( match[1] );
                var html = '<html>' + t + '</html>'
                var e = createTiddlyElement( w.output, 'div', null, 'MarkdownBody' );
                wikify( html, e );

                // ## syntax highlighting and linenums ## 
                addClass( '.MarkdownBody pre', 'prettyprint linenums' );
                addClass( '.MarkdownBody pre code', 'prettyprint linenums' );
                w.nextMatch = this.lookaheadRegExp.lastIndex;                          
            }
        }
    });

    config.extensions.PluginMarkdown.install();
}
//}}}

0 件のコメント :