PandocでTemplateを使うときのためのメモ

Pandocの--Templateオプションを利用して、Markdownから完全なHTMLを出力するときにTemplateを使うためのメモ。

Pandoc User’s GuidePandoc ユーザーズガイド 日本語版を基に記載。 環境はWindows 10 (64bit)。 随時更新。

正確な一次ソースとしてはPandoc User’s GuideのTemplatesがあります。

デフォルトテンプレートを確認する

単に-s/--standaloneオプションを利用した際に使われるデフォルトのテンプレートはpandoc -D *FORMAT*で確認できる。 FORMATは出力フォーマットを指定する。

PS D:\SandBox> pandoc -D markdown
$if(titleblock)$
$titleblock$

$endif$
$for(header-includes)$

# *sinp*

PS D:\SandBox> pandoc -D html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
<head>

# *snip*

Templateを使って変換する

一番簡単なのはtemplateファイルを--templateオプションで指定すること。 (--templateを指定すると、自動的に-s/--standaloneオプションも有効になる)

PS D:\SandBox> pandoc --template=template.html D:\Sandbox\PandocでTemplateを使うためのメモ.md

テンプレートファイルの優先順位

テンプレートファイルの利用優先順位は以下の通り。

どの優先順位でテンプレートやユーザデータディレクトリが使われるかは、(よく読めば)Pandocのユーザーズガイドに書かれています。

*snip*

  1. カレントディレクトリを見る
    • 指定されている文字通りのファイル名を探す
    • 拡張子が無い場合は、出力フォーマットに対応する拡張子を勝手に補う
  2. --data-dir で指定されるユーザデータディレクトリの中にある「templates」ディレクトリを探す
  3. デフォルトユーザデータディレクトリの中にある「templates」を探す
    1. Pandoc既定のデータディレクトリの中にある「templates」を探す

メモ: Pandocのテンプレートとデータディレクトリの優先順位

自作テンプレートを作る

  • テンプレートファイルに記載された$body$部がPandocにより生成したHTMLに置き換わる。
  • 自分で定義した変数も$var$のように利用できる(--variable=*KEY*:*VAL*なり、--metadata=*KEY*:*VAL*で指定する)。
  • ifやforといった制御構造も利用できる
  • 各種組み込みの変数もある。メタデータ向けの変数はファイルで読める(--metadata-file=*FILE*))

その他

以下のような拡張機能も便利そう。

Extension: pandoc_title_block

  • 入力ファイル冒頭の%で始まる行を、title,author,dataという変数として読み込んでくれる。
  • デフォルトで有効だが、明示的に指定したい場合は--from *FORMAT*+pandoc_title_blockする。
  • Lintツール(markdownlintなど)によっては警告が出力されるので、Lintツール側で無効化する必要あり。

WindowsでPandocをいれてみる

  • Markdownを手軽にHTMLに変換したい
  • かつて、DISCOUNTを使ったりしてみたのだが、結局Windowsマシンでも動かないと面倒なので、メジャーなPandocをいれてみる。

Pandocについて

環境

PS D:\>  "$((get-wmiobject win32_operatingsystem).caption) ($((get-wmiobject win32_operatingsystem).version))"
Microsoft Windows 10 Pro (10.0.17134)

PS D:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      17134  228

実際にやること

ようはPandoc で Windows に作るmarkdown to html, docx 環境において書かれていることをやるだけ。

  • github pandoc から最新版の Pandoc-x.yy.z-windows.msi をダウンロード。
  • Pandoc-x.yy.z-windows.msi をインストール。
  • システム環境変数 Path に 「C:\Users\UserName\AppData\Local\Pandoc」を通す。(※UserName は現在のログインユーザ名)

インストールされたことはpandoc --versionを実行して確認できる。

Markdown to HTML

細かいところはユーザガイドを読めばよいのでひとまず動かしてみる (ヘルプを表示するpandoc --helpWindowsでは説明のないオプションの一覧だけなので)

# 完全なHTMLを作る(head,body,htmlタグあり))
pandoc ./test.md -f markdown -t html -o test.html -s

# 部分的なHTMLをつくる(パーツとしてのHTMLへの変換)
pandoc ./test.md -f markdown -t html -o test.html

# githubのmarkdownにしたい
pandoc ./test.md -f markdown_github -t html -o test.html

先送り事項

pandoc は UTF8 を前提にしているのだが、日本語環境のPowershell文字コードは932(Shift-JIS)。 このため標準出力に結果を出力すると文字化けする。

chcp 65001文字コードUTF-8にし、かつ日本語フォントを指定すれば良いかと思ったが、その場合は日本語を含むファイル名がつぶれる。

ひとまず、ファイルへの書き出しに問題はないので先送りとした。

PosgtreSQLをpg_restore -c でリストアするとスキーマの権限が正しくリストアされない話

ただの備忘録。別にPostgreSQLに詳しいわけではない。

やったこと

pg_dump -d <hoge> -FtPostgreSQLのバックアップを取得 pg_restore -c -F t -d <hoge>PostgreSQLをリストアしようとした。

起こったこと

postgresのスキーマ(PUBLIC)に権限(privilages)がリストアされない。 -cもとい--cleanオプションを付けてprivilagesを削除しているので、リストアされたスキーマはprivilagesがない形になる。

スキーマのprivilegesがバックアップ前後で以下のように変わる*1

バックアップ前

全ロールにUSAGEとCREATEが付与されていた。

  name  |  owner   |  access privileges   |      description
--------+----------+----------------------+------------------------
 public | postgres | postgres=uc/postgres+| standard public schema
        |          | =uc/postgres         |

バックアップ後

一切の権限が付与されていない。

   Name  |  Owner   | Access privileges |      Description
 --------+----------+-------------------+------------------------
  public | postgres |                   | standard public schema

このためpostgresユーザ以外はスキーマへのアクセスができなくなる。 実際にはテーブル一覧を表示できなくなったり、スキーマ名を省略できなくなる。

オブジェクトへの権限がついていれば、明示的にスキーマを指定すればオブジェクトへアクセスはできるよう。 (schema.tablenameのように指定する)

なお、PUBLIC以外のスキーマで起こるかは未確認。

原因

詳細は不明なのだが、おそらくPostgreSQLバグ。

PostgreSQL: Re: BUG #14788: `pg_restore -c` won't restore schema access privileges.を参照すると同じような事象が報告されている。

上記では9.6.4だが、まだfixされているわけではないのだろう。

暫定対処

schemaに手動でGRANTする。PUBLICスキーマなら以下。

GRANT ALL ON SCHEMA public TO PUBLIC

その他

\dn+のアクセス権限の読み方が分からなかった。コマンド名で調べても情報がないが、ちゃんと大本のGRANTのドキュメントには記載があった。 困ったときはググるまえに公式ドキュメントをちゃんと読んだ方がよい。

*1:後述するメーリングリストからの引用

神崎洋治(2017)人工知能解体新書

人工知能がどういったもので、何ができるのか勉強する前ふりとして読んだ。

本としては悪くないと思うのだが、求めていた内容ではなかった。

本書はその内容の大半が実例だ。人工知能そのものの説明は2割あるかないかで、しかも体系だってはいない。

ビジネス向けの本、といったところで、いちおう科学向けの新書レーベルに期待していたものでば下さいはなかった。 (単に著者が想定した読者像と私にもがアンマッチだっただけなのだが)

Windowsの送る(SendTo)メニューでスラッシュ区切りのパス文字列をクリップボードにコピーする

概要

  • Windowsのパス文字列を他の言語に渡す際、円記号(¥)もといバックスラッシュ(\)を毎回処理するのが面倒
  • エクスプローラなどのGUIメニューで選択するときにスラッシュ(/)を区切り文字とする標準的なパス文字列を取得したい。
  • Powershellスクリプトを作成して、右クリックメニューの「送る(SendTo)」に登録することで簡単に取得できた。

背景

歴史的な経緯もあり*1Windowsのパスは円記号もといバックスラッシュ(\)区切り。

ただ、バックスラッシュはRやPythonといった各種プログラミング言語ではエスケープ文字として使われている。

このため、例えばRで以下のようにバックスラッシュが含まれるWindowsのパス文字列を直接利用できない。

#以下は動かない
> setwd("D:\SandBox\")
 エラー:  ""D:\S" で始まる文字列の中で '\S' は文字列で認識されないエスケープです

#以下のどちらかなら動く
> setwd("D:/SandBox/")
> setwd("D:\\SandBox\\")

大したことではないのだが、毎度バックスラッシュを処理して渡すのはめんどくさいので簡単にしたい。

方法

Windowsエクスプローラには、ファイル・フォルダの右クリックメニューの中に「送る(SendTo)」というメニューがある。

このメニューはSendToフォルダにあるショートカットの集合体であり、実行すると選択したファイル・フォルダを引数としてそのショートカットを起動してくれる。

そこで、エクスプローラ上で簡単にバックスラッシュをスラッシュに変換した文字列を取得するために、パス文字列を変換するスクリプトを作成してそのショートカットをSendToに登録した。
これでファイル・フォルダを右クリックしてショートカットを選択すると、スラッシュで区切られた文字列を取得できるようになる。

以下のようなGet-FilePathWithSlash.ps1を作成する。cf.Powershell上で、パイプで渡すと文字化けする。

$OutputEncoding = [System.Text.Encoding]::GetEncoding('shift-jis')
$args[0] -replace "\\", "/" | clip.exe

追記 2018-07-04

上記だとクリップボードに改行が入っていしまうのでPowershell5.0以上が入っている環境なら以下のようにした方が良い

$OutputEncoding = [System.Text.Encoding]::GetEncoding('shift-jis')
$args[0] -replace "\\", "/" | Set-Clipboard

SendToフォルダの場所を確認する。cf.【PowerShell】SendToフォルダを表示するスクリプト2 | ほそぼそプログラミング日記

#SendToフォルダの場所
[Environment]::GetFolderPath('SendTo')

Path
----
C:\Users\majima_ko16\AppData\Roaming\Microsoft\Windows\SendTo

上記のフォルダにショートカットを任意の名前で作成し、プロパティのリンク先を以下のように書き換える。 cf. 「送る」with PowerShell - なにか作る

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -File "D:\<scriptPath>\Get-FilePathWithSlash.ps1"

その他

この方法を応用するとでCygwin用のパスも作れるだろう(cygpathはあるが)。

Powershellを使ってBasic認証を通してWebアクセスする

概要

  • PowershellInvoke-WebrequestのCredentialパラメータを使えば、簡単にBasic認証のかかったページにwebアクセスできる

実際

基本的に上記の通りCredentialを生成した上で、Invoke-Webreques-Credentialを指定してやればよい。 環境はWindows10で実行して試した、Powerhell 5.0以降であれば動作するはず。

その他

  1. ベーシック認証については以下を参照のこと

  2. Powershellを使って正しく認証プロキシ経由でWebアクセスする - mk_55's diaryでも記載したが、パスワードはSecureString等で事前に暗号化しておくことが望ましい。

Powershellを使って正しく認証プロキシ経由でWebアクセスする

概要

  • プロキシの自動構成スクリプト(.pac)に従って、正しい認証プロキシの認証を通した上で、Powershellでwebアクセスしたい。
  • つまり、アクセスするURLに対応するプロキシのURLを取得して、Invoke-Webrequestに渡してWebアクセスしたい。
  • [System.Net.WebRequest]::GetSystemWebProxy()を使うとOS設定を利用して、URLに対応するプロキシを取得することができる。

実際

OSでプロキシ設定がなされていることを前提としている

# 各種設定
$URL = "http://example.com"

# 認証情報の生成(本来は暗号化して外だししておく)
$ProxyUser = "User"
$ProxyPassword = "PassWord"
$securePassword = ConvertTo-SecureString $ProxyPassword -AsPlainText -Force
$proxyCredntial  = System.Management.Automation.PSCredential ($ProxyUser, $securePassword)

#システムのProxy設定を利用して、URLに対応するProxy経由でアクセス
$SystemProxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy = $SystemProxy.GetProxy($URL)
Invoke-Webrequest $URL -Proxy $proxy.AsoluteUri -ProxyCredential $proxyCredntial  Method Get

環境はWindows10で実行しているので、Powerhell 5.0以降であれば動作するはず。

その他

  1. web上にはデフォルトプロキシを設定してしまうという例が散見されるが、汎用性に欠ける。

  2. プロキシの自動構成スクリプト(.pac)、要はJavascriptなので、ScriptControllerで実行してやろうと思った。しかし、ScriptControllerは64bit OSでは廃止されており不可能だった。

  3. 実用を考えるなら、パスワードはスクリプトに記載しせず、事前にSecureStringを利用してファイルに保存しておき、スクリプトの中でCredentialを生成する必要すべき。*1

  4. 例示用のドメインについてはRFC2606を参照のこと。

*1:正直なところ、私はSecureStringについて正しく理解しているとは言い難い。どこかで調べてまとめたい