メモ:R MarkdownにpLaTeX用のdocumentclassを適用する

というのは、たとえばjsarticleを使いたい、みたいな話だけど、これは端的にできない。 ので、.texを吐き出した後に手動でplatexするしかないっぽい...

(免責事項:LaTeXまったく詳しくないです。間違ってたら優しく教えてください...)

とりあえずやってみる

とりあえずこんな感じのやつをknitしたいとする。 相互参照を使いたいのでbookdownパッケージのpdf_document2にしている。

---
title: "test"
output: bookdown::pdf_document2
---

ここでおもむろに図\@ref(fig:plot1)をプロットしよう。

 ```{r plot1, fig.cap="ご覧ください、このきれいなプロット!"}
plot(1)
 ```

しかしこれはエラーになる。

! Package inputenc Error: Unicode char 縺・(U+3053)
(inputenc)                not set up for use with LaTeX.

Error: Failed to compile test.tex. See test.log for more info.
In addition: Warning message:
In grepl("==> Fatal error occurred", x[i], fixed = TRUE) :
  input string 1 is invalid in this locale
Execution halted

日本語がだめだった。

R Markdownで日本語を使いたい

まずは日本語を使えるようにしたい。 ググるといろいろ引っかかるけどとりあえずこれを参考にやってみる。keep_tex: yesはこのあとTeXファイルをいじることになるので入れている。

---
title: "test"
output:
  bookdown::pdf_document2:
    latex_engine: lualatex 
    keep_tex: yes
documentclass: ltjsarticle
---

これは無事に成功する。

f:id:yutannihilation:20180812123311p:plain:h450

documentclassjsarticleを指定してみる

ではいよいよ、jsarticleを指定してみよう。

---
title: "test"
output:
  bookdown::pdf_document2:
    latex_engine: lualatex 
    keep_tex: yes
documentclass: jsarticle
---

これは次のようなエラーになる。まあそうなりますよね。。

! LaTeX Error: This file needs format `pLaTeX2e'
               but this is `LaTeX2e'.

Error: Failed to compile test.tex. See test.log for more info.
Execution halted

latex_engineplatexにしてみる

じゃあplatexを使えばいいんじゃないか?というと、そんなことはできない。

---
title: "test"
output:
  bookdown::pdf_document2:
    latex_engine: platex 
    keep_tex: yes
documentclass: jsarticle
---
Error in match.arg(latex_engine, c("pdflatex", "lualatex", "xelatex")) : 
  'arg' should be one of "pdflatex", "lualatex", "xelatex"
Calls: <Anonymous> ... <Anonymous> -> pdf_book -> base_format -> match.arg
Execution halted

LaTeXファイルをいじる

仕方ないので、中間生成されたLaTeXファイルをいじる。具体的にはこういうのができている。

\documentclass[]{ltjsarticle}
\usepackage{lmodern}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc}
\else % if luatex or xelatex
  \ifxetex
    \usepackage{mathspec}
  \else
    \usepackage{fontspec}
  \fi
  \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
\fi
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{%
\usepackage{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\usepackage[margin=1in]{geometry}
\usepackage{hyperref}
\hypersetup{unicode=true,
            pdftitle={test},
            pdfborder={0 0 0},
            breaklinks=true}
\urlstyle{same}  % don't use monospace font for urls
\usepackage{color}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\usepackage{framed}
\definecolor{shadecolor}{RGB}{248,248,248}
\newenvironment{Shaded}{\begin{snugshade}}{\end{snugshade}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{#1}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\ImportTok}[1]{#1}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{#1}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.81,0.36,0.00}{\textbf{#1}}}
\newcommand{\BuiltInTok}[1]{#1}
\newcommand{\ExtensionTok}[1]{#1}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.77,0.63,0.00}{#1}}
\newcommand{\RegionMarkerTok}[1]{#1}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{0.94,0.16,0.16}{#1}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{0.64,0.00,0.00}{\textbf{#1}}}
\newcommand{\NormalTok}[1]{#1}
\usepackage{longtable,booktabs}
\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}
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
}
\setlength{\emergencystretch}{3em}  % prevent overfull lines
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{5}
% 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

%%% Use protect on footnotes to avoid problems with footnotes in titles
\let\rmarkdownfootnote\footnote%
\def\footnote{\protect\rmarkdownfootnote}

%%% Change title format to be more compact
\usepackage{titling}

% Create subtitle command for use in maketitle
\newcommand{\subtitle}[1]{
  \posttitle{
    \begin{center}\large#1\end{center}
    }
}

\setlength{\droptitle}{-2em}

  \title{test}
    \pretitle{\vspace{\droptitle}\centering\huge}
  \posttitle{\par}
    \author{}
    \preauthor{}\postauthor{}
    \date{}
    \predate{}\postdate{}
  

\begin{document}
\maketitle

{
\setcounter{tocdepth}{2}
\tableofcontents
}
ここでおもむろに図\ref{fig:plot1}をプロットしよう。

\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{plot}\NormalTok{(}\DecValTok{1}\NormalTok{)}
\end{Highlighting}
\end{Shaded}

\begin{figure}
\centering
\includegraphics{test_files/figure-latex/plot1-1.pdf}
\caption{\label{fig:plot1}ご覧ください、このきれいなプロット!}
\end{figure}


\end{document}

platexコマンド

とりあえず冒頭部分を書き換えてplatexを実行してみよう。差分は以下。

-\documentclass[]{ltjsarticle}
+\documentclass[]{jsarticle}
$ platex test.tex

するとこんなエラーになる。

Package microtype Warning: You don't seem to be using pdftex, luatex or xetex.
(microtype)                `microtype' only works with these engines.
(microtype)                I will quit now.

)

! Package microtype Error: The protrusion set `basicmath' is undeclared.
(microtype)                Using set `\MT@default@pr@set ' instead.

See the microtype package documentation for explanation.
Type  H <return>  for immediate help.
 ...

l.23 }{}

?

microtypeパッケージを取り除く

「use microtype if available」って書かれているので、たぶんなくても大丈夫でしょ、ということで取り除いてみる。 差分は以下。

-% use microtype if available
-\IfFileExists{microtype.sty}{%
-\usepackage{microtype}
-\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
-}{}

しかし、これもまだエラーで止まってしまう。

! LaTeX Error: Cannot determine size of graphic in test_files/figure-latex/plot
1-1.pdf (no BoundingBox).

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...

l.138 ...hics{test_files/figure-latex/plot1-1.pdf}

?

graphicxパッケージにdvipdfmxオプションを指定する。

これは調べてもちょっとうまく理解できなかった。 pdf_documents2でknitするときはどうやってるんだろう、と思ったんですけど、そこはPandocがいい感じに渡してたりするのかな? 謎ですが、とりあえずgraphicxdvipdfmxを指定すると解決します。

-\usepackage{graphicx,grffile}
+\usepackage[dvipdfmx]{graphicx}
+\usepackage{grffile}

これは通るので、dvipdfmxでPDFを生成すれば終わり。

$ dvipdfmx test

f:id:yutannihilation:20180812125853p:plain:h450

ソースコード部分が黒くて見えないけど、そこはまあもうちょっとスタイルを適用すればなんとかなる...?

まとめ

とりあえず、

  1. keep_tex: yesで中間生成物である.texファイルを残す
  2. microtypeパッケージを使わないようにする
  3. graphicxパッケージにdvipdfmxオプションを指定する

というのをやれば、まあpLaTeX用のdocumentclassでPDFを生成できることがわかりました。あってる?

Makefileで自動化するとたぶんこんな感じになるはず。