プログラムでおかえしできるかな

Python、フェイジョア、日常のあれこれでお返し、元SEの隠居生活。

Markdownテキストをブラウザでプレビュー【Python】

このエントリーをはてなブックマークに追加

f:id:juu7g:20210521115807p:plain:left:w120 Markdown 記法で文章を書く場合、テキストエディタを使用する方も多いと思います。
Markdown 記法の文書はそのままでも読めることが特徴でもありますが、HTML になったものはさらに読みやすいですよね。
そこで、Markdown 記法の文書をブラウザで読めるようにプログラムレスで対応してみました。
PythonMarkdown パッケージを使用します。


目次

■できること

Markdown 記法で書かれたテキストファイルをHTMLファイルに変換しブラウザで表示します。
そのためのバッチファイルを作成します。

PythonMarkdown パッケージのコマンドラインでの使い方が理解できます。

■準備するもの

次の物を準備します。
Pythonの環境が必要です。環境構築は、既にできている前提で説明します。

  • Pythonのパッケージ(インストール)
    • Markdown パッケージ(Python-Markdown)
      pip install Markdown
    • pygments パッケージ
      pip install pygments
    • pyyaml パッケージ
      pip install pyyaml
  • バッチファイル(作成)
  • HTMLファイルのヘッダーファイル、フッターファイル(作成)
    スタイルシートを指定するため
  • コードハイライト用CSSファイル(作成)
  • markdownのオプション指定 yml ファイル(作成)
    Python-Markdownの目次機能を日本語対応するため

作成するものをフォルダごとにまとめます。

  • 任意のフォルダ
    • バッチファイル
  • Pythonを実行するフォルダ
    • blog_head.txt
    • blog_footer.txt
    • config.yml
  • HTMLを保存するフォルダ
    • codehilite.css

次に作成するものを説明します。

□バッチファイル

バッチファイルは、Markdownのテキストファイルを読み込んで同じフォルダにHTMLファイルを作成し、そのHTMLファイルを起動します。
バッチファイルは、任意のファイル名、拡張子はbat 、任意のフォルダに作成します。
内容は次の通りです。

rem %1 入力ファイル(txtファイル)

setlocal
set pythonpath=Pythonがインストールされているフォルダ名
set targetpath=%~p1
set targetname=%~n1

pushd %pythonpath%
rem もし仮想環境なら実行 call Scripts\activate.bat

rem markdownでmarkdown文書をhtmlに変換する
python -m markdown %1 -f  blog_body.html -x extra -x codehilite -x toc  -c config.yml

rem ヘッダーとフッターを付けてhtmlファイルにする
copy /y blog_head.txt + blog_body.html + blog_footer.txt "%targetname%.html"
move /y "%targetname%.html" "%targetpath%\"
rem htmlファイルを起動する
"%targetpath%\%targetname%.html"
popd

CSSファイル

コードハイライト用のCSSファイルを作成します。
Pythonの実行環境で次のコマンドを実行します。(pygments パッケージのインストールが済んでいること)
ファイル名は、codehilite.css とします。 HTMLファイルを保存するフォルダに置きます。

  • pygmentize -S default -f html -a .codehilite > codehilite.css

□ヘッダー、フッターファイル

HTML のヘッダーとして文字コードの指定と CSS ファイルの指定をし、フッターとして body タグの終了を指定します。
メモ帳やテキストエディタでファイルを作成します。
Pythonを実行するフォルダに置きます。
内容は次の通りです。

blog_head.txt (ファイル名)

<head>
   <meta charset="utf-8">
   <link rel="stylesheet" href="codehilite.css">
</head>
<body>

blog_footer.txt (ファイル名)

</body>

スタイルシートを指定しているだけの簡単なHTMLになるように作成しています。
他にも適用したいスタイルシートがあれば、ヘッダーファイルに追加すれば可能です。

私の場合 はてなブログの標準のCSSやテーマのCSSをローカルに保存して、はてなブログ特有のクラス名を削除したりした編集済みのCSSを用意して、ローカルでも実際に近い見栄えになるようにして使っています。

□ymlファイル(markdown のオプション指定ファイル)

メモ帳やテキストエディタでymlファイルを作成します。
Pythonを実行するフォルダに置きます。
内容は次の通りです。

config.yml (ファイル名)

toc:
    slugify: !!python/name:markdown.extensions.toc.slugify_unicode

■起動方法

バッチファイルに引数としてmarkdown 記法で書かれたテキストファイルを指定して実行すれば、既定のブラウザでプレビューされます。

□起動例

  • DOSプロンプトの場合
    バッチファイル名 テキストファイル名

  • エクスプローラーの場合
    バッチファイルのアイコンにmarkdown 記法の文書をドラッグする

  • テキストエディタ(Mery)の場合
    ツール ⇒ 外部ツール ⇒ 登録したツール名
    ※ショートカットを設定しておけばショートカットでプレビューできます
    ※参考までに私は Ctrl + Shift + V にしました(VS codeと同じ)

    • 外部ツールの設定方法
      • ツール ⇒ 外部ツール ⇒ 外部ツールの設定
      • 追加
      • タイトル:Markdown など
        コマンド:作成したバッチファイルのパス
        引数:「"$(Path)"」(「"」で括るとパスに空白が含まれても大丈夫です)
        ファイルを保持する:チェックオン。プレビュー前に保存してくれます

■詳細説明

markdown コマンドの詳細

python -m markdown [オプション] [入力ファイル]

▼オプション

今回使用したオプションは、出力ファイルの指定、拡張機能の指定です。
主なオプションは次の通りです。

オプション 説明
-f OUTPUT_FILE
--file=OUTPUT_FILE
出力ファイル(デフォルト:標準出力)
-x EXTENSION
--extension=EXTENSION
拡張機能の指定 複数可
-c ファイル名
--extension_configs ファイル名
拡張機能のオプション 拡張機能に続けて指定
-e ENCODING
--encoding=ENCODING
入出力ファイルのエンコーディング
-o OUTPUT_FORMAT
--output_format=OUTPUT_FORMAT
出力フォーマット
'xhtml' (デフォルト) または 'html'.

▼オプションの拡張機能の指定方法

今回使用した拡張機能は、Extra、CodeHilite、tocです。

拡張機能は、エントリポイントで指定します。外部Doc⤴

  • オプションなしの記述例

    python -m markdown input_file.txt > output_file.html

  • オプションありの記述例

    python -m markdown input_file.txt -f output_file.html -x tables

主な拡張機能は次の通りです。

名前 エントリポイント 機能
Extra extra 拡張機能 Abbreviations、Attribute Lists、Definition Lists、Fenced Code Blocks、Footnotes、Tables、Markdown in HTML をまとめて指定
Tables tables 表の対応
CodeHilite codehilite コードのハイライト
☆pip install pygmentsが必要
目次 toc 目次、アンカーリンク
目次機能をunicode対応するには拡張機能の slugify オプションを指定
☆pip install pyyaml が必要
Markdown in HTML md_in_html ブロックレベルでもmarkdown を有効にできる
タグに「markdow="1"」を付加する

▼コードのハイライト

codehiliteオプションを指定します。☆pip install pygmentsが必要
表示に必要なスタイルシート(CSSファイル)を用意します。

次のコマンドを実行してCSSファイルを作成します。

  • pygmentize -S default -f html -a .codehilite > codehilite.css

-a .codehilitePython-Markdown の出力に合わせてクラス名を指定しています。

TOCunicode対応

目次機能をオンにすると目次の出力が可能になるだけでなく、アンカーリンクも使えるようになります。
目次機能は、デフォルトで、日本語対応していません。
日本語に対応するためには、unicode対応用のオプション(slugify)を指定します。

プチ情報 Markdown 3.3.3でTOCunicode対応が提供されました。TOCとして使うには問題ないのですが、アンカーリンクとして使うには問題があります。
見出しに濁音半濁音があるとうまくジャンプできません。
3.3.5以降で直る予定です。

具体的には、

-x toc -c config.yml  

を指定し、config.yml ファイルを作成します。
ファイルには、slugifyオプションに slugify_unicode メソッドを使用するように設定します。

toc:
    slugify: !!python/name:markdown.extensions.toc.slugify_unicode

オプション指定はYAML形式を使用します。
JSONでも可能なようですが、YAML形式でないとうまく設定できませんでした。(理由は不明)

拡張機能のオプション指定方法】

拡張機能にもオプションがあります。
拡張機能のオプションを指定するには、オプション指定用のファイルを作成し、指定します。

  • -c (または --extension_configs) ファイル名
    ファイル名:YAMLJSON形式のファイル
  • 拡張機能の指定の後に続けて指定
    -x toc -c config.yml
YAML形式ファイルでの指定方法の一般例】
 myext:  
    option1: 'value1'  
    option2: True  

YAML形式のファイルを使用する場合、pip install pyyaml が必要
 pyyamlがインストールされているとYAMLとして解釈されます。

□バッチファイルの説明

ソースは、こちらを参照してください。

  1. コマンドライン引数としてテキストファイルを想定
    コマンドライン引数は %1 で参照できる
  2. 次を変数に設定
    • Pythonがインストールされているフォルダ
    • テキストファイルのフォルダ( %~p1 )
    • テキストファイルの拡張子を除いたファイル名( %~n1 )
  3. Pythonが動作するフォルダへ移動( pushd %pythonpath% )
  4. Python-Markdown を実行( python -m markdown %1 … )
  5. Python-Markdown の出力とヘッダー、フッターを結合、HTMLファイルとして作成
  6. HTMLファイルをテキストファイルと同じフォルダに移動
  7. 作成したHTMLファイルを起動

□ヘッダー、フッターの説明

コードは、こちらを参照してください。

■作成済みファイル

自分で作るのが面倒という方、こちらからダウンロードできます。
ただし、Pythonの実行環境は別途用意してください。

■余談(テキストエディタについて)

永い間、備忘録などをテキストで管理してきました。
最初は、「知子の情報」1というアプリを使いました。
それが使えなくなって(理由は忘れました)から、「紙」2というフリーソフトを使いました。
「紙」は、紆余曲折ありましたが現在でもフリーソフトとして「紙copi Lite」が供給されています。

私は、現在も「紙copi Lite」を愛用しています。
しかし、フリー版にはバッチファイルを起動する機能がありません。
有償版には、「外部連携」という機能があります。(買えばいいのに・・・)

Markdown で書いている時にプレビューを表示する便利な方法は、VS Codeを使うことだと思っています。
VS Code拡張機能Markdown Preview Enhanced』をインストールしておけば、テキストの編集画面とプレビュー画面を並べて表示でき、編集画面を編集するとプレビューも追従して直ぐに確認することが出来ます。3

もちろん、Markdown 対応エディタという選択肢もあると思いますが、VS Codeを既に使用している(プログラム作成で)ので、個人的に興味が湧きません。

それでも、「紙copi Lite」を使いたかったので、今回のバッチを作成しました。

テキストのアウトライン表示をご存知でしょうか。 簡単に言うと見出しを別表示する機能です。
アウトライン表示はMarkdown 記法で書いたテキストファイルを見やすくしてくれます。
さらに見出しを移動するだけで見出しに含まれる文章も移動できます。
フリーのテキストエディタMery4は、アウトライン表示機能のあるテキストエディタです。
その上、外部コマンドを起動する機能が付いています。
今後はMeryを使っていくのかどうか、自分でも楽しみです。

「Notion」5というサービスを知りました。機能的に「紙」とダブるところがあります。その上、データベースという機能があって、好奇心に駆られています。

■さいごに

はてなブログをはじめました。(この記事がそうなので当たり前ですよね)
はてなブログには3種類の記事の書き方があります。
元エンジニアの私は、少しネット検索しただけで Markdown 記法を選びました。

Markdown 記法は、手元にテキストとして原稿が残せるし、オフラインで下書きを作ることもできるので自分には合っていると思います。

そんな私は、はてなIDを取得する前から記事の下書きをはじめました。
そもそも記事が書けそうになかったらブログをはじめても無駄だと思ったからです。

この記事も書き始めてからずいぶん経ちます。やっと公開です。

今は、「紙copi Lite」とMeryの二刀流という感じです。
概要は、「紙copi Lite」で、プレビューしたくなったらMeryで、という感じです。
やはり、バッチを起動するのは手間なので、Meryでショートカット登録して使っています。

CSSファイルも、はてなブログやテーマのCSSを保存してローカルでもある程度動作するように修正して、見た目ができるだけ はてなブログと同じになるようにして使っています。

いづれ、この辺りもご紹介できればと思います。

□ご注意

本記事は次のバージョンの下で動作した内容を元に記述しています。

■参考

Pyton-Markdownマニュアル:Python-Markdown — Python-Markdown 3.3.4 documentation
PyYAMLマニュアル:pyyaml.org/wiki/PyYAMLDocumentation

投稿:2021-05-25