maranget / hevea

Hevea is a fast latex to html translator
http://hevea.inria.fr
Other
97 stars 12 forks source link

Introduce CSS-classes for font families and font variants. #21

Open cspiel opened 4 years ago

cspiel commented 4 years ago

Hevea "hard-codes" font-family: monospace for typewriter text. Obviously, this has not riled anybody until now. If you are chasing a consistent appearance of the Hevea-translated document or simply want to swap out this bland default monospace font, things change.

This P/R introduces CSS-classes for six font families or font variants:

The existing \@span calls are adjusted accordingly and new \@spans are introduced where necessary. The defaults leave unaffected the appearance of all translated documents. So this is a visually neutral change, which actually is quite small. The much larger change is a rewrite of chapter B.15 "Font Selection" of the reference manual along with an additional subsection on "Controlling Font Selection with CSS".

Here is a little demo document to play around with.

%%%  font-selection.tex
\documentclass{article}

\usepackage{bold-extra}         % bold typewriter
\usepackage{hevea}

%%  Also try (super-) families...
%%      "Go" / "Go" / "Go Mono"
%%      "DejaVu Serif" / "DejaVu Sans" / "DejaVu Sans Mono"
%%      "Noto Serif" / "Noto Sans" / "Noto Mono"
%%      "Georgia" / "Trebuchet MS" / "Courier New" and rescale monospace with `font-size: 120\%'
\newcommand*{\seriffontfamily}{"FreeSerif", serif}
\newcommand*{\sansfontfamily}{"FreeSans", sans-serif}
\newcommand*{\fixedfontfamily}{"FreeMono", monospace}

%%  Uncomment to activate...
%%  \newstyle{.serif}{font-family: \seriffontfamily}
%%  \newstyle{.sansserif}{font-family: \sansfontfamily}
%%  \newstyle{.monospace}{font-family: \fixedfontfamily}

%%  Fill in your fonts of choice and compare.
%%  \newstyle{.italic}{font-family: ...;
%%                     font-style: italic}
%%  \newstyle{.slanted}{font-family: ...;
%%                      font-style: oblique}

%%  \newstyle{.smallcaps}{font-family: ...;
%%                        font-variant: small-caps}% or: `font-variant: normal' for SC-fonts

\newstyle{.oldstyle}{font-feature-settings: "onum"}
\newstyle{@supports (font-variant-numeric: oldstyle-nums)}{%
  .oldstyle \{font-variant-numeric: oldstyle-nums\}
}

\newstyle{.chapter, .section, .subsection, .subsubsection}{font-family: \sansfontfamily}

\newcommand*{\shortphrase}{White Handgloves}
\newcommand*{\longphrase}{The quick brown fox jumps over the lazy dog.}

\begin{document}
\section{Font Samples}
\begin{description}
\item[Roman:] \textrm{\longphrase}
\item[Italic:] \textit{\longphrase}  And emphasized: \emph{\shortphrase.}
\item[Bold:] \textbf{\longphrase}
\item[Bold Italic:] \textit{\textbf{\longphrase}}
\item[Sans Serif:] \textsf{\longphrase}
\item[Oblique Sans Serif:] \textsl{\textsf{\longphrase}}
\item[Bold Sans Serif:] \textsf{\textbf{\longphrase}}
\item[Bold Oblique Sans Serif:] \textbf{\textsl{\textsf{\longphrase}}}
\item[Typewriter:] \texttt{\longphrase}
\item[Bold Typewriter:] \textbf{\texttt{\longphrase}}
\item[Oblique Typewriter:] \textsl{\texttt{\longphrase}}
\item[Bold Oblique Typewriter:] \textbf{\textsl{\texttt{\longphrase}}}
\item[Slanted:] \textsl{\longphrase}
\item[Small Caps:] \textsc{\longphrase}
\item[Oldstyle Numerals:] \oldstylenums{0123456789} vs.~0123456789.
\end{description}

\section{Paragraph Text}
In This Paragraph We Intentionally Start Every Word With A Capital
Letter!  The \textrm{Roman Typeface} And The \texttt{Typewriter Face}
Must Match In \textrm{Visual Size} For A \texttt{Uniform Appearance}.
Well, At Least \textit{As Much As\/} This Is
\textit{\texttt{Possible\/}} On A \texttt{Web Page}.

\section{Roman/Italics/Slanted}
\begin{itemize}
\item \textrm{\longphrase} (roman)
\item \textit{\longphrase} (italics)
\item \textsl{\longphrase} (slanted)
\end{itemize}
\end{document}

What this P/R fixes:

Open questions:

\newstyle{@supports (font-variant-caps: small-caps)}{%
    .smcp \{font-variant-caps: small-caps\}
}

With \newatrule{name}[arg, ...]{body}:

\newatrule{.smcp}[font-variant-caps: small-caps]{%
    .smcp \{font-variant-caps: small-caps\}
}

What doesn't work yet:

cspiel commented 4 years ago

We need to augment each style-changing macro that expands to a @span without its own font-family. Currently these are

I ran into the problem with the "Quattrocento" font which has bold, but no italics. Simply hooking up a font with matching italics, say "TeX Gyre Pagella" as

  \newstyle{.italic}{font-family: "TeX Gyre Pagella", serif}

does work, but also changes slanted text and typewriter to Pagella. My solution is to look at the pending styles (\@top@pending@style) and pick the topmost that matches one of the main font-class names (\@main@styles).

\newsavebox{\@top@style}
\newcommand{\@main@styles}{serif,sansserif,monospace,cursive,fantasy}
\newcommand{\@save@top@style}{\sbox{\@top@style}{\@top@pending@style{\@main@styles}}}
\newcommand{\@use@top@style}{\@getprint{\usebox{\@top@style}}}

\newenvironment{it}{\@save@top@style\@span{class="\@use@top@style italic"}}{}

With this change we can write a more specific ("conjunction") CSS selector:

  \newstyle{.serif.italic}{font-family: "TeX Gyre Pagella", serif}

The OCaml code already looks ok, but the HeVeA code with \sbox/\usebox seems complicated. @maranget, do we have a possibility to define a macro that immediately evaluates its body? The "usual" \expandafter is off, AFAICS.