azukipochette's weblog

memory dump (mini)

PowerShell を使って Markdown を GitHub 風の HTML ファイルに変換する

TL;DR *1

PowerShell 6 以降で、下記のコマンドのように実行すればよい。

$mdfile = 'C:\path\to\yourmarkdownfile.md'
ConvertTo-Html -Body ('<div class="markdown-body">' + (ConvertFrom-Markdown -Path $mdfile).Html + '</div>')  -Head '<link rel="stylesheet" href="https://github.com/sindresorhus/github-markdown-css/blob/main/github-markdown.css">' | Out-File -FilePath out.html

おまけ (雑談)

皆さんは何でメモを書いているだろうか。私は最近もっぱら Markdown である。
Visual Studio Code は標準でプレビュー表示できるし、Pandoc によって MarkdownPowerPoint にも Word ファイルにもなる。
Pandoc は様々なドキュメントを相互に変換する非常に野心的なプロジェクトで、細かい部分で物足りないことも多いが大変便利なツールである。

pandoc.org

だが、実行環境の準備が 辛すぎる

私たちが望んでいることは単純明快である。Markdown ファイルを非エンジニアな人に見せて「拡張子 md って何のアプリで開くんですか?」とか「開いたら所々よく分からない文字が書いてあるんだけど」と言わわれずに、誰でも簡単に読めるファイルに変換したいのである。それなのに、HTML ファイルに変換するだけで、(Pandoc の場合) Haskell の環境整備が必要だったり、Markdown Parser なライブラリを使ったツールを作らなければならないなんて 辛すぎる

そんなある日、PowerShellMicrosoft Docs を眺めていたら、ConvertFrom-Markdown なるコマンドレットを見つけた。

docs.microsoft.com

しかも、このコマンドレットは PowerShell 6 以降で標準搭載されており、必要なときに気軽に変換できる *2

更に、この変換は内部的に Markdig という OSS ライブラリを使っているらしく、"Markdown" 仕様だけではなく "CommonMark" 仕様にも対応している。*3
なので、表や注釈といった表現もしっかり変換してくれる。

github.com

ConvertFrom-MarkdownHtml プロパティなどを持つオブジェクトを返すが、Html プロパティの中身は Markdown で記述された HTML タグだけを持っている。
最近の Web ブラウザはとても賢いので、そのまま不完全な HTML ファイルとして出力しても表示はできるが、正しい HTML ファイルとして出力するなら次のように記述することになる。

ConvertTo-Html -Body (ConvertFrom-Markdown -Path $mdfile).Html | Out-File -FilePath out.html

これで出力すると HTML ファイルにはなるが、見た目がシンプルすぎて物足りない。
開発者視点で最も見慣れている且つオシャレな Markdown の表示は GitHub だろうということで、GitHubMarkdownスタイルシートを使うことにする。

とはいっても、GitHub 社は直接 Markdown 用の CSS ファイルを提供していない。だが、同じことを思う人は既にたくさんいて、GitHubスタイルシートMarkdown 部分を抜いているリポジトリGitHub 上に公開されている。*4

github.com

このプロジェクトのファイルを直接参照してもよいが、表示は速いに越したことがないので CDN (Content Delivery Network) 上のファイルを使う。今回は Cloudflare 社が提供している cdnjs 上にあるファイルを使用する。

cdnjs.com

では、これをスタイルシートとしてヘッダーに追記すれば終わりか...と思うかもしれないがそうではない。
CSS の中身を見てみると、次のように記載されていることがわかる(一部のみ抜粋)。

.markdown-body details,
.markdown-body figcaption,
.markdown-body figure {
  display: block;
}

.markdown-body summary {
  display: list-item;
}

つまり、markdown-body クラスの範囲になければならない。 ということで、ConvertFrom-Markdown で変換した HTML タグを <div class="markdown-body></div> で囲む。
こうして完成したのが、最初に表示した以下のコードである。

$mdfile = 'C:\path\to\yourmarkdownfile.md'
ConvertTo-Html -Body ('<div class="markdown-body">' + (ConvertFrom-Markdown -Path $mdfile).Html + '</div>')  -Head '<link rel="stylesheet" href="https://github.com/sindresorhus/github-markdown-css/blob/main/github-markdown.css">' | Out-File -FilePath out.html

Enjoy!

*1:"Too Long Don't Read" の略で、「長すぎて読めないよ」 というが転じて「要約」として用いられている言葉らしい。

*2:PowerShell を入れなければならないじゃないか、というツッコミは私には聞こえない

*3: 私の記憶による歴史の話 : Markdown は かの John Gruber が作成したものでテキストで見やすくリッチな表現ができるので人気が出た。しかし John Gruber が作った仕様では表現力が物足りないと思ったものたちが「方言(Flavor)」として拡張し始めた。代表的なものに GitHub Flavored Markdown (GFM) がある。このように様々な方言ができたせいで、互換性に問題が出てしまい混乱した。そこで Markdown を標準化するために John Gruber に相談を持ちかけたが、John Gruber は自分が決めた仕様で十分だと取り合わなかったため、Markdown ではなく CommonMark として仕様をまとめたのである。つまり John Gruber 的には Markdown は彼が決めた Markdown であるが、私たちが知っている Markdown は CommonMark な部分も多分に含んでいるということである。曖昧な記憶なので、間違っていたら正解を教えてください。

*4:この記事を記述している時点で 5.8k スター...とんでもない需要だ

開発環境にインストールされている Visual Studio のバージョンをコマンドラインで取得する

Visual Studio 2017 以降のバージョンでは、同一マシンに安全に Visual Studio を複数バージョンインストールことができるようになった一方で、どの場所にどの Visual Studio がインストールされているのかが把握しにくいという新しい管理上の問題を生んでいる。その問題を解決するために提供されているツールが vswhere コマンドである。

vswhere コマンドは、Visual Studio Installer の中にバンドルされているが、GitHub からも入手することができる。

github.com

vswhere を使ってインストールされているバージョンを取得する例を以下に示す。

(& $(Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe') -prerelease -format json | ConvertFrom-Json).catalog.productDisplayVersion

実行結果の例を以下に示す。

16.11.5
17.0.0 Preview 6.0

なお、PowerShell で ConvertFrom-Json で変換しなくても -property オプションを指定すれば、指定した情報だけを取得できる。

 & $(Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe') -prerelease -property catalog_productDisplayVersion

ただし、この方法の場合、複数のプロパティを取得したいということはできない (そういう "仕様" のようだ)。

github.com

補足

上記の例で、-prelease オプションを付けている理由は、vswhere は既定でリリース済みのプロダクトのみを表示するという仕様になっているためである (未リリースである Visual Studio Preview が表示されない)。
さらに混乱しやすいのが -all オプションで、このオプションは Preview リリースは含まない。-all オプションを付けると不完全なインストールになっているものであっても表示するという意味合いとなる。

Windows Installer (MSI) 形式のファイルをインストールせずに展開する方法

Windows Installer (*.msi 形式) のファイルをインストールせずに展開するには Windows Installer 向けのコマンドライン ツールである msiexec を使用する。

docs.microsoft.com

このツールには管理者用モードと呼ばれる /a オプションがあり、このオプションを使うことで特定の場所に展開することができる。
実行例を以下に示す。

msiexec /a setup.msi targetdir="C:\path\to\extractdir" /qn

WinDbgX をインストールした環境でも旧バージョンの WinDbg を起動したい

WinDbg vNext こと WinDbgX をインストールすると、旧バージョンの WinDbg を起動しても自動的に WinDbgX が起動するようになる。*1

WinDbg を使いたい場合は下記のレジストリを有効にすることで、リダイレクトを止めることができる。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windbg]
"ShouldRedirectToWinDbgNext"=dword:00000000

*1:正確には、WinDbg.exe がレジストリを確認して、リダイレクトが有効だと WinDbgX を起動して自身は終了する実装になっている

VMWare Workstation で簡易インストールした仮想マシンのキーボードを英語配列にする

VMWare Workstation は日本語の Windows を使っている場合、日本語のキーボードレイアウトに自動設定してくれる。
英語キーボードを使っている人はこのままだと一部のキーが刻印通りに入力できないため、以下のようにレジストリファイルを作成してインポートすると良い。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters]
"LayerDriver JPN"="kbd101.dll"
"OverrideKeyboardIdentifier"="PCAT_101KEY"
"OverrideKeyboardSubtype"=dword:00000000

2020 年もブログをご覧いただき、ありがとうございました。

2020 年も今日で終わりですね。今年もこんなブログをご覧頂きありがとうございました。
「仕事の話はしない」、「イライラしている日は更新しない」、「自分の日々のメモになりつつ、誰かに役立つ記事を書く」をテーマに書いているこのブログ。自分で設定した縛りがキツすぎて全然更新できなかった 2019 年。それを反省した 2020 年でした。
蓋を開けてみれば、2019 年は 4 回、2020 年はこの記事を入れて 12 回投稿しておりました。これを 300% 増とみるか、わずか 12 回と見るかは....今日は触れないでおきましょう(笑)
検索エンジンの結果にヒットして「あ、そうなんだ」という役立つ情報になっていればいいなと思って書いています。時々しか書かないので「前説が長い」とか、「結論から遠い」とかいろいろなご意見があろうかと思いますが、個人ブログなので「個性」ということで許していただければ幸いです。
皆様、よいお年をお迎えください!

(追伸)
このブログの運営元である「はてな」という会社を応援する目的で有料版である PRO にしておりましたが、来年から無料版にダウングレードすることにしました。
広告の表示や、記事にはてなキーワードのリンクなどが付くと思いますので予めご了承ください。

deepL REST API で XML タグを含む文字列を渡すと課金はどうなるかを検証

日本語への翻訳が群を抜いていると話題の deepL ですが、有償版である deepL Pro の開発者向けプランでは、deepL の翻訳サービスを REST API として呼び出す事ができます。
私は PowerPoint のスライドを翻訳するアプリを作り、内部の翻訳エンジンに deepL を使うことにしました。

www.deepl.com

deepL が提供する REST API では、パラメータに tag_handling=xml と指定することで、XML タグを考慮して翻訳してくれます。
これにより、タグによって修飾(色、フォント サイズ、強調など)されている箇所を気にせず、そのまま翻訳することができます。

しかし、気になるのが課金対象となる「文字数」です。 REST API に渡したテキストの文字数なのか、タグを除いた翻訳対象となる文字数なのかがよく分かりません。

そこで、実際に実験してみました。

まず PowerPoint のスライドを解析し、パラグラフを取得します。実際のデータは以下の通りです。

<a:r xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:rPr lang="en-US" dirty="0" /><a:t>Developing Cross-Platform Web Apps With Blazor</a:t></a:r>

これを REST API で翻訳した結果 (JSON) は以下の通りです。

{
  "translations": [
    {
      "detected_source_language": "EN",
      "text": "<a:r xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:rPr lang=\"en-US\" dirty=\"0\" /><a:t>BlazorでクロスプラットフォームのWebアプリを開発する</a:t></a:r>"
    }
  ]
}

ダッシュボードで確認したところ、課金対象となっているのは 46 文字 ($0.12) でした。 「翻訳した文字数」で課金されていますので、安心して XML タグを投げられますね。 :-)