Markdown

静的サイトジェネレータでテンプレート言語のコードを記述する場合のエラー対処方法

HexoでGenerateに失敗しまくった

このブログはHexoで作成していますが、ある時、Generateの際にやたらと失敗続きになることがありました。

消したり戻したりしながら原因を特定した結果、Codeblock内の一部記述が問題であることが分かりました。

具体的には、とりあえず画像で示しますが、AppleScriptの以下の部分。

AppleScript

そして、Jekyll templateの以下の部分です。

html

どうも、{}(BRACE/CURLY BRACKET)が重なっていたり、%と絡んでいる部分が引っかかる模様。

MarkdownにおけるInine code/Codeblock/Fenced codeblock全てで同様の問題が発生します。エラーが出ない場合でも、Codeの内容が空になったり。

どこでエラーが発生しているのか?

ここで、静的サイトジェネレータを利用したコンテンツ生成フローは、以下のようになっています。

静的サイトジェネレータによるコンテンツ生成フロー1

例えばインラインコードの記述を例に取るなら、まあ内容は適当ですが、以下のような順序でコンテンツが生成されます。

静的サイトジェネレータによるコンテンツ生成フロー2

どうやら、問題が起こっているのはテンプレートエンジンによる処理の部分。Hexoで利用されているテンプレートエンジンであるSwigのシンタックスとかぶるため、Swigで処理しようとしているようです。

うん、まず、<code>内をテンプレートエンジンで処理しようとするのバカなの死ぬのと言いたいのはやまやまなのですが、そうなるものは仕方ない。

となると、テンプレートエンジンに渡すデータ内で、Code部分がエスケープしてあればいいということになります。

Markdownパーサにおける特殊文字エスケープ

ここで、Markdownパーサにおける特殊文字エスケープ方法を確認してみましょう。

HTMLでは、特別な考慮を要する文字が2つあります: < と & がそれです。小なり記号はタグを書き出すのに使用しますし、アンパサンドはHTMLエンティティを示すのに使います。もしこれらの文字をそのものとして使いたければ、それぞれ< と & とHTMLエンティティの形式にエスケープ処理を施す必要があります。

Markdownはあなたの代わりに必要なエスケープ処理を実施することで、これらの文字をそのままのかたちで使用できるようにしてくれます。もしあなたがアンパサンドをHTMLエンティティの宣言のために使用している場合はそれはそのまま変換されずに置かれます。それ以外の場合には& に変換されます。

Gruber wrote a Perl script, Markdown.pl, which converts marked-up text input to valid, well-formed XHTML or HTML and replaces left-pointing angle brackets (‘<’) and ampersands with their corresponding character entity references.

ジョン・グルーバーによる「元祖Markdownパーサ」であるmarkdown.plは、<,>,&を自動的にエンティティに置き換えてエスケープします。そして、その他の特殊文字については\による手動エスケープが可能(必要)なわけです。

これはHexoでも同様で、CURLY BRACKETをBACKSLASHで/{のようにエスケープできます。(なお、ドキュメントは見付からなかったが、Hexo公式サイトトップページを見ると、たぶんGitHub Flavored Markdownに基づくパースを行っている)

1
\{% for page in site.pages %\}

しかし、Code部分でこの方法を使うと、\自体がブラウザで出力されてしまいます。上記の記述例自体がまさにそうです。

うん、Markdownパーサ、キミは悪くないそれで正しい。しかし解決には結びつかない。

HTMLエンティティによるエスケープ

ならば、HTMLエンティティ(実体参照)に置き換えたらどうか。例えば、{,}のエンティティは&#123;, &#125;ですから、以下のように記述できます。

1
&#123;% for page in site.pages %&#125;

ところが、これはCode部分ではうまく働かない場合があります。そう、&自体が自動的にエンティティに置き換えられるためです。

つまりこうです。

静的サイトジェネレータによるコンテンツ生成フロー3

ほん!とに!ややこしいなもう!

ということは、アレか。ここの処理でMarkdownパーサ挟まなければいいのか。

HTMLエンティティにエンコードし、さらに<code>,<pre>を直接記述する

結論として。

MarkdownにおけるInine code/Codeblock(Fenced codeblock)の代わりに、<code>/<pre><code>を使用し、さらにHTMLエンティティに置き換えた場合、正常に記号が表示されました。

つまり、以下のような記述です。

1
<code>&#123;% for page in site.pages %&#125;</code>

ただし、これだと静的サイトジェネレータのシンタックスハイライト機能を活かせません。

外部ソース(Gist)でEmbed

これはMarkdownパーサ由来の問題ですから、Codeblock/Fenced codeblockの場合、コード本体を外部に置いて参照する方法もあります。

自分の手が加わっているコードなら、Private GistにしてEmbedするのが、比較的楽でシンタックスハイライトも利きます。

自分の手が一切加わってないコードの場合、Gistで管理するのも抵抗がある、というか邪魔なので、おとなしく<pre><code>するほうがいいと思われます。

まとめ

  • テンプレートエンジンに渡すソースに、テンプレート言語と解釈できる部分があると、処理されてしまう
    • Codeとして記述しても無意味
  • HTMLエンティティによるエスケープは有効
    • ただし、その前にMarkdownパーサで処理するとそのままテンプレートエンジンに渡せない場合がある
  • Markdownソース内で<code>タグを利用することで、HTMLエンティティによってエスケープしたコードをそのままテンプレートエンジンに渡すことができる
  • 外部ソースからのEmbedは極めて有効

無料Markdownプレビューアプリ「Marko」でFoldingTextからプレビューしてみた

Marked 買いたくないねん!

この世の中にはMarkdownドキュメントを書くときプレビュー派と生派がいるのですが、私は後者のシンタックスハイライト分派です。

Markdownというのはソースのままでも読みやすいようにうんぬんかんぬんというのもあるのですが、それよりプレビューとソースの間で首振りながら執筆ってシャビかと思うので。

しかし、たまーにはプレビューしたいときもあります。特にHTMLタグ直書きしなきゃいけないとき。しかしたまーにしかないので、そのためにMarked買いたくないのです。というかこの手のアプリに課金することが何かに負けたように感じる。

Markoあった!


ver. 1.2 - 無料( 仕事効率化 )
TXTLABS

無料で似たようなことできるやつおらんのかと思ったらおった。

こいつでMarkdownファイル開くとプレビューしてくれて、HTMLとかで保存もできる模様。

FoldingTextからAlfred Workflowで開いてみた

上記ページにあるFoldingText Workflowのうち、ft:markedを書き換えたら普通に動きました。


property pTitle : "Open FoldingText file in Marked"
property pVer : "0.02"
property pAuthor : "Robin Trew"

property pblnPositionWindows : true -- Set this to false to disable the window positioning at the end of the script

on alfred_script(q)
    tell application "FoldingText"
        set lstDocs to documents
        if lstDocs = {} then return
        set {strName, oFile} to {name, file} of item 1 of lstDocs
        activate
        if oFile is missing value then
            display dialog "The document: " & return & return & strName & ¬
                return & return & "needs to be saved before Marked can preview it." buttons {"OK"} ¬
                default button "OK" with title pTitle & "  ver. " & pVer
            return
        end if
    end tell

    ---- Marked
    tell application "Marko.app"
        activate
        open oFile
    end tell

    -- Try to position windows left and right (to disable this, if it doesn't suit your workflow or your screen setup,
    -- set pblnPositionWindows at the top of the script to false )
    if pblnPositionWindows then
        set lngWidth to (do shell script "system_profiler SPDisplaysDataType | awk '/Resolution/{print $2}'")
        set lngHeight to (do shell script "system_profiler SPDisplaysDataType | awk '/Resolution/{print $4}'")
        set lngHalf to lngWidth / 2
        set lngHeight to lngHeight - 22

        tell application id "sevs"
            tell process "Marko" to tell window 1 to set {position, size} to {{lngHalf, 22}, {lngHalf, lngHeight}}
            tell process "FoldingText" to tell window 1 to set {position, size} to {{0, 22}, {lngHalf, lngHeight}}
        end tell
    end if
end alfred_script

カレントファイルをMarkoで開いた後、ウインドウの左半分にFoldingText、右半分にMarkoを配置します。要はAppleScriptからカレントファイルを取得して渡しているだけですね。

なお、下記のスクリプトも見つけましたが、古いのか、ウインドウ移動ができないようです。(Mac OS X 10.9.3)

色んなエディタでMarkedでプレビューするよ系のスクリプトが公開されてますが、全部置き換えられるんじゃないでしょうか。

なおMarkedはこちら。


ver. 2.4 (846) - ¥1,400( 仕事効率化 )
Brett Terpstra

Markdownドキュメントを一番簡単に公開できるのはCloudAppだったかも

いきなりだけどやってみた

早く言えシリーズ。

内容転載

参照

方法

通常のMarkdownドキュメントを記述し、CloudAppにアップロードするだけ。

公開

「Direct Link」でも「Download Link」でもなく「Link」にアクセスするとレンダリングして表示される。

使用可能な記法

レンダリングにはredcarpetが用いられる。

使用可能なフォーマットについては以下を参照。

Google検索

HTMLヘッダにはnoindexなどは含まれないため、普通に検索可能だと思われる。

ただし、descriptionなどは含まれないため、SEO的な努力はほとんどできない。

問題点

調べきれていないだけかもしれないが、CloudAppでは一度アップロードしたファイルの編集ができない。ローカルで編集して再アップロードするとURLが変わってしまう。

(追記)

やはり不可能な模様。

Ulysses III/Marked 2が提起した「Textbundle」ってなんぞ?

なんかリリースが出てたのだが。

とりあえず原文をどうにか訳してみる

異なるMarkdownアプリケーションの間で作業を行う際、いくらかの厄介事が起こりえます。よりよい未来のため、私たちはMarkedの製作者であるBrett Terpstraとの連携し、TextBundleを開発しました。

これは、「サンドボックス化」されたアプリケーション同士でMarkdownテキストをやり取りするための、新たなファイル・フォーマットです。
「サンドボックス」は、MacおよびiOSのApp Storeで利用可能な全てのアプリケーションに要求されており、これらのアプリケーションは、ユーザーに対し極めて限定されたファイルへのアクセスしか提供することができません。

この手続きは、より高度なデータセキュリティを目指したものですが、不便さをもたらすものでもあります。例えば、Markdownファイルが外部画像ファイルへの参照を含む場合、このようなファイルをMarkdownエディタからプレビューワへ送る際、ユーザは個々の画像ファイル毎に、明確なアクセス許可を与える必要があります。

TextBundleは、サンドボックス化されたアプリケーションのための、新たなデータ互換フォーマットです。それはMarkdownテキストと、全ての参照された画像を、ひとつのファイル内に同梱します。現在、TextBundleは最新バージョンのUlysses (1.2.2)およびMarked (2.3.4)でのみサポートされています。しかし、各種のMarkdownアプリケーションのユーザは、互換的な可搬性から利益を得られると考えます――そのため、私たちは他の開発者が、彼らのアプリケーションでTextBundleをサポートしてくれることを期待しています! 仕様書と詳細は、以下の専用ページで参照できます。 textbundle.org

なるほど。要するに、Markdown文書から画像(を含む外部ファイル)を参照するためのフォーマットということらしい。端々から林檎てめぇ調子こいて開発者イビってんじゃねぇぞという恨み節が聞こえる気もするが、それはとりあえず措く。

  • Announcing the Textbundle format (and Ulysses 3 giveaway) - BrettTerpstra.com

    私はUlyssesの作者であるSoulmenと共同で、アプリケーション間でプレーンテキストを運搬するための新たな標準作りに取り組んでいました。それはTextBundleと呼ばれ、私はその可能性に非常に興奮しています。私は、多くの開発者が参加してくれることを期待しています。

    TextBundleフォーマットは非常にシンプルです。プレーンテキストファイル、JSONデータファイル、そしてアセットサブフォルダを含むフォルダです。Ulyssesようなアプリは、TextBundleを書き出し、Markedに渡すことができ、全ての必要なコンポーネントが自動的にインクルードされます。画像、追加テキストファイル、そしてこれらが必要とする各種のメタデータが、サンドボックス化の制限を満たした上で。

    サンドボックス化は、第一の動機であり、TextBundleはMarkdownにおける外部ファイル参照に関する主要な問題を解消します。

    Ulysses IIIとMarked 2の間でやり取りされるバンドルは、JSONデータにおいて「一時的に」ラベリングされます。これは、Ulyssesがファイル上書きに関して自由であり、そしてMarkedが、データがいつでも書き換えられ得ることを知っていることを意味します。一時的でないファイルは、その非一時性にもかかわらず、複数の筆記アプリケーション間で仕様され得ます。これは、ファイルに保存される変更履歴、書き込み状態、そしてあらゆる種類の予期し得ないデータが、フォルダ、マシン全体、またはプラットフォーム間で移動され得ることを意味します。

    PCユーザがTextBundleを開く際には、オリジナルのMarkdownファイルに関する完全なアクセス権を持ちます。ユーザはそれを編集し、フォルダへ送り返し、再びMacにおいて単一の「TextBundle」ファイルとして表示させることができます。

    これらは将来において、多くの、非常に多くのエキサイティングな可能性を持っています。TextBundleへのサポートを実装する全てのアプリは、それらに対して役立つ情報を書き込むために、データファイル内に名前空間のセクションを持つことができます。その他のアプリもまた、これらの情報にアクセスし、また適切に行動することができます。

こっちはだいぶブロークンで訳しづらい……。しかし、TextBundleフォーマットが、ユーザが意図的に保存するというより、アプリケーション連携によって自動生成されるっぽいというのは優位な情報だろうか。

実際どうなん?

Web公開を前提とする文書の作成に際しては、これはそれほど重要ではないと思う。

一方で、公開を前提としない個人的な文書、具体的には小説のキャラ設定とかを書くに当たっては、かなり有効なものになるかもしれない。

しかしね、君らね、その今あるフォーマットがイケてないから独自フォーマット作りますフォローミーって姿勢はどうなの。前から思ってたけど、Markdownフォーマットすら守る気ないのはさすがにどうかと思うよ。リンクは[]()形式にしようや、なあ。

Ulyssese 3での基本的な画像ファイルの挿入方法

まず、Ulyssesではライブラリ外部ソースが区別される。

ライブラリにおいては、全てのシート(文書)は統合され、各々にファイルとして扱われることはない。ライブラリは、「このMac」「iCloud(他のMacと同期)」「Daedalus Touch(iOSアプリと同期)」に分かれる。

外部ソースとは、要するにローカルストレージ内のファイル・フォルダを指す。Dropbox等の同期フォルダを指定することもできる。

外部ソースのシートにイメージを挿入する場合、それはURLをソースとする。つまり、Web公開された画像しか挿入することができない。画像ファイルをドラッグアンドドロップした場合、ファイルパスがテキストとして記述されるが、イメージとして参照されることはない。

一方、ライブラリにおいては、ドラッグアンドドロップでローカルの画像を挿入することができる。これは、Ulyssesでのプレビュー時に表示される。しかし、ファイルをリネームなどして参照不可能にすると表示されない。

また、ライブラリのみ、シートへの添付ファイルとして画像を与えることもできる。この場合、添付ファイルボタンをクリックすることで画像がプレビューされ、シートにドラッグアンドドロップすることで挿入することができる。この場合、ファイルはライブラリに統合され、元ファイルが参照不可能になった場合も閲覧できる。

TextBundleファイルの作成方法

たぶん、画像ファイル付きのシートをMarkedでプレビューする際に自動生成されるのではないだろうか?

Marked持ってないので検証終了。買ったら追記する。

(追記)Marked 2買ったので追加検証するかも。

Notebooks for MacでのTOC生成時に日本語見出しが正常に出力されない件について

Notebooks for MacのTOC生成機能

Notebooks for Macには、Table of Contents、いわゆる目次を自動生成する機能があります。

目次の元となる見出し(Heading)をMarkdownで記述すれば、非常に簡単にTOCを作成することができます。

しかも、TOCには、リンクアンカーが付与されるため、各見出しにジャンプすることも可能です。HTML的には、見出しの内容が、そのままアンカー名になります。

アンカー名のエスケープにまつわる問題

この際、アンカー名に含まれる一部の文字は自動的にエスケープ(ドット(.)に置換)されるのですが、日本語文字が全てエスケープ対象なのです。

そのため、同じ文字数の日本語見出しは同じアンカー名になってしまい、正常にジャンプできない事態が多発します。

例えば、以下のような見出しがあるとして、

# 見出し赤
# 見出し青

TOCのHTMLソースは、以下のようになってしまいます。

<ul>
 <li><a href="#L............">見出し赤</a></li>
 <li><a href="#L............">見出し青</a></li>
</ul>

おいそのLはなんだ。

問い合わせてみた

thanks a lot for your bug report, we were not aware of this issue before. I am not sure if we can find a short term solution for this, because these anchors are automatically inserted during Markdown conversion (we are using a third party component for that). To ensure correct and easily manageable URLs, all “special characters” are escaped, and that seems to be the reason why Japanese characters are replaced, too. - We will see what we can do about it, though.

これはバグ報告です。

見出しが日本語を含む場合、TOCを挿入すると問題が生じます。アンカーの名前において、見出しの日本語文字がドットに置換されてしまいます。そのため、正しくジャンプできない場合があります。

This is a bug report.

Problems arise if the headers containing Japanese, when you insert a TOC. In the name of the anchor, Japanese characters in headings would have been replaced by a dot. Therefore, you might not be able to jump correctly.

例によって怪しい意訳するとこんなところでしょうか。

  • バグレポート多すぎてそんなバグ埋もれてたわすまん。
  • ちと一朝一夕には解決できないっぽい。
  • というのも、アンカーはサードパーティ製のコンポーネントによって自動的に挿入されるからね。
  • URLを簡単確実に生成するために、特殊文字は全部エスケープしとるんで、日本語も置換されちゃうんだろうね。
  • けどまあ、なんかうまい方法考えてみるよ。レポートありがと。

いや、あのLはなんだ。

ともあれ、使用しているサードパーティ製コンポーネント、この場合はMarkdownパーサーを指すのでしょうが、その仕様であるようです。

他のパーサーの場合

例えばSublime TextのMarkdown Prevewパッケージに使われているpython-markdown(のTOC拡張、ああややこい)、あるいはJekyllなどで利用されているKramdownでは、日本語文字を含む特殊文字は全部消去した上で、アンカー名が重複する場合には接尾辞で連番を付与しています。

例えば、以下のような見出しがあるとして、

# 見出し赤
# 見出し青

これをSublime Textで変換すると、TOC部分のHTMLソースは、以下のようになるわけです。なお、TOCを挿入するには、[TOC]と記述します。

<ul>
<li><a href="#_1">見出し赤</a></li>
<li><a href="#_2">見出し青</a></li>
</ul>

こちらの方が、エスケープルールとしてスマートであるようには思われますね。

なお、python-markdownでは、以下のような記述で、任意のアンカー名を与えることが可能です。

# 見出し赤 {#red}
# 見出し青 { #blue }

あえて記法をぶれさせましたが、どちらも有効です。この場合、日本語のアンカー名も記述できます。

Kramdownを含む、Jekyllに組み込まれた各種パーサーでのTOC生成ルールについては、後日別の記事にまとめようと思います。

このように、パーサーによっては対策の取りようもあるわけですが、Notebooks for Macの場合、そもそも利用されているパーサーが不明なため、このような対策もとれません。それも問い合わせしてみようかな。

AlfredからもMarkdownをクイックルックできるMarkdown Quick Look Plugin

Alfred2のFile Navigation

以前もご紹介しました通り、Alfred2のPowerpackに含まれるFile Navigation機能では、Windowsでいうfenrirのように、フォルダ階層を自在に移動することができます。

普通にフォルダを探してFinderで開くといった使い方でも十分に便利なのですが、フォルダを掘って中のファイルを見るという使い方が最高に便利です。

というのも、もともとAlfredではテキストファイルなどを検索することができるわけですが、デフォルトの検索対象にそういったファイルを含めると、検索結果が多すぎてアプリなどの使用頻度が高い項目が埋もれる上に、動作が非常に遅くなるからです。フォルダを検索してそこから掘り進めていけば、そういった問題は起こりません。

探し出したファイルは、関連付けされたアプリで開いたり、その他のアプリに渡したりすることができますし、ファイルを選択してシフトキーを押せば、Mac標準のクイックルックでプレビューすることもできます。

しかし、昔からある問題なのですが、拡張子.mdなどのMarkdownファイルは、クイックルックで開くことができません。しょせん拡張子が違うだけのテキストファイルなのですが、とにかくダメなのです。

クイックルックでMarkdownを開けるようにするプラグイン

そこで、プラグインを導入すると、Markdownファイルをスタイルを適用した状態で閲覧することができるようになります。

この手のプラグインも昔からあって、オープンソースのQLMarkdownがつとに有名なようです。しかし、導入がやや煩雑で、更新も長く行われていないようなので、今回はパッケージで提供されているプラグインを導入してみました。

こちらはMavericks対応で、パッケージ形式のため、ウィザードで簡単にインストールすることができます。

これはAlfred2からのクイックルックにも適用され、以下の画像のように、Markdownを見やすくプレビューすることができます。

クイックルックでMarkdownをプレビュー

ただし、ご覧の通り、前後にスペースのないボールド指定が解釈されないようです。これはバグというより、使用されているMarkdownパーサーの仕様でしょう。

一応、本来の定義では、Emphasisはin the middle of a wordで使えるはずなんですがねえ……。

1.1アップデートで少し大人びたWrite For Macも、まだまだお子様

正式リリース時にかなり微妙な評価のレビューを書いたWrite For Macですが、本日のアップデートでかなり大幅な改修が入りました。そこで、個人的には最大の欠点だった部分の改善がありました。

変更点が多いため全てとは言いませんが、他にも注目している点ついても書こうと思います。あと相変わらず不安定さがパないのでそこきっちりと。

ネストされたリストが書けるようになった

以前のバージョンでは、Write For Macはネスト(入れ子)のリストに対応していませんでした。

というのも、そもそもリスト行をインデントするコマンドがない上、えっちらおっちら行頭に戻ってタブを入力したとしても、改行時にリスト記号を自動入力する機能(オートバレット)が無効になってしまったからです。

しかし、今回のアップデートで、タブキーによるリスト行のインデントと、インデントされたリスト行で改行した際のオートバレットにも対応しました!

これにより、ネストされたリストを簡単に書くことが可能になりました。

メニューバーアイコンとスクラッチパッドの採用

メニューバーアイコンとスクラッチパッド

上記画像のように、メニューバーにアイコンが表示され、そこからスクラッチパッドが利用できるようになりました。

スクラッチパッドの内容は、ファイルとして保存されることのない、完全な「走り書き」です。右上の「+」ボタンをクリックすると、アプリがアクティベートされ新規ノートを作成します。

なお、スクラッチパッドに入力してから「+」ボタンをクリックしても、スクラッチパッドの内容がノートに挿入されることはありません。あくまで、スクラッチパッドは完全に独立したものです。

これに伴い、非アクティブ時にもCmd+Control+Nで新規ノートを作成できるようになりました。

新規ノート作成時の挙動の変更

従来では、新規作成時には、アクティブなフォルダに(ファイル保存操作をしなくても)新規ファイルが作成され、それは右パネルに表示されていました。

しかし、上記のようなメニューバーアイコンおよびグローバルホットキー、またはアクティブ時のCmd+Nホットキーによって新規ノートを作成した場合、従来と挙動が異なります。

下記画像のように独立ウインドウで新規ノートが作成され、それはファイルとして保存されていません。ファイル保存操作をすると、改めて保存先フォルダを指定することになります。

新規ノート

既存ファイルをダブルクリックした場合も、この独立ウインドウが開きます。

なお、従来のようにファイル自動保存かつ保存先フォルダ指定でノートを作成するには、中央パネルの検索バー右側にある「+」をクリックします。

「+」で自動保存しつつ新規作成

個人的には、この挙動ではWrite For Macの魅力のひとつであったiOSアプリ的なファイル操作を意識しない記述ができないため、よくないなと。

ダークテーマの追加

もともとテーマの書き換えは簡単にできたのですが、まあスクリーンショットがものの見事に真っ黒なので念のため。

設定から、従来のライトモードと、ダークモードを選択できます。どちらかというと、テーマを複数設定できるという点に価値を見いだせるかもしれません。

未解決問題

リッチテキストまたはハイブリッド表示の際の画面ちらつき

設定でリッチテキストまたはハイブリッド表示を選択している場合、入力中に再描画が行われ、かなり画面がちらつきます。この点は、従来よりいくぶんマシなような気もしますが、根本的には解決されていません。もっとハイスペックなMacなら違うのかもしれませんが、これでは、プレーンテキスト以外の選択肢はありません。

独立ウインドウで入力中テキストがしょっちゅう消える

これはまずいでしょー。

特に表示設定を変更した場合なのですが、入力中のテキストが思いっきり消えます。この原稿書きながら3回消されました。いい加減にしろといいたい。

見出し・リストフォーマット挿入コマンドなし

せめて Traditional Markdown の10種フォーマットくらいは揃えないか。

私はかわせみとかTextExpanderで簡単に入力できるようにしているからあまり気になりませんが、ことえりとかGoogle日本語入力を使っている日本語ユーザーは、かなり半角記号の入力が面倒です。ここはどうにかして欲しいもの。

結論:まだまだ

リストがまともになったので喜んだのが5分ともたなかった件。

とりあえず、基本的なテキスト入力とか保存とかの部分で、不安さが他に類を見ないレベルなのをどうにかしていただきたい。ああいやNotebooks for Macとかもあったか。これだからiOS出身は!

あと独立ウインドウが最悪なのでせめてオプションにしてもらえませんかね。いちいちCmd+S押さなくていいのがよかったのに。

Simplenoteやめました―nvALT中心のメモ環境

Simplenote中心のメモ環境

Simplenoteは、テキストのみを同期することに関しては、現状で最良といえるクラウドサービスです。

Evernoteに速度で大幅に勝り、タイトルを付ける必要もなく、いちおうMarkdownをサポートし、連携アプリも多い。アプリを通せばテキストファイルとしての保存もできます。

Android使いならGoogle Keepという選択肢もあったでしょうが、残念そこはiPhone。そこで、しばらくの間、私のありとあらゆるメモはSimplenoteに放り込まれた後、加工されていずこかへと消えていきました。

iPhone MacBook Air Windows
使用アプリ Simplenote nvALT Simplenote(ChromeApp)

次第に中心的な位置を占めていくnvALT

当初はSimplenoteクライアントとして利用し始めたnvALTでしたが、私は徐々にその虜になっていきました。

高速検索・高速メモ作成、基本的なMarkdown作成支援といった特長はもとより、重要なのは他アプリに渡すコマンドが存在することです。これによりnvALTは、FoldingTextでの編集、Byword経由でのEvernoteへの保存など、テキストをさまざまなアプリで取り回す上でのハブとして機能することになりました。

iOS版Simplenoteへの不満

私は、Markdownでメモを取る上での最大の利点は、リスト作成のしやすさだと思います。アウトラインプロセッサを利用する手もあるのですが、汎用的なデータフォーマットであるプレーンテキストで、通常のテキスト内に、簡単にアウトラインを記述することができるメリットは非常に大きいものです。

ここで「箇条書き」ではなく「アウトライン」という呼び方をしたのは、入れ子(ネスト)にすることを考慮してのことです。単なる箇条書きであれば、Markdownという形式にこだわる必要はありません。構造を視覚化したいのです。

まあ、トラディショナルなMarkdownには入れ子の書き方が指定されてなかったりもしますが、HTMLのULでできることがMarkdownでできてはならぬ理由もなく、たいていのMarkdownエディタ(パーサー)はタブまたはスペース4個によるインデントを、リストを入れ子にするフォーマットとして、適切に取り扱ってくれます。

ただし。iOS版のSimplenoteアプリでは、オートバレット(リストで改行したときに記号を補完)はしてくれるものの、簡単にインデントを行う方法がありません。

というより、これはiOSにおけるテキスト入力全般の問題なのですが、iPhoneのキーボードではタブ文字を入力できないからです。TextExpander Touchをサポートしてくれていれば、どうとでもなったのですが。

いちおうタブ文字を辞書登録したりして頑張ってはみたものの、1週間くらいで心が折れました。

というか、そもそもnvALTで他のアプリにノートを渡すにはローカルフォルダにプレーンテキストファイルを保存する設定にせねばならないため、どうせローカルのファイルはあるのです。だったら、Dropboxに保存して他のアプリを使えばいいじゃない!

SimplenoteとDropboxのコンフリクト

nvALTなりの、ローカルフォルダへのプレーンテキストファイル保存機能を持つSimplenoteクライアントを使えば、Simplenote内のノートをDropboxにも保存することができます。

(実は、SimplenoteのプレミアムアカウントにはDropbox保存サービスがあったらしいのですが、現在はプレミアムアカウントの登録自体が行われていません。)

ところが、実際にこれをやると、同期のコンフリクトによりファイルが複製される現象が頻発します。(nvALTでは警告が出る。)色んなアプリを試しましたが、まあアプリの問題でもありませんし、この問題は解消しませんでした。

Simplenoteを捨てよ、Dropboxに出よう

開かれたクラウドサービスであるDropboxであれば、アプリの選択肢は大幅に増えます。現在ではDropboxへの完全移行が完了しており、環境は以下のようになっています。

iPhone MacBook Air Windows
使用アプリ 1Writer/Notesy nvALT ResophNotes

1WriterとNotesyはいずれも拡張キーボードによるMarkdown作成支援機能を持ち、TextExpander Touchにも対応しています。また、常にファイルがDropbox上に存在することにより、どの端末でもデータの取り回しが容易です。

一昔前は、iPhoneのメモアプリでDropbox連携と言ったら、同期フォルダを選べないことが多かったのですが、現在ではそんなアプリはほとんどなくなりました。つまり、状況に応じて使うアプリを柔軟に選ぶことも可能なわけです。

なお、nvALTとSimplenoteで同期していた時に悩まされていた、タブ文字がスペースに置換される現象はすっかりなくなりました。どうやら、Simplenoteに起因する問題であった模様。

「Markdownシンタックス」と「Markdownパーサー」

今更:Markdownとはなんなのか?

  • MarkdownとはHTMLを簡単に記述するためのメソッドである
  • それは、シンタックスとパーサーによって成る
    • シンタックス: ルールとして定められた記法、構文
      • # 〜で見出し
      • ****でボールド
      • etc…
    • パーサー: シンタックスを解析(してHTMLに変換)するプログラム
      • markdown.py
      • PHP Markdown Extra
      • kramdown
      • etc…
  • 従って、利用可能なシンタックスは、パーサーによって定義される。
  • 基本的にはあるシンタックスとパーサーは結びついているものと考えられるが、著名・有用であるため、独立して流通するシンタックスも存在する。
    • Github flavored Markdownとか
  • ただし、Markdownはプレーンテキストとしての可読性が考慮されており、HTML化しなくとも有用である
    • エディタにおけるシンタックスハイライト機能も広義にはパーサーであるといえる
    • 可読性を高めるためのフォーマットを自動補完する機能を求める立場からは、「共通プレーンテキスト フォーマットとしてのMarkdown」も十分有用である
      • リストとか
  • ファイルとしてのMarkdownドキュメントはプレーンテキストであり、拡張子を除きプレーンテキスト ファイルとの違いはない

Automatorで半角スペースをタブ記号に変換する

(はてなブログからの移行記事です。正常に表示されていない場合、ご連絡いただけると助かります。)

承前。

半角スペース×4をタブに変換するワークフローを作成しました。

参考

ワークフロー概要

  1. シェルスクリプトで取得したテキストを置換
  2. クリップボードにコピー
  3. AppleScriptでペースト(⌘V)を実行

シェルスクリプトコードを以下に記します。

1
2
3
4
for f in "$@"
do
echo "$f" | sed -e "s/ / /g"
done

Automatorにはペースト(または⌘V)を実行するアクションがありません。しかし、キーボード操作を記録してからAppleScriptとして展開することで、アプリを問わず「⌘Vを押す」操作を実行させることができます。そのスクリプトコードは以下の通りです。

(修正:2014-07-09)
えらく時間がかかるのでdelayおよびtimeoutSecondsを0に。けっこう速くなった。とりあえずちゃんと動いている。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- ⌘Vを押す
delay 0
set timeoutSeconds to 0
set uiScript to "keystroke "v" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application "System Events"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout

Automatorのスクリーンショットは以下の通りです。
スクリーンショット

また、ワークフローファイルを以下にリンクします。解凍して「Library/Services」に置くことで利用できます。テキストを選択した状態で、メニューバーまたはコンテクストメニュー内の「サービス」から実行できます。

4Space2Tab.workflow(前バージョン:4Space2Tab.workflow

注意

なぜか一部アプリで正常に機能しない(1行しかペーストされない)ことがありました。(miなど)

バージョン2(2014-07-09)

もうテキスト選択とかコンテクストメニューから実行とかめんどくさいので、ワークフローに⌘A+⌘Cも含めてみた。

ワークフロー概要

入力なしにして、

  1. AppleScriptで全文選択(⌘A)を実行
  2. AppleScriptでコピー(⌘C)を実行(delay1秒)
  3. クリップボードの内容を取得
  4. シェルスクリプトで取得したテキストを置換
  5. クリップボードにコピー
  6. AppleScriptでペースト(⌘V)を実行

ワークフローファイルは以下。

4Space2TabSel.workflow

テキスト未選択状態で、メニューバーの「サービス」から実行できます。「システム環境設定>キーボード>ショートカット」で割り振りしておくと楽です。

さすがに、delayを多少取っておかないと、コピー処理が間に合わず失敗する模様。

(2014-12-31追記)選択したテキストを入力で置き換える

なんでコピペとかしているのか、冷静に考えると意味が分からない。

スクリーンショット

これでOKです。