LuaTaTeXでギリシア文字のボールド体を出力する

経緯

普段はLuaLaTeXで講義資料を作成しています。フォントとして TeX Gyre Termis などを好んで使用しています。

texlive2015のパッケージのアップデートをしていたらいつの間にかギリシア文字のボールド体が出力されないようになっていました。解決したのでその時のメモを残しておきます。ただし、otfフォントを指定している場合の話です。

方法

これまでの方法

まず先にLaTeX文章を示します。

\documentclass[a4paper, 11pt]{ltjsarticle}

% mathematical font
\usepackage{amsmath}
\usepackage{fontspec}
\usepackage{unicode-math}
\unimathsetup{math-style=TeX,bold-style=TeX,vargreek-shape=TeX}
\setmathfont{texgyretermes-math}

% Serif, Sans, Monospace
\setmainfont[ItalicFont=texgyretermes-italic, Ligatures=TeX, Scale=0.95]{texgyretermes-regular}
\setsansfont[Ligatures=TeX, Scale=0.95]{texgyreheros-bold}
\setmonofont[BoldFont=Inconsolatazi4-Bold, Ligatures=TeX, Scale=1]{Inconsolatazi4-Regular}

% other setting
\renewcommand{\bfdefault}{bx}
\renewcommand{\bf}{\gtfamily\sffamily\bfseries}

\begin{document}

\begin{itemize}
 \item $\alpha_\text{1}$
 \item {\bf $\mathbf{\alpha_\text{1}}$}
\end{itemize}

\end{document}

これまではこのように \mathbf を使用してギリシア文字をボールド体にしていました。これが、ある時点からうまく行かなくなりました。

改善策

色々とネット上で調べていると、 unicode-mathパッケージの説明書(英語)や このページ\symbf を使う例が載っていました。

そこで

\begin{itemize}
 \item {\bf $\symbf{\alpha_\text{1}}$}
\end{itemize}

のように変更することでボールド体が出力されるようになりました。

その他

ちなみに \text{1}としているのは数式フォントではなく、通常のフォントを使用するためです(\usepackage{amsmath}が必要)。また、このようにすることで全体を{\bf }で囲ったときにボールド体になるようにするためです。

本来は\textbf{}で囲む方がいいのでしょうが、欧文フォントと日本語フォントの両方をゴシック体にするように設定しているためです(\section{}などと同じ挙動になるように)。

追記(2015/8/30)

ギリシア文字だけをボールド体にするのであれば

\begin{itemize}
 \item $\symbf{\alpha}$
\end{itemize}

で十分です。

また、 unicode-mathのバージョンが 0.7e(2014/06/30)から0.8(2015/07/29)に上った際にこのような現象が起きたようです。

org-modeのBeamerクラスのフレームの縦位置を中間ではなく上に固定する

経緯

org-modeのBeamerクラスの欠点

先の記事 でorg-modeのBeamerクラスでスライドを作成するための設定を行いましたが、実は不満が残っていました。それは

  • フレームの縦位置が中央にきてしまう

ことでした。

サンプルファイルとして

#+TITLE: Sample
#+AUTHOR: Toshiaki Ara
#+OPTIONS: H:1 toc:nil
#+LATEX_CLASS: beamer
#+BEAMER_THEME: Madrid

* Frame
** block
+ contents 1
+ contents 2

を用意し、PDFファイルに変換するとこのような感じになります。

test_nul.png

これではスライドを進めていくたびにフレームの始まる位置が異なるため、見る方としては非常につらいです(個人の感想です)。

これを何とか上に固定したいと思い、 ox-beamer のソースコードを調べました。

結論

init.elに

(setq org-beamer-frame-default-options "t")

を追加することでフレームの縦位置が上に固定されるようになりました。

test_t.png

ただし、これでは各ファイルごとの設定ができません。 orgファイルのオプションで設定できる方法があればいいのですが。

それでも、 org-modeによる簡単な記述でこれほど見栄えのよいスライドが作成できるので、積極的に使用したいと思います。 org-modeは見出しレベルで折り畳みできるのが気に入ってます。

ox-beamer.elの解析

先に結論だけを書いたので、次にこの結論に至った経緯を簡単に書きます。

org-beamer–format-frame関数の発見

まずox-beamer.elの中でフレームを定義している関数を探しました。するとすぐにorg-beamer–format-frameが見つかりました。

少し長いですが、ox-beamer.elに書かれている org-beamer–format-frameの関数定義を下に示します。

見やすくするためにタブを空白に変換し、さらに C-M-q でコードを整形しています。

すると26行目に

(org-split-string org-beamer-frame-default-options ",")

という記述がありました。これは org-beamer-frame-default-options という変数に含まれているリストを,で区切った文字列として返す関数であると予想しました。

M-: org-beamer-frame-default-options

で変数の中身を調べると””でした(何も定義されていない)。

そこでフレームを上に固定するためのオプションである”t”を設定したところ希望通りの結果が得られました。

org-beamer–format-frameの関数定義

(defun org-beamer--format-frame (headline contents info)
  "Format HEADLINE as a frame.
CONTENTS holds the contents of the headline.  INFO is a plist
used as a communication channel."
  (let ((fragilep
         ;; FRAGILEP is non-nil when HEADLINE contains an element
         ;; among `org-beamer-verbatim-elements'.
         (org-element-map headline org-beamer-verbatim-elements 'identity
                          info 'first-match)))
    (concat "\\begin{frame}"
            ;; Overlay specification, if any. When surrounded by
            ;; square brackets, consider it as a default
            ;; specification.
            (let ((action (org-element-property :BEAMER_ACT headline)))
              (cond
               ((not action) "")
               ((string-match "\\`\\[.*\\]\\'" action )
                (org-beamer--normalize-argument action 'defaction))
               (t (org-beamer--normalize-argument action 'action))))
            ;; Options, if any.
            (let* ((beamer-opt (org-element-property :BEAMER_OPT headline))
                   (options
                    ;; Collect options from default value and headline's
                    ;; properties.  Also add a label for links.
                    (append
                     (org-split-string org-beamer-frame-default-options ",") ;; <= ココ
                     (and beamer-opt
                          (org-split-string
                           ;; Remove square brackets if user provided
                           ;; them.
                           (and (string-match "^\\[?\\(.*\\)\\]?$" beamer-opt)
                                (match-string 1 beamer-opt))
                           ","))
                     ;; Provide an automatic label for the frame
                     ;; unless the user specified one.
                     (unless (and beamer-opt
                                  (string-match "\\(^\\|,\\)label=" beamer-opt))
                       (list
                        (format "label=%s"
                                (org-beamer--get-label headline info)))))))
              ;; Change options list into a string.
              (org-beamer--normalize-argument
               (mapconcat
                'identity
                (if (or (not fragilep) (member "fragile" options)) options
                  (cons "fragile" options))
                ",")
               'option))
            ;; Title.
            (let ((env (org-element-property :BEAMER_ENV headline)))
              (format "{%s}"
                      (if (and env (equal (downcase env) "fullframe")) ""
                        (org-export-data
                         (org-element-property :title headline) info))))
            "\n"
            ;; The following workaround is required in fragile frames
            ;; as Beamer will append "\par" to the beginning of the
            ;; contents.  So we need to make sure the command is
            ;; separated from the contents by at least one space.  If
            ;; it isn't, it will create "\parfirst-word" command and
            ;; remove the first word from the contents in the PDF
            ;; output.
            (if (not fragilep) contents
              (replace-regexp-in-string "\\`\n*" "\\& " (or contents "")))
            "\\end{frame}")))

このコードはGNU Emacsの一部であるため GNU General Public Licenseが適用されています。