LoginSignup
7
3

More than 3 years have passed since last update.

.mdファイルをScrapboxの書式に変換するスクリプトをpythonで作った

Posted at

はじめに

  • Qiitaに投稿するときはよくマークダウンでローカルに下書きしています.
    • 論文の要約をマークダウンでメモする用途を想定しています
  • Scrapboxが見やすい&メモしやすい&リンクしやすい のでメモ代わりによく使うのですが,マークダウン形式は対応していないので,マークダウンファイルをscrapboxでみやすい形式に変換するスクリプトを書きました.
  • python3

変換する対象

箇条書き

入力.md
* イメージキャプショニングはビジュアルシーンに対して自然言語の説明をつけるタスク
    * この分野ではここ5年でニューラルencoder-decoderが人気
        * sotaはCNNのエンコーダ,LSTM(やTransformer)のデコーダ,とattention機構で構成されている

マークダウンでは*-で書きます.
scrapboxではスペース1文字でインデント+バレット(黒丸●のこと)1個分になるので,スペースに置き換わります.

出力.txt
 イメージキャプショニングはビジュアルシーンに対して自然言語の説明をつけるタスク
  この分野ではここ5年でニューラルencoder-decoderが人気
   sotaはCNNのエンコーダ,LSTM(やTransformer)のデコーダ,とattention機構で構成されている

スクリーンショット 2020-04-29 21.10.08.png
scrapbox上ではこのように見えます

角括弧[]

入力.md
[27]はCNN encoder, LSTM decoderからなるモデルを提案

論文の引用に使う角括弧[]を丸括弧()に変換します
この理由はscrapboxでは角括弧[]は記事間のリンクを意味するからです

出力.txt
(27)はCNN encoder, LSTM decoderからなるモデルを提案

タイトル

入力.md
## 2. 関連研究

### 2.1. Image Captioning

マークダウンでは見出しとしてh1 ~ h6までを#を複数続けることで表現します.
scrapboxには見出しはないので,代わりに太字を使います.太字は角括弧[]で二重に囲みます.[[強調したい文字列]]

出力.txt
[[ 2. 関連研究]]

[[ 2.1. Image Captioning]]

スクリーンショット 2020-04-29 21.11.33.png
scrapbox上ではこのように見えます

数式

入力.md
$f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)$

マークダウンでは$数式$で1行内での数式を表現できます.
scrapboxでは同じことが[$ 数式]でできます.

出力.txt
[$ f_t = \sigma(W_f \cdot (h_{t-1}, x_t) + b_f)]

スクリーンショット 2020-04-29 21.12.33.png
scrapbox上ではこのように見えます

ちなみにscrapboxでは\tag{1}などの数式番号を入れると1行におさまらず,2行になってしまいます.今回はこれに対応できていません.

太字

入力.md
**強調のテスト**

マークダウンでは**強調したい文字**などの方法で太字表現できます.
scrapboxでは先述の通り,[[強調したい文字列]]になります.

出力.txt
[[強調のテスト]]

ソースコード

愚直にrestr.replace()で文字列を置き換えるだけです.
変なところあったら教えていただけると助かります.

エスケープ\の影響でシンタックスハイライトの色が消えてしまった・・・

md2scrapbox.py

import os
import argparse
import re

parser = argparse.ArgumentParser()
parser.add_argument("in_file")
args = parser.parse_args()

sentence = "" # output
tab = "    " 
space = " "
bullet = "* "
strong = r"\*\*.*\*\*.?"
title = r"#*"
math = r"\$[^\$]*\$"

with open(args.in_file, "r") as f:
    lines = f.readlines()
for line in lines:

    # blaket    
    line = line.replace("[", "(")
    line = line.replace("]", ")")


    # indentation
    for m in re.finditer(tab, line):
        line = re.sub(tab, space, line)
    line = line.replace(bullet, space, 1)


    # title
    m = re.search(title, line)
    if len(m.group()) > 0:
        line = "[[" + line[m.end():].replace("\n", "") + "]]\n"


    # math
    m = re.findall(math, line)
    if m:
        for matched in m:
            m2 = re.sub(r"^\$", "[$ ", matched)
            m2 = re.sub(r"\$$", "]", m2)
            line = line.replace(matched, m2)
        sentence += line
        continue
    else:
        # enphasis
        m = re.findall(strong, line)
        if m:
            for matched in m:
                m2 = re.sub(r"^\*\*", "[[", matched)
                m2 = re.sub(r"\*\*$", "]]", m2)
                line = line.replace(matched, m2)
        sentence += line

print("==========")
print(sentence)

dirname = os.path.dirname(args.in_file)
name = os.path.basename(args.in_file)
name, ext = os.path.splitext(name)
name = name + "_scrapbox.txt"
name = os.path.join(dirname, name)
print(name)

with open(name, "w") as f:
    f.write(sentence)

使い方

python md2scrapbox.py path/to/some_file.md

変換結果は入力と同じ場所に名前を変えて保存されます
上の例だとpath/to/some_file_scrapbox.txtになります.

あとは出来上がった文字列をscrapboxに貼るだけです.

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