« Neural networks and the Unix p... | Home | Why language models need not g... »

自分のドキュメントクラスを作ろう

Wed 21 Dec 2022 by mskala Tags used: , , ,

LaTeXで文書を書いてなら、時々すべてに体裁を指せたいです。

たとえば僕の仕事で、アナログシンサーのマニュアルを書いて、いつも同じの体裁が欲しいです。

LaTeXのデフォルトは普通過ぎます。 個性的な体裁を書きたいです。 でも全部のNorth Coast Synthesisユーサーマニュアルは、同じの体裁が必要です。 だから、自分のLaTeXクラスファイルを作りました。

これは「TeX & LaTeX Advent Calendar 2022」の21日めの記事です。 (20日めは MusicDump さん、22日めは tasusu さん です。)

ユーサーマニュアルの特性

各マニュアルで一定ものは欲しいです。

フォントとフォントのサイズ

フォントとフォントのサイズ

欄外

欄外

自分の扉で、著者と会社の名前

自分の扉で、著者と会社の名前

著作権のページとGPL3通告

著作権のページとGPL3通告

目次で、ハイパーリンクと好きな色

目次で、ハイパーリンクと好きな色

一つと二つのコラム

一つと二つのコラム

無番の章と横のライン

無番の章と横のライン

TikZのグラフィック

TikZのグラフィック

クラスとスタイルと、どっち?

日々のマクローは、スタイルファイルに入れられできます。 クラスファイルに入れられできます。 その上、テンプレートを作ってそれから文書にいつもコピペできます。 どのがいいですか?

CTANでのファイルを見つめましょう。 スタイルファイルの敏腕は、いろいろな文書で便利です。 たとえばulemスタイルはアンダーラインに\emを変えます。 手紙や本でそれは便利です。

また、クラスファイルが文書の組織を設けます。 本では章あります。 手紙で章ありません。 \documentclass{book}と書けば文書が本です。 \documentclass{letter}と書けば、手紙です。 それがクラスファイルです。

ゆーサーマニュアルはいつも同じの組織を持っています。 マニュアルのためにクラスファイルを作りたいです。

コピペはどうですか? 文書の体裁はユーニークなら、クラスファイルやスタイルファイルの作ることが便利じゃないです。 その分で例文書を書いてコピペがいいです。 ゆーサーマニュアルの体裁は同じだから、クラスファイルを作りたいです。

例クラス

North Coast Synthesisのクラスファイルncmanual.clsは、各プロダクトソースコードの中であります。 たとえばMSK 013 Middle Path VCOのソースで:ZIPリンク。 MSK 013のユーザーマニュアルは例文書です:PDFリンク

クラスファイルで4つの要素が必要です。

ncsmanual.clsの細部が退屈だから、今抜粋だけ教えています。 ファイルの全体がZIPの中であります。

初期化

クラスファイルの中でまず互換テストを書きます。 LaTeX 2.09のクラスのシンタックスは古くさいです。 このクラスファイルはLaTeX 2eだけ使われます。 だから\NeedsTeXFormat{LaTeX2e}を書きました。

次に\ProvidesClassが呼び出されました。 このラインだからファイルがクラスです。 クラスの名前は『ncmanual』とです。 その後年月日とバージャンと説明あります。

   \NeedsTeXFormat{LaTeX2e}
   \ProvidesClass{ncmanual}[2018/01/01 v0.01 North Coast Synthesis documentation]

クラスファイルはいつも初めでそのラインを持ちます。

オプション

あのLaTeXクラスは、いろいろなオプションを使っています。 たとえば、articleでletterpaperやa4paperができます。 実は、ncmanualで何もオプションありません。 いつも同じの紙と体裁を使います。 やっぱり\ProcessOptionsの呼び出し事がなければならないです。

   % FIXME process and pass options
   \ProcessOptions\relax

他のクラスとスタイル

NCSのncmanualと、LaTeXのreportとは、酷似だから、 reportから全部コードをコピペしなくて \LoadClass{report}が呼び出されました。 それで継承します。

   % handle inheritance from report
   \LoadClass[letter,twocolumn]{report}

マニュアルでいろいろはスタイルを使っています。 \RequirePackageは呼び出します。 XeTeXならfontspecを使いたくても他のエンジンで使いたくないから、そのラインが条件付きです。

   \RequirePackage{ifxetex}
   \ifxetex
     \RequirePackage{fontspec}
   \fi
 
   \RequirePackage[T1]{fontenc}
   \RequirePackage{textcomp}
 
   \RequirePackage{amsmath}
   \RequirePackage{calc}
   \RequirePackage{chngcntr}
   \RequirePackage{graphicx}
   \RequirePackage{helvet}
   \RequirePackage{longtable}
   \RequirePackage{pdfpages}
   \RequirePackage{tikz}
   \RequirePackage[rigidchapters]{titlesec}
   \RequirePackage{tocloft}
   \RequirePackage{xcolor}

あるスタイルは自分のオプションを持っています。 TikZのライブラリーとhyperrefの色を決めます。

   \usetikzlibrary{arrows}
 
   \definecolor{darkgreen}{rgb}{0,0.35,0}
   \definecolor{purplish}{rgb}{0.4,0,0.6}
 
   % must be last
   \RequirePackage[letterpaper,breaklinks,bookmarks,plainpages=false,
      colorlinks,citecolor=darkgreen,linkcolor=purplish]{hyperref}

未来でもしかしたら環境設定のファイルを使いたいです。 それのためにncmanual.cfgを読みできます。

   % config file
   \InputIfFileExists{ncmanual.cfg}{}{}

ページのレイアウト

生LaTeXで、欄外が難しいです。 calcでちょっと便利でもまー難しいです。 でも、クラスファイルを書いたからたった一回だけに知ることが必要です。

   % page layout
 
   \setlength{\topmargin}{0.25in}
   \setlength{\headheight}{0pt}
   \setlength{\headsep}{0pt}
 
   \setlength{\oddsidemargin}{\paperwidth*2/17-1in}
   \setlength{\marginparsep}{\paperwidth*1/68}
   \setlength{\marginparwidth}{\paperwidth*1/17}
   \setlength{\columnsep}{1em}
   \setlength{\textwidth}{\paperwidth*13/17}
   \setlength{\textheight}{8.5in}

スペーシング

ここで字下げとリストの体裁を決めます。

   % indentation, lists, line heights
 
   \setlength{\parindent}{1.5em}
 
   \setlength{\topsep}{0pt}
   \setlength{\partopsep}{0pt}
   \setlength{\itemsep}{0pt}
   \setlength{\parsep}{0pt}
   \setlength{\listparindent}{1em}
 
   \setlength{\leftmargini}{2.5em}
   \setlength{\labelsep}{0.5em}

フォントサイズのコードのは、reportのコードを真似ました。 これが低級コードだから、生TeXの算数を使います。

   \dimen@=\f@size\p@\dimen@6\dimen@\divide\dimen@5\edef\l@rgesize{\the\dimen@}
   \dimen@=\f@size\p@\dimen@2\dimen@\edef\@hugesize{\the\dimen@}
 
   \renewcommand\normalsize{%
      \@setfontsize\normalsize\@xpt\@xiipt
      \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
      \abovedisplayshortskip \z@ \@plus3\p@
      \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
      \belowdisplayskip \abovedisplayskip}
   \normalsize
   \renewcommand\small{%
      \@setfontsize\small\@ixpt{11}%
      \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
      \abovedisplayshortskip \z@ \@plus2\p@
      \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
      \belowdisplayskip \abovedisplayskip
   }
   \renewcommand\footnotesize{%
      \@setfontsize\footnotesize\@viiipt{9.5}%
      \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@
      \abovedisplayshortskip \z@ \@plus\p@
      \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
      \belowdisplayskip \abovedisplayskip
   }

ヘディング

North Coast Synthesisのマニュアルで、一つコラムの章も二つコラムの章もあります。 reportの章のヘディングは、二つのコラムなら間違います。 だからコードのコピペして直します。

   % heading formatting
 
   % chapter head copied from report, just adding \@afterheading in 2col case
   \def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
                         \refstepcounter{chapter}%
                         \typeout{\@chapapp\space\thechapter.}%
                         \addcontentsline{toc}{chapter}%
                                   {\protect\numberline{\thechapter}#1}%
                    \else
                      \addcontentsline{toc}{chapter}{#1}%
                    \fi
                    \chaptermark{#1}%
                    \addtocontents{lof}{\protect\addvspace{10\p@}}%
                    \addtocontents{lot}{\protect\addvspace{10\p@}}%
                    \if@twocolumn
                      \@topnewpage[\@makechapterhead{#2}]%
                      \@afterheading
                    \else
                      \@makechapterhead{#2}%
                      \@afterheading
                    \fi}
 
   \newcommand{\ch@pterform@t}[1]{%
     \begin{@twocolumnfalse}%
       \fontsize{\@hugesize}{3\baselineskip}\sffamily\bfseries\selectfont
       #1\,\leaders\hrule height 0.2ex\hfill\null
     \end{@twocolumnfalse}%
   }%

titlesecのスタイルファイルで自分のヘディングを作ります。 これで横のラインを頼みます。

   \titlespacing*{\chapter}{0pt}{6\baselineskip}{2\baselineskip}
   \titleformat{\chapter}[hang]{}{}{0pt}{\ch@pterform@t}
 
   \titleformat{\section}[runin]%
      {\fontsize{\l@rgesize}{\baselineskip}\sffamily\bfseries}{}{0pt}{}%
      [\,\leaders\hrule height 0.16ex\hfill\null\\]
   \titlespacing*{\section}{0pt}{\baselineskip}{0pt}
 
   \titleformat{\subsection}[runin]{\sffamily\bfseries}{}{0pt}{}
   \titlespacing*{\subsection}{0pt}{\baselineskip}{0.666em}
 
   \titleformat{\subsubsection}[runin]{\rmfamily\scshape}{}{0pt}{}
   \titlespacing*{\subsubsection}{0pt}{\baselineskip}{0.666em}
 
   \titleformat{\paragraph}[runin]{\rmfamily\itshape}{}{0pt}{}
   \titlespacing*{\paragraph}{\parindent}{0pt}{0.666em}

他のマクロ

クラスファイルで重宝のマクロを書きます。 たとえばクヌース先生のヤバイ角の道標あります。

   % miscellaneous
 
   \newcommand{\DangerousBend}{\marginpar{\large\hfill\dbend\hfill\null}}
   \newcommand{\DangerousSection}{\marginpar{\large\hfill
   \raisebox{-0.5\baselineskip}[0pt][0pt]{\dbend}\hfill\null}}

AMS-TeXで1つや2つや3つや4つの積分を持っても、 Leapfrog VCFのマニュアルで5つの積分を使います。 だからそのマクロを作りました。

   \newcommand{\FiveIntegral}[1]{%
     \edef\ints@c{\noexpand\intop\noexpand\intkern@
       \noexpand\intop\noexpand\intkern@
       \noexpand\intop\noexpand\intkern@
       \noexpand\intop\noexpand\intkern@
       \noexpand\intop
       \noexpand\ilimits@
     }%
     \futurelet\@let@token\ints@a
   }
 
   \ams@newcommand{\iiiiint}{\DOTSI\protect\FiveIntegral}

クラスファイルの使い方

新しいマニュアルを書く時、\documentclassでncmanualを書きます。

   \documentclass{ncmanual}

このクラスで\title\authorがマストです。 例文書で年月日も書きました。

   \title{Sample manual}
   \author{Matthew Skala}
   \date{December 21, 2022}

その後ドキュメントの始まりできます。

      \begin{document}
 
   \maketitle
 
   \chapter{Greeting}
 
   Hello, world.
 
   \end{document}

例文書

TUGboatでFlynnさんの論文は、自分のクラスについて情報あります。 面白いなら読んでください。

0 comments



(optional field)
(optional field)
Answer "bonobo" here to fight spam. ここに「bonobo」を答えてください。SPAMを退治しましょう!
I reserve the right to delete or edit comments in any way and for any reason. New comments are held for a period of time before being shown to other users.