小技チョコレート

ちょっとした小技を紹介するだけのブログです。

Dynalistからプレーンテキスト形式でエクスポートした内容をScrapbox記法に置換するUserScript

Dynalistからプレーンテキスト形式でエクスポートした内容をScrapbox記法に置換するUserScript(dy2sc.js)を作ったので、コードと使い方を書いておきます。

コードは更新されることがあります(更新履歴)。


〈目次〉


機能

概要

Dynalistの内容をプレーンテキスト形式でエクスポートし、それをScrapboxにペーストしてからマウスでドラッグし、ボタンを1回クリックすると、そこに含まれているMarkdownや、Dynalistの独自記法をScrapbox記法に置換します。Dynalistにおける階層も再現されます。


(Dynalistのコンテンツ)


(DynalistのコンテンツをScrapboxにペーストし、範囲選択して“Dynalist"ボタンを押す)


Scrapbox記法に置換された状態)

置換できるもの/できないもののリスト

全てのMarkdownやDynalistの独自記法を完全にScrapbox記法へ置換できるわけではなく、置換できないものも存在します。置換できるもの/できないものの詳しいリストは下記のとおりです。

置換できるもの
  • リンク
    • [リンクテキスト](URL)[リンクテキスト URL]
    • [](URL)[URL]
  • 画像
    • ![リンクテキスト](画像のURL)[リンクテキスト 画像のURL]*1
    • ![](画像のURL)[画像のURL]
  • 強調を太字へ置換(**hoge**[* hoge]
  • イタリック(__hoge__[/ hoge]
  • 取り消し線(~~hoge~~[- hoge]
  • ハイライトを太字へ置換(==hoge==[* hoge]
  • 日時記法
    • !(2019-09-08)2019-09-08
    • !(2019-09-08 10:00)2019-09-08 10:00
    • !(2020-03-02 - 2020-03-10)2020-03-02 - 2020-03-10
    • !(2020-03-03 01:00 - 2020-03-06 01:00)2020-03-03 01:00 - 2020-03-06 01:00
  • ハッシュタグ用の@#へ置換(@hoge#hoge
  • 数式をTexへ置換($$E=mc^2$$[$ E=mc^2]
  • コードブロック記法をScrapboxコード記法へ置換(```hoge```→`hoge`)
  • 余分なインデントを除去(Dynalistでは階層が1段下がるごとにインデントが4個ずつ付くので、これをインデント1個ずつに置換)*2

なお、Dynalistのコード記法(`hoge`)および、#を用いたハッシュタグ#hoge)は、Scrapboxでもそれらと同一の書き方をしますので、元通りに再現されます。

置換できないもの
  • Scrapboxのページタイトルに含まれているMarkdownや、同じくページタイトルに含まれているDynalistの独自記法(ただし、ちょっとした工夫を加えれば解決します)。
    • Dynalistからエクスポートしたテキストの1行目がこれに相当します。
  • Dynalistにおいて見出し(H1, H2, H3)の状態にある項目(Ctrl+Shift+Hを押した行)は、Dynalistではフォントサイズが大きくなっていますが、そのサイズ変更は再現されません。
  • カラーラベル(Dynalistで特定の行にのみ使用している背景色)は再現されません。
  • Dynalistでチェック(Check off)した項目(hogeのように表示されているもの=Ctrl+Enterを押した行)そのものは消さずに引き継ぐことができますが、この項目のフォントカラーの変更(色が薄くなっていること)と、同項目に付けられている取り消し線は再現されません。
    • Dynalistのcheckbox(行頭に付けることができるチェック機能)にチェックを入れた項目も、これに該当します。
    • それらの取り消し線をScrapboxで再現するには別の方法を利用して下さい。
  • Dynalistのcheckbox(行頭に付けることができるチェック機能)は再現されません。
  • Dynalistの1項目(1行)の内部で改行してある場合(Ctrl+Shift+Enterを押してある場合)は、その項目における改行以降の部分には、階層の深さが引き継がれません。他の項目の階層は正しく再現されます。
  • Dynalistのnoteに記入したものは、Dynalistにおけるスタイル(小さいフォントで各項目の下側に付いている状態)がScrapboxに引き継がれず、独立の1項目(1行)に置き換えられます。

その他の、仕様上どうしても実現できないことなどを「既知の問題点」の節にまとめています。細かいことなので、詳しく知りたい場合はお読み下さい。

他のツールとの機能比較も参考にしてください。

導入のしかた

こちらのヘルプに書かれている手順で、ScrapboxのUserScriptをEnableにします。

次に、Scrapboxの「自分のページ」を開き、code:script.jsと記入します。その下の行にdy2sc.jsのコードをペーストします。全体で約40行あります。


dy2sc.jsのコード

そしてブラウザをリロードし、Scrapboxの上部に表示される“Load new UserScript”をクリックします。

ペーストした部分はこのようになっているはずです(行頭のインデントの数は、この画像のとおりでなくても構いません)。


dy2sc.jsをUserScriptとして導入した状態のサンプル

これで完了です。

使い方

Dynalistにこのような内容があるとき、これをScrapbox記法に置換する、という例を示します。


(この例では1行の中にMarkdownやDynalistの独自記法が1つずつあるだけですが、複数個ある場合も正しく置換できます。)

Dynalistからエクスポートしたい内容の、最上位の行の行頭にマウスポインタを合わせると、「≡」の形のアイコンが表示されるので、それをクリック。

すると、メニューが開くので、その中の“Export...”をクリック。

このような画面が開きます。

中央上部の“Plain text”をマウスで選択し、下の方にある“Indentation style”のところで“Spaces”を選択しておきます(通常は何もしなくても“Spaces”が選択されていると思います)。

そして“Copy to clipboard”のボタンを押すか、もしくは、中央の入力欄の内容を選択した状態でCtrl + Cなどと操作して、この入力欄の内容をクリップボードにコピーします。

それをScrapboxの新規ページや既存のページに貼り付けます。


(エクスポートしたテキストをそのまま貼り付けた状態)

エクスポートしたテキストのうち、ページタイトルを除いた部分をマウスで選択します。
すると、“Dynalist”という名前のボタンが表示されます。


(ページタイトルより下側をマウスで選択した状態)

“Dynalist"のボタンを押すと、このように置換されます。


Texのところで行頭のマーカー(・)が見えなくなっているのはScrapboxの仕様です)

置換を元に戻す方法

置換後にCtrl + Zのショートカットキーを押せば、置換前の状態に戻ります。

ただし、そのページを閉じた後や、別のページに移動した後では、そのショートカットキーを押しても元に戻せません。

ページタイトルを置換対象に含める方法

上掲のとおり、Scrapboxのページタイトル部分は、このUserScriptでの置換対象に含めることができません。


(ページタイトルまで選択範囲に含めると、置換操作のための“Dynalist”ボタンが出ない)

この問題は、次のような小さな工夫で解決します。

DynalistからエクスポートしたテキストをScrapboxに貼り付ける際に、Scrapboxページの1行目(すなわちページタイトルの位置)に貼り付けるのではなく、2行目以降の位置に貼り付けます。そうすれば、全体をUserScriptの置換対象に含めることができます。置換が終わった後で、本来ページタイトルになるべきだった行を、ページタイトルの位置まで上げてやれば完了です。


(ページタイトルよりも下の行に貼り付ければ、全体が置換対象に入る)

〈Dynalistに存在しているが画面上で見えていないもの〉をエクスポート対象から除外する方法

Dynalistにおいて「存在はしているけれども画面上で見えていないもの」を、エクスポート対象に含めないようにすることができます。詳細は別の記事をご覧ください。

カスタマイズ

「画像へのリンク」にはリンクテキストを付けないように変更する

置換元(Dynalist)においては、![リンクテキスト](画像のURL)という書き方をすれば、その位置に画像が表示されます。
それを本記事のUserScriptでScrapbox記法に置換すると、[リンクテキスト 画像のURL]というScrapbox記法になります。そのままだと、Scrapboxページ上では、その「リンクテキスト」すなわち文字のほうだけが画面上に表示され、画像は画面上に現れません。

例えば、Dynalistに![logo](https://scrapbox.io/assets/img/logo.png)という箇所がある場合には、次のようになります。

![logo](https://scrapbox.io/assets/img/logo.png)がUserScriptで置換されて、
[logo https://scrapbox.io/assets/img/logo.png]という「画像へのリンク」となります。


Scrapboxにて[ ]内にリンクテキスト(Logo)と画像URLがある「画像へのリンク」)


(そのままではLogoというリンクテキストだけが表示され、画像は見えない)

Scrapboxにて[ ]内からリンクテキストを取り除いて、画像URLのみにすれば、画像が見えるようになります。


[ ]内を画像URLのみにした例)


(画像が見える)

このような![リンクテキスト](画像のURL)という箇所がDynalistに存在しているとき、その「リンクテキスト」の除去を手作業でするのではなく、UserScriptで一律に取り除くようにすることができます。
すなわち、全ての![リンクテキスト](画像のURL)[画像のURL]へと置換することができるように、UserScriptをカスタマイズできます。その方法は下記のとおりです。

dy2sc.jsのコードの8-10行目付近に、このような行があります。

////Image with alt text
//e.g. ![Google logo](https://www.google.com/google.png)
text=text.split(/\n/).map(line => line.replace(/!\[([^\]]+)\]\((https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-]+)\)/g,'[$1 $2]')).join('\n')

この末尾の方の[$1 $2][$2]に書き換えます。

書き換えたら必ずブラウザをリロードし、Scrapboxのページ上部に現れる"Load new UserScript"をクリックしておきます。

ボタンの名前を変える

置換対象の範囲をマウスで選択したときに表示されるボタンの名前は、デフォルトでは“Dynalist"ですが、この名前は変更できます。

変更するには、dy2sc.jsのコードの2行目のtitle: 'Dynalist',のところを書き換えます。

書き終えたら必ずブラウザをリロードし、Scrapboxのページ上部に現れる"Load new UserScript"をクリックしておきます。

置換対象を増やす

デフォルトで置換できるもののほかに、置換対象を加えたい場合は、dy2sc.jsのコードの末尾のほうにあるreturn text;よりも上の行に、コードを書き加えます。

コードの基本的な形は

text=text.split(/\n/).map(line => line.replace(/置換前/g,'置換後')).join('\n')

です。「置換前」の部分はJavaScriptでの正規表現の書き方に従って書きます。「置換後」の部分の書き方はdy2sc.jsのコードを参考にしてください。

書き終えたら必ずブラウザをリロードし、Scrapboxのページ上部に現れる"Load new UserScript"をクリックしておきます。

Dynalistで作った内部リンクに付随する余分な"()"を取り除く

Dynalistの内容をScrapboxに移そうとするとき、Scrapbox用の内部リンク(例えば[hoge])をDynalistで作っておくこともできます。その操作をするには、DynalistにおけるCtrl + KまたはCmd + Kのショートカットキーを使うのが便利です。このショートカットキーを押すと、その位置に[]()というMarkdownが記入されます。また、例えばhogeなどの文字を選択したうえでそのショートカットキーを押すと、[hoge]()というようにMarkdownが記入されます。
この[]で囲まれた部分は、Scrapboxにおいては内部リンクになりますから、このショートカットキーを「Scrapbox用の内部リンクをDynalistで作る用途」で使うことができます。
その際、()の部分はScrapboxにおいては不要です。Dynalistの内容をScrapboxに移したあとで、不要な()をUserScriptで一括して取り除くことができます。
そのためのコードは下記です。「置換対象を増やす」の節に書いてある手順でUserScriptに適用して下さい。

text=text.split(/\n/).map(line => line.replace(/\]\(\)/g,']')).join('\n')

ちなみに、UserScriptで()の除去のみをしたい場合(他のものを置換する必要が全くない場合)は、UserScriptのコードは下記のようになります。

code:script.js
 scrapbox.PopupMenu.addButton({
    title: '()消去',  //"()消去"はポップアップするボタンの名前。変更可能。
    onClick: text =>{
        text=text.split(/\n/).map(line => line.replace(/\]\(\)/g,']')).join('\n')
        return text;
    }
 })

なお、()Dynalistの置換機能で取り除くこともできます。

置換対象を減らす

デフォルトで置換できるもののなかに、置換したくないものがある場合は、dy2sc.jsのコードの中でそれに対応している行の行頭に//と書き加えます。

書き終えたら必ずブラウザをリロードし、Scrapboxのページ上部に現れる"Load new UserScript"をクリックしておきます。

既知の問題点

  • 次のような場合は、その箇所では正しい置換結果になりません。

    • Markdown入れ子になっている場合(**__hoge__**~~**hoge **~~など)
    • Dynalistの数式記法($$〜$$)で式に]を含む場合(例:$$[a + b]$$*3
    • Dynalistの数式記法($$〜$$)で半角の$が3個以上連続している場合
      • 数式の左端や右端に$がある場合($aとかa+$のような数式)がこれに該当します。
      • 1行の中で数式記法が連続しているだけの場合は、問題ありません。
        • $$a+b$$$$x-y$$[$ a+b][$ x-y]と正しく置換される。
  • Dynalistで行頭に半角スペースがあると、Scrapboxにおいて階層が正しく再現されません。行頭の半角スペースがインデントとして解釈されてしまうためです。


(行頭に半角スペースがある例(一行目))

おわりに

不具合のご報告やご要望、改良のアイデアなどがありましたら、本記事のコメント欄か筆者のTwitterメールGithubなどへお知らせ下さい。

免責事項

本記事で紹介したUserScriptの使用やその不具合等により生じたいかなる損害に関しましても、筆者は一切の責任を負いません。予めご了承ください。

関連記事

本記事で紹介したUserScriptと同様に、MarkdoownとDynalistの独自記法をScrapboxに置換するPythonスクリプトがあります。ただし、置換機能は本記事のUserScriptのほうが充実しています。

Markdownのみを置換対象として、Scrapbox記法に置換するUserScriptがあります。

iOS / Androidバイスにおける手法

iOS / Androidバイスにおいて、Dynalistの内容をScrapboxにコピーするには、Workextendというアプリを利用した方法が使えるようです。


*1:ただし、[リンクテキスト 画像のURL]という形のままだと、Scrapboxの仕様上、「リンクテキスト」のみがページに表示され、画像はリンク先で開くスタイルになります。この場合にScrapboxページ上に画像を表示させるには、「リンクテキスト」の部分を手動で消していくか、もしくはそれを一律に消すよう後述のカスタマイズを施す必要があります。

*2:インデントを4個のままにすると、Scrapboxにおいては箇条書きの階層が深くなりすぎます。

*3:これはScrapboxの仕様によるものです。