From 1e78bb2dd94517a51a300e0df1e3f10007e03b61 Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Mon, 15 Jun 2020 10:04:13 +0200 Subject: [PATCH 1/7] Introduce CSS-classes for font families and font variants. Add macro \oldstylenums. Rewrite and extend documentation accordingly. --- doc/text.tex | 446 ++++++++++++++++++++++++++++++++++++++++++------- html/hevea.hva | 29 ++-- 2 files changed, 404 insertions(+), 71 deletions(-) diff --git a/doc/text.tex b/doc/text.tex index f8aaf73f..98a994ef 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -5832,66 +5832,63 @@ \subsubsection{From High-Level Colours to Low-Level Colours}\label{getcolor} \section{Font Selection} \subsection{Changing the Type Style}\label{type-style} -All \LaTeXe{} declarations and environments for changing type style -are recognised. Aspect is rather like \LaTeXe{} output, but there is -no guarantee. - -As \html{} does not provide the same variety of type styles as -\LaTeX{} does. -However \css{} provide a wide variety of font properties. -\hevea{} uses generic properties, proper rendering will then depend -upon user agent. -For instance, it belongs to the user agent -to make a difference between -\textit{italics} (rendered by the font style ``italic'') -and \textsl{slanted} (rendered by the font style ``oblique''). - -Here is how \hevea{} implements text-style declarations by default: -\begin{center} -\newcommand{\heveastyle}[2]{{\ifhevea#1\fi#2}} -\begin{tabular}{*{3}{p{.3\linewidth}}} -\begin{tabular}{l@{\quad}l} \hline -\verb+\itshape+ & \heveastyle{\itshape}{font-style:italic}\\ -\verb+\slshape+ & \heveastyle{\slshape}{font-style:oblique}\\ -\verb+\scshape+ & \heveastyle{\scshape}{font-variant:small-caps}\\ -\verb+\upshape+ & \heveastyle{\upshape}{no style}\\ \hline -\end{tabular} - & -\begin{tabular}{l@{\quad}l} \hline -\verb+\ttfamily+ & \heveastyle{\ttfamily}{font-family:monospace}\\ -\verb+\sffamily+ & \heveastyle{\sffamily}{font-family:sans-serif}\\ -\verb+\rmfamily+ & \heveastyle{\rmfamily}{no style}\\ \hline -\end{tabular} +All \LaTeXe{} declarations and environments for changing the type +style are recognised. Visual appearance resembles that of \LaTeX's +output, but there is no guarantee for far-reaching concordance. + +HTML does not offer the same repertory of type styles as \LaTeX{} +does. However, CSS provide a wide variety of font +properties. \hevea{} uses generic properties, proper rendering will +then depend upon user agent. For instance, it belongs to the user +agent to make a difference between \textit{italics} (rendered by +font~style ``italic'') and +\textsl{slanted} (rendered by font~style ``oblique''), but also see +Sec.~\ref{sec:italics-vs-slanted} below. + +Here is a table that shows how \hevea{} implements text-style +declarations. See Sec.~\ref{sec:controlling-font-selection-with-css} +for the default definitions of all CSS-classes. -& -\begin{tabular}{l@{\quad}l} \hline -\verb+\bfseries+ & \heveastyle{\bfseries}{font-weight:bold}\\ -\verb+\mdseries+ & \heveastyle{\mdseries}{no style}\\ \hline -\end{tabular} +\begin{center} +\newcommand{\samplephrase}{White Handgloves} +\begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l@{\quad}l@{\quad}l@{\quad}l} +Axis & Name & Generator & \multicolumn{2}{c}{Macro} & Implementation & Font-Sample \\ + & & & \LaTeXe & Old & ``Style-''Attribute & \\ +\hline +Family & normal & \verb+\rmfamily+ & \verb+\textrm+ & \verb+\rm+ & \verb+class: serif+ & \textrm{\samplephrase} \\ + & sans serif & \verb+\sffamily+ & \verb+\textsf+ & \verb+\sf+ & \verb+class: sans-serif+ & \textsf{\samplephrase} \\ + & typewriter & \verb+\ttfamily+ & \verb+\texttt+ & \verb+\tt+ & \verb+class: monospace+ & \texttt{\samplephrase} \\ +Variant & upright & \verb+\upshape+ & \verb+\upshape+ & \verb+\up+ & \textit{no style} & \upshape{\samplephrase} \\ + & italics & \verb+\itshape+ & \verb+\textit+ & \verb+\it+ & \verb+class: italic+ & \textit{\samplephrase} \\ + & slanted & \verb+\slshape+ & \verb+\textsl+ & \verb+\sl+ & \verb+class: slanted+ & \textsl{\samplephrase} \\ + & small caps & \verb+\scshape+ & \verb+\textsc+ & \verb+\sc+ & \verb+class: smallcaps+ & \textsc{\samplephrase} \\ + & emphasized & \verb+\em+ & \verb+\emph+ & \verb+\em+ & HTML-element ``em'' & \emph{\samplephrase} \\ +Weight & normal & \verb+\mdseries+ & \verb+\textmd+ & \verb+\md+ & \textit{no style} & \mdseries{\samplephrase} \\ + & bold & \verb+\bfseries+ & \verb+\textbf+ & \verb+\bf+ & \verb+font-weight: bold+ & \textbf{\samplephrase} \\ \end{tabular} \end{center} -Text-style commands also exists, they are defined as -\verb+\mbox{\+\textit{decl}\ldots\verb+}+. For instance, -\verb+\texttt+ is defined as a command with one argument whose body is -\verb+\mbox{\ttfamily#1}+. -Finally, the \verb+\emph+ command for emphasised text also exists, -it yields text-level \verb+em+ elements. +Text-style commands exist as well; they are defined +as \verb+\mbox{\+\textit{decl}\ldots\verb+}+. For +instance, \verb+\texttt+ is defined as a command with one argument +whose body is \verb+\mbox{\ttfamily #1}+. Finally, +the \verb+\emph+~command for emphasised text also exists, it yields +text-level \verb+em+~elements. -As in \LaTeX{}, type styles consists in three components: -\emph{shape}, \emph{series} and \emph{family}. -\hevea{} implements the three components by making one declaration to -cancel the effect of other declarations of the same kind. +As in \LaTeX{}, type styles consist of three +components: \emph{shape}, \emph{series} and \emph{family}. \hevea{} +implements the three components by making one declaration to cancel +the effect of other declarations of the same kind. \begin{htmlonly} For instance consider the following source, that exhibits shape changes: \begin{verbatim} {\itshape italic shape \slshape slanted shape \scshape small caps shape \upshape upright shape} \end{verbatim} -Then, in the rendering below, ``small caps shape'' appears in small caps shape -only and not in italics: +Then, in the rendering below, ``small caps shape'' appears in small +caps shape only and not in italics: \begin{htmlout} {\itshape italic shape \slshape slanted shape \scshape small caps shape \upshape upright shape} @@ -5900,28 +5897,355 @@ \subsection{Changing the Type Style}\label{type-style} Old style declarations are also recognised, they translate to -text-level elements. However, no elements are cancelled when using -old style declaration. Thus, the source -``\verb+{\sl\sc slanted and small caps}+'' yields ``slanted'' -small caps\ifhevea: ``{\sl\sc slanted and small caps}''\fi. -Users need probably not worry about this. However this has an -important practical consequence: to change the default rendering of -type styles, one should redefine old style declaration in order to -benefit from the cancellation mechanism. See +text-level elements. However, no elements are cancelled when using +old style declaration. Thus, the source ``\verb+{\sl\sc slanted and +small caps}+'' yields ``slanted'' small~caps\ifhevea: ``{\sl\sc +slanted and small caps}''\fi. Users do not need not worry about this, +though it has an important practical consequence: to change the +default rendering of type styles, one should redefine old style +declaration in order to benefit from the cancellation mechanism. See section~\ref{customize-style} for a more thorough description. \subsection{Changing the Type Size} All declarations, from \verb+\tiny+ to \verb+\Huge+ are recognised. -Output is not satisfactory inside headers elements -generated by sectioning commands. +Output is not satisfactory inside header elements generated by +sectioning commands. \subsection{Special Symbols} +The \verb+\symbol{+\textit{num}\verb+}+ outputs character +number~\textit{num} (decimal) from the Unicode character set. This +departs from \LaTeX{} which outputs symbol number~\textit{num} in the +current font. + +\subsection{\label{sec:controlling-font-selection-with-css}% + Controlling Font Selection with CSS} +\hevea{} predefines CSS~classes that control the font selection of an +HTML-document. + +\begin{center} +\begin{tabular}{l@{\quad}l@{\quad}lp{.5\linewidth}} +Class & Default & Application \\ +\hline +\verb+serif+ & \verb+font-family: serif+ & Body text and math; used by \verb+\textrm+. \\ +\verb+sansserif+ & \verb+font-family: sans-serif+ & Text tagged with \verb+\textsf+. \\ +\verb+monospace+ & \verb+font-family: monospace+ & Any typewriter text and in particular environment~\verb+verbatim+, macros~\verb+\verb+, and \verb+\texttt+. \\ +\verb+italic+ & \verb+font-style: italic+ & Text tagged with \verb+\textit+. \\ +\verb+slanted+ & \verb+font-style: oblique+ & Text tagged with \verb+\textsl+. \\ +\verb+smallcaps+ & \verb+font-variant: small-caps+ & Text tagged with \verb+\textsc+. \\ +\end{tabular} +\end{center} + +The defaults for classes \verb+serif+, \verb+sansserif+, and +\verb+monospace+ are the browser's defaults, namely \verb+serif+, +\verb+sans-serif+, and \verb+monospace+. Users can simply override +the classes in the document preamble. Moreover, as these are +CSS~classes \emph{all} properties apply. Besides gaudy effects this +comes in handy to adjust the base size of the typewriter font to match +the body text, for example with + +\begin{verbatim} +\newstyle{.monospace}{font-family: "Courier New", Courier, monospace; font-size: 120\%} +\end{verbatim} + +\noindent or to fine-tune \verb+font-stretch+ and \verb+font-weight+. + +Despite their names the classes can host any font chosen from any +family: + +\begin{verbatim} +\newstyle{.serif}{font-family: Go, sans-serif} +\newstyle{.sansserif}{font-family: Go, sans-serif} +\newstyle{.monospace}{font-family: "Go Mono", monospace} +\end{verbatim} + +Furthermore, the \verb+monospace+~class does not need to reference +mono-spaced fonts, though proportional fonts probably will skew output +that aligns for fonts with a fixed width. -The \verb+\symbol{+{\it num}\verb+}+ outputs character number {\it num} -(decimal) from the Unicode character set. -This departs from \LaTeX{}, which output symbol number \textit{num} in -the current font. +To achieve consistency in font selection it is constructive to define +a macro for each family and then use these to set the document's font +families as well as selected elements as, for example, the chapter and +section headings. + +\begin{verbatim} +\newcommand{\seriffontfamily}{"Noto Serif", serif} +\newcommand{\sansfontfamily}{"Noto Sans", sans-serif} +\newcommand{\fixedfontfamily}{"Noto Mono", monospace} + +\newstyle{.serif}{font-family: \seriffontfamily} +\newstyle{.sansserif}{font-family: \sansfontfamily} +\newstyle{.monospace}{font-family: \fixedfontfamily} + +\newstyle{.chapter, .section, .subsection, .subsubsection}{font-family: \sansfontfamily} +\end{verbatim} + +\subsubsection{\label{sec:italics-vs-slanted}% + Italics vs.\ Slanted} + +\TeX{} serves separate fonts for italics and slanted characters in the +same superfamily ``Latin Modern'', for example, ``Latin Modern Roman +10~Italic'' and ``Latin Modern Roman Slanted 10~Regular''. Needless +to say all members in the superfamily are extremely well matched! On +the HTML-side it is hard to recreate this kind of super-pairing; most +often a font family will \emph{lack} a ``slanted'' variant and -- +depending on the font-synthesis settings -- browsers substitute +``italic''. This means \verb+\textit+ and \verb+\textsl+ will be +mapped to the \emph{same} font. + +To remedy this, \hevea{} supports two separate, dedicated CSS-classes +for italics and slanted type, appropriately called \verb+italic+ and +\verb+slanted+. These can be overridden by users in concert with the +three font-family classes~\verb+serif+, \verb+sansserif+, and +\verb+monospace+ either to approximate the output of \LaTeX{} or to +create enough of visual distinction (``contrast'') of \verb+italic+ +and \verb+slanted+ to convey the semantic differences of +\verb+\textit+ and \verb+\textsl+. + +\begin{verbatim} +\newstyle{.serif}{font-family: "FreeSerif", serif} +\newstyle{.sansserif}{font-family: "FreeSans", sans-serif} +\newstyle{.monospace}{font-family: "FreeMono", monospace} +\newstyle{.slanted}{font-family: "Liberation Serif", "FreeSerif", serif; font-style: oblique} +\end{verbatim} + +\noindent In the example above there is no need to redefine +\verb+italic+ as the italics of \verb+FreeSerif+ and +\verb+Liberation Serif+ are quite distinct. + +A complementary approach is to use the default italics for +class~\verb+slanted+ and supply a different font family for +\verb+italic+: + +\begin{verbatim} +\newstyle{.serif}{font-family: "FreeSerif", serif} +\newstyle{.sansserif}{font-family: "FreeSans", sans-serif} +\newstyle{.monospace}{font-family: "FreeMono", monospace} +\newstyle{.italic}{font-family: "Accanthis ADF Std No3", serif; font-style: italic} +\newstyle{.slanted}{font-family: "FreeSerif", serif; font-style: oblique} +\end{verbatim} + +\subsubsection{Dedicated Smallcaps} + +\hevea{} translates \verb+\textsc+ into CSS~class \verb+smallcaps+, +which in turn activates \verb+font-variant: small-caps+ by default. +This instructs the browser to look for small-capital letters in the +\emph{currently selected font}, but no further. Regrettably, only few +fonts come with small~caps included (look for, e.g., ``Pro'' or +``Expert'' series), for all others the browser synthesizes the glyphs +based on the selected font. See also +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps}. + +\paragraph{Separate Small-Caps Fonts.} What is more common today are +regular fonts that pair with separate fonts that cover their +small~caps. Here are some representative examples: + +\begin{itemize} +\item Cormorant -- Cormorant SC +\item Go -- Go Smallcaps +\item Latin Modern Roman -- Latin Modern Roman Caps +\end{itemize} + +\noindent By overriding the default definition of +CSS~class \verb+smallcaps+ these font pairings can be lifted +into \hevea. + +\begin{verbatim} +\newstyle{.serif}{font-family: "Berenis ADF Pro", serif} +\newstyle{.smallcaps}{font-family: "Berenis ADF Pro SC", serif; font-variant: normal} +\end{verbatim} + +It is important to set \verb+font-variant: normal+ with a small~caps +font so that the default is overridden and font synthesis does +\emph{not} kick in! Otherwise the browser uses the uppercase letters +of a resized variant of the small~caps font to synthesize the small +caps, which defeats the very purpose of the class override and -- on +top of that -- generally looks ugly. + +If you latch a non-smallcaps font, stick with the default as here +glyph synthesis in fact is desired. + +\begin{verbatim} +\newstyle{.smallcaps}{font-family: "Baskervville", serif; font-variant: small-caps} +\end{verbatim} + +\noindent Note that \hevea's default acts like an operator -- only +setting \verb+font-variant: small-caps+ means: whatever font is +current, use its downsized uppercase letters as small caps. When the +default of class~\verb+smallcaps+ is replaced with a definition that +contains a \verb+font-family+ the operator character is lost and the +original \LaTeX{} behavior is recovered. + +\paragraph{OpenType Feature: \verb+smcp+.} + +Some OpenType~fonts harbor their own small caps. Not all browsers +support the access of OpenType~features from CSS, but for those that +do the following code activates the small caps in an sufficently +``enriched'' OpenType~font. See also the +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide}{OpenType~fonts + guide} and help on +\footahref{https://helpx.adobe.com/fonts/using/use-open-type-features.html}{using + OpenType~features}. + +\begin{verbatim} +\newstyle{.smallcaps}{% + font-variant-caps: small-caps; + font-feature-settings: "smcp"; +} +\end{verbatim} + +\noindent Note: In the example right above any other +font-feature-settings than \verb+smcp+ are cleared! + +If the browser supports the CSS at-rule \verb+@supports+ the recipe is +improved by + +\begin{verbatim} +\newstyle{.smallcaps}{font-feature-settings: "smcp"} +\newstyle{@supports (font-variant-caps: small-caps)}{% + .smallcaps \{font-variant-caps: small-caps\} +} +\end{verbatim} + +\subsubsection{Oldstyle Numerals} + +\LaTeX{} \verb+\oldstylenums+ are not easily translated to the web +because their glyphs cannot be synthesized. The \hevea{} macro +\verb+\oldstylenums+ accesses class~\verb+oldstyle+, which has no +definition by default. The most straightforward way to get oldstyle +numerals is to rely on OpenType~font features with the following +definitions: + +\begin{verbatim} +\newstyle{.oldstyle}{font-feature-settings: "onum"} +\newstyle{@supports (font-variant-numeric: oldstyle-nums)}{% + .oldstyle \{font-variant-numeric: oldstyle-nums\} +} +\end{verbatim} + +\noindent If a font has no oldstyle-nums the common numerals will be +used. In a pinch another font's numerals can be borrowed given the +other font is highly similar. + +\subsubsection{Variable Typewriter Variant} + +\TeX{} offers a ``variable typewriter'' variant. In fact this is a +proportional font. We can mimick this font with proportional +typewriter fonts. + +\begin{verbatim} +\ifhevea + \newstyle{.varispace}{font-family: Typewriter, monospace} + \newcommand{\textvtt}[1]{\mbox{\@span{class="varispace"}#1}}% +\else + \newcommand{\variabletypewriter}{\fontfamily{cmvtt}\defaulthyphenchar=127\selectfont}% + \DeclareTextFontCommand{\textvtt}{\variabletypewriter}% +\fi +\end{verbatim} + +\noindent Now, macro~\verb+\textvtt+ could be used as a drop-in +replacement for \verb+\texttt+. + +If no proportional typewriter font is readily available on the +HTML-side, a similar effect is achieved with a slab-serif, +proportional font, like for example ``Zilla Slab''. + +\subsubsection{Hints to Practitioners} + +Some hints to get legible and portable output. + +\begin{itemize} +\item Restrict the selection to fonts that cover the the required set + of special characters (accented, mathematics, \dots). + H\aa{}mb\"urg\'ef\o{}\~ns! + +\item Choose families with at least four variations for + classes~\verb+serif+ and \verb+sansserif+: + + \begin{enumerate} + \item regular, + \item italic/oblique, + \item bold, and + \item bold italic/bold oblique. + \end{enumerate} + + If a variation is not available a browser may substitute a different + font or even try to synthesize the font, something typographers call + ``fake scaling, embolding and slanting''. See also + CSS~\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-synthesis}{font-synthesis}. + +\item Class~\verb+monospace+ often is only needed in variants + + \begin{enumerate} + \item regular and + \item oblique + \end{enumerate} + + However, some authors like to typeset the reserved words of a + programming language in boldface. They load package~``bold-extra'' + for additional, bold typewriter fonts. In this case it is also + advisable to use font families with four variations as described + above. + +\item Write down the full set of font-name aliases where applicable, + for example, + + \begin{itemize} + \item \verb+"Courier New"+ and \verb+"Courier"+ + \item \verb+"Trebuchet MS"+ and \verb+"Trebuchet"+ + \item \verb+"Times New Roman"+ and \verb+"Times"+ + \end{itemize} + + Different operating systems may use different names for exactly the + same family. + +\item Pass attribute~\verb+font-style+ with classes~\verb+italic+ and + \verb+slanted+. Override the default font~variant of + class~\verb+smallcaps+ with \verb+normal+ if the font~family + designates genuine small-caps fonts. + +\item Always put the default family in the last position of any + \verb+font-family+. + +\item Starting points for CSS~font selection. + + \begin{itemize} + \newcommand{\tablenotesymbol}{\dagger} + \newcommand{\tablenotemark}{$^\tablenotesymbol$} + \newcommand{\tablenote}[1]{\tablenotemark:~{\footnotesize #1}} + \item Some ``workhorse'' font families that all have been designed + with online readability in mind. + + \begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l} + Family & Serif & Sans Serif & Monospace \\ + \hline + %% Prefer `DejaVu' to `Bitstream Vera'. + %Bitstream Vera & Bitstream Vera & Bitstream Vera Sans & Bitstream Vera Sans Mono \\ + DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ + Free & FreeSerif & FreeSans & FreeMono \\ + IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ + Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ + Noto\tablenotemark & Noto Serif & Noto Sans & Noto Mono \\ + Source Pro\tablenotemark & Source Serif Pro & Source Sans Pro & Source Code Pro \\ + \end{tabular} + + \noindent\tablenote{OpenType-compliant font family, supporting for example oldstyle numerals.} + + \item If the result looks too ``oldstyle'' try the sans serif font + also in the serif position or interchange sans serif and serif. + + \item If the monospace font does not convey enough of an ``at the + terminal'' feeling give Anonymous Pro or Inconsolata a spin. + The latter font family also comes to the rescue when program + listings constantly are ``too wide'', this is, they overflow to + the right. Inconsolata has variants ``Semi Condensed'', + ``Condensed'', ``Extra Condensed'', and ``Ultra Condensed'' + among many others. + \end{itemize} + +\item Check the results with different browsers preferably on multiple + systems. +\end{itemize} \section{Extra Features}\cutname{extras.html} This section describes \hevea{} functionalities that extends on plain \LaTeX{}, diff --git a/html/hevea.hva b/html/hevea.hva index 32fa1171..59465841 100644 --- a/html/hevea.hva +++ b/html/hevea.hva @@ -309,7 +309,7 @@ }\fi \@print{ }% -\@print{ +\@print{ }% \@print{ }% @@ -378,11 +378,19 @@ \newcommand{\@open@quote}[1]{\@open{blockquote}{#1}} \newcommand{\@close@quote}{\@close{blockquote}} %%%%%%%%%%%%%%%% LaTeX 2.09 style declarations -\newenvironment{tt}{\@span{style="font-family:monospace"}}{} +\newstyle{.serif}{font-family: serif} +\newstyle{.sansserif}{font-family: sans-serif} +\newstyle{.monospace}{font-family: monospace} +\newstyle{.italic}{font-style: italic} +\newstyle{.slanted}{font-style: oblique} +\newstyle{.smallcaps}{font-variant: small-caps} +% +\newenvironment{tt}{\@span{class="monospace"}}{} \newenvironment{bf}{\@span{style="font-weight:bold"}}{} \newenvironment{em}{\@style{em}}{} -\newenvironment{it}{\@span{style="font-style:italic"}}{} -\newenvironment{rm}{\@anti{\it,\bf,\em,\sf,\tt}}{} +\newenvironment{it}{\@span{class="italic"}}{} +\newenvironment{rm}{\@anti{\it,\bf,\em,\sf,\tt}\@span{class="serif"}}{} +\newenvironment{oldstyle}{\@span{class="oldstyle"}}{} \newenvironment{tiny}{\@fontsize{1}}{} \newenvironment{footnotesize}{\@fontsize{2}}{} \newenvironment{scriptsize}{\@fontsize{2}}{} @@ -411,13 +419,13 @@ \newenvironment{blue}{\@fontcolor{blue}}{} \newenvironment{teal}{\@fontcolor{teal}}{} \newenvironment{aqua}{\@fontcolor{aqua}}{} -\def\cal{\ifmath\ifmathml\@style{font-family: cursive }% +\def\cal{\ifmath\ifmathml\@style{font-family: cursive}% \else\red\fi\else\red\fi} -\def\sf{\ifmath\ifmathml\@style{font-family: sans-serif }% -\else\@span{style="font-family:sans-serif"}\fi\else\@span{style="font-family:sans-serif"}\fi} -\def\sl{\ifmath\ifmathml\@style{font-family: fantasy; font-style: italic }% -\else\@span{style="font-style:oblique"}\fi\else\@span{style="font-style:oblique"}\fi} -\def\sc{\@span{style="font-variant:small-caps"}}% +\def\sf{\ifmath\ifmathml\@style{font-family: sans-serif}% +\else\@span{class="sansserif"}\fi\else\@span{class="sansserif"}\fi} +\def\sl{\ifmath\ifmathml\@style{font-family: fantasy; font-style: italic}% +\else\@span{class="slanted"}\fi\else\@span{class="slanted"}\fi} +\def\sc{\@span{class="smallcaps"}}% %%%% LaTeX2e verbose declarations \newenvironment{mdseries}{\@anti{\bf}}{} \newenvironment{bfseries}{\bf}{} @@ -441,6 +449,7 @@ \def\textsl#1{\mbox{\slshape#1}} \def\textsc#1{\mbox{\scshape#1}} \newcommand{\emph}[1]{\mbox{\em#1}} +\newcommand{\oldstylenums}[1]{\mbox{\oldstyle#1}}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % New implementation of \sc & \textsc using "small-caps" style. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From 1223ddb20c68f6945dd2c17f9a446ef8520573c1 Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Thu, 23 Jul 2020 15:42:14 +0200 Subject: [PATCH 2/7] Point out that font-family classes are helpful with font-specific OpenType features. --- doc/text.tex | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/doc/text.tex b/doc/text.tex index 98a994ef..f03fc53a 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -5948,10 +5948,17 @@ \subsection{\label{sec:controlling-font-selection-with-css}% \newstyle{.monospace}{font-family: "Courier New", Courier, monospace; font-size: 120\%} \end{verbatim} -\noindent or to fine-tune \verb+font-stretch+ and \verb+font-weight+. +\noindent or to fine-tune \verb+font-stretch+ and \verb+font-weight+; +it is also the perfect place to activate (or deactivate) +OpenType~features exactly for one specific family -Despite their names the classes can host any font chosen from any -family: +\begin{verbatim} +\newstyle{.sansserif}{font-family: Jost, sans-serif; + font-feature-settings: "ss01"}% Futura-like single-storey "a" +\end{verbatim} + +\noindent Despite their names the classes can host any font chosen +from any family: \begin{verbatim} \newstyle{.serif}{font-family: Go, sans-serif} @@ -6157,7 +6164,7 @@ \subsubsection{Hints to Practitioners} \begin{itemize} \item Restrict the selection to fonts that cover the the required set of special characters (accented, mathematics, \dots). - H\aa{}mb\"urg\'ef\o{}\~ns! + !`H\aa{}mb\"urg\'ef\o{}\~ns! \item Choose families with at least four variations for classes~\verb+serif+ and \verb+sansserif+: From 59aa9fe912f131a603019f7f382417b2ead8375e Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Thu, 27 Aug 2020 10:36:41 +0200 Subject: [PATCH 3/7] Allow to selectively override variants of font classes like e.g. `serif'. Make the font selection more fine-grained so that users can substitute e.g. the small-caps font of the serif class while leaving all other font classes (here: sans-serif and fixed) alone. The CSS-selectors are very easy to construct by abuttal; see documentation. --- doc/text.tex | 175 +++++++++++++++++++++++++++++-------------------- html.ml | 1 + html/hevea.hva | 15 +++-- htmlCommon.ml | 22 +++++++ info.ml | 1 + latexscan.mll | 38 +++++++++++ outManager.mli | 1 + scanattr.mli | 16 +++++ scanattr.mll | 60 +++++++++++++++++ text.ml | 2 +- 10 files changed, 254 insertions(+), 77 deletions(-) create mode 100644 scanattr.mli create mode 100644 scanattr.mll diff --git a/doc/text.tex b/doc/text.tex index f03fc53a..7a4e3650 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -5852,19 +5852,19 @@ \subsection{Changing the Type Style}\label{type-style} \begin{center} \newcommand{\samplephrase}{White Handgloves} \begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l@{\quad}l@{\quad}l@{\quad}l} -Axis & Name & Generator & \multicolumn{2}{c}{Macro} & Implementation & Font-Sample \\ - & & & \LaTeXe & Old & ``Style-''Attribute & \\ +Axis & Name & Generator & \multicolumn{2}{c}{Macro} & Implementation & Font-Sample \\ + & & & \LaTeXe & Old & ``Style-''Attribute & \\ \hline -Family & normal & \verb+\rmfamily+ & \verb+\textrm+ & \verb+\rm+ & \verb+class: serif+ & \textrm{\samplephrase} \\ - & sans serif & \verb+\sffamily+ & \verb+\textsf+ & \verb+\sf+ & \verb+class: sans-serif+ & \textsf{\samplephrase} \\ - & typewriter & \verb+\ttfamily+ & \verb+\texttt+ & \verb+\tt+ & \verb+class: monospace+ & \texttt{\samplephrase} \\ -Variant & upright & \verb+\upshape+ & \verb+\upshape+ & \verb+\up+ & \textit{no style} & \upshape{\samplephrase} \\ - & italics & \verb+\itshape+ & \verb+\textit+ & \verb+\it+ & \verb+class: italic+ & \textit{\samplephrase} \\ - & slanted & \verb+\slshape+ & \verb+\textsl+ & \verb+\sl+ & \verb+class: slanted+ & \textsl{\samplephrase} \\ - & small caps & \verb+\scshape+ & \verb+\textsc+ & \verb+\sc+ & \verb+class: smallcaps+ & \textsc{\samplephrase} \\ - & emphasized & \verb+\em+ & \verb+\emph+ & \verb+\em+ & HTML-element ``em'' & \emph{\samplephrase} \\ -Weight & normal & \verb+\mdseries+ & \verb+\textmd+ & \verb+\md+ & \textit{no style} & \mdseries{\samplephrase} \\ - & bold & \verb+\bfseries+ & \verb+\textbf+ & \verb+\bf+ & \verb+font-weight: bold+ & \textbf{\samplephrase} \\ +Family & normal & \verb+\rmfamily+ & \verb+\textrm+ & \verb+\rm+ & \verb+class: serif+ & \textrm{\samplephrase} \\ + & sans serif & \verb+\sffamily+ & \verb+\textsf+ & \verb+\sf+ & \verb+class: sans-serif+ & \textsf{\samplephrase} \\ + & typewriter & \verb+\ttfamily+ & \verb+\texttt+ & \verb+\tt+ & \verb+class: monospace+ & \texttt{\samplephrase} \\ +Variant & upright & \verb+\upshape+ & \verb+\upshape+ & \verb+\up+ & \textit{no style} & \upshape{\samplephrase} \\ + & italics & \verb+\itshape+ & \verb+\textit+ & \verb+\it+ & \verb+class: italic+ & \textit{\samplephrase} \\ + & slanted & \verb+\slshape+ & \verb+\textsl+ & \verb+\sl+ & \verb+class: slanted+ & \textsl{\samplephrase} \\ + & small caps & \verb+\scshape+ & \verb+\textsc+ & \verb+\sc+ & \verb+class: smallcaps+ & \textsc{\samplephrase} \\ + & emphasized & \verb+\em+ & \verb+\emph+ & \verb+\em+ & HTML-element ``em'' & \emph{\samplephrase} \\ +Weight & normal & \verb+\mdseries+ & \verb+\textmd+ & \verb+\md+ & \textit{no style} & \mdseries{\samplephrase} \\ + & bold & \verb+\bfseries+ & \verb+\textbf+ & \verb+\bf+ & \verb+font-weight: bold+ & \textbf{\samplephrase} \\ \end{tabular} \end{center} @@ -5873,7 +5873,7 @@ \subsection{Changing the Type Style}\label{type-style} as \verb+\mbox{\+\textit{decl}\ldots\verb+}+. For instance, \verb+\texttt+ is defined as a command with one argument whose body is \verb+\mbox{\ttfamily #1}+. Finally, -the \verb+\emph+~command for emphasised text also exists, it yields +the \verb+\emph+~command for emphasized text also exists, it yields text-level \verb+em+~elements. @@ -5945,7 +5945,8 @@ \subsection{\label{sec:controlling-font-selection-with-css}% the body text, for example with \begin{verbatim} -\newstyle{.monospace}{font-family: "Courier New", Courier, monospace; font-size: 120\%} +\newstyle{.monospace}{font-family: "Courier New", Courier, monospace; + font-size: calc(19 / 16)} \end{verbatim} \noindent or to fine-tune \verb+font-stretch+ and \verb+font-weight+; @@ -5971,7 +5972,7 @@ \subsection{\label{sec:controlling-font-selection-with-css}% that aligns for fonts with a fixed width. To achieve consistency in font selection it is constructive to define -a macro for each family and then use these to set the document's font +macros for each family and then use these to set the document's font families as well as selected elements as, for example, the chapter and section headings. @@ -5995,10 +5996,10 @@ \subsubsection{\label{sec:italics-vs-slanted}% 10~Italic'' and ``Latin Modern Roman Slanted 10~Regular''. Needless to say all members in the superfamily are extremely well matched! On the HTML-side it is hard to recreate this kind of super-pairing; most -often a font family will \emph{lack} a ``slanted'' variant and -- -depending on the font-synthesis settings -- browsers substitute -``italic''. This means \verb+\textit+ and \verb+\textsl+ will be -mapped to the \emph{same} font. +often a font family will lack a ``slanted'' variant and -- depending +on the font-synthesis settings -- browsers substitute ``italic''. +This means \verb+\textit+ and \verb+\textsl+ will be mapped to +the \emph{same} font. To remedy this, \hevea{} supports two separate, dedicated CSS-classes for italics and slanted type, appropriately called \verb+italic+ and @@ -6009,11 +6010,34 @@ \subsubsection{\label{sec:italics-vs-slanted}% and \verb+slanted+ to convey the semantic differences of \verb+\textit+ and \verb+\textsl+. +\begin{quote}\small + \hevea{} propagates font styles inward in scope and the controlling + CSS~class arguments accumulate. For example + \verb+\textit{\textrm{emphasized text}}+ as well as + \verb+\textrm{\textit{emphasized text}}+ as well associate classes + \verb+serif+ (font family~serif) \emph{and} \verb+italic+ (font + style~italic) with ``emphasized text''. Of course one or both + classes could have been redefined by the user. +\end{quote} + +\noindent The CSS~selector to target \emph{exactly} the \verb+italic+ +or \verb+slanted+ variant of the \verb+serif+~family takes a bit care +to construct. Simple matching \verb+.italic+ or \verb+.slanted+ also +would change the fonts used for sans-serif and monospace families, +which probably is not intended. So, we use a conjunctive CSS~selector +to specifically overide the slanted version of the serif~class only: +\verb+.slanted.serif+ (order does not matter). Note that there is +\emph{no} space between the two class~selectors! This is the prudent +way to replace a font-family for any predefined class that does not +itself set the font-family; currently these are \verb+italic+, +\verb+slanted+, and \verb+smallcaps+. + \begin{verbatim} \newstyle{.serif}{font-family: "FreeSerif", serif} \newstyle{.sansserif}{font-family: "FreeSans", sans-serif} \newstyle{.monospace}{font-family: "FreeMono", monospace} -\newstyle{.slanted}{font-family: "Liberation Serif", "FreeSerif", serif; font-style: oblique} +\newstyle{.serif.slanted}{font-family: "Liberation Serif", "FreeSerif", serif; + font-style: oblique} \end{verbatim} \noindent In the example above there is no need to redefine @@ -6028,10 +6052,13 @@ \subsubsection{\label{sec:italics-vs-slanted}% \newstyle{.serif}{font-family: "FreeSerif", serif} \newstyle{.sansserif}{font-family: "FreeSans", sans-serif} \newstyle{.monospace}{font-family: "FreeMono", monospace} -\newstyle{.italic}{font-family: "Accanthis ADF Std No3", serif; font-style: italic} -\newstyle{.slanted}{font-family: "FreeSerif", serif; font-style: oblique} +\newstyle{.serif.italic}{font-family: "Accanthis ADF Std No3", serif; + font-style: italic} +\newstyle{.serif.slanted}{font-family: "FreeSerif", serif; + font-style: oblique} \end{verbatim} + \subsubsection{Dedicated Smallcaps} \hevea{} translates \verb+\textsc+ into CSS~class \verb+smallcaps+, @@ -6039,8 +6066,10 @@ \subsubsection{Dedicated Smallcaps} This instructs the browser to look for small-capital letters in the \emph{currently selected font}, but no further. Regrettably, only few fonts come with small~caps included (look for, e.g., ``Pro'' or -``Expert'' series), for all others the browser synthesizes the glyphs -based on the selected font. See also +``Expert'' series or check with tools like, e.g.\ \textbf{otfinfo(1)} +for \textsc{OpenType}~feature ``\verb+smcp+'' -- small capitals). For +all others the browser synthesizes the glyphs based on the selected +font; see also \footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps}. \paragraph{Separate Small-Caps Fonts.} What is more common today are @@ -6058,8 +6087,12 @@ \subsubsection{Dedicated Smallcaps} into \hevea. \begin{verbatim} -\newstyle{.serif}{font-family: "Berenis ADF Pro", serif} -\newstyle{.smallcaps}{font-family: "Berenis ADF Pro SC", serif; font-variant: normal} +\newstyle{.serif}{font-family: "Alegreya", serif} +\newstyle{.serif.smallcaps}{font-family: "Alegreya SC", serif; + font-variant: normal} +\newstyle{.sansserif}{"Alegreya Sans", sans-serif} +\newstyle{.sansserif.smallcaps}{font-family: "Alegreya Sans SC", serif; + font-variant: normal} \end{verbatim} It is important to set \verb+font-variant: normal+ with a small~caps @@ -6067,32 +6100,35 @@ \subsubsection{Dedicated Smallcaps} \emph{not} kick in! Otherwise the browser uses the uppercase letters of a resized variant of the small~caps font to synthesize the small caps, which defeats the very purpose of the class override and -- on -top of that -- generally looks ugly. +top of that -- generally looks ugly. Furthermore, the example +demonstrates selective override of the serif and the sans~serif fonts. -If you latch a non-smallcaps font, stick with the default as here +If you latch a non-small~caps font, stick with the default as here glyph synthesis in fact is desired. \begin{verbatim} -\newstyle{.smallcaps}{font-family: "Baskervville", serif; font-variant: small-caps} +\newstyle{.serif.smallcaps}{font-family: "Baskervville", serif; + font-variant: small-caps} \end{verbatim} \noindent Note that \hevea's default acts like an operator -- only setting \verb+font-variant: small-caps+ means: whatever font is -current, use its downsized uppercase letters as small caps. When the -default of class~\verb+smallcaps+ is replaced with a definition that -contains a \verb+font-family+ the operator character is lost and the -original \LaTeX{} behavior is recovered. - -\paragraph{OpenType Feature: \verb+smcp+.} - -Some OpenType~fonts harbor their own small caps. Not all browsers -support the access of OpenType~features from CSS, but for those that -do the following code activates the small caps in an sufficently -``enriched'' OpenType~font. See also the -\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide}{OpenType~fonts +current, generate small-caps by accessing the font's own small capital +letters, use its downsized uppercase letters as small caps, or another +technique. When the default of class~\verb+smallcaps+ is replaced +with a definition that contains a \verb+font-family+ the operator +character is lost and the original \LaTeX{} behavior is recovered. + +\paragraph{\textsc{OpenType} Feature: \verb+smcp+.} + +Some \textsc{OpenType}~fonts harbor their own small caps. Not all +browsers support the access of \textsc{OpenType}~features from CSS, +but for those that do the following code activates the small caps in +an sufficently ``enriched'' \textsc{OpenType}~font. See also the +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide}{\textsc{OpenType}~fonts guide} and help on \footahref{https://helpx.adobe.com/fonts/using/use-open-type-features.html}{using - OpenType~features}. + \textsc{OpenType}~features}. \begin{verbatim} \newstyle{.smallcaps}{% @@ -6120,8 +6156,8 @@ \subsubsection{Oldstyle Numerals} because their glyphs cannot be synthesized. The \hevea{} macro \verb+\oldstylenums+ accesses class~\verb+oldstyle+, which has no definition by default. The most straightforward way to get oldstyle -numerals is to rely on OpenType~font features with the following -definitions: +numerals is to rely on \textsc{OpenType}~font features with the +following definitions: \begin{verbatim} \newstyle{.oldstyle}{font-feature-settings: "onum"} @@ -6220,34 +6256,29 @@ \subsubsection{Hints to Practitioners} \newcommand{\tablenotesymbol}{\dagger} \newcommand{\tablenotemark}{$^\tablenotesymbol$} \newcommand{\tablenote}[1]{\tablenotemark:~{\footnotesize #1}} - \item Some ``workhorse'' font families that all have been designed - with online readability in mind. - - \begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l} - Family & Serif & Sans Serif & Monospace \\ - \hline - %% Prefer `DejaVu' to `Bitstream Vera'. - %Bitstream Vera & Bitstream Vera & Bitstream Vera Sans & Bitstream Vera Sans Mono \\ - DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ - Free & FreeSerif & FreeSans & FreeMono \\ - IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ - Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ - Noto\tablenotemark & Noto Serif & Noto Sans & Noto Mono \\ - Source Pro\tablenotemark & Source Serif Pro & Source Sans Pro & Source Code Pro \\ - \end{tabular} - - \noindent\tablenote{OpenType-compliant font family, supporting for example oldstyle numerals.} - - \item If the result looks too ``oldstyle'' try the sans serif font - also in the serif position or interchange sans serif and serif. - - \item If the monospace font does not convey enough of an ``at the - terminal'' feeling give Anonymous Pro or Inconsolata a spin. - The latter font family also comes to the rescue when program - listings constantly are ``too wide'', this is, they overflow to - the right. Inconsolata has variants ``Semi Condensed'', - ``Condensed'', ``Extra Condensed'', and ``Ultra Condensed'' - among many others. + \item Some ``workhorse'' font families that all have been designed + with online readability in mind. + + \begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l} + Family & Serif & Sans Serif & Monospace \\ + \hline + DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ + Fira\tablenotemark & & Fira Sans & Fira Mono \\ + Go & & Go & Go Mono \\ + IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ + Liberation & Liberation Serif & Liberation Sans & Liberation Mono \\ + Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ + Noto\tablenotemark & Noto Serif & Noto Sans & Noto Mono \\ + Roboto & Roboto Slab & Roboto & Roboto Mono \\ + Source Pro\tablenotemark & Source Serif Pro & Source Sans Pro & Source Code Pro \\ + Ubuntu & & Ubuntu & Ubuntu Mono \\ + \end{tabular} + + \noindent\tablenote{\textsc{OpenType}-compliant font family, + supporting oldstyle numerals.} + + \item If the result looks too ``oldstyle'' try the sans-serif font + also in the serif position or interchange sans-serif and serif. \end{itemize} \item Check the results with different browsers preferably on multiple diff --git a/html.ml b/html.ml index a0e84d45..63f7ee47 100644 --- a/html.ml +++ b/html.ml @@ -419,6 +419,7 @@ and has_mod = has_mod and clearstyle = clearstyle and nostyle = nostyle and get_fontsize = get_fontsize +and get_pending_styles = get_pending_styles and to_string = to_string (****************************************) diff --git a/html/hevea.hva b/html/hevea.hva index 59465841..d7e23833 100644 --- a/html/hevea.hva +++ b/html/hevea.hva @@ -385,11 +385,18 @@ \newstyle{.slanted}{font-style: oblique} \newstyle{.smallcaps}{font-variant: small-caps} % +\newsavebox{\@pending@style} +\newcommand{\@main@styles}{serif,sansserif,monospace,cursive,fantasy} +\newcommand{\@main@modifier@styles}{italic,slanted,smallcaps} +\newcommand{\@save@top@style}{\sbox{\@pending@style}{\@top@pending@style{\@main@styles}}} +\newcommand{\@save@all@styles}{\sbox{\@pending@style}{\@all@pending@styles{\@main@modifier@styles}}} +\newcommand{\@use@pending@style}{\@getprint{\@pending@style}} +% \newenvironment{tt}{\@span{class="monospace"}}{} \newenvironment{bf}{\@span{style="font-weight:bold"}}{} \newenvironment{em}{\@style{em}}{} -\newenvironment{it}{\@span{class="italic"}}{} -\newenvironment{rm}{\@anti{\it,\bf,\em,\sf,\tt}\@span{class="serif"}}{} +\newenvironment{it}{\@save@top@style\@span{class="\@use@pending@style italic"}}{} +\newenvironment{rm}{\@anti{\em,\sf,\tt}\@save@all@styles\@span{class="\@use@pending@style serif"}}{} \newenvironment{oldstyle}{\@span{class="oldstyle"}}{} \newenvironment{tiny}{\@fontsize{1}}{} \newenvironment{footnotesize}{\@fontsize{2}}{} @@ -424,8 +431,8 @@ \def\sf{\ifmath\ifmathml\@style{font-family: sans-serif}% \else\@span{class="sansserif"}\fi\else\@span{class="sansserif"}\fi} \def\sl{\ifmath\ifmathml\@style{font-family: fantasy; font-style: italic}% -\else\@span{class="slanted"}\fi\else\@span{class="slanted"}\fi} -\def\sc{\@span{class="smallcaps"}}% +\else\@span{class="slanted"}\fi\else\@save@top@style\@span{class="\@use@pending@style slanted"}\fi} +\def\sc{\@save@top@style\@span{class="\@use@pending@style smallcaps"}}% %%%% LaTeX2e verbose declarations \newenvironment{mdseries}{\@anti{\bf}}{} \newenvironment{bfseries}{\bf}{} diff --git a/htmlCommon.ml b/htmlCommon.ml index 2973067f..6611d60e 100644 --- a/htmlCommon.ml +++ b/htmlCommon.ml @@ -824,6 +824,28 @@ let all_to_pending out = let all_to_active out = activate "all_to_active" (all_to_pending out) +let get_pending_styles () = + let {pending = pending_styles; active = _active_environments; top = _top_info} = !cur_out in + List.fold_left + (fun accumulator style -> + match style with + | StyleAttr (_element, attribute) -> + (*prerr_endline ("get_pending_styles: StyleAttr: " ^ element ^ ", " ^ attribute);*) + List.fold_left + (fun a {Scanattr.name = attribute_name; value = attribute_value} -> + match attribute_name with + | "class" -> a @ String.split_on_char ' ' attribute_value + | _other -> a) + accumulator + (Scanattr.scan_html_attribute (Lexing.from_string attribute)) + | Style _s -> + (*prerr_endline ("get_pending_styles: Style " ^ s);*) + accumulator + | Font _index -> accumulator + | Color _name -> accumulator) + [] + pending_styles + (* Clear styles *) let clearstyle () = close_active_mods !cur_out.active ; diff --git a/info.ml b/info.ml index 32da0e88..8ca39cbd 100644 --- a/info.ml +++ b/info.ml @@ -22,6 +22,7 @@ let restart = Text.restart;; let is_empty=Text.is_empty;; let get_fontsize=Text.get_fontsize;; +let get_pending_styles=Text.get_pending_styles;; let nostyle=Text.nostyle;; let clearstyle=Text.clearstyle;; let open_mod=open_mod;; diff --git a/latexscan.mll b/latexscan.mll index 32252201..78c9c38d 100644 --- a/latexscan.mll +++ b/latexscan.mll @@ -2529,6 +2529,44 @@ def_code "\\@anti" Dest.erase_mods envs) ;; +def_code "\\@all@pending@styles" + (fun lexbuf -> + let wanted_styles = String.split_on_char ',' (get_prim_arg lexbuf) + and pending_styles = Dest.get_pending_styles () in + let rec iter = function + | top :: rest -> + if wanted_styles = [] || List.mem top wanted_styles then + begin + Dest.put top; + Dest.put_char ' ' + end; + iter rest + | [] -> () + in + iter pending_styles) +;; + +def_code "\\@top@pending@style" + (fun lexbuf -> + let wanted_styles = String.split_on_char ',' (get_prim_arg lexbuf) + and pending_styles = Dest.get_pending_styles () in + let rec iter = function + | top :: rest -> + if List.mem top wanted_styles then + begin + Dest.put top; + Dest.put_char ' ' + end + else + iter rest + | [] -> () + in + (*prerr_endline ("@top@pending@style: " ^ String.concat ", " pending_styles);*) + (* This is an ugly heuristic: if we find no style pending, assume the first + of the [wanted_styles] is active. *) + iter (if pending_styles = [] then wanted_styles else pending_styles)) +;; + let styles_stack = MyStack.create "styles" ;; diff --git a/outManager.mli b/outManager.mli index 915044e5..b7269e13 100644 --- a/outManager.mli +++ b/outManager.mli @@ -18,6 +18,7 @@ val restart : unit -> unit val is_empty : unit -> bool val get_fontsize : unit -> int +val get_pending_styles : unit -> string list val nostyle : unit -> unit val clearstyle : unit -> unit val open_mod : Element.text -> unit diff --git a/scanattr.mli b/scanattr.mli new file mode 100644 index 00000000..39a4cc83 --- /dev/null +++ b/scanattr.mli @@ -0,0 +1,16 @@ +(* + * This file is distributed under the terms of the GNU General Public + * License either version 2 of the License, or (at your option) any + * later version, as detailed in the file LICENSE. + * + * Copyright (C) 2020 Christoph L. Spiel + *) + + +type html_attribute = { + name: string; + value: string; +} + + +val scan_html_attribute: Lexing.lexbuf -> html_attribute list diff --git a/scanattr.mll b/scanattr.mll new file mode 100644 index 00000000..d98d665a --- /dev/null +++ b/scanattr.mll @@ -0,0 +1,60 @@ +(* + * This file is distributed under the terms of the GNU General Public + * License either version 2 of the License, or (at your option) any + * later version, as detailed in the file LICENSE. + * + * Copyright (C) 2020 Christoph L. Spiel + *) + + +{ + type html_attribute = { + name: string; + value: string; + } +} + + +let optional_white = ['\t' '\n' '\r' ' ']* +let attribute_name = [^ '\x00'-'\x1F' '\x20' '\x22' '\x27' '\x2F' '\x3D' '\x3E' '\x7F'-'\x9F']+ +let unquoted_value = [^ '\x20' '"' '\'' '=' '<' '>' '`']+ +let single_quoted_value = [^ '\'']+ +let double_quoted_value = [^ '"']+ + + +rule scan attributes = parse +| ['\t' '\n' '\r' ' ']+ + { + scan attributes lexbuf + } +| (attribute_name as name) + { + {name; value = ""} :: attributes + } +| (attribute_name as name) optional_white '=' optional_white (unquoted_value as attribute_value) + { + {name; value = attribute_value} :: attributes + } +| (attribute_name as name) optional_white '=' optional_white '\'' (single_quoted_value as attribute_value) '\'' + { + {name; value = attribute_value} :: attributes + } +| (attribute_name as name) optional_white '=' optional_white '"' (double_quoted_value as attribute_value) '"' + { + {name; value = attribute_value} :: attributes + } +| eof + { + [] + } + + +{ + let scan_html_attribute a_lexbuffer = + let rec scan_all a = + match scan a a_lexbuffer with + | [] -> List.rev a + | xs -> scan_all xs + in + scan_all [] +} diff --git a/text.ml b/text.ml index 629a0358..fa81501d 100644 --- a/text.ml +++ b/text.ml @@ -633,7 +633,7 @@ let is_list = function ;; let get_fontsize () = 3;; - +let get_pending_styles () = [];; let nostyle () = !cur_out.nostyle<-true ;; From 0008afca8c37d0bda9ba61ef4dd31c8768632ac5 Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Wed, 2 Sep 2020 16:45:15 +0200 Subject: [PATCH 4/7] Give "bold" its own class and add `\bf' to our system of saving and looking up the top-most style. Update the documentation. Explain the use-case of ".monospace.bold". --- doc/text.tex | 147 ++++++++++++++++++++++++++++++------------------- html/hevea.hva | 7 ++- 2 files changed, 94 insertions(+), 60 deletions(-) diff --git a/doc/text.tex b/doc/text.tex index 7a4e3650..5a1f8e6f 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -5864,7 +5864,7 @@ \subsection{Changing the Type Style}\label{type-style} & small caps & \verb+\scshape+ & \verb+\textsc+ & \verb+\sc+ & \verb+class: smallcaps+ & \textsc{\samplephrase} \\ & emphasized & \verb+\em+ & \verb+\emph+ & \verb+\em+ & HTML-element ``em'' & \emph{\samplephrase} \\ Weight & normal & \verb+\mdseries+ & \verb+\textmd+ & \verb+\md+ & \textit{no style} & \mdseries{\samplephrase} \\ - & bold & \verb+\bfseries+ & \verb+\textbf+ & \verb+\bf+ & \verb+font-weight: bold+ & \textbf{\samplephrase} \\ + & bold & \verb+\bfseries+ & \verb+\textbf+ & \verb+\bf+ & \verb+class: bold+ & \textbf{\samplephrase} \\ \end{tabular} \end{center} @@ -5930,6 +5930,7 @@ \subsection{\label{sec:controlling-font-selection-with-css}% \verb+serif+ & \verb+font-family: serif+ & Body text and math; used by \verb+\textrm+. \\ \verb+sansserif+ & \verb+font-family: sans-serif+ & Text tagged with \verb+\textsf+. \\ \verb+monospace+ & \verb+font-family: monospace+ & Any typewriter text and in particular environment~\verb+verbatim+, macros~\verb+\verb+, and \verb+\texttt+. \\ +\verb+bold+ & \verb+font-weight: bold+ & Text tagged with \verb+\textbf+. \\ \verb+italic+ & \verb+font-style: italic+ & Text tagged with \verb+\textit+. \\ \verb+slanted+ & \verb+font-style: oblique+ & Text tagged with \verb+\textsl+. \\ \verb+smallcaps+ & \verb+font-variant: small-caps+ & Text tagged with \verb+\textsc+. \\ @@ -5949,7 +5950,7 @@ \subsection{\label{sec:controlling-font-selection-with-css}% font-size: calc(19 / 16)} \end{verbatim} -\noindent or to fine-tune \verb+font-stretch+ and \verb+font-weight+; +\noindent or to fine-tune \verb+font-variant+ and \verb+font-weight+; it is also the perfect place to activate (or deactivate) OpenType~features exactly for one specific family @@ -5988,6 +5989,29 @@ \subsection{\label{sec:controlling-font-selection-with-css}% \newstyle{.chapter, .section, .subsection, .subsubsection}{font-family: \sansfontfamily} \end{verbatim} +\subsubsection{Selective Overrides} + +\hevea{} propagates font styles inward in scope and the controlling +CSS~class arguments accumulate. For example +\verb+\textit{\textrm{emphasized text}}+ as well as +\verb+\textrm{\textit{emphasized text}}+ associate classes +\verb+serif+ (font family~serif) \emph{and} \verb+italic+ (font +style~italic) with ``emphasized text''. Of course one or both classes +could have been redefined by the user. + +Another use-case arises if the bold-face chosen by \verb+\textbf+ -- +translated to HTML-element \verb+b+ -- in \verb+verbatim+, +\verb+\verb+, or \verb+\texttt+ is too heavy (default weight: 700). +We can tell the browser to use a medium weight \emph{only} for the +typewriter font with + +\begin{verbatim} +\newstyle{.monospace.bold}{font-weight: 500} +\end{verbatim} + +\noindent Other applications of selective overrides are discussed in +some of the following sections. + \subsubsection{\label{sec:italics-vs-slanted}% Italics vs.\ Slanted} @@ -5995,7 +6019,7 @@ \subsubsection{\label{sec:italics-vs-slanted}% same superfamily ``Latin Modern'', for example, ``Latin Modern Roman 10~Italic'' and ``Latin Modern Roman Slanted 10~Regular''. Needless to say all members in the superfamily are extremely well matched! On -the HTML-side it is hard to recreate this kind of super-pairing; most +the HTML-side it is hard to recreate this kind of super-pairing. Most often a font family will lack a ``slanted'' variant and -- depending on the font-synthesis settings -- browsers substitute ``italic''. This means \verb+\textit+ and \verb+\textsl+ will be mapped to @@ -6010,27 +6034,17 @@ \subsubsection{\label{sec:italics-vs-slanted}% and \verb+slanted+ to convey the semantic differences of \verb+\textit+ and \verb+\textsl+. -\begin{quote}\small - \hevea{} propagates font styles inward in scope and the controlling - CSS~class arguments accumulate. For example - \verb+\textit{\textrm{emphasized text}}+ as well as - \verb+\textrm{\textit{emphasized text}}+ as well associate classes - \verb+serif+ (font family~serif) \emph{and} \verb+italic+ (font - style~italic) with ``emphasized text''. Of course one or both - classes could have been redefined by the user. -\end{quote} - -\noindent The CSS~selector to target \emph{exactly} the \verb+italic+ -or \verb+slanted+ variant of the \verb+serif+~family takes a bit care -to construct. Simple matching \verb+.italic+ or \verb+.slanted+ also +The CSS~selector to target \emph{exactly} the \verb+italic+ or +\verb+slanted+ variant of the \verb+serif+~family takes a bit care to +construct. Simple matching of \verb+.italic+ or \verb+.slanted+ also would change the fonts used for sans-serif and monospace families, which probably is not intended. So, we use a conjunctive CSS~selector -to specifically overide the slanted version of the serif~class only: +to specifically override the slanted version of the serif~class only: \verb+.slanted.serif+ (order does not matter). Note that there is \emph{no} space between the two class~selectors! This is the prudent way to replace a font-family for any predefined class that does not -itself set the font-family; currently these are \verb+italic+, -\verb+slanted+, and \verb+smallcaps+. +itself set the font-family; currently these are \verb+bold+, +\verb+italic+, \verb+slanted+, and \verb+smallcaps+. \begin{verbatim} \newstyle{.serif}{font-family: "FreeSerif", serif} @@ -6061,16 +6075,16 @@ \subsubsection{\label{sec:italics-vs-slanted}% \subsubsection{Dedicated Smallcaps} -\hevea{} translates \verb+\textsc+ into CSS~class \verb+smallcaps+, -which in turn activates \verb+font-variant: small-caps+ by default. +\hevea{} translates \verb+\textsc+ into \verb+span+s with +class~\verb+smallcaps+ which in turn activate +\verb+font-variant: small-caps+ by default. (See also +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps}.) This instructs the browser to look for small-capital letters in the \emph{currently selected font}, but no further. Regrettably, only few -fonts come with small~caps included (look for, e.g., ``Pro'' or -``Expert'' series or check with tools like, e.g.\ \textbf{otfinfo(1)} -for \textsc{OpenType}~feature ``\verb+smcp+'' -- small capitals). For -all others the browser synthesizes the glyphs based on the selected -font; see also -\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps}. +fonts come with small~caps included (e.g.\ some ``Pro'' or ``Expert'' +series). For all others the browser synthesizes the glyphs based on +the selected font -- depending on the browser even if the font +supports \textsc{OpenType}~feature ``\verb+smcp+''. \paragraph{Separate Small-Caps Fonts.} What is more common today are regular fonts that pair with separate fonts that cover their @@ -6101,7 +6115,7 @@ \subsubsection{Dedicated Smallcaps} of a resized variant of the small~caps font to synthesize the small caps, which defeats the very purpose of the class override and -- on top of that -- generally looks ugly. Furthermore, the example -demonstrates selective override of the serif and the sans~serif fonts. +demonstrates selective overrides of the serif and the sans~serif fonts. If you latch a non-small~caps font, stick with the default as here glyph synthesis in fact is desired. @@ -6132,19 +6146,20 @@ \subsubsection{Dedicated Smallcaps} \begin{verbatim} \newstyle{.smallcaps}{% - font-variant-caps: small-caps; font-feature-settings: "smcp"; -} + font-variant: normal} \end{verbatim} -\noindent Note: In the example right above any other -font-feature-settings than \verb+smcp+ are cleared! +\noindent Note: In the example right above any other font-feature +settings than \verb+smcp+ are cleared! If the browser supports the CSS at-rule \verb+@supports+ the recipe is improved by \begin{verbatim} -\newstyle{.smallcaps}{font-feature-settings: "smcp"} +\newstyle{.smallcaps}{% + font-feature-settings: "smcp"; + font-variant: normal} \newstyle{@supports (font-variant-caps: small-caps)}{% .smallcaps \{font-variant-caps: small-caps\} } @@ -6186,12 +6201,12 @@ \subsubsection{Variable Typewriter Variant} \fi \end{verbatim} -\noindent Now, macro~\verb+\textvtt+ could be used as a drop-in +\noindent Now, macro~\verb+\textvtt+ can be used as a drop-in replacement for \verb+\texttt+. If no proportional typewriter font is readily available on the -HTML-side, a similar effect is achieved with a slab-serif, -proportional font, like for example ``Zilla Slab''. +HTML-side, a similar effect may be achieved with a slab-serif, +proportional font. \subsubsection{Hints to Practitioners} @@ -6253,32 +6268,50 @@ \subsubsection{Hints to Practitioners} \item Starting points for CSS~font selection. \begin{itemize} - \newcommand{\tablenotesymbol}{\dagger} - \newcommand{\tablenotemark}{$^\tablenotesymbol$} - \newcommand{\tablenote}[1]{\tablenotemark:~{\footnotesize #1}} - \item Some ``workhorse'' font families that all have been designed - with online readability in mind. - - \begin{tabular}{l@{\quad}l@{\quad}l@{\quad}l} - Family & Serif & Sans Serif & Monospace \\ + \newcommand{\divider}{$\bullet$} + \newcommand{\tablenotemark}[1]{$^{#1}$} + \newcommand{\tablenote}[2]{#1~{\footnotesize #2}} + \newcommand{\hasoldstylenums}{\tablenotemark{\S}} + \newcommand{\hassmallcapitals}{\tablenotemark{\dagger}} + \newcommand{\substitutesans}{\tablenotemark{\ast}} + \item Some font families that all have been designed with onscreen + readability in mind. + + \begin{tabular}{rl@{\quad}l@{\quad}l@{\quad}l} + & Family & Serif & Sans Serif & Monospace \\ \hline - DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ - Fira\tablenotemark & & Fira Sans & Fira Mono \\ - Go & & Go & Go Mono \\ - IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ - Liberation & Liberation Serif & Liberation Sans & Liberation Mono \\ - Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ - Noto\tablenotemark & Noto Serif & Noto Sans & Noto Mono \\ - Roboto & Roboto Slab & Roboto & Roboto Mono \\ - Source Pro\tablenotemark & Source Serif Pro & Source Sans Pro & Source Code Pro \\ - Ubuntu & & Ubuntu & Ubuntu Mono \\ + \divider & \multicolumn{3}{l}{\textit{Families of two or three fonts belonging together.}} \\ + & DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ + & Fira\hasoldstylenums & \substitutesans & Fira Sans & Fira Mono \\ + & Go & \substitutesans & Go & Go Mono \\ + & IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ + & Liberation & Liberation Serif & Liberation Sans & Liberation Mono \\ + & Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ + & Noto\hasoldstylenums & Noto Serif & Noto Sans & Noto Mono \\ + & Roboto\hassmallcapitals & Roboto Slab & Roboto & Roboto Mono \\ + & Source Pro\hasoldstylenums\hassmallcapitals + & Source Serif Pro & Source Sans Pro & Source Code Pro \\ + & Ubuntu & \substitutesans & Ubuntu & Ubuntu Mono \\ + \divider & \multicolumn{3}{l}{\textit{Two-font families with visually matching monospace fonts.}} \\ + & Inria\hasoldstylenums/Fira + & Inria Serif & Inria Sans & Fira Code \\ + & Merriweather\hasoldstylenums/League + & Merriweather & Merriweather Sans & League Mono \\ \end{tabular} - \noindent\tablenote{\textsc{OpenType}-compliant font family, - supporting oldstyle numerals.} + \begin{trivlist} + \item\tablenote{\substitutesans}{Use the sans-serif font in the + \verb+serif+~class, too.} + + \item\tablenote{\hasoldstylenums}{\textsc{OpenType}-compliant + font family supporting oldstyle numerals (\verb+onum+).} + + \item\tablenote{\hassmallcapitals}{\textsc{OpenType}-compliant font + family supporting small capitals (\verb+smcp+).} + \end{trivlist} \item If the result looks too ``oldstyle'' try the sans-serif font - also in the serif position or interchange sans-serif and serif. + also in the serif position or swap sans-serif and serif. \end{itemize} \item Check the results with different browsers preferably on multiple diff --git a/html/hevea.hva b/html/hevea.hva index d7e23833..32965df4 100644 --- a/html/hevea.hva +++ b/html/hevea.hva @@ -384,16 +384,17 @@ \newstyle{.italic}{font-style: italic} \newstyle{.slanted}{font-style: oblique} \newstyle{.smallcaps}{font-variant: small-caps} +\newstyle{.bold}{font-weight: bold} % \newsavebox{\@pending@style} \newcommand{\@main@styles}{serif,sansserif,monospace,cursive,fantasy} -\newcommand{\@main@modifier@styles}{italic,slanted,smallcaps} +\newcommand{\@main@modifier@styles}{bold,italic,slanted,smallcaps} \newcommand{\@save@top@style}{\sbox{\@pending@style}{\@top@pending@style{\@main@styles}}} \newcommand{\@save@all@styles}{\sbox{\@pending@style}{\@all@pending@styles{\@main@modifier@styles}}} \newcommand{\@use@pending@style}{\@getprint{\@pending@style}} % -\newenvironment{tt}{\@span{class="monospace"}}{} -\newenvironment{bf}{\@span{style="font-weight:bold"}}{} +\newenvironment{tt}{\@save@all@styles\@span{class="\@use@pending@style monospace"}}{} +\newenvironment{bf}{\@save@top@style\@span{class="\@use@pending@style bold"}}{} \newenvironment{em}{\@style{em}}{} \newenvironment{it}{\@save@top@style\@span{class="\@use@pending@style italic"}}{} \newenvironment{rm}{\@anti{\em,\sf,\tt}\@save@all@styles\@span{class="\@use@pending@style serif"}}{} From 443a4f60643b518bea9a6101f39b3c11aada131e Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Sat, 3 Oct 2020 15:06:52 +0200 Subject: [PATCH 5/7] Fix `normalfont' environment to exactly reflect LaTeX's behavior. --- html/hevea.hva | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/hevea.hva b/html/hevea.hva index 32965df4..4518678b 100644 --- a/html/hevea.hva +++ b/html/hevea.hva @@ -444,7 +444,7 @@ \newenvironment{itshape}{\@anti{\sl,\sc}\it}{} \newenvironment{slshape}{\@anti{\it,\sc}\sl}{} \newenvironment{scshape}{\@anti{\it,\sl}\sc}{} -\newenvironment{normalfont}{\rm\mdseries\upshape}{} +\newenvironment{normalfont}{\@anti{\em,\bf,\sf,\tt}\upshape}{} %%%%%%%%%%%%%%%% \def\textrm#1{\mbox{\rmfamily#1}} \def\textup#1{\mbox{\upshape#1}} From 896145fa1045e98c2bbf130907e23e8019a494e4 Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Wed, 21 Oct 2020 09:39:43 +0200 Subject: [PATCH 6/7] Update the section "Controlling Font Selection with CSS" with the latest findings. Add "Dangerous Bend" sub-sections on particularly delicate properties. --- doc/text.tex | 423 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 323 insertions(+), 100 deletions(-) diff --git a/doc/text.tex b/doc/text.tex index 5a1f8e6f..f01913ee 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -3934,7 +3934,7 @@ \subsection{Changing the format of images} \texttt{imagen} are bit special: \texttt{imagen} produces both PNG\footnote{or GIF, if \texttt{gif.hva} is loaded} and SVG~images; while \texttt{hevea} offers both image sources, letting client browser select the most appropriate one by the means of -teh \verb+srcset+ attribute of the \verb+img+ element. +the \verb+srcset+ attribute of the \verb+img+ element. \subsection{Storing images in a separate directory} \comindex{heveaimagedir} @@ -5943,20 +5943,23 @@ \subsection{\label{sec:controlling-font-selection-with-css}% the classes in the document preamble. Moreover, as these are CSS~classes \emph{all} properties apply. Besides gaudy effects this comes in handy to adjust the base size of the typewriter font to match -the body text, for example with +the body text, for example with (see +\ref{sec:dangerous-bend-compounding} why three new styles are +necessary here) \begin{verbatim} \newstyle{.monospace}{font-family: "Courier New", Courier, monospace; - font-size: calc(19 / 16)} + font-size: calc(1em * 19 / 16)} +\newstyle{.monospace.bold}{font-size: inherit} +\newstyle{.monospace.italic}{font-size: inherit} \end{verbatim} -\noindent or to fine-tune \verb+font-variant+ and \verb+font-weight+; -it is also the perfect place to activate (or deactivate) +\noindent or to fine-tune a family's \verb+font-weight+. +It is also the perfect place to activate (or deactivate) OpenType~features exactly for one specific family \begin{verbatim} -\newstyle{.sansserif}{font-family: Jost, sans-serif; - font-feature-settings: "ss01"}% Futura-like single-storey "a" +\newstyle{.serif.bold}{font-weight: 600}% semi bold \end{verbatim} \noindent Despite their names the classes can host any font chosen @@ -5970,7 +5973,8 @@ \subsection{\label{sec:controlling-font-selection-with-css}% Furthermore, the \verb+monospace+~class does not need to reference mono-spaced fonts, though proportional fonts probably will skew output -that aligns for fonts with a fixed width. +that aligns for fonts with a fixed width; a statement that also holds +for changing \verb+word-spacing+ of mono-spaced fonts. To achieve consistency in font selection it is constructive to define macros for each family and then use these to set the document's font @@ -5989,15 +5993,20 @@ \subsection{\label{sec:controlling-font-selection-with-css}% \newstyle{.chapter, .section, .subsection, .subsubsection}{font-family: \sansfontfamily} \end{verbatim} +On the \LaTeX~side +package~\footahref{https://ctan.org/pkg/typeface}{typeface} simplifies +font selection. + + \subsubsection{Selective Overrides} \hevea{} propagates font styles inward in scope and the controlling CSS~class arguments accumulate. For example -\verb+\textit{\textrm{emphasized text}}+ as well as -\verb+\textrm{\textit{emphasized text}}+ associate classes +\verb+\textit{\textrm{accentuated text}}+ as well as +\verb+\textrm{\textit{accentuated text}}+ associate classes \verb+serif+ (font family~serif) \emph{and} \verb+italic+ (font -style~italic) with ``emphasized text''. Of course one or both classes -could have been redefined by the user. +style~italic) with ``accentuated text''. Of course one or both +classes could have been redefined by the user. Another use-case arises if the bold-face chosen by \verb+\textbf+ -- translated to HTML-element \verb+b+ -- in \verb+verbatim+, @@ -6009,8 +6018,8 @@ \subsubsection{Selective Overrides} \newstyle{.monospace.bold}{font-weight: 500} \end{verbatim} -\noindent Other applications of selective overrides are discussed in -some of the following sections. +\noindent Some other applications of selective overrides are discussed +in the following sections. \subsubsection{\label{sec:italics-vs-slanted}% Italics vs.\ Slanted} @@ -6018,7 +6027,7 @@ \subsubsection{\label{sec:italics-vs-slanted}% \TeX{} serves separate fonts for italics and slanted characters in the same superfamily ``Latin Modern'', for example, ``Latin Modern Roman 10~Italic'' and ``Latin Modern Roman Slanted 10~Regular''. Needless -to say all members in the superfamily are extremely well matched! On +to say all members in the superfamily are extremely well matched. On the HTML-side it is hard to recreate this kind of super-pairing. Most often a font family will lack a ``slanted'' variant and -- depending on the font-synthesis settings -- browsers substitute ``italic''. @@ -6040,10 +6049,10 @@ \subsubsection{\label{sec:italics-vs-slanted}% would change the fonts used for sans-serif and monospace families, which probably is not intended. So, we use a conjunctive CSS~selector to specifically override the slanted version of the serif~class only: -\verb+.slanted.serif+ (order does not matter). Note that there is -\emph{no} space between the two class~selectors! This is the prudent -way to replace a font-family for any predefined class that does not -itself set the font-family; currently these are \verb+bold+, +\verb+.slanted.serif+, where order does not matter. Note that there +is \emph{no} space between the two class~selectors! This is the +prudent way to replace a font-family for any predefined class that +does not itself set the font-family; currently these are \verb+bold+, \verb+italic+, \verb+slanted+, and \verb+smallcaps+. \begin{verbatim} @@ -6078,13 +6087,16 @@ \subsubsection{Dedicated Smallcaps} \hevea{} translates \verb+\textsc+ into \verb+span+s with class~\verb+smallcaps+ which in turn activate \verb+font-variant: small-caps+ by default. (See also -\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps}.) -This instructs the browser to look for small-capital letters in the -\emph{currently selected font}, but no further. Regrettably, only few -fonts come with small~caps included (e.g.\ some ``Pro'' or ``Expert'' -series). For all others the browser synthesizes the glyphs based on -the selected font -- depending on the browser even if the font -supports \textsc{OpenType}~feature ``\verb+smcp+''. +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-caps}{font-variant-caps} +and +\footahref{https://creativepro.com/understanding-applying-small-caps/}{understanding + and applying small caps}.) This instructs the browser to look for +small-capital letters in the \emph{currently selected font}, but no +further. Regrettably, only few fonts come with small~caps included +(e.g.\ some ``Pro'' or ``Expert'' series). For all others the browser +synthesizes the glyphs based on the selected font -- depending on the +browser even if the font supports \textsc{OpenType}~feature +``\verb+smcp+''. \paragraph{Separate Small-Caps Fonts.} What is more common today are regular fonts that pair with separate fonts that cover their @@ -6096,9 +6108,12 @@ \subsubsection{Dedicated Smallcaps} \item Latin Modern Roman -- Latin Modern Roman Caps \end{itemize} -\noindent By overriding the default definition of -CSS~class \verb+smallcaps+ these font pairings can be lifted -into \hevea. +\noindent The font names do not always give away their contents that +clearly. It is worth to check out the font files (.ttf, .otf, \dots) +if small~caps are needed. + +By overriding the default definition of CSS~class \verb+smallcaps+ +these font pairings can be lifted into \hevea. \begin{verbatim} \newstyle{.serif}{font-family: "Alegreya", serif} @@ -6117,18 +6132,10 @@ \subsubsection{Dedicated Smallcaps} top of that -- generally looks ugly. Furthermore, the example demonstrates selective overrides of the serif and the sans~serif fonts. -If you latch a non-small~caps font, stick with the default as here -glyph synthesis in fact is desired. - -\begin{verbatim} -\newstyle{.serif.smallcaps}{font-family: "Baskervville", serif; - font-variant: small-caps} -\end{verbatim} - -\noindent Note that \hevea's default acts like an operator -- only -setting \verb+font-variant: small-caps+ means: whatever font is -current, generate small-caps by accessing the font's own small capital -letters, use its downsized uppercase letters as small caps, or another +Note that \hevea's default acts like an operator -- only setting +\verb+font-variant: small-caps+ means: whatever font is current, +generate small~caps by accessing the font's own small capital letters, +use its downsized uppercase letters as small caps, or another technique. When the default of class~\verb+smallcaps+ is replaced with a definition that contains a \verb+font-family+ the operator character is lost and the original \LaTeX{} behavior is recovered. @@ -6138,16 +6145,17 @@ \subsubsection{Dedicated Smallcaps} Some \textsc{OpenType}~fonts harbor their own small caps. Not all browsers support the access of \textsc{OpenType}~features from CSS, but for those that do the following code activates the small caps in -an sufficently ``enriched'' \textsc{OpenType}~font. See also the +an sufficently enriched \textsc{OpenType}~font. See also the \footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide}{\textsc{OpenType}~fonts guide} and help on \footahref{https://helpx.adobe.com/fonts/using/use-open-type-features.html}{using \textsc{OpenType}~features}. \begin{verbatim} -\newstyle{.smallcaps}{% +\newstyle{.smallcaps}{ font-feature-settings: "smcp"; - font-variant: normal} + font-variant: normal; +} \end{verbatim} \noindent Note: In the example right above any other font-feature @@ -6157,14 +6165,61 @@ \subsubsection{Dedicated Smallcaps} improved by \begin{verbatim} -\newstyle{.smallcaps}{% +\newstyle{.smallcaps}{ font-feature-settings: "smcp"; - font-variant: normal} -\newstyle{@supports (font-variant-caps: small-caps)}{% + font-variant: normal; +} +\newstyle{@supports (font-variant-caps: small-caps)}{ .smallcaps \{font-variant-caps: small-caps\} } \end{verbatim} +\paragraph{Avoiding Faux Small Caps.} + +If the font of choice neither has a small~caps companion font, nor +hosts its own small~caps \`{a} l\`{a} \textsc{OpenType} and the user +does not want fake, browser-generated small~caps, the original font +reduced to its own ``x''-height in all-uppercase sometimes can be +substituted for true small~caps. + +\begin{verbatim} +\newcommand{\seriffontfamily}{Martel, serif} +\newstyle{.serif}{font-family: \seriffontfamily} +\newstyle{.serif.smallcaps}{ + font-family: \seriffontfamily; + font-feature-settings: "cpsp"; % improve on capital spacing + font-size: 71\%; % rescale to x-height + font-variant: normal; % undo default (if any) + font-weight: 600; % demi-bold to match weight of lower-case serif + text-transform: uppercase; +} +\end{verbatim} + +\noindent These kind of ``stand-in'' small~caps benefit from the +\verb+cpsp+-feature because we transform the text to rescaled +all-uppercase. To pull off the trick sucessfully it is necessary that +the font offers a weight between the weight of the +\verb+\seriffontfamily+ and bold such that the visual appearance of +the small~caps can be matched with the regular lower-case serif +letters. + +Some browsers are overzealous. They synthesize small~caps or italics +even if \verb+font-synthesis: none+ is in effect. A discriminating +author who wants to avoid ugly synthetic glyphs can explicitly prevent +font synthesis with + +\begin{verbatim} +\newstyle{.serif.smallcaps}{font-variant-caps: normal} +\end{verbatim} + +\noindent for the small~caps variant or + +\begin{verbatim} +\newstyle{.serif.italic}{font-style: normal} +\end{verbatim} + +\noindent for italics. + \subsubsection{Oldstyle Numerals} \LaTeX{} \verb+\oldstylenums+ are not easily translated to the web @@ -6176,14 +6231,13 @@ \subsubsection{Oldstyle Numerals} \begin{verbatim} \newstyle{.oldstyle}{font-feature-settings: "onum"} -\newstyle{@supports (font-variant-numeric: oldstyle-nums)}{% +\newstyle{@supports (font-variant-numeric: oldstyle-nums)}{ .oldstyle \{font-variant-numeric: oldstyle-nums\} } \end{verbatim} \noindent If a font has no oldstyle-nums the common numerals will be -used. In a pinch another font's numerals can be borrowed given the -other font is highly similar. +used. \subsubsection{Variable Typewriter Variant} @@ -6208,6 +6262,148 @@ \subsubsection{Variable Typewriter Variant} HTML-side, a similar effect may be achieved with a slab-serif, proportional font. + +\subsubsection{Dangerous Bend: Compounding\label{sec:dangerous-bend-compounding}} + +Font sizes can be specified in absolute or relative +\footahref{https://www.w3schools.com/cssref/css_units.asp}{CSS units}. +However, absolute lengths preclude fonts from being scaled by \hevea's +size-changing macros. Absolute lengths may even defy browsers' +``zoom'' functionalities. Relative lengths react properly to +size-changing macros and zoom but suffer from compounding which means +their effective values change depending on their scope; see also MDN +Web Docs on +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#Description}{font-size}. + +The \verb+monospace+ example in +section~\ref{sec:controlling-font-selection-with-css} uses the +relative length unit~\verb+em+ and as soon as more than one modifier +manipulates the re-sized font its size change compounds. To typeset a +programming-language keyword in bold typewriter font we write + +\begin{verbatim} +\texttt{\emph{keyword}} +\end{verbatim} + +\noindent which is translated by \hevea{} to + +\begin{verbatim} + + + keyword + + +\end{verbatim} + +\noindent Let us assume that at the root level of the document all +font sizes are $1\mbox{em} = 16\mbox{px} = 1\mbox{rem}$. At the +opening \verb+em+-element by virtue of the enclosing +\verb+span+-element the new monospace font size is $1\mbox{em} \times +19/16 (= 19\mbox{px} = 1.1875\mbox{rem})$ at the same time this +redefines the current ``em''-unit for class~monospace to $1\mbox{em} = +1\mbox{rem} \times 19/16$. The second \verb+span+-element changes the +font size once again arriving at $1\mbox{em} \times 19/16 (= +22.5625\mbox{px} = 1.41015625\mbox{rem})$. + +The example's two additional styles stating \verb+font-size: inherit+ +instruct the browser to use the \emph{value} of the font~size at the +enclosing scope, this is, they suppress reevaluation of the relative +font~size and thus suppress compounding for bold and italic variants. + +Note that the relative unit \verb+rem+ works around some of the +absolute lengths' limitations but still renders the resizing macros +inoperative. + + +\subsubsection{Dangerous Bend: Set Override\label{sec:dangerous-bend-set-override}} + +CSS-features are always overridden as a whole. This behavior must be +kept in mind when working with \verb+font-feature-settings+ and +\verb+font-variation-settings+. Neither single font-feature settings +nor single font-variation settings can be overridden, the override +always redefines the whole set. So, if we define + +\begin{verbatim} +\newcommand{\sansfontfamily}{"Work Sans", sans-serif} +\newstyle{.sansserif}{ + font-family: \sansfontfamily; + font-feature-settings: "ss01", "ss04"; +} +\newstyle{.sansserif.smallcaps}{ + font-family: \sansfontfamily; + font-feature-settings: "smcp"; + font-variant: normal; +} +\end{verbatim} + +our smallcaps class looses font-features~\verb+ss01+ and \verb+ss04+. + +Solutions of the problem are the use of +\footahref{https://www.w3schools.com/css/css3_variables.asp}{CSS~variables} +or \LaTeX~macros. Let us fix the last example with a macro. + +\begin{verbatim} +\newcommand{\sansfontfamily}{"Work Sans", sans-serif} +\newcommand{\sansbasefeatures}{"ss01", "ss04"} +\newstyle{.sansserif}{ + font-family: \sansfontfamily; + font-feature-settings: \sansbasefeatures; +} +\newstyle{.sansserif.smallcaps}{ + font-family: \sansfontfamily; + font-feature-settings: \sansbasefeatures, "smcp"; + font-variant: normal; +} +\end{verbatim} + +\noindent Care has to be taken that the macro-enriched style still +generates valid CSS. + +Parameterized macros handle more complicated applications as for +example variable fonts. + +\begin{verbatim} +\newcommand{\variablefontrecursive}[1]{ + font-family: Recursive, monospace; + font-feature-settings: "ss02", "ss12"; + font-style: \ifthenelse{\equal{#1}{0}}{normal}{oblique #1deg}; + font-synthesis: none; + font-variant: slashed-zero; + font-variation-settings: "CASL" 0, "CRSV" 0.5, "MONO" 1, "slnt" -#1; +} +\newstyle{.monospace}{\variablefontrecursive{0}} +\newstyle{.monospace.italic}{\variablefontrecursive{8}} +\end{verbatim} + +\noindent As an example for the use of CSS~variables we define the +basic font feature settings in the \verb+:root+~pseudo-element: + +\begin{verbatim} +\newstyle{:root}{ + --root-font-feature-settings: "calt", "ccmp", "clig", "kern", "liga", "size"; + /* more variable definitions... */ +} +\end{verbatim} + +\noindent to apply it to the document's \verb+body+~element + +\begin{verbatim} +\newstyle{body}{ + font-feature-settings: var(--root-font-feature-settings); + /* more properties... */ +} +\end{verbatim} + +\noindent and any font-family that touches \verb+font-feature-settings+. + +\begin{verbatim} +\newstyle{.sansserif}{ + font-family: "Work Sans", sans-serif; + font-feature-settings: var(--root-font-feature-settings), "ss01", "ss04"; +} +\end{verbatim} + + \subsubsection{Hints to Practitioners} Some hints to get legible and portable output. @@ -6260,62 +6456,89 @@ \subsubsection{Hints to Practitioners} \item Pass attribute~\verb+font-style+ with classes~\verb+italic+ and \verb+slanted+. Override the default font~variant of class~\verb+smallcaps+ with \verb+normal+ if the font~family - designates genuine small-caps fonts. + designates genuine small~caps fonts. \item Always put the default family in the last position of any \verb+font-family+. -\item Starting points for CSS~font selection. - - \begin{itemize} - \newcommand{\divider}{$\bullet$} - \newcommand{\tablenotemark}[1]{$^{#1}$} - \newcommand{\tablenote}[2]{#1~{\footnotesize #2}} - \newcommand{\hasoldstylenums}{\tablenotemark{\S}} - \newcommand{\hassmallcapitals}{\tablenotemark{\dagger}} - \newcommand{\substitutesans}{\tablenotemark{\ast}} - \item Some font families that all have been designed with onscreen - readability in mind. - - \begin{tabular}{rl@{\quad}l@{\quad}l@{\quad}l} - & Family & Serif & Sans Serif & Monospace \\ - \hline - \divider & \multicolumn{3}{l}{\textit{Families of two or three fonts belonging together.}} \\ - & DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono \\ - & Fira\hasoldstylenums & \substitutesans & Fira Sans & Fira Mono \\ - & Go & \substitutesans & Go & Go Mono \\ - & IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono \\ - & Liberation & Liberation Serif & Liberation Sans & Liberation Mono \\ - & Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter \\ - & Noto\hasoldstylenums & Noto Serif & Noto Sans & Noto Mono \\ - & Roboto\hassmallcapitals & Roboto Slab & Roboto & Roboto Mono \\ - & Source Pro\hasoldstylenums\hassmallcapitals - & Source Serif Pro & Source Sans Pro & Source Code Pro \\ - & Ubuntu & \substitutesans & Ubuntu & Ubuntu Mono \\ - \divider & \multicolumn{3}{l}{\textit{Two-font families with visually matching monospace fonts.}} \\ - & Inria\hasoldstylenums/Fira - & Inria Serif & Inria Sans & Fira Code \\ - & Merriweather\hasoldstylenums/League - & Merriweather & Merriweather Sans & League Mono \\ - \end{tabular} - - \begin{trivlist} - \item\tablenote{\substitutesans}{Use the sans-serif font in the - \verb+serif+~class, too.} - - \item\tablenote{\hasoldstylenums}{\textsc{OpenType}-compliant - font family supporting oldstyle numerals (\verb+onum+).} - - \item\tablenote{\hassmallcapitals}{\textsc{OpenType}-compliant font - family supporting small capitals (\verb+smcp+).} - \end{trivlist} - - \item If the result looks too ``oldstyle'' try the sans-serif font - also in the serif position or swap sans-serif and serif. - \end{itemize} - \item Check the results with different browsers preferably on multiple systems. + +\item Some font families that all have been designed with onscreen + readability in mind. They can serve as starting points for font + selection. + \newcommand{\pkg}[1]{\texttt{#1}} + \newcommand{\divider}{$\bullet$} + \newcommand*{\tabelnoteref}[1]{\mbox{$^{\ref{#1}}$}} + \begin{tabular}{rl@{\quad}l@{\quad}l@{\quad}l@{\quad}p{10em}} + {} & Family & \multicolumn{3}{l}{\hevea via CSS} & \LaTeX\tabelnoteref{enum:simlatexpackage} \\ + {} & & Serif & Sans Serif & Monospace & \\ + \hline + \divider & \multicolumn{4}{l}{\textit{Families of two or three fonts belonging together.}} \\ + {} & DejaVu & DejaVu Serif & DejaVu Sans & DejaVu Sans Mono & \pkg{dejavu}; \pkg{typeface} \\ + {} & Droid & Droid Serif & Droid Sans & Droid Sans Mono & \pkg{droidserif}, \pkg{droidsans}, \pkg{droidmono}; \pkg{typeface} \\ + {} & Fira & \tabelnoteref{enum:substitutesans} + {} & Fira Sans\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Fira Mono & \pkg{FiraSans}, \pkg{FiraMono} \\ + {} & Go & \tabelnoteref{enum:substitutesans} + {} & Go & Go Mono & \pkg{GoSans}, \pkg{GoMono} \\ + {} & IBM Plex & IBM Plex Serif & IBM Plex Sans & IBM Plex Mono & \pkg{plex-otf} \\ + {} & Liberation & Liberation Serif & Liberation Sans & Liberation Mono & \\ + {} & Lucida & Lucida Bright & Lucida Sans & Lucida Sans Typewriter & \pkg{typeface} \\ + {} & Noto & Noto Serif\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Noto Sans\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Noto Mono & \pkg{noto} \\ + {} & Roboto & Roboto Slab\tabelnoteref{enum:hassmallcapitals} + {} & Roboto\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Roboto Mono & \pkg{roboto} \\ + {} & Source Pro & Source Serif Pro\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Source Sans Pro\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Source Code Pro & \pkg{sourceserifpro}, \pkg{sourcesanspro}, \pkg{sourcecodepro} \\ + {} & Ubuntu & \tabelnoteref{enum:substitutesans} + {} & Ubuntu & Ubuntu Mono & \\ + \divider & \multicolumn{4}{l}{\textit{Two-font families with visually matching monospace fonts.}} \\ + {} & Inria & Inria Serif\tabelnoteref{enum:hasoldstylenums} + {} & Inria Sans\tabelnoteref{enum:hasoldstylenums} + {} & Fira Code & \pkg{InriaSerif}, \pkg{InriaSans} \\ + {} & Merriweather & Merriweather\tabelnoteref{enum:hasoldstylenums} + {} & Merriweather Sans\tabelnoteref{enum:hasoldstylenums} + {} & Recursive\tabelnoteref{enum:recursiveinstatiation} + {} & \pkg{merriweather} \\ + \divider & \multicolumn{4}{l}{\textit{Three matching font families.}} \\ + {} & & Minion Pro\tabelnoteref{enum:hasoldstylenums},\tabelnoteref{enum:hassmallcapitals} + {} & Myriad Pro\tabelnoteref{enum:hasoldstylenums} + {} & Courier Std & \pkg{typeface} \\ + \end{tabular} + + \begin{quote} + \begin{RaggedRight}\footnotesize + \textbf{Notes} + \begin{enumerate} + \item\label{enum:simlatexpackage}% + Similar \LaTeX~packages. Package~\pkg{typeface} does not + require any additional package, others need + \verb+\usepackage[T1]{fontenc}+ and sometimes extra arguments + to their \verb+\usepackage+ calls. See the documentation of + \ahref{https://ctan.org/pkg/typeface}{package~\pkg{typeface}} + and the \LaTeX~\ahref{https://tug.org/FontCatalogue/}{Font + Catalogue}. + + \item\label{enum:substitutesans}% + Use the sans-serif font in the \verb+serif+~class, too. + + \item\label{enum:hasoldstylenums}% + \textsc{OpenType}-compliant font family supporting oldstyle + numerals (\verb+onum+). + + \item\label{enum:hassmallcapitals}% + \textsc{OpenType}-compliant font family supporting small capitals + (\verb+smcp+). + + \item\label{enum:recursiveinstatiation}% + CASL~0, CRSV~0.5, MONO~1, slnt~0, wght~400 + \end{enumerate} + \end{RaggedRight} + \end{quote} \end{itemize} \section{Extra Features}\cutname{extras.html} From 4318774cef678fae2275a550f1b410e3decd90b0 Mon Sep 17 00:00:00 2001 From: Chris Spiel Date: Sun, 15 Nov 2020 14:01:09 +0100 Subject: [PATCH 7/7] Correct LaTeX errors that crept in by only checking the translation of the documentation with Hevea, which is much more forgiving. --- doc/text.tex | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/doc/text.tex b/doc/text.tex index b9bbda28..a30f0176 100644 --- a/doc/text.tex +++ b/doc/text.tex @@ -5954,12 +5954,13 @@ \subsection{Changing the Type Style}\label{type-style} Old style declarations are also recognised, they translate to text-level elements. However, no elements are cancelled when using -old style declaration. Thus, the source ``\verb+{\sl\sc slanted and -small caps}+'' yields ``slanted'' small~caps\ifhevea: ``{\sl\sc -slanted and small caps}''\fi. Users do not need not worry about this, -though it has an important practical consequence: to change the -default rendering of type styles, one should redefine old style -declaration in order to benefit from the cancellation mechanism. See +old style declaration. Thus, the source +``\verb+{\sl\sc slanted and small caps}+'' +yields ``slanted'' small~caps\ifhevea: ``{\sl\sc slanted and small + caps}''\fi. Users do not need not worry about this, though it has +an important practical consequence: to change the default rendering of +type styles, one should redefine old style declaration in order to +benefit from the cancellation mechanism. See section~\ref{customize-style} for a more thorough description. @@ -6010,9 +6011,7 @@ \subsection{\label{sec:controlling-font-selection-with-css}% \newstyle{.monospace.italic}{font-size: inherit} \end{verbatim} -\noindent or to fine-tune a family's \verb+font-weight+. -It is also the perfect place to activate (or deactivate) -OpenType~features exactly for one specific family +\noindent or to fine-tune a family's \verb+font-weight+ \begin{verbatim} \newstyle{.serif.bold}{font-weight: 600}% semi bold @@ -6196,13 +6195,13 @@ \subsubsection{Dedicated Smallcaps} with a definition that contains a \verb+font-family+ the operator character is lost and the original \LaTeX{} behavior is recovered. -\paragraph{\textsc{OpenType} Feature: \verb+smcp+.} +\paragraph{\textsc{OpenType} Feature: \texttt{smcp}.} Some \textsc{OpenType}~fonts harbor their own small caps. Not all browsers support the access of \textsc{OpenType}~features from CSS, but for those that do the following code activates the small caps in an sufficently enriched \textsc{OpenType}~font. See also the -\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide}{\textsc{OpenType}~fonts +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS\_Fonts/OpenType\_fonts\_guide}{\textsc{OpenType}~fonts guide} and help on \footahref{https://helpx.adobe.com/fonts/using/use-open-type-features.html}{using \textsc{OpenType}~features}. @@ -6322,14 +6321,14 @@ \subsubsection{Variable Typewriter Variant} \subsubsection{Dangerous Bend: Compounding\label{sec:dangerous-bend-compounding}} Font sizes can be specified in absolute or relative -\footahref{https://www.w3schools.com/cssref/css_units.asp}{CSS units}. +\footahref{https://www.w3schools.com/cssref/css\_units.asp}{CSS units}. However, absolute lengths preclude fonts from being scaled by \hevea's size-changing macros. Absolute lengths may even defy browsers' ``zoom'' functionalities. Relative lengths react properly to size-changing macros and zoom but suffer from compounding which means their effective values change depending on their scope; see also MDN Web Docs on -\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#Description}{font-size}. +\footahref{https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\#Description}{font-size}. The \verb+monospace+ example in section~\ref{sec:controlling-font-selection-with-css} uses the @@ -6395,7 +6394,7 @@ \subsubsection{Dangerous Bend: Set Override\label{sec:dangerous-bend-set-overrid our smallcaps class looses font-features~\verb+ss01+ and \verb+ss04+. Solutions of the problem are the use of -\footahref{https://www.w3schools.com/css/css3_variables.asp}{CSS~variables} +\footahref{https://www.w3schools.com/css/css3\_variables.asp}{CSS~variables} or \LaTeX~macros. Let us fix the last example with a macro. \begin{verbatim}