Markdownによる資料作成環境
概要
普段latexを使って週間報告資料等を作っているが、 簡単な資料を作るのにlatexを書くのは少々面倒である。
pandoc(およびlualatex)を使ってMarkdownからpdfを作成する環境を作成した。
環境は Windows 10 Home 64bit で、 インストールしたソフトは次の通りである。
- latex環境(TexLive or w32tex)
- pandoc 1.19.2.1
- pandoc-crossref
- UML図作成環境
- Visual Studio Code
インストール
latexのインストール
TexLive または w32tex をインストール
TexLiveの場合はfullでインストールするとサイズが巨大になり、 インストールに時間もかかり容量も大きくなるため注意。 ただしパッケージを選択する場合は、LuaLatexを使用するのでLuaLatexも選択すること。
pandocのインストール
pandocのプロジェクトページから、pandoc-1.19.2.1-windows.msiをインストール https://github.com/jgm/pandoc/releases/
pandoc-crossref を追加
https://github.com/lierdakil/pandoc-crossref/releases
windows-ghc8-pandoc1-19.zip をダウンロードして解凍
C:\Program Files (x86)\Pandoc\pandoc-crossref.exe
に配置(パスが通っている場所)
UML図環境のインストール
UML図を作成するのに便利なPlantUMLをインストールする。
Javaのインストール
Graphviz をインストール
PlantUML が使用しているソフトである Graphviz をインストール
一応 Windows Update を行っておく。
PlantUML をインストール
plantuml.jar をダウンロード
これが実行ファイルとなるので、お好みの場所に置く。 私の場合は
C:\Program Files Portable\PlantUML\plantuml.jar
Inkscape のインストール
PlantUML は ライブラリを追加したらpdfも出力できるということが書いてあったが、 情報が古いし失敗したのでやめた。
ベクター形式を保ったまま出力するために、PlantUMLの出力をsvgとし、 フィルターでinkscapeを用いてsvgからpdfへ変換する。
https://inkscape.org/ja/download/
からインストール
PlantUML filter の導入
mickey-happygolucky.hatenablog.com
こちらを参考にして少し変更 python3 がインストールされていること(Anaconda3-4.4.0-Windows-x86_64 等) PATHの設定も忘れずに。
C:\Program Files Portable\PlantUML\plantuml-filter.py
""" Pandoc filter to process code blocks with plantuml into plantuml-generated images. """ import subprocess import hashlib import os import sys import subprocess from pandocfilters import toJSONFilter, Str, Para, Image, attributes def sha1(x): return hashlib.sha1(x.encode('utf-8')).hexdigest() def out(s): sys.stderr.write('\t[PLTUML] ' + s + '\n'); imagedir = "plantuml-images" def pipe(cmd, data): p = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.stdin.write(data.encode('utf-8')) p.stdin.close() data = p.stdout.read() p.stdout.close() err = p.stderr.read().decode('utf-8') p.stderr.close() return data, err def graphviz(key, value, fmt, meta): if key == 'CodeBlock': [[ident,classes,keyvals], code] = value caption = "" if "plantuml" in classes: path = os.path.dirname(os.path.abspath(__file__)) filename = sha1(code) alt = Str(caption) tit = "" svg = imagedir + '/' + filename + '.svg' pdf = imagedir + '/' + filename + '.pdf' if not os.path.isfile(svg): try: os.mkdir(imagedir) except OSError: pass data, err = pipe(["java", "-jar", "C:\Program Files Portable\PlantUML\plantuml.jar", "-pipe", "-Tsvg", "-charset", "UTF-8"], code) if (len(err) > 0): out(err) return Para([Str(err)]) with open(svg, 'wb') as f: f.write(data) subprocess.call('"C:\Program Files\Inkscape\inkscape.exe" -z -f '+svg+' -A '+pdf , shell=True) try: image = Image(attributes({}), [alt], [pdf,tit]) return Para([image]) except: try: image = Image([alt], [pdf,tit]) return Para([image]) except: pass if __name__ == "__main__": toJSONFilter(graphviz)
Visual Studio Code のインストール
Visual Studio Code をインストール
https://code.visualstudio.com/download
拡張をインストール
- vscode-pandoc : vscode上でMarkdownからpdfを作成
- Paste-image : クリップボードの画像を、Markdownに貼り付け(画像の保存とリンクの作成)
- LaTex Workshop : texのテンプレートをいじるため
- Trailing Spaces : 行末の空白を可視化
- PlantUML 2.2.1 jebbs
テンプレートの作成
テンプレートファイル template.tex を AppData/Roaming/pandoc/templates/template.tex
に作成
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} \renewcommand{\theenumi}{\arabic{enumi}.} \renewcommand{\theenumii}{\arabic{enumii}.} \renewcommand{\theenumiii}{\arabic{enumiii}.} \renewcommand{\theenumiv}{\arabic{enumiv}.} \renewcommand{\labelenumi}{\arabic{enumi}.} \renewcommand{\labelenumii}{\arabic{enumi}.\arabic{enumii}.} \renewcommand{\labelenumiii}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}.} \renewcommand{\theenumiv}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}.\arabic{enumiv}.} \renewcommand{\labelitemi}{$$\circ$$} \renewcommand{\labelitemii}{$$\circ$$} \renewcommand{\labelitemiii}{$$\circ$$} \renewcommand{\labelitemiv}{$$\circ$$} $if(beamerarticle)$ \usepackage{beamerarticle} % needs to be loaded first $endif$ $if(fontfamily)$ \usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} $else$ \usepackage{lmodern} $endif$ $if(linestretch)$ \usepackage{setspace} \setstretch{$linestretch$} $endif$ \usepackage{amssymb,amsmath} \usepackage{ifxetex,ifluatex} \usepackage{fixltx2e} % provides \textsubscript \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} \usepackage[utf8]{inputenc} $if(euro)$ \usepackage{eurosym} $endif$ \else % if luatex or xelatex $if(mathspec)$ \ifxetex \usepackage{mathspec} \else \usepackage{unicode-math} \fi $else$ \usepackage{unicode-math} $endif$ \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase} $for(fontfamilies)$ \newfontfamily{$fontfamilies.name$}[$fontfamilies.options$]{$fontfamilies.font$} $endfor$ $if(euro)$ \newcommand{\euro}{€} $endif$ $if(mainfont)$ \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} $endif$ $if(sansfont)$ \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} $endif$ $if(monofont)$ \setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$} $endif$ $if(mathfont)$ $if(mathspec)$ \ifxetex \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} \else \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} \fi $else$ \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} $endif$ $endif$ $if(CJKmainfont)$ \usepackage{xeCJK} \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} $endif$ \fi % use upquote if available, for straight quotes in verbatim environments \IfFileExists{upquote.sty}{\usepackage{upquote}}{} % use microtype if available \IfFileExists{microtype.sty}{% \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts }{} \PassOptionsToPackage{hyphens}{url} % url is loaded by hyperref $if(verbatim-in-note)$ \usepackage{fancyvrb} $endif$ \usepackage[unicode=true]{hyperref} $if(colorlinks)$ \PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref $endif$ \hypersetup{ $if(title-meta)$ pdftitle={$title-meta$}, $endif$ $if(author-meta)$ pdfauthor={$author-meta$}, $endif$ $if(keywords)$ pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, $endif$ $if(colorlinks)$ colorlinks=true, linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$, citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$, urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$, $else$ pdfborder={0 0 0}, $endif$ breaklinks=true} \urlstyle{same} % don't use monospace font for urls $if(verbatim-in-note)$ \VerbatimFootnotes % allows verbatim text in footnotes $endif$ $if(geometry)$ \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} $endif$ $if(lang)$ \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} $if(babel-newcommands)$ $babel-newcommands$ $endif$ \else \usepackage{polyglossia} \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} $for(polyglossia-otherlangs)$ \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} $endfor$ \fi $endif$ $if(natbib)$ \usepackage{natbib} \bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} $endif$ $if(biblatex)$ \usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} $for(bibliography)$ \addbibresource{$bibliography$} $endfor$ $endif$ $if(listings)$ \usepackage{listings} $endif$ $if(lhs)$ \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} $endif$ $if(highlighting-macros)$ $highlighting-macros$ $endif$ $if(tables)$ \usepackage{longtable,booktabs} % Fix footnotes in tables (requires footnote package) \IfFileExists{footnote.sty}{\usepackage{footnote}\makesavenoteenv{long table}}{} $endif$ $if(graphics)$ \usepackage{graphicx,grffile} \makeatletter \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} \makeatother % Scale images if necessary, so that they will not overflow the page % margins by default, and it is still possible to overwrite the defaults % using explicit options in \includegraphics[width, height, ...]{} \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} $endif$ $if(links-as-notes)$ % Make links footnotes instead of hotlinks: \renewcommand{\href}[2]{#2\footnote{\url{#1}}} $endif$ $if(strikeout)$ \usepackage[normalem]{ulem} % avoid problems with \sout in headers with hyperref: \pdfstringdefDisableCommands{\renewcommand{\sout}{}} $endif$ $if(indent)$ $else$ \IfFileExists{parskip.sty}{% \usepackage{parskip} }{% else \setlength{\parindent}{0pt} \setlength{\parskip}{6pt plus 2pt minus 1pt} } $endif$ \setlength{\emergencystretch}{3em} % prevent overfull lines \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} $if(numbersections)$ \setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} $else$ \setcounter{secnumdepth}{0} $endif$ $if(subparagraph)$ $else$ % Redefines (sub)paragraphs to behave more like sections \ifx\paragraph\undefined\else \let\oldparagraph\paragraph \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} \fi \ifx\subparagraph\undefined\else \let\oldsubparagraph\subparagraph \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} \fi $endif$ $if(dir)$ \ifxetex % load bidi as late as possible as it modifies e.g. graphicx $if(latex-dir-rtl)$ \usepackage[RTLdocument]{bidi} $else$ \usepackage{bidi} $endif$ \fi \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex \TeXXeTstate=1 \newcommand{\RL}[1]{\beginR #1\endR} \newcommand{\LR}[1]{\beginL #1\endL} \newenvironment{RTL}{\beginR}{\endR} \newenvironment{LTR}{\beginL}{\endL} \fi $endif$ % set default figure placement to htbp \makeatletter \def\fps@figure{htbp} \makeatother $for(header-includes)$ $header-includes$ $endfor$ $if(title)$ \title{$title$$if(thanks)$\thanks{$thanks$}$endif$} $endif$ $if(subtitle)$ \providecommand{\subtitle}[1]{} \subtitle{$subtitle$} $endif$ $if(author)$ \author{$for(author)$$author$$sep$ \and $endfor$} $endif$ $if(institute)$ \providecommand{\institute}[1]{} \institute{$for(institute)$$institute$$sep$ \and $endfor$} $endif$ \date{$date$} \begin{document} $if(title)$ \maketitle $endif$ $if(abstract)$ \begin{abstract} $abstract$ \end{abstract} $endif$ $for(include-before)$ $include-before$ $endfor$ $if(toc)$ { $if(colorlinks)$ \hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$} $endif$ \setcounter{tocdepth}{$toc-depth$} \tableofcontents } $endif$ $if(lot)$ \listoftables $endif$ $if(lof)$ \listoffigures $endif$ $body$ $if(natbib)$ $if(bibliography)$ $if(biblio-title)$ $if(book-class)$ \renewcommand\bibname{$biblio-title$} $else$ \renewcommand\refname{$biblio-title$} $endif$ $endif$ \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} $endif$ $endif$ $if(biblatex)$ \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ $endif$ $for(include-after)$ $include-after$ $endfor$ \end{document}
設定
ユーザ設定に次を追加
//pandocの設定 "pandoc.pdfOptString": "--template=template.tex --filter \"C:\\Program Files Portable\\PlantUML\\plantuml-filter.py\" --latex-engine=lualatex -V documentclass=ltjarticle -V geometry:a4paper -V geometry:margin=2.5cm -V geometry:nohead --toc"
目次が必要ない場合は --toc
を外す
使ってみる
---
title: Markdownサンプル
author: takec
date: 2017/09/13
figureTitle: "図 "
tableTitle: "表 "
listingTitle: "コード "
figPrefix: "図"
eqnPrefix: "式"
tblPrefix: "表"
lstPrefix: "コード"
...
# セクション
## 番号付きリスト
1. リスト
1. リスト
1. リスト
1. リスト
#. リスト
#. リスト
#. \label{item:item1}リスト
#. リスト
#. リスト
#. リスト
\ref{item:item1}を参照
## 番号無しリスト
- リスト
- リスト
- リスト
- リスト
- リスト
- リスト
```plantuml
@startuml
skinparam {
defaultFontName メイリオ
}
skinparam sequence {
ArrowColor #000000
LifeLineBorderColor #000000
LifeLineBackgroundColor #1695a3
ActorBorderColor #000000
ActorBackgroundColor #ffffff
ActorFontStyle bold
ParticipantBorderColor #000000
ParticipantBackgroundColor #225378
ParticipantFontColor #ffffff
ParticipantFontStyle bold
}
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response
Bob --> Alice: 日本語もOK
|||
Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml
```
[@tbl:table] は表
| head1 | head2 |
|:------|------:|
| 1/1 | 1/2 |
| 2/1 | 2/2 |
: 表の例 {#tbl:table}
[@eq:equation] は数式
$$ e^{j\theta} = \cos(\theta) + j\sin(\theta) $$ {#eq:equation}
[@lst:listing] はコード
```{#lst:listing .python .numberLines caption="コードサンプル"}
import math
print(math.pi)
```
[@fig:figure]は画像
![画像サンプル](2017-09-13-11-59-49.png){#fig:figure width=50%}