背景

最近在公司用Markdown写技术博客时,需要插入伪代码块,而Markdown里没有找到比较美观的实现方案,想到之前在学校写论文时一直用LaTex,里面的伪代码非常漂亮,所以就想在Markdown里混合使用LaTex,下面是从网上找到的解决方案汇总,方便自己以后查阅。

安装Tex环境

  • 从以下网址下载Tex环境后安装,这个是MacOS下的Tex,Windows系统的是别的。
    http://www.tug.org/mactex/mactex-download.html

VSCode配置

  • 安装LaTeX Workshop插件
  • settings.json增加以下配置
    "latex-workshop.latex.recipes": [
    {
    "name": "xelatex",
    "tools": [
    "xelatex"
    ]
    },
    {
    "name": "latexmk",
    "tools": [
    "latexmk"
    ]
    },
    {
    "name": "pdflatex -> bibtex -> pdflatex*2",
    "tools": [
    "pdflatex",
    "bibtex",
    "pdflatex",
    "pdflatex"
    ]
    }
    ],
    "latex-workshop.latex.tools": [
    {
    "name": "latexmk",
    "command": "latexmk",
    "args": [
    "-synctex=1",
    "-interaction=nonstopmode",
    "-file-line-error",
    "-pdf",
    "%DOC%"
    ]
    },
    {
    "name": "xelatex",
    "command": "xelatex",
    "args": [
    "-synctex=1",
    "-interaction=nonstopmode",
    "-file-line-error",
    "%DOC%"
    ]
    },
    {
    "name": "pdflatex",
    "command": "pdflatex",
    "args": [
    "-synctex=1",
    "-interaction=nonstopmode",
    "-file-line-error",
    "%DOC%"
    ]
    },
    {
    "name": "bibtex",
    "command": "bibtex",
    "args": [
    "%DOCFILE%"
    ]
    }
    ],
    "latex-workshop.view.pdf.viewer": "tab",
    "latex-workshop.latex.clean.fileTypes": [
    "*.aux",
    "*.bbl",
    "*.blg",
    "*.idx",
    "*.ind",
    "*.lof",
    "*.lot",
    "*.out",
    "*.toc",
    "*.acn",
    "*.acr",
    "*.alg",
    "*.glg",
    "*.glo",
    "*.gls",
    "*.ist",
    "*.fls",
    "*.log",
    "*.fdb_latexmk"
    ],

中文字体支持

完成上面工作后,就可以在VSCode下编辑和预览Tex文件了。不过中文支持不好,需要按下面操作兼容中文字体。

  • 打开~/.pandoc/templates/default.latex文件,把以下内容填进去。
    \documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$]{$documentclass$}
    \usepackage{geometry} % 設定邊界
    \geometry{
    top=1in,
    inner=1in,
    outer=1in,
    bottom=1in,
    headheight=3ex,
    headsep=2ex
    }
    \usepackage[T1]{fontenc}
    \usepackage{lmodern}
    \usepackage{amssymb,amsmath}
    \usepackage{ifxetex,ifluatex}
    \usepackage{fixltx2e} % provides \textsubscript
    % use upquote if available, for straight quotes in verbatim environments
    \IfFileExists{upquote.sty}{\usepackage{upquote}}{}
    \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
    \usepackage[utf8]{inputenc}
    $if(euro)$
    \usepackage{eurosym}
    $endif$
    \else % if luatex or xelatex
    \usepackage{fontspec} % 允許設定字體
    \usepackage{xeCJK} % 分開設置中英文字型
    \setCJKmainfont{STSong} % 設定中文字型
    \setmainfont{Georgia} % 設定英文字型
    \setromanfont{Georgia} % 字型
    \setmonofont{Courier New}
    \linespread{1.2}\selectfont % 行距
    \XeTeXlinebreaklocale "zh" % 針對中文自動換行
    \XeTeXlinebreakskip = 0pt plus 1pt % 字與字之間加入0pt至1pt的間距,確保左右對整齊
    \parindent 0em % 段落縮進
    \setlength{\parskip}{20pt} % 段落之間的距離
    \ifxetex
    \usepackage{xltxtra,xunicode}
    \fi
    \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
    \newcommand{\euro}{€}
    $if(mainfont)$
    \setmainfont{$mainfont$}
    $endif$
    $if(sansfont)$
    \setsansfont{$sansfont$}
    $endif$
    $if(monofont)$
    \setmonofont{$monofont$}
    $endif$
    $if(mathfont)$
    \setmathfont{$mathfont$}
    $endif$
    \fi
    % use microtype if available
    \IfFileExists{microtype.sty}{\usepackage{microtype}}{}
    $if(geometry)$
    \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
    $endif$
    $if(natbib)$
    \usepackage{natbib}
    \bibliographystyle{plainnat}
    $endif$
    $if(biblatex)$
    \usepackage{biblatex}
    $if(biblio-files)$
    \bibliography{$biblio-files$}
    $endif$
    $endif$
    $if(listings)$
    \usepackage{listings}
    $endif$
    $if(lhs)$
    \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
    $endif$
    $if(highlighting-macros)$
    $highlighting-macros$
    $endif$
    $if(verbatim-in-note)$
    \usepackage{fancyvrb}
    $endif$
    $if(tables)$
    \usepackage{longtable}
    $endif$
    $if(graphics)$
    \usepackage{graphicx}
    % We will generate all images so they have a width \maxwidth. This means
    % that they will get their normal width if they fit onto the page, but
    % are scaled down if they would overflow the margins.
    \makeatletter
    \def\maxwidth{\ifdim\[email protected]@width>\linewidth\linewidth
    \else\[email protected]@width\fi}
    \makeatother
    \let\Oldincludegraphics\includegraphics
    \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=\maxwidth]{#1}}
    $endif$
    \ifxetex
    \usepackage[setpagesize=false, % page size defined by xetex
    unicode=false, % unicode breaks when used with xetex
    xetex]{hyperref}
    \else
    \usepackage[unicode=true]{hyperref}
    \fi
    \hypersetup{breaklinks=true,
    bookmarks=true,
    pdfauthor={$author-meta$},
    pdftitle={$title-meta$},
    colorlinks=true,
    urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
    linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
    pdfborder={0 0 0}}
    \urlstyle{same} % don't use monospace font for urls
    $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$
    \setlength{\parindent}{0pt}
    %\setlength{\parskip}{6pt plus 2pt minus 1pt}
    \setlength{\emergencystretch}{3em} % prevent overfull lines

    \title{\huge 在OSX平台上的XeLaTeX中文測試} % 設置標題,使用巨大字體
    \author{FoolEgg.com} % 設置作者
    \date{February 2013} % 設置日期
    \usepackage{titling}
    \setlength{\droptitle}{-8em} % 將標題移動至頁面的上面

    \usepackage{fancyhdr}
    \usepackage{lastpage}
    \pagestyle{fancyplain}

    $if(numbersections)$
    \setcounter{secnumdepth}{5}
    $else$
    \setcounter{secnumdepth}{0}
    $endif$
    $if(verbatim-in-note)$
    \VerbatimFootnotes % allows verbatim text in footnotes
    $endif$
    $if(lang)$
    \ifxetex
    \usepackage{polyglossia}
    \setmainlanguage{$mainlang$}
    \else
    \usepackage[$lang$]{babel}
    \fi
    $endif$
    $for(header-includes)$
    $header-includes$
    $endfor$

    $if(title)$
    \title{$title$}
    $endif$
    \author{$for(author)$$author$$sep$ \and $endfor$}
    \date{$date$}

    \begin{document}
    $if(title)$
    \maketitle
    $endif$

    $for(include-before)$
    $include-before$

    $endfor$
    $if(toc)$
    {
    \hypersetup{linkcolor=black}
    \setcounter{tocdepth}{$toc-depth$}
    \tableofcontents
    }
    $endif$
    $body$

    $if(natbib)$
    $if(biblio-files)$
    $if(biblio-title)$
    $if(book-class)$
    \renewcommand\bibname{$biblio-title$}
    $else$
    \renewcommand\refname{$biblio-title$}
    $endif$
    $endif$
    \bibliography{$biblio-files$}

    $endif$
    $endif$
    $if(biblatex)$
    \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$

    $endif$
    $for(include-after)$
    $include-after$

    $endfor$
    \end{document}

Markdown里使用LaTex

Markdown文件里可以插入LaTex片段,可以通过Pacdoc将md文件转成pdf或其他文件。

  • 新建一个md文件test.md,填入以下内容

    ## 背景
    MacOS LaTex环境配置

    ## 嵌入latex算法伪代码

    ---
    header-includes:
    - \usepackage[ruled,vlined,linesnumbered]{algorithm2e}
    ---
    # Algorithm 1
    Just a sample algorithmn
    \begin{algorithm}[H]
    \DontPrintSemicolon
    \SetAlgoLined
    \KwResult{Write here the result}
    \SetKwInOut{Input}{Input}\SetKwInOut{Output}{Output}
    \Input{Write here the input}
    \Output{Write here the output}
    \BlankLine
    \While{While condition}{
    instructions\;
    \eIf{condition}{
    instructions1\;
    instructions2\;
    }{
    instructions3\;
    }
    }
    \caption{While loop with If/Else condition}
    \end{algorithm}
  • md生成pdf

    pandoc --pdf-engine=xelatex test.md -o test.pdf

    或者

    pandoc --pdf-engine=xelatex --template=[template.latex的路径] test.md -o test.pdf

    不配置--template时默认使用~/.pandoc/templates/default.latex

总结

在VSCode里,如果Markdown文件里有LaTex片段的话,是无法完全预览的,所以只能用Pandoc转成pdf来看效果,如果你有更好的办法欢迎提供。