%% This is file `novel-TextMacros.sty', part of `novel' document class.
%% Copyright 2017-2023 Robert Allgeyer.
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, version 1.3c only.
%%   https://www.latex-project.org/lppl/lppl-1-3c/
%%
\ProvidesFile{novel-TextMacros.sty}%
[2023/03/25 v1.81b LaTeX file (text macros usable within document body)]
%%


%% This file contains various commands usable within the document body,
%%   for styling and otherwise manipulating text.
%% These are not commands used in Preamble for setup, although a few of them
%%   can be used in Preamble for setup, then again in body for change.



%% The following commands are BANNED.
%% ----------------------------------------------------------------------------
% The `novel' class disallows these commands, or neutralizes them by simply
%   repeating their arguments. In some cases, they request functionality
%   not implemented in `novel'. In other cases, the function is part of core,
%   but would interfere with the `novel' emphasis on constant line skip.
%   You may re-define the commands via your own code in Preamble (discouraged).
%
%% Standard LaTeX font sizes are ineffective. Use novel's own methods.
% If you write one of these size commands, it will silently be ignored:
%   \small, \footnotesize, \scriptsize, \tiny,
% \  large, \Large, \LARGE, \huge, \Huge, \HUGE, \textls
%
%% Internal subdivisions are ineffective.
% The command will merely echo its argument, without any functionality:
%   \part, \chapter, \section, \subsection, \subsubsection,
%   \paragraph, \subparagraph.
%
%% Some commands will generate an error, so that you know they cannot be used:
%   \maketitle, \makeindex, \tableofcontents, \listoftables, \listoffigures,
%
%% You can only use \includepdf (package: pdfpages) for pdf files pre-processed
%%   by novel-scripts.
%
%% You cannot use \includegraphics. Instead use novel's own image commands.
%
%% Commands normally provided in other classes, pertaining to floats, figures,
%    and tables, are not defined in `novel' class.
%    If you attempt to use them, an error will result.
%%


%% AND NOW TO THE GOOD STUFF
%% ----------------------------------------------------------------------------

%%
\gdef\straightquote{{\addfontfeature{Ligatures=ResetAll}'}}
\gdef\straightdblquote{{\addfontfeature{Ligatures=ResetAll}"}}
%%

%% Acronyms often look too big in regular capitals, but too small in
% small caps. Command \midcase{} provides an intermediate size:
\gdef\midcase#1{%
  \if@HasDecoFont%
    {\decofont{#1}}%
  \else%
    #1% simply echo the argument, if no decofont
  \fi%
}%
%%

%% Deco glyphs are decorative elements chosen from the decofont by code.
% They are documented in file NovelDeco-glyphs.pdf, in the `extras' folder.
\gdef\decoglyph#1{%
  \if@HasDecoFont%
    \IfBeginWith{#1}{n}{% normal weight symbol (same as regular)
      \StrBehind{#1}{n}[\@tempdecoglyph]{\@decoglyph\symbol{\@tempdecoglyph}}%
    }{}%
    \IfBeginWith{#1}{r}{% regular weight symbol
      \StrBehind{#1}{r}[\@tempdecoglyph]{\@decoglyph\symbol{\@tempdecoglyph}}%
    }{}%
    \IfBeginWith{#1}{l}{% light weight symbol
      \StrBehind{#1}{l}[\@tempdecoglyph]{\@decoglypha\symbol{\@tempdecoglyph}}%
    }{}%
    \IfBeginWith{#1}{e}{% extra light weight symbol
      \StrBehind{#1}{e}[\@tempdecoglyph]{\@decoglyphb\symbol{\@tempdecoglyph}}%
    }{}%
    \IfBeginWith{#1}{t}{% thin weight symbol
      \StrBehind{#1}{t}[\@tempdecoglyph]{\@decoglyphc\symbol{\@tempdecoglyph}}%
    }{}%
  \else%
    ~% non-breaking space, if no decofont
  \fi%
}%
%%

%% \memo{} does not print or save its argument.
% Useful when you wish to put a note to yourself in the *.tex document.
% Not the same as % comment, because anything after the braces will print.
\long\gdef\memo#1{}
%%

%% \stake is like \strut, but does not occupy uch vertical space.
\gdef\stake{\rule{0pt}{1pt}} % placeholder
%%

%% \smcp{} and \textsc{} small caps (Open Type) and \allsmcp{}:
\DeclareDocumentCommand \smcp { +m } {% lowercase to small caps
  {\addfontfeature{Letters=SmallCaps}#1}%
}
\ExplSyntaxOn
\DeclareDocumentCommand \allsmcp { +m } {% lowercase+uppercase to small caps
  \fontspec_if_feature:nTF {c2sc}{%
   {\addfontfeatures{Letters=UppercaseSmallCaps, Letters=SmallCaps}#1}%
  }{%
   {\addfontfeature{Letters=SmallCaps}\MakeLowercase{#1}}%
  }%
 }
\ExplSyntaxOff
\let\textsc\smcp\relax % unified
\let\oldscshape\scshape\relax % in case needed later
\let\scshape\smcp\relax % unified
\providecommand\FirstLineFont{\smcp} % package `magaz'
\renewcommand\FirstLineFont{\smcp}
%%

%% `novel' class normally allows only black or grayscale text on white paper.
%% In draft mode, option `shademargins` provides light gray margins,
%%   but still black text on white paper.
%% Just in case `xcolor' re-defines its internals, to prevent code bomb:
\ProvideDocumentCommand\@declaredcolor { m } {}
\ProvideDocumentCommand\@undeclaredcolor { o m } {}
% For convenience:
\definecolor[named]{gray1}{gray}{0.15} % ten percent gray, etc.
\definecolor[named]{gray2}{gray}{0.25}
\definecolor[named]{gray3}{gray}{0.33}
\definecolor[named]{gray4}{gray}{0.4}
\definecolor[named]{gray5}{gray}{0.5}
\definecolor[named]{gray6}{gray}{0.6}
\definecolor[named]{gray7}{gray}{0.68}
\definecolor[named]{gray8}{gray}{0.75}
\definecolor[named]{gray9}{gray}{0.87}
%%
% This code is slightly modified from package `etextools' by Florent Chervet.
% Its license: "This work may be distributed and/or modified under the 
%   conditions of the LaTeX Project Public License, either version 1.3 of this 
%   license or (at your option) any later version."
% My rationale for not simply loading the package: Other parts of the package
%   generate warning messages, but the warnings do not apply in `novel'
%   Also, I might wish to hack the code at some point.
\newcount\nov@ettl@fter
\newrobustcmd\nov@AfterGroup{%
  \@ifstar{\nov@ettl@AfterGroup\@firstofone}{\nov@ettl@AfterGroup\unexpanded}%
}
\newrobustcmd\nov@ettl@AfterGroup[2]{%
\csxdef{nov@ettl@fterGroup\number\numexpr\the\nov@ettl@fter+1}%
{\global\csundef{nov@ettl@fterGroup\number\numexpr\the\nov@ettl@fter+1}#1{#2}}%
\global\advance\nov@ettl@fter\@ne%
\expandafter\aftergroup\csname nov@ettl@fterGroup\the\nov@ettl@fter\endcsname%
}
%% End code from `etextools`.

%% \flexbox based on code by Werner at tex.stackexchange.com, CC-by-sa-3.0:
% Optional first argument is minimum width of box.
% Second argument is contents of box.
% Box width will be the greater of #1 or the width of #2.
\newcommand{\flexbox}[2][\parindent]{%
  \settowidth{\@tempLength}{#2}%
  \ifdimcomp{\@tempLength}{<}{#1}{\makebox[#1][l]{#2}}{#2}%
}
%%

%% \bigemdash inspired by code by RTBarnard at stackoverflow.com, CC-by-sa-3.0:
% Allows a rule of variable length to fill available space at its right.
% There must be a "right-hand limit" imposed by something, such as by enclosing
%   the rule in a \makebox of known width, or by an immediate \par.
%   Without this limit, rule will be missing (zero width) or excessively long,
%   or an error will result (referring to \leaders).
% Takes a single optional argument: Comma-separated raise, line thickness.
%   If no argument or empty, defaults to [1,1].
%   Without comma, argument defaults to [argument,1].
%   First number: Scales raise/down. 1 = raise of emdash in typical fonts.
%   Second number: Scales line thickness. 1 = emdash in typical fonts.
% NOTE: Built-in TeX PDF viewer might show the line at slightly incorrect
%   width and height. Best seen in a "real" PDF viewer.
\DeclareDocumentCommand \bigemdash { O{1,1} }
 {%
  \ifthenelse{\equal{#1}{}\OR\equal{#1}{\space}}{%
    \def\@myargsi{1,1}}{\def\@myargsi{#1}%
  }%
  \StrDel{\@myargsi}{\space}[\@myargs]%
  \StrCut{\@myargs}{,}{\@myraisei}{\@mythicki}%
  \ifthenelse{\equal{\@myraisei}{}\OR\equal{\@myraisei}{\space}}{%
    \def\@myraise{1}}{\def\@myraise{\@myraisei}%
  }%
  \ifthenelse{\equal{\@mythicki}{}\OR\equal{\@mythicki}{\space}}{%
    \def\@mythick{1}}{\def\@mythick{\@mythicki}%
  }%
  \FPmul{\@myraise}{\@myraise}{0.56}% ex, typical font emdash raise
  \FPmul{\@mythick}{\@mythick}{0.049}% em, typical font emdash thickness
  {\leaders\hbox{\rule[\@myraise ex]{1pt}{\@mythick em}}\hfill\stake}%
 }
%%

%% \charscale[scale,x,y]{text} and starred version
% This is an "in-line" means of adjusting font size
%   and position, without changing the baselineskip.
% If the optional argument is unused or empty, then the text is not scaled
%   or moved, but equivalent to \stake\smash{text}.
% Up to 3 arguments may be used in the single optional argument.
% They are separated by commas. Spaces ignored.
% First argument is scale. Number>=0.5. Default 1. Relative to what the size
%   would otherwise be. May multiply with an already-scaled font.
% Second and third arguments are x-offset and y-offset, respectively.
% Offsets are lengths, best measured in em or \nfs for horizontal,
%   and em or \nfs or \nbs for vertical. Default 0pt. Can abbreviate as 0.
% Posiive offsets are horizontal right, vertical up.
% Text is "smashed" and may go anywhere, even overlying other text or image.
% The unstarred command occupies width equal to the scaled text,
%   thus leaving a "hole" where the text would have been.
% The starred command occupies zero width, thus no hole. Consecutive starred
%   commands, without intervening space, displace from same origin.
% The text must be on a single line, without break or wrap.
% Do not use \\ or \par inside \charscale. Sometimes you need \par after it.
% If the text is in a font other than usual, place the font command
%   outside \charscale, not inside.
\DeclareDocumentCommand \charscale { s O{1} m } {%
  % Allows empty or blank to be used, and still provide default values:
  \ifthenelse{\equal{#2}{}\OR\equal{#2}{\space}}{%
    \def\@myargs{1}%
  }{%
    \def\@myargs{#2}%
  }%
  \StrDel{\@myargs}{\space}[\@myargsns]% needs {\space} not { }
  \StrCut{\@myargsns}{,}{\@myscalet}{\@mycoord}%
  \ifthenelse{\equal{\@myscalet}{}}{%
    \def\@myscale{1}%
  }{%
    \def\@myscale{\@myscalet}%
  }%
  \FPmax{\@myscale}{\@myscale}{0.5}% not permitted below this scale
  \StrCut{\@mycoord}{,}{\@myxt}{\@myyt}%
  \ifthenelse{\equal{\@myxt}{}\OR\equal{\@myxt}{0}}{%
    \def\@myx{0pt}%
  }{%
    \def\@myx{\@myxt}%
  }%
  \ifthenelse{\equal{\@myyt}{}\OR\equal{\@myyt}{0}}{%
    \def\@myy{0pt}%
  }{%
    \def\@myy{\@myyt}%
  }%
  \IfBooleanTF{#1}%
  {% starred
    \ifvmode\else\unskip\fi%
    \stake\makebox[0pt][l]{%
      \smash{\hspace{\@myx}\raisebox{\@myy}{\scalebox{\@myscale}{#3}}}%
    }%
  }{% unstarred
    \stake\makebox[0pt][l]{%
      \smash{\hspace{\@myx}\raisebox{\@myy}{\scalebox{\@myscale}{#3}}}%
    }%
    \smash{\phantom{\scalebox{\@myscale}{#3}}}%
  }%
 }% end \charscale
%%


% Note that \savepos is a luatex primitive, not a macro from gridset package.
% Length \TotalYpos is measured from the very bottom of the page,
% upward to the baseline of non-existent "line zero" in main text.
% The first printed main text line is line 1.
% Neither header nor footer influence this.
\newlength\TotalYpos
\gdef\@GetInitialYpos{% called by `novel.cls' \AtEndPreamble
  \begingroup%
    \savepos%
    \protected@write\@auxout{}{%
      \protect\@TotalYpos{\noexpand\number\lastypos}%
    }%
  \endgroup%
}
%
\gdef\@TotalYpos#1{\gsetlength\TotalYpos{#1sp}}
%


%%
\newlength\PosTolerance % How close is close enough?
\setlength\PosTolerance{0.0625pt} % should be good enough
%%


%% Environment parascale. Scales one or more paragraphs.
% Warns when (as is often the case) the line after \end{parascale}
%   will be off grid. Then, add some \vspace just before \end{parascale}.
\newenvironment{parascale}[1][1]{% optional argument is scale, default 1.
  \FPmax{\@mytempDetailsN}{#1}{0.5}% must be at least half normal.
  \FPmul{\@mytempDetailsFontN}{\@mytempDetailsN}{\strip@pt\@SetFontSize}%
  \FPround{\@mytempDetailsFontN}{\@mytempDetailsFontN}{2}%
  \FPmul{\@mytempDetailsSkipN}{\@mytempDetailsN}{\strip@pt\baselineskip}%
  \FPround{\@mytempDetailsSkipN}{\@mytempDetailsSkipN}{2}%
  \FPsub{\@mytempSkipN}{\strip@pt\baselineskip}{\@mytempDetailsSkipN}%
  \vspace{\@mytempSkipN pt}% puts first scaled line at normal baseline
  \begingroup%
  \fontsize{\@mytempDetailsFontN pt}{\@mytempDetailsSkipN pt}\selectfont%
  \ignorespaces%
}{%
  \par\endgroup%
  \vspace{-\nbs}%
  \leavevmode\getParapos\par% detects if following line will be off-grid
  \vspace{0.002\nbs plus 0pt minus 0.2pt}% math fudge factor, in case of roundoff
}
%
\gdef\getParapos{%
  \begingroup%
    \savepos%
    \protected@write\@auxout{}{%
      \protect\@getParapos{\noexpand\number\lastypos}{\thepage}%
    }%
  \endgroup%
}
%
\newlength\CurrentParapos
\gdef\@getParapos#1#2{} % initialized to nothing, when reading aux at beginning
\gdef\@RedefineParapos{ % called by `novel.cls' \AtBeginDocument
  \gdef\@getParapos##1##2{% numerical position sp, page
    \gsetlength\CurrentParapos{##1sp}% measured up from very bottom of page.
    % Now change it, to measure downward from "line zero" of main text:
    \gsetlength\CurrentParapos{\TotalYpos-\CurrentParapos}% calc package.
    \FPdiv{\ParaHowdown}{\strip@pt\CurrentParapos}{\strip@pt\nbs}% package fp
    \FPtrunc{\ParaLinesdown}{\ParaHowdown}{0}% integer number of lines down
    \FPsub{\ParaResidual}{\ParaHowdown}{\ParaLinesdown}% portion of line
    \FPdiv{\@PosTolerance}{\strip@pt\PosTolerance}{\strip@pt\nbs}%
    \gdef\ParaComplain{yes}%
    \FPifgt{\@PosTolerance}{\ParaResidual}%
      \gdef\ParaComplain{no}% within tolerance
    \fi%
    \FPsub{\ParaDeficit}{\strip@pt\nbs}{\ParaResidual}%
    \FPifgt{\@PosTolerance}{\ParaDeficit}%
      \gdef\ParaComplain{no}%
    \fi%
    \FPsub{\ParaResidual}{1}{\ParaResidual}%
    \FPifgt{\@PosTolerance}{\ParaResidual}%
      \gdef\ParaComplain{no}% within tolerance
    \fi%
    \FPifgt{\@PosTolerance}{\ParaDeficit}%
      \gdef\ParaComplain{no}%
    \fi%
    \FPround{\ParaResidual}{\ParaResidual}{3}%
    \FPclip{\ParaResidual}{\ParaResidual}%
    \ifthenelse{\equal{\ParaComplain}{yes}}{%
      \ClassWarning{novel}{Line after parascale may be off-grid, page ##2. ^^J%
       Appears to be \ParaResidual\string\nbs\space higher than expected.}%
    }{}%
  }
} % end @RedefineParapos
%%


%% Environment toc (alternative table of contents):
% optional argument: additional vspace (\nbs) after each \tocitem entry.
% required: LR margin increase, to narrow the table (0pt = full textwidth).
\newlength\@tocnumwid
\newlength\@tocskip
\newenvironment{toc}[2][0]{%
  \begin{adjustwidth}{#2}{#2}%
  \begingroup%
  \setlength\parindent{0pt}% local
  \setlength\@tocnumwid{\widthof{00.~}}% local
  \setlength\@tocskip{#1\nbs}% local
}{%
  \endgroup%
  \end{adjustwidth}\par%
}%
% \tocitem[number]{description}{page} provides a one-line table entry in toc.
% optional number might be chapter number. Can use ~ to offset.
% unstarred: distance between description and page is not decorated.
% starred (better): distance between description and page has dotted line.
\newcommand\tocitem{\@ifstar\@tocitemst\@tocitemns}
\newcommand\@tocitemst[3][]{%
  \ifthenelse{\equal{#1}{}}{}{%
    \ifthenelse{\equal{#1}{~}}{%
      \makebox[\@tocnumwid][l]{~}%
    }{%
      \makebox[\@tocnumwid][l]{#1.}%
    }%
  }%
  #2\,%
  \leaders\hbox to 0.3em{\hfil.\hfil}\hfill% Thanks to user daniel-j via GitHub.
  \,#3\par\vspace{\@tocskip}%
}%
%
\newcommand\@tocitemns[3][]{%
  \ifthenelse{\equal{#1}{}}{}{%
    \ifthenelse{\equal{#1}{~}}{%
      \makebox[\@tocnumwid][l]{~}%
    }{%
      \makebox[\@tocnumwid][l]{#1.}%
    }%
  }%
  #2%
  \hfill%
  #3\par\vspace{\@tocskip}%
}%
%% end toc and \tocitem.

%% legalese environment. Certain info, such as Copyright page, customarily is
% neither justified nor hyphenated. Can be used wherever desired, of course.
\newenvironment{legalese}
{\raggedright\hyphenpenalty=10000\exhyphenpenalty=10000}
{}
%
\gdef\hangleft#1{% places content to left of usual position.
  \setlength\@tempLength{\widthof{#1}}% local
  \stake\hspace{-\@tempLength}#1%
}
%%

%% \showlength[decimal places]{length}{units}
% Returns length as a string with the units, but does not change the length.
% length is any existing length
% units may be pt, bp, mm, cm, in
% decimal places for rounding (0=integer, 1=one decimal point, etc.)
% Example: \showlength[3]{17bp}{in}  returns  0.236in
\newcommand\showlength[3][]{%
  \setlength\@tempLength{#2}%
  \def\@tempLengthN{\strip@pt\@tempLength}%
  \ifthenelse{\equal{#3}{bp}}{%
    \FPmul{\@tempLengthN}{\@tempLengthN}{0.99626401}%
  }{}%
  \ifthenelse{\equal{#3}{mm}}{%
    \FPmul{\@tempLengthN}{\@tempLengthN}{0.351459804}%
  }{}%
  \ifthenelse{\equal{#3}{cm}}{%
    \FPmul{\@tempLengthN}{\@tempLengthN}{0.0351459804}%
  }{}%
  \ifthenelse{\equal{#3}{in}}{%
    \FPmul{\@tempLengthN}{\@tempLengthN}{0.013837}%
  }{}%
  \ifthenelse{\equal{#1}{}}{}{\FPround{\@tempLengthN}{\@tempLengthN}{#1}}%
  \@tempLengthN{#3}%
} %
%% end \showlength

%% \lnum for lining numbers.
\gdef\lnum#1{{\addfontfeature{Numbers=Lining}#1}}
%%


%% For developer use: prints a number of yada yada lines.
% Starred version adds extra smashed lines above and below.
\newcount\yadacurrentcount
\newcount\yadaendcount
\DeclareDocumentCommand\novelyadayada { s O{1} }{%
  \yadacurrentcount=1%
  \yadaendcount=#2%
  \ifthenelse{\equal{#2}{0}}{}{%
    \IfBooleanTF{#1}{%
      \def\@yadadblup{\charscale*[1,\normalparindent,2\nbs]{Dbl Raised yada}}%
      \def\@yadaup{\charscale*[1,\normalparindent,\nbs]{Raised yada}}%
      \def\@yadadown{%
        \ifnum\yadacurrentcount=\yadaendcount%
          \charscale*[1,\normalparindent,-\nbs]{Dropped yada}%
        \fi%
      }%
      \def\@yadadbldown{%
        \ifnum\yadacurrentcount=\yadaendcount%
          \charscale*[1,\normalparindent,-2\nbs]{Dropped yada}%
        \fi%
      }%
    }{%
      \def\@yadadblup{}%
      \def\@yadaup{}%
      \def\@yadadown{}%
      \def\@yadadbldown{}%
    }%
    \loop%
      \noindent\@yadadblup\@yadaup\@yadadown\@yadadbldown%
      \makebox[\normalparindent][l]{\the\yadacurrentcount.}%
      Lotta yada.\par
      \def\@yadaup{}%
      \def\@yadadblup{}%
      \advance\yadacurrentcount 1%
    \ifnum\yadacurrentcount<\yadaendcount%
    \repeat%
  }%
}
%%


%% Two columns, cannot cross page break.
%% \sidebyside[a,b,c,d]{column 1 content}{column 2 content} % a,b,c,d lengths
% a = left margin to left edge of left column (left indent)
% b = left margin to right edge of left column ( = a + column width)
% c = left margin to left edge of right column ( = a + b + gap)
% d = left margin to right edge of right column ( = textwidth - right indent)
% Thus 0pt <= a < b < c < d <= \textwidth.
% Default: no indents, equal column widths, separated by \normalparindent.
\DeclareDocumentCommand\sidebyside { O{} +m +m } {% no ExplSyntax, no more %:
  \StrDel{#1}{\space}[\@argsns]
  \StrCut{\@argsns}{,}{\@argsone}{\@argsothera}
  \StrCut{\@argsothera}{,}{\@argstwo}{\@argsotherb}
  \StrCut{\@argsotherb}{,}{\@argsthree}{\@argsfour}
  \ifthenelse{\equal{\@argsone}{}}{%
    \def\@sbsll{0pt}
  }{%
    \def\@sbsll{\@argsone}
  }%
  \setlength\@tempLength{0.5\textwidth-0.5\normalparindent}
  \ifthenelse{\equal{\@argstwo}{}}{%
    \edef\@sbslr{\the\@tempLength}
  }{%
    \edef\@sbslr{\@argstwo}
  }%
  \setlength\@tempLength{0.5\textwidth+0.5\normalparindent}
  \ifthenelse{\equal{\@argsthree}{}}{%
    \edef\@sbsrl{\the\@tempLength}
  }{%
    \edef\@sbsrl{\@argsthree}
  }%
  \ifthenelse{\equal{\@argsfour}{}}{%
    \edef\@sbsrr{\the\textwidth}
  }{%
    \edef\@sbsrr{\@argsfour}
  }%
  \null\vspace{-\baselineskip}
  \begin{adjustwidth}{\@sbsll}{\dimexpr\textwidth-\@sbsrr}
  \noindent\begin{minipage}[t]{\dimexpr\@sbslr-\@sbsll}
  \strut #2\strut
  \end{minipage}\hspace{\normalparindent}\begin{minipage}[t]{\dimexpr\@sbsrr-\@sbsrl}
  \strut #3\strut
  \end{minipage}
  \end{adjustwidth}
  \null\vspace{-\baselineskip}
} %
%% end \sidebyside



%% Some things must wait until after layout calculations:
\gdef\@ActivateTextLengths{% called by `novel.cls' \AtEndPreamble
  % Store some normal values (main font) for global use in document body:
  \newlength\nfs % abbreviation for normal font point size
    \gsetlength\nfs{\@SetFontSize}
  \newlength\nbs % abbreviation for normal baselineskip
    \gsetlength\nbs{\baselineskip}
  \gsetlength\parindent{1.5em} % may be locally changed
  \newlength\normalparindent
    \gsetlength\normalparindent{\parindent}
  \newlength\normalxheight % height of lowercase x
    \gsetlength\normalxheight{\heightof{x}}
  \newlength\normalXheight % height of uppercase X
    \gsetlength\normalXheight{\heightof{X}}
  \newlength\normalscxheight % height of small cap x
    \gsetlength\normalscxheight{\heightof{\textsc{x}}}
  \newlength\normalAringheight % height of Å (usually tallest in Latin-1)
    \gsetlength\normalAringheight{\heightof{Å}}
  \newlength\normaldescender % depth of lowercase gjpqy
    \gsetlength\normaldescender{\depthof{gjpqy}}
}% end \@ActivateTextLengths
%%


%% More things that must wait:
\gdef\@ActivateTextMacros{% called by `novel.cls' \AtBeginDocument
  % \forceindent and \backindent perform or remove indent, using \hspace{}.
  % Rationale: Sometimes \indent and \noindent neutralized by another command.
  \gdef\forceindent{\ifvmode\else\unskip\fi\stake\hspace{\normalparindent}}
  \gdef\backindent{\ifvmode\else\unskip\fi\hspace{-\normalparindent}}
}% end \@ActivateTextMacros
%%


%%
\endinput
%%
%% End of file `novel-TextMacros.sty'.


