summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/novel/tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-02-16 03:01:36 +0000
committerNorbert Preining <norbert@preining.info>2023-02-16 03:01:36 +0000
commit024d47cb1c4e5ba541f3865b69168bef20f2bfce (patch)
tree4e55e91ce72e278a079000c9871135034111f910 /macros/luatex/latex/novel/tex
parenta7d99429152acee049db679dc26a92e01faf4992 (diff)
CTAN sync 202302160301
Diffstat (limited to 'macros/luatex/latex/novel/tex')
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-CGATSTR001.clo28
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-CalculateLayout.sty312
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-ChapterScene.sty402
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-DropCap.sty223
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-FOGRA39.clo27
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-FileData.sty207
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-Fonts.sty426
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-Footnotes.sty431
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-HeadFootStyles.sty498
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-Images.sty565
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-JC200103.clo27
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-LayoutSettings.sty419
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-PostLayout.sty263
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-Sandbox.sty145
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-TextMacros.sty586
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-microtype.cfg252
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-pdfx.sty517
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel-xmppacket.sty111
-rw-r--r--macros/luatex/latex/novel/tex/lualatex/novel/novel.cls643
19 files changed, 6082 insertions, 0 deletions
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-CGATSTR001.clo b/macros/luatex/latex/novel/tex/lualatex/novel/novel-CGATSTR001.clo
new file mode 100644
index 0000000000..a304ed3e63
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-CGATSTR001.clo
@@ -0,0 +1,28 @@
+%%
+%% This is file `novel-CGATSTR001.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+%%
+\ProvidesFile{novel-CGATSTR001.clo}%
+[2023/02/08 any version. (novel Output Intent CGATS TR 001)]
+%%
+
+% Typically used in the USA.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+% This identifier has spaces, even though file name has no spaces.
+\gdef\@OIidentifier{CGATS TR 001} % also called "reference name"
+\gdef\@OIcondition{SWOP (Publication) printing in USA (Printing process definition: ANSI CGATS.6).}
+\gdef\@OIinfo{U.S. Web Coated (SWOP) v2}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{USWebCoatedSWOP.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-CGATSTR001.clo'
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-CalculateLayout.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-CalculateLayout.sty
new file mode 100644
index 0000000000..40308f6590
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-CalculateLayout.sty
@@ -0,0 +1,312 @@
+%%
+%% This is file `novel-CalculateLayout.sty', part of `novel' document class.
+%% Copyright 2017-2023 Robert Allgeyer.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-CalculateLayout.sty}%
+[2023/02/08 v1.80 LaTeX file (layout calculations)]
+%%
+
+%%
+%% This file is loaded \AtEndPreamble, which precedes \AtBeginDocument.
+%%
+
+
+
+%% PROVIDE DEFAULT TRIM SIZE, MARGINS, AND NORMAL EM SIZE, IF NOT SET BY USER
+%% ----------------------------------------------------------------------------
+% Default Trim Size is 5.5in W x 8.5in H, unless \SetTrimSize used.
+% This size is typical of American P.O.D. softcover fiction:
+\if@SetTrimSize\else
+ \gsetlength\@TrimWidth{5.5in}
+ \gsetlength\@TrimHeight{8.5in}
+\fi
+% Default margins based on Trim Height, unless \SetMargins used:
+\if@SetMargins\else
+ \ifdimcomp{\@TrimHeight}{<}{8.99in}{ % small sizes:
+ \gsetlength\@TopMargin{0.5in}
+ \gsetlength\@OuterMargin{0.5in}
+ \gsetlength\@BottomMargin{0.5in}
+ \gsetlength\@InnerMargin{0.75in}
+ }{ % medium sizes:
+ \ifdimcomp{\@TrimHeight}{<}{9.99in}{ %
+ \gsetlength\@TopMargin{0.75in}
+ \gsetlength\@OuterMargin{0.75in}
+ \gsetlength\@BottomMargin{0.75in}
+ \gsetlength\@InnerMargin{1in}
+ }{ % large sizes:
+ \gsetlength\@TopMargin{1in}
+ \gsetlength\@OuterMargin{1in}
+ \gsetlength\@BottomMargin{1in}
+ \gsetlength\@InnerMargin{1.25in}
+ } %
+ } %
+\fi
+% Default normal em size is based on Trim Width:
+\if@FontSizeSet\else
+ \ifdimcomp{\@TrimWidth}{<}{5.49in}{
+ \gsetlength\@SetFontSize{11pt} % smaller books
+ }{
+ \ifdimcomp{\@TrimWidth}{<}{6.24in}{
+ \gsetlength\@SetFontSize{11.4pt} % medium books
+ }{
+ \gsetlength\@SetFontSize{12pt} % larger books
+ } %
+ } %
+\fi
+%% end set default trim, margins, normal em size.
+
+
+%% THEORY OF PAGE LAYOUT
+%% ----------------------------------------------------------------------------
+% The "available width" is the trim width minus the outer and inner margins:
+\newlength\@AvailableWidth
+\gsetlength\@AvailableWidth{\@TrimWidth-\@OuterMargin-\@InnerMargin}
+% The "occupied width" of the text block is the TeX dimension \textwidth.
+% Your originally set layout can always fill the available width.
+\gsetlength\textwidth{\@AvailableWidth}
+% The "available height" is the trim height minus the top and bottom margins:
+\newlength\@AvailableHeight
+\gsetlength\@AvailableHeight{\@TrimHeight-\@TopMargin-\@BottomMargin}
+% The "occupied height" includes header, textblock, footer, and allowances
+% for risers/diacriticals at top, descenders at bottom. It must fit within
+% the available height. This is the tricky part, so pay attention:
+% In `novel' class, the topmost line of text (main block or header)
+% is positioned with its baseline at 1 normal em below available top.
+% That provides good clearance for uppercase letters with diacritical marks.
+% The lowermost line of text (main block or footer) is positioned with its
+% baseline at 0.3 normal em above available bottom. This provides
+% good clearance for descenders.
+% So, if your text does not have uppercase diacriticals, or if you use
+% a footer with lining numbers (no descenders), then the upper/lower margins
+% will appear to be a little larger than you set them.
+% The headjump includes the line itself, plus any added gap to the main text.
+% An unused jump is re-set to 0:
+\if@HasHeader\else\gdef\@HeadJump{0}\fi
+%%
+% TeX assumes that your layout has a footer, even if you do not want one.
+% Novel handles this by setting the baseline of the mandatory footer at
+% 1 normal baselineskip below the last line of main text. Then, one line is
+% subtracted from the occupied line count. That places the empty, unused
+% virtual footer in the lower margin, where it does not matter. When you
+% do have a footer, the necessary line space is added, and the content
+% is positioned from the virtual footer using \smash and \raisebox.
+% Yes, it is complicated, but it handles more layout possibilities.
+% The \@FootJumpFix is one less than \@FootJump, or -1 when no footer:
+\if@HasFooter
+ \FPsub\@FootJumpFix{\@FootJump}{1}
+\else
+ \gdef\@FootJumpFix{-1}
+\fi
+% Putting it all together, the "occupied height" is:
+% 1.3\@SetFontSize + (\@HeadJump+\@LinesPerPage+\@FootJumpFix)\baselineskip
+%
+%% end theory of page layout.
+
+
+%% SET DEFAULT LINES PER PAGE, IF NOT SET BY USER
+%% ----------------------------------------------------------------------------
+% Lines per page refers only to the main text block, not header/footer:
+\if@LinesPerPage\else
+ % Estimate \baselineskip as 1.3\@SetFontSize, which is a comfortable value.
+ % Calculate resulting \@LinesPerPage, then proceed as if set.
+ % Actual \baselineskip will be re-calculated later.
+ \edef\@tempLPP{%
+ \fpeval{% package xfp
+ (\@AvailableHeight - 0.3\@SetFontSize) % adjusts for final descenders
+ / (1.3*\@SetFontSize) % denominator, with desired skip/em ratio
+ -\@HeadJump -\@FootJumpFix % adjustments
+ }%
+ } %
+ \FPtrunc{\@LinesPerPage}{\@tempLPP}{0} % final, integer floor
+\fi
+% Error if too few lines per page, whether set or default:
+\FPiflt{\@LinesPerPage}{2}
+ \ClassError{novel}{Calculated LinesPerPage less than 2}%
+ {Too few lines. Either font size too big, or text height too small.}%
+\fi
+%% end set default lines per page.
+
+
+%% CALCULATE BASELINESKIP
+%% ----------------------------------------------------------------------------
+% In `novel' class, the user does not directly set line-to-line spacing,
+% known as \baselineskip. Instead, \baselineskip is calculated from other
+% settings, so that "occupied height" fills "available height."
+% See the above theory of layout, for the equations. Solve for \baselineskip =
+% (\@AvailableHeight-1.3\@SetFontSize) divided by
+% (\@HeadJump+\@LinesPerPage+\@FootJumpFix)
+%
+\xdef\@AdjLPP{\fpeval{\@HeadJump+\@LinesPerPage+\@FootJumpFix}} % used often
+\edef\@tempBLS{%
+ \fpeval{(\@AvailableHeight-1.3\@SetFontSize) / \@AdjLPP}%
+} %
+\FPtrunc\@tempBLS{\@tempBLS}{2} % round down to 2 decimalplaces
+\gsetlength\baselineskip{\@tempBLS pt}
+%
+% Error if \baselineSkip is too tight, in relation to normal em size:
+\ifdimcomp{\baselineskip}{<}{1.2\@SetFontSize}{%
+ \ClassError{novel}{Calculated baselineskip is too small}%
+ {Default baselineskip is calculated from normal em size, ^^J%
+ available text height, and lines per page. Result is too small. ^^J%
+ Change something, then try again.}%
+}{}%
+%% end calculate baselineskip.
+
+
+%% FINISH LAYOUT (but post-layout deals with special class options)
+%% ----------------------------------------------------------------------------
+% Caution if font size is small:
+\ifdimcomp{\@SetFontSize}{<}{10pt}{ %
+ \typeout{^^JClass `novel' Alert: Normal font at less than 10pt. ^^J%
+ Whether or not this is too small, depends on circumstances. ^^J%
+ Beware if you use footnotes, which are smaller. ^^J%
+ }
+}{} %
+\ifdimcomp{\@SetFontSize}{<}{8.03pt}{ % 8 PostScript points (TeX bp)
+ \ClassWarning{novel}{^^JNormal font at less than 8 points. ^^J%
+ This is usually undesirable. May be rejected by some print services. ^^J%
+ }
+}{} %
+% Default Media Size is same as Trim Size, unless \SetMediaSize used:
+\if@MediaSize\else
+ \gsetlength\paperwidth{\@TrimWidth}
+ \gsetlength\paperheight{\@TrimHeight}
+\fi
+% Sanity check for cover art, which needs bleed:
+\if@coverart
+ \setlength\@tempLength{\paperwidth-\@TrimWidth}
+ \ifthenelse{\dimtest{\@tempLength}{<}{6mm}}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Insufficient bleed width ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. But your dimensions do not provide this.^^J%
+ Perhaps you need to increase the Media Width ?^^J}
+ }{}
+ \ifthenelse{\dimtest{\@tempLength}{>}{0.5in}}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Too much bleed width ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. Sometimes as much as 0.25in (6mm) each.^^J%
+ But your dimensions provide more than this.
+ Perhaps you need to decrease the Media Width ?^^J}
+ }{}
+ \setlength\@tempLength{\paperheight-\@TrimHeight}
+ \ifthenelse{\dimtest{\@tempLength}{<}{5.83mm}}{% allows for pixel rounding
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Insufficient bleed height ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. But your dimensions do not provide this.^^J%
+ Perhaps you need to increase the MediaSize ?^^J}
+ }{}
+ \ifthenelse{\dimtest{\@tempLength}{>}{0.507in}}{% allows for pixel rounding
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Too much bleed height ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. Sometimes as much as 0.25in (6mm) each.^^J%
+ But your dimensions provide more than this.
+ Perhaps you need to decrease the MediaSize ?^^J}
+ }{}
+\fi
+% \textheight, normal font size, etc:
+\gsetlength\textheight{\@LinesPerPage\baselineskip}
+\renewcommand\normalsize{%
+ \@setfontsize\normalsize{\strip@pt\@SetFontSize}{\strip@pt\baselineskip}%
+}
+\normalsize % from this point, the "real" normal font size is effective
+%
+
+%
+\if@HasHeader
+ % \headheight is mis-named. Text "height" is supposed to be measured upward
+ % from the baseline. But \headheight is measured from 0.3em below
+ % the baseline, to allow for descenders. Thus, to provide actual "height"
+ % of 1em, \headheight must be set to 1.3em:
+ \gsetlength\headheight{1.3\@SetFontSize}
+ % \headsep is a confusing term. It is the separation between the nominal
+ % 0.3em descenders of header text, and one baseline above the baseline
+ % of the top line of main text. Got that? Let me do the thinking for you:
+ \gsetlength\headsep{\@HeadJump\baselineskip-\baselineskip-0.3\@SetFontSize}
+\else % no header, no problem:
+ \gsetlength\headheight{0pt}
+ \gsetlength\headsep{0pt}
+\fi
+% \oddsidemargin is at the left (inner, spine edge) of recto pages.
+% Measured 1in (72.27pt) inside MediaBox, to the textblock. May be negative.
+
+ \gsetlength\oddsidemargin{%
+ \@InnerMargin+0.5\paperwidth-0.5\@TrimWidth-72.27pt%
+ }
+
+%
+% \evensidemargin is at the left (outer edge) of verso pages.
+
+ \gsetlength\evensidemargin{%
+ \@OuterMargin+0.5\paperwidth-0.5\@TrimWidth-72.27pt%
+ }
+
+%
+\if@closecrop
+ \gsetlength\oddsidemargin{-0.9in}
+ \gsetlength\evensidemargin{-0.9in}
+\fi
+%
+% \topmargin is measured from 1in (72.27pt) below the top of the MediaBox,
+% to the top of whatever comes first (header or textblock). May be negative.
+% For consistency, the topmost baseline (header or main text) will be
+% positioned at 1em below the margin.
+
+ \gsetlength\topmargin{\@TopMargin+0.5\paperheight-0.5\@TrimHeight-72.27pt}
+ \if@HasHeader\else
+ \gsetlength\topmargin{\topmargin-\baselineskip+\@SetFontSize}
+ \fi
+
+% novel.cls sets a tentative em size (probably 10pt) so that packages requiring
+% an integer point size of 10, 11, or 12 will load without complaint.
+% Then, the real point size is established here, when it is too late for
+% such packages to complain. Sneaky, eh?
+% However, TeX places a strut in the header, rising 0.7x tentative size above
+% the header baseline. If the real size is too small, then the strut is
+% too large, which displaces the header text downward, simultaneously
+% shrinking the headsep and possibly affecting the textblock position.
+% This unlikely problem cannot be fixed by adjusting the headheight, but it
+% can be fixed by adjusting the topmargin and headsep to compensate:
+\ifdimcomp{\@SetFontSize}{<}{\@TentativeEmN pt}{ %
+ \setlength\@tempLength{\@TentativeEmN pt}
+ \gsetlength\topmargin{\topmargin-0.7\@tempLength+0.7\@SetFontSize}
+ \gsetlength\headsep{\headsep+0.7\@tempLength-0.7\@SetFontSize}
+}{} %
+%%
+% It seems that, unless specified by user, TeX may place the top text baseline
+% in a vertical position that depends on the height of text in that line.
+% That height may vary, depending on ascenders or diacriticals there.
+% In order to fix the position, \topskip gets a non-flexible setting.
+% The best value is normal baselineskip, partly because it looks right,
+% and also to avoid underfull vboxes on nearly every page.
+\gsetlength\topskip{\baselineskip} % absorber
+% In `novel' class, footers are done in an unusual manner, as explained above.
+% To fix the position of the virtual footer baseline:
+\gsetlength\footskip{\baselineskip}
+%% Sanity check: Trim Size must be contained within Media Size.
+\ifthenelse{%
+ \dimtest{\@TrimWidth}{>}{\paperwidth} %
+ \OR \dimtest{\@TrimHeight}{>}{\paperheight}%
+}{%
+ \ClassError{novel}{Media Size too small for TrimSize}%
+ {You wrote \string\SetMediaSize\space with length(s) too small ^^J%
+ for the default Trim Size or your values in \string\SetTrimSize.}%
+}{} %
+% end sanity check
+%% end finish layout.
+
+
+%%
+\endinput
+%%
+%% End of file `novel-CalculateLayout.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-ChapterScene.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-ChapterScene.sty
new file mode 100644
index 0000000000..89d77c718f
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-ChapterScene.sty
@@ -0,0 +1,402 @@
+%%
+%% This is file `novel-ChapterScene.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-ChapterScene.sty}%
+[2023/02/08 v1.80 LaTeX file (chapter and scene macros)]
+%%
+
+
+% Each new chapter generally has its own header/footer style. This allows a
+% default setting when chapters begin with ChapterStart environment:
+\gdef\SetChapterStartStyle#1{%
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{fancy}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{empty}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{plain} %
+ \OR \equal{#1}{fancyplain} \OR \equal{#1}{footer}}{%
+ \@tempTFtrue%
+ }{}%
+ \ifthenelse{\equal{#1}{forcenumber}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{dropfolioinside} %
+ \OR \equal{#1}{dropfolio} \OR \equal{#1}{dropfoliolater}}{%
+ \@tempTFtrue%
+ }{}%
+ \ifthenelse{\equal{#1}{dropfoliobeneath}}{\@tempTFtrue}{}%
+ \if@tempTF%
+ \gdef\@setchapterstart{#1}%
+ \else%
+ \ClassError{novel}{Invalid choice for \string\SetChapterStartStyle}%
+ {Choose: fancy, empty, plain, footer, forcenumber, %
+ dropfolioinside, dropfoliobeneath.}%
+ \fi%
+}
+\let\SetChapterStart\SetChapterStartStyle\relax % deprecated from v1.40.3.
+\SetChapterStartStyle{footer} % default
+\gdef\SetChapterStartHeight#1{%
+ \FPifint{#1}\else%
+ \ClassError{novel}{\string\SetChapterStartHeight\space integer >= 4}%
+ {Height of ChapterStart must be integer, greater than or equal to 4.}%
+ \fi%
+ \FPiflt{#1}{4}%
+ \ClassError{novel}{\string\SetChapterStartHeight\space integer >= 4}%
+ {Height of ChapterStart must be integer, greater than or equal to 4.}%
+ \else\fi%
+ \gdef\@setchapterstartheight{#1}%
+}
+\SetChapterStartHeight{10} % default
+% See novel.cls for the accompanying AtBeginDocument routine.
+% Scene breaks:
+% \SetScenebreakIndent controls whether line after \scenebreak, \sceneline,
+% or \scenestars will be indented. Set true or false, default false.
+%% End reserve space for header/footer and set default ChapterStart
+\newif\if@IndentAfterScenebreak
+\newcommand\SetScenebreakIndent[1]{% true or false, default false.
+ \@tempTFfalse
+ \ifthenelse{\equal{#1}{true}}{%
+ \@tempTFtrue
+ \global\@IndentAfterScenebreaktrue
+ }{}%
+ \ifthenelse{\equal{#1}{false}}{%
+ \@tempTFtrue
+ \global\@IndentAfterScenebreakfalse
+ }{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Bad argument for \string\SetScenebreakIndent\space}%
+ {\string\SetScenebreakIndent\space argument must be true or false.}%
+ \fi%
+}
+\SetScenebreakIndent{false} % default
+% Deprecated:
+\newcommand\IndentAfterScenebreak{\global\@IndentAfterScenebreaktrue}
+
+
+
+%% SCENE CHANGES
+%% ----------------------------------------------------------------------------
+% \scenebreak \sceneline \scenestars
+% Use anywhere in document body.
+% These commands skip a line.
+% \scenebreak leaves the gap empty.
+% \sceneline centers a line, about 1/3 textwidth.
+% \scenestars centers three widely-spaced asterisks.
+% Default behavior is \noindent for following paragraph.
+% Use \SetScenebreakIndent{true or false} in Preamble to change globally.
+% Either way, local behavior changed using \forceindent or \backindent.
+% \newcommand\scenebreak{\null}
+%
+\newcommand\scenebreak{%
+ \leavevmode\getBreakpos{scenebreak}~\par
+}
+%
+\newcommand\sceneline{%
+ \noindent\getBreakpos{sceneline}\hfil%
+ \raisebox{0.2em}{\rule{0.35\textwidth}{.4pt}}\hfil\par%
+}
+%
+\newcommand\scenestars{%
+ \noindent\getBreakpos{scenestars}\hfil%
+ \raisebox{-.3em}{*\quad\quad*\quad\quad*}\hfil\par%
+}
+%
+\gdef\getBreakpos#1{%
+ \begingroup%
+ \savepos%
+ \protected@write\@auxout{}{%
+ \protect\@getBreakpos{\noexpand\number\lastypos}{\thepage}{#1}%
+ }%
+ \endgroup%
+}
+%
+\newlength\CurrentBreakpos
+\gdef\@getBreakpos#1#2#3{} % nothing, when reading aux at beginning
+\gdef\@RedefineBreakpos{ % called by `novel.cls' \AtBeginDocument
+ \gdef\@getBreakpos##1##2##3{% numerical position sp, page, break type
+ \gsetlength\CurrentBreakpos{##1sp}% measured up from very bottom of page.
+ \FPsub{\@BreakLines}{\strip@pt\TotalYpos}{\strip@pt\CurrentBreakpos}
+ \FPdiv{\@BreakLines}{\@BreakLines}{\strip@pt\nbs}%
+ \FPround{\@BreakLines}{\@BreakLines}{0}% integer lines from text top
+ \ifthenelse{\equal{##3}{scenebreak}}{%
+ \xdef\thisline{\@BreakLines}%
+ \ifnum\@BreakLines=1%
+ \ClassWarning{novel}{Replace \string\scenebreak\space at top of ^^J%
+ page ##2 with \string\sceneline\space or \string\scenestars.}%
+ \fi%
+ \ifnum\@BreakLines=\@LinesPerPage%
+ \ClassWarning{novel}{Replace \string\scenebreak\space at bottom of ^^J%
+ page ##2 with \string\sceneline\space or \string\scenestars.}%
+ \fi%
+ }{}%
+ \FPsub{\@nearthebottom}{\@LinesPerPage}{1}%
+ \ifnum\@BreakLines=2%
+ \ClassWarning{novel}{\string\ ##3 too close to top of page ##2.}%
+ \fi%
+ \ifnum\@BreakLines=\@nearthebottom%
+ \ClassWarning{novel}{\string\ ##3 too close to bottom of page ##2.}%
+ \fi%
+ }%
+} % end @RedefineBreakpos
+%%
+
+
+%% Repair \FirstLine{} command from `magaz' package.
+% Problem: Conflict with \noindent\nov@AfterGroup as used in ChapterStart.
+% The \noindent is carried past \FirstLine to the following paragraph.
+% Solution: After FirstLine completes, back up one line vertically, then insert
+% and empty line to restore grid and absorb the noindent.
+% Starred version uses the original \FirstLine definition, just in case
+% the following paragraph has some exotic feature.
+% Thanks to user `egreg' at tex.stackexchange.com for assistance.
+\let\oldFirstLine\FirstLine
+\def\FirstLine{\@ifstar\FirstLineFoo\@FirstLineFoo} % improved
+\def\FirstLineFoo#1{\oldFirstLine{#1}} % starred restores original def.
+\def\@FirstLineFoo#1{%
+ \oldFirstLine{#1}\par\vspace{-\nbs}\strut\par%
+}
+%%
+
+
+%% Chapter number count.
+%% Do NOT use for "chapter-like" sections, only numbered chapters.
+\newcounter{novelcn}
+\setcounter{novelcn}{1}
+%%
+
+%% ChapterStart environment.
+% The most useful way to start a new chapter. Occupies a fixed amount of
+% vertical space. Also self-adjust when used with dropfolio. Automatically
+% calls \thispagestyle if set for all chapter displays.
+% This environment is not restricted to chapters. It is also used for
+% chapter-like sections in front matter or main matter,
+% as long as they are styled like a chapter.
+\newcounter{@linequarter}
+
+%
+% The argument is the number of normal baselineskips high.
+\newif\if@WithinChapterStart
+\DeclareDocumentEnvironment {ChapterStart} %
+{ O{\@setchapterstartheight} O{\@setchapterstart} }{%
+ \if@ThisPageStyle\else%
+ \gdef\@thiscsstyle{#2}%
+ \thispagestyle{\@thiscsstyle}%
+ \fi%
+ \global\@WithinChapterStarttrue%
+ \suppressfloats[t]% ensures that a floated image does not go on top
+ \gsetlength\parindent{0pt}% within environment
+ \ResetFootnoteSymbol% resets symbolic markers, but not numerical markers
+ \IfStrEq{#1}{*}{%
+ \gdef\@thiscsheight{\@setchapterstartheight}%
+ }{%
+ \gdef\@thiscsheight{#1}%
+ }%
+ \FPsub{\@fixlines}{\@thiscsheight}{2}%
+ \FPsub{\@fixlines}{\@fixlines}{0.001}% fudge to avoid rounding problems
+ \FPround{\@thiscsheight}{\@thiscsheight}{0}%
+ \FPiflt{\@thiscsheight}{4}%
+ \def\@smcserr{%
+ \ClassError{novel}{ChapterStart height insufficient for thispagestyle}%
+ {With your choice for thispagestyle, the height must be at least 4.}%
+ }%
+ \IfStrEq{\@thiscsstyle}{dropfolioinside}{\@smcserr}{}%j
+ \IfStrEq{\@thiscsstyle}{plain}{\@smcserr}{}%
+ \IfStrEq{\@thiscsstyle}{fancyplain}{\@smcserr}{}%
+ \else\fi%
+ \FPiflt{\@thiscsheight}{3}%
+ \ClassError{novel}{ChapterStart height must be at least 3}%
+ {If you need height less than 3, consider \string\QuickChapter.}%
+ \else\fi%
+ \null% always a line above the first thing to appear within the environment
+ \setcounter{@linequarter}{0}%
+ \begin{textblock*}{\textwidth}[0,0](0pt,0pt)%
+}{% close the environment:
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{1} \OR \equal{\value{@linequarter}}{5}%
+ \OR \equal{\value{@linequarter}}{9} \OR \equal{\value{@linequarter}}{13}%
+ }{\vspace{0.75\nbs}}{}%
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{2} \OR \equal{\value{@linequarter}}{6}%
+ \OR \equal{\value{@linequarter}}{10} \OR \equal{\value{@linequarter}}{14}%
+ }{\vspace{0.5\nbs}}{}%
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{3} \OR \equal{\value{@linequarter}}{7}%
+ \OR \equal{\value{@linequarter}}{11} \OR \equal{\value{@linequarter}}{15}%
+ }{\vspace{0.25\nbs}}{}%
+ \end{textblock*}%
+ \vspace{\@fixlines\nbs}%
+ \if@DeleteCSline\else\null\fi% adjusts when dropfolioinside
+ \global\@WithinChapterStartfalse%
+ \vspace{0.1pt plus 0pt minus 0.2pt}% caulk
+ \gsetlength\parindent{\normalparindent}% restored
+ \nov@AfterGroup\NoIndentAfterThis% etextools and noindentafter
+}
+% end ChapterStart environment
+
+
+%%
+\LetLtxMacro\ChapterDisplay\ChapterStart\relax % deprecated
+\LetLtxMacro\endChapterDisplay\endChapterStart\relax % deprecated
+%
+\newcommand\ChapterTitle[2][c]{% optional alignment l, c, r
+ \ignorespaces%
+ \vspace{0.5\nbs}\addtocounter{@linequarter}{2}%
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{l}}{\let\@csalign\relax\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{c}}{\let\@csalign\centering\relax\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{r}}{\let\@csalign\hfill\relax\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Chapter Title, Deco, Subtitle align must be l, c, or r}%
+ {On page \thepage you wrote a Chapter command with alignment ^^J%
+ other than the allowed l, c, or r.}%
+ \fi%
+ {\@csalign\stake\smash{{\chapterfont{}#2}}\par}%
+}
+%
+\newcommand\ChapterSubtitle[2][c]{% optional alignment l, c, r
+ \vspace{0.25\nbs}\addtocounter{@linequarter}{1}
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{l}}{\let\@csalign\relax\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{c}}{\let\@csalign\centering\relax\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{r}}{\let\@csalign\hfill\relax\@tempTFtrue}{}
+ \if@tempTF\else%
+ \ClassError{novel}{Chapter Title, Deco, Subtitle align must be l, c, or r}%
+ {On page \thepage you wrote a Chapter command with alignment ^^J%
+ other than the allowed l, c, or r.}%
+ \fi%
+ {\@csalign{\stake\smash{\subchfont #2}}\par}%
+}
+% In ChapterDeco, a trick is used. Instead of two optional arguments, and
+% instead of using expl3 syntax to create different argument delimiters,
+% the arguments for alignment and scale are passed as a single option.
+% This works because one is a letter, and the other is a number.
+% So it is easy to separte them by parsing.
+\newcommand\ChapterDeco[2][c1]{% optional alignment and scale, either order
+ \@tempTFfalse
+ \StrDel{#1}{ }[\temp@cds]% may use space separator
+ \StrDel{\temp@cds}{,}[\temp@cd]% may use comma separator
+ \IfSubStr{#1}{l}{% left align
+ \let\@csalign\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{l}[\temp@cd]%
+ }{}%
+ \IfSubStr{#1}{c}{% centered
+ \let\@csalign\centering\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{c}[\temp@cd]%
+ }{}%
+ \IfSubStr{#1}{r}{% right align
+ \let\@csalign\hfill\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{r}[\temp@cd]%
+ }{}%
+ \if@tempTF\else%
+ \let\@csalign\centering\relax\@tempTFtrue%
+ \fi%
+ % Now for scaling, with adjusted vertical position:
+ \IfEndWith{\temp@cd}{.}{\StrSubstitute{\temp@cd}{.}{.0}[\temp@cd]}{}%
+ \IfBeginWith{\temp@cd}{.}{\StrSubstitute{\temp@cd}{.}{1.}[\temp@cd]}{}%
+ \IfDecimal{\temp@cd}{\def\@thisScale{\temp@cd}}{\def\@thisScale{1}}%
+ {\@csalign\charscale[\@thisScale,0pt,0.2\nbs]{#2}\par}%
+}
+%
+%%
+
+
+%% \QuickChapter[line style]{text} intended for a story consisting of numerous
+% short chapters without page breaks. Two blank lines are inserted. In the gap
+% is the text, using subchfont. Optional line follows using \bigemdash style.
+% If option is empty, no line. If a length, then the line is that length.
+% If option * then the line fills to end of text line.
+\newcommand\QuickChapter[2][]{%
+ \null%
+ \noindent{\subchfont\charscale[1,0pt,0.3em]{#2}%
+ \gsetlength\@tempLength{\heightof{x}}% height of x in subchfont
+ }% end subchfont
+ \FPdiv{\@qclineth}{\strip@pt\@tempLength}{\strip@pt\normalxheight}% fontscale
+ \FPmul{\@howthick}{\@qclineth}{0.049}% typical emdash thickness, em.
+ \FPmul{\@howraise}{0.23}{\@qclineth}% typical emdash height em raised.
+ \ifthenelse{\equal{#1}{} \OR \equal{#1}{ }}{}{% no line, else:
+ \ifthenelse{\equal{#1}{*}}{% line fills:
+ ~\leaders%
+ \hbox{\smash{\rule[\@howraise em]{1pt}{\@howthick em}}}%
+ \hfill\stake\par%
+ }{% else line at specific length:
+ ~\makebox[#1][l]{%
+ \leaders\hbox{\smash{\rule[\@howraise em]{1pt}{\@howthick em}}}\hfill%
+ }%
+ }%
+ }%
+ \NoIndentAfterThis%
+} % end \QuickChapter
+%%
+
+
+%%
+% \cleartorecto works same as \clearpage when next page is recto.
+% If next page would be verso, a blank verso is inserted,
+% so that the following material is recto.
+% \cleartoend is used at very end of book.
+% It adds a blank page. If the blank is verso, end of book.
+% But if that blank is recto, it adds a second blank page, end of book.
+% So, the book always ends with a blank verso.
+\gdef\cleartorecto{
+ \clearpage
+ \ifodd\c@page
+ \else
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+}
+\newif \if@cleartoend
+\gdef\cleartoend{
+ \if@cleartoend\else
+ \clearpage
+ \ifodd\c@page
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+ \global\@cleartoendtrue
+}
+%
+
+
+%%
+\gdef\@ActivateChapterScene{% called by `novel.cls' \AtBeginDocument
+ % Activate user choice of whether or not to indent after scenebreak commands:
+ \if@IndentAfterScenebreak\else
+ \NoIndentAfterCmd{\scenebreak}
+ \NoIndentAfterCmd{\sceneline}
+ \NoIndentAfterCmd{\scenestars}
+ \fi
+}% end \@ActivateChapterScene
+%%
+
+
+%% Neutralize settings commands:
+\gdef\@DisableChapterSceneSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetHeadFootStyle\relax
+ \LetLtxMacro\IndentAfterScenebreak\relax
+ \LetLtxMacro\SetScenebreakIndent\relax
+}% end \@DisableChapterSceneSettings
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-ChapterScene.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-DropCap.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-DropCap.sty
new file mode 100644
index 0000000000..7d418b45f5
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-DropCap.sty
@@ -0,0 +1,223 @@
+%%
+%% This is file `novel-DropCap.sty', part of `novel' document class.
+%% Copyright (C) 2017-2023 Robert Allgeyer.
+%%
+%% It is based on `lettrine.sty', part of `lettrine' package,
+%% Copyright (C) 1999-2015 Daniel Flipo.
+%%
+%% The license for this file is that same for `lettrine':
+%
+% This program can be distributed and/or modified under the terms
+% of the LaTeX Project Public License either version 1.3c of this
+% license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%%
+\ProvidesFile{novel-DropCap.sty}%
+ [2023/02/08 v1.80 (Drop Caps)]
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%
+%
+
+%
+\newcounter{NDCDefaultLines}
+\setcounter{NDCDefaultLines}{3}
+\newcounter{NDCDefaultDepth}
+\newdimen\NDCDefaultVoffset
+\newdimen\NDCDefaultHoffset
+\newcommand*{\NDCDefaultScale}{1}
+\newcommand*{\NDCDefaultBloat}{1}
+\newdimen\NDCDefaultGap
+\gsetlength{\NDCDefaultGap}{0.25em} % approx. width of normal space
+\newsavebox{\NDC@dropcapbox}
+\newsavebox{\NDC@normalXbox}
+\newcounter{NDC@lines}
+\newcounter{NDC@depth}
+\newdimen\NDC@antewidth
+\newdimen\NDC@Pindent
+\newdimen\NDC@Gap % equivalent to lettrine findent
+\newdimen\NDC@Nindent % not a user setting
+\newdimen\NDC@voffset
+\newdimen\NDC@hoffset
+\newdimen\NDC@first
+\newdimen\NDC@next
+\newdimen\NDC@height
+\newcommand*{\NDC@ante}{}
+\newcommand*{\NDC@bloat}{}
+\newcommand*{\NDC@scale}{}
+\def\@getNDCheight{% offsets do not affect height:
+ \@tempdima=\baselineskip
+ \setlength{\NDC@height}{\value{NDC@lines}\@tempdima}% local
+ \addtolength{\NDC@height}{-\@tempdima}%
+ \sbox{\NDC@normalXbox}{X}% Normal capital X, rather than something else.
+ \addtolength{\NDC@height}{\ht\NDC@normalXbox}%
+ \setlength{\NDC@height}{\NDC@scale\NDC@height}% local
+} %
+\newcommand*{\NDC@char}{%
+ \@getNDCheight%
+ % Measures drop cap capital X, rather than something else:
+ \sbox{\@tempboxa}{%
+ \NDC@charstyle\fontsize{\NDC@height}{\NDC@height}\selectfont X%
+ }%
+ \@tempcntb=\ht\@tempboxa%
+ \@tempcnta=\NDC@height%
+ \multiply\@tempcnta by 100%
+ \divide\@tempcntb by 100%
+ \divide\@tempcnta by \@tempcntb%
+ \advance\@tempcnta by -9999%
+ \ifnum\@tempcnta>0%
+ \def\@tempa{1.\the\@tempcnta}%
+ \else%
+ \def\@tempa{1}%
+ \fi%
+ \NDC@charstyle\fontsize{\@tempa\NDC@height}{\@tempa\NDC@height}\selectfont
+} %
+\define@key{NDC}{lines}{\setcounter{NDC@lines}{#1}}
+\define@key{NDC}{depth}{\setcounter{NDC@depth}{#1}}
+\define@key{NDC}{hoffset}{\setlength{\NDC@hoffset}{#1}}
+\define@key{NDC}{voffset}{\setlength{\NDC@voffset}{#1}}
+\define@key{NDC}{ante}{\renewcommand*{\NDC@ante}{#1}} % Like `lettrine' ante,
+\define@key{NDC}{ante*}{\renewcommand*{\NDC@ante}{% Like `lettrine' ante, but
+ \setlength\NDC@antewidth{\widthof{#1}}% auto-hangs the ante in left margin.
+ \addtolength\NDC@antewidth{0.2em}% provides breathing room
+ \stake\hspace{-\NDC@antewidth}#1\hspace{0.2em}}% restores alignment
+}
+\define@key{NDC}{gap}{\setlength{\NDC@Gap}{#1}}
+\define@key{NDC}{bloat}{\renewcommand*{\NDC@bloat}{#1}}
+\define@key{NDC}{scale}{\renewcommand*{\NDC@scale}{#1}}
+\newdimen\NDCboxwidth
+\newdimen\NDCboxheight
+\newdimen\NDCboxdepth
+%
+\DeclareDocumentCommand \NDC@boxcap { m }{%
+ \begingroup%
+ % The model letter has no upper diacritical.
+ \def\@NDCmodel{}%
+ \IfSubStr{ÀÁÂÃÄÅĀĂ}{#1}{\def\@NDCmodel{A}}{}%
+ \IfSubStr{ĆĈĊČ}{#1}{\def\@NDCmodel{C}}{}%
+ \IfSubStr{Ď}{#1}{\def\@NDCmodel{D}}{}%
+ \IfSubStr{ÈÉÊËĒĔĖĚ}{#1}{\def\@NDCmodel{E}}{}%
+ \IfSubStr{ĜĞĠ}{#1}{\def\@NDCmodel{G}}{}%
+ \IfSubStr{Ĥ}{#1}{\def\@NDCmodel{H}}{}%
+ \IfSubStr{ÌÍÎÏĨĪĬİ}{#1}{\def\@NDCmodel{I}}{}%
+ \IfSubStr{Ĵ}{#1}{\def\@NDCmodel{J}}{}%
+ \IfSubStr{Ĺ}{#1}{\def\@NDCmodel{L}}{}%
+ \IfSubStr{ÑŃŇ}{#1}{\def\@NDCmodel{N}}{}%
+ \IfSubStr{ÒÓÔÕÖŌŎŐ}{#1}{\def\@NDCmodel{O}}{}%
+ \IfSubStr{ŔŘ}{#1}{\def\@NDCmodel{R}}{}%
+ \IfSubStr{ŚŜŠ}{#1}{\def\@NDCmodel{S}}{}%
+ \IfSubStr{Ť}{#1}{\def\@NDCmodel{T}}{}%
+ \IfSubStr{ÙÚÛÜŨŪŬŮŰ}{#1}{\def\@NDCmodel{U}}{}%
+ \IfSubStr{Ŵ}{#1}{\def\@NDCmodel{W}}{}%
+ \IfSubStr{ÝŶŸ}{#1}{\def\@NDCmodel{Y}}{}%
+ \IfSubStr{ŹŻŽ}{#1}{\def\@NDCmodel{Z}}{}%
+ \IfSubStr{DŽ}{#1}{\def\@NDCmodel{DZ}}{}% diglyph
+ \setlength\fboxsep{0.16\@SetFontSize}%
+ \setlength\fboxrule{0.02\@SetFontSize}%
+ \ifthenelse{\equal{\@NDCmodel}{}}{%
+ \framebox{\phantom{|}#1\phantom{|}}%
+ }{%
+ \framebox{\phantom{|\@NDCmodel}\llap{\smash{#1}}\phantom{|}}%
+ }%
+ \endgroup%
+}% end boxcap
+%
+\DeclareDocumentCommand \dropcap { s O{} m } {%
+ \@tempTFfalse%
+ \IfSubStr{#3}{png}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{PNG}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{jpg}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{JPG}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{jpeg}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{JPEG}{\@tempTFtrue}{}%
+ \setcounter{NDC@lines}{\value{NDCDefaultLines}}%
+ \setcounter{NDC@depth}{\value{NDCDefaultDepth}}%
+ \setlength{\NDC@hoffset}{\NDCDefaultHoffset}%
+ \renewcommand*{\NDC@bloat}{\NDCDefaultBloat}%
+ \renewcommand*{\NDC@scale}{\NDCDefaultScale}%
+ \setlength{\NDC@voffset}{\NDCDefaultVoffset}%
+ \renewcommand*{\NDC@ante}{}%
+ \setlength{\NDC@Gap}{\NDCDefaultGap}%
+ \setlength{\NDC@Nindent}{0pt}%
+ \setkeys{NDC}{#2}%
+ \if@tempTF%
+ \def\@dropthisthing{\InlineImage[0em,b]{#3}}%
+ \else%
+ \IfBooleanTF{#1}%
+ {\def\@dropthisthing{\NDC@boxcap{#3}}}%
+ {\def\@dropthisthing{#3}}%
+ \fi%
+ \ifnum\value{NDC@lines}=1%
+ \par\noindent%
+ \NDC@ante%
+ \@dropthisthing%
+ \else%
+ \sbox{\NDC@normalXbox}{X}% Normal capital X.
+ \sbox{\NDC@dropcapbox}{\scalebox{\NDC@bloat}[1]{\NDC@char\@dropthisthing}}%
+ \@tempdima=\baselineskip%
+ \setlength{\NDC@first}{-\value{NDC@lines}\@tempdima}%
+ \addtolength{\NDC@first}{\@tempdima}%
+ \sbox{\@tempboxa}{X}%
+ \addtolength{\NDC@first}{-\ht\@tempboxa}%
+ \addtolength{\NDC@first}{\NDC@voffset}%
+ \addtolength{\NDC@first}{\ht\NDC@dropcapbox}%
+ \addtolength{\NDC@voffset}{-\value{NDC@lines}\@tempdima}%
+ \addtolength{\NDC@voffset}{\@tempdima}%
+ \par%
+ \setlength{\NDC@Pindent}{\wd\NDC@dropcapbox}%
+ \addtolength{\NDC@Pindent}{\NDC@hoffset}%
+ \settowidth{\NDC@first}{\NDC@ante}%
+ \addtolength{\NDC@Pindent}{\NDC@first}%
+ \addtolength{\NDC@Pindent}{\NDC@Gap}%
+ \setlength{\NDC@first}{\linewidth}%
+ \addtolength{\NDC@first}{-\NDC@Pindent}%
+ \addtolength{\NDC@Nindent}{\NDC@Pindent}%
+ \setlength{\NDC@next}{\linewidth}%
+ \addtolength{\NDC@next}{-\NDC@Nindent}%
+ \addtolength{\NDC@Pindent}{\rightmargin}%
+ \addtolength{\NDC@Nindent}{\rightmargin}%
+ \setlength{\NDCboxwidth}{\wd\NDC@dropcapbox}%
+ \setlength{\NDCboxheight}{\ht\NDC@dropcapbox}%
+ \setlength{\NDCboxdepth}{\dp\NDC@dropcapbox}%
+ \addtocounter{NDC@lines}{1}%
+ \addtocounter{NDC@lines}{\value{NDC@depth}}%
+ \def\NDC@parshape{\c@NDC@lines \the\NDC@Pindent \the\NDC@first}%
+ \@tempcnta=\tw@%
+ \@whilenum \@tempcnta<\c@NDC@lines\do{%
+ \edef\NDC@parshape{\NDC@parshape \the\NDC@Nindent \the\NDC@next}%
+ \advance\@tempcnta\@ne}%
+ \edef\NDC@parshape{\NDC@parshape \rightmargin \the\linewidth}%
+ \noindent%
+ \parshape=\NDC@parshape\relax%
+ \smash{%
+ \llap{%
+ \mbox{\NDC@ante}%
+ \raisebox{\NDC@voffset}{\usebox{\NDC@dropcapbox}}%
+ \hskip\the\NDC@Gap%
+ }%
+ }%
+ \fi%
+}% end @NDCdropcap
+%%
+
+
+%% In case the user prefers `lettrine':
+\gdef\@ActivateDropCaps{% called by `novel.cls' \AtBeginDocument
+ \@ifpackageloaded{lettrine}{%
+ \global\LettrineOnGridtrue % Necessary.
+ \gsetlength\DiscardVskip{10\nbs} % effectively infinite
+ }{ % For test purposes only:
+ \providecommand\lettrine[3][]{##2##3} % echoes its mandatory arguments
+ }%
+}% end \@ActivateDropCaps
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-DropCap.sty'.
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-FOGRA39.clo b/macros/luatex/latex/novel/tex/lualatex/novel/novel-FOGRA39.clo
new file mode 100644
index 0000000000..fb20757902
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-FOGRA39.clo
@@ -0,0 +1,27 @@
+%%
+%% This is file `novel-FOGRA39.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+\ProvidesFile{novel-FOGRA39.clo}%
+[2023/02/08 any version. (novel Output Intent FOGRA39)]
+%%
+
+
+% Typically used in Europe.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+\gdef\@OIidentifier{FOGRA39} % also called "reference name"
+\gdef\@OIcondition{Offset commercial and specialty printing according to ISO 12647-2:2004 / Amd 1, paper type 1 or 2 (gloss or matte coated offset, 115 g/m2), screen frequency 60/cm.}
+\gdef\@OIinfo{Coated FOGRA39 (ISO 12647-2:2004)}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{CoatedFOGRA39.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-FOGRA39.clo'
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-FileData.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-FileData.sty
new file mode 100644
index 0000000000..4d4535ead0
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-FileData.sty
@@ -0,0 +1,207 @@
+%%
+%% This is file `novel-FileData.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-FileData.sty}%
+[2023/02/08 v1.80 LaTeX file (File Data settings)]
+%%
+
+
+%% File Data, also known as PDF Metadata, is non-printing identifying
+%% information in the PDF file. Some or all of it can be read by various
+%% PDF reader software.
+%% PDF/X is also considered File Data, as it concerns the structure of the
+%% file and its relationaship to printers, rather than its visible content.
+%% In principle, you could set the title as empty. But in that case, no other
+%% File Data will be included, and you cannot have PDF/X compliance.
+%% There are many more kinds of File Data that a PDF can include, such as
+%% subject and keywords. But `novel' is specifically for printing to paper,
+%% not for electronic documents that would be found by database search.
+%% Thus, there is no provision for such additional File Data.
+%% When you sign up with a print service, you will provide subject, keywords,
+%% and description directly to their database, rather than in the PDF.
+%% No need to set copyright in metadata, since your file is only for use by
+%% the print service, and is not being distributed as a PDF e-book.
+%% Your copyright notice is on the printed page, where it should be.
+%% Particularly note that your print service is NOT the publisher: YOU are!
+
+
+%% FILE DATA (PDF Metadata)
+%% ----------------------------------------------------------------------------
+%%
+% \title{} or \SetTitle{}
+% Copied to File Data at end of Preamble, unless not set.
+% Provides \theTitle anywhere.
+% If not set, PDF cannot conform to PDF/X.
+\newif \if@HasTitle % true if \SetTitle or \title used
+\gdef\SetTitle#1{\gdef\@title{#1}} % for stylistic consistency
+\gdef\title#1{\gdef\@title{#1}}
+\gdef\thetitle{\@title} % for convenience
+\gdef\theTitle{\@title}
+\SetTitle{IMPORTANT: Provide Book Title} % Default.
+%
+% \author{} or \SetAuthor{}
+% Copied to File Data at end of preamble, unless not set.
+% Provides \theAuthor anywhere.
+\gdef\SetAuthor#1{\gdef\@author{#1}} % for stylistic consistency
+\gdef\author#1{\gdef\@author{#1}}
+\gdef\theauthor{\@author} % for convenience
+\gdef\theAuthor{\@author}
+\SetAuthor{}
+%
+% \subtitle{} or \SetSubtitle{} (if any)
+% Not copied to File Data by itself, as there is no such metadata entry.
+% Provides \theSubtitle anywhere.
+\gdef\SetSubtitle#1{\gdef\@subtitle{#1}} % for stylistic consistency
+\gdef\subtitle#1{\gdef\@subtitle{#1}}
+\gdef\thesubtitle{\@subtitle} % compatibility
+\gdef\theSubtitle{\@subtitle}
+\SetSubtitle{}
+%
+% \SetApplication{} (rarely used)
+% Also known as CreatorTool.
+% Name of the software that created the source document.
+% Changing this does not change the software, it just changes the information.
+% Normally leave as default, but can change if urgent.
+\gdef\SetApplication#1{\gdef\@novelApplication{#1}}
+\SetApplication{LuaLaTeX with novel and microtype} % default
+%
+% \SetProducer{} (rarely used)
+% Name of the software that compiles the source to make PDF.
+% Changing this does not change the software, it just changes the information.
+% Normally leave as default, but can change if urgent.
+\gdef\SetProducer#1{\gdef\@novelProducer{#1}}
+\SetProducer{LuaLaTeX with novel-pdfx and hyperref} % default
+%
+%% End file data.
+
+
+%% SET PDF/X ARGUMENTS
+%% ----------------------------------------------------------------------------
+%% \SetPDFX[Output Intent]{compliance standard} % No embed *.icc. Default.
+%% \SetPDFX*[Output Intent]{compliance standard} % Embed *.icc.
+%% Default: \SetPDFX[CGATSTR001]{X-1a:2001}
+%
+% \@pdfxSEToff refers to the setting, rather than whether it really is off.
+% \@pdfxISoff refers to whether it really is off.
+\newif \if@pdfxSEToff
+\newif \if@pdfxISoff
+% These will get meaningful info when an output intent file is loaded:
+\gdef\@OIidentifier{}
+\gdef\@OIcondition{}
+\gdef\@OIinfo{}
+\gdef\@OIregistry{}
+\gdef\@OIprofile{}
+%
+%%
+\newif \if@HasConformance
+\newif \if@EmbedICC
+\gdef\SetPDFX{\@ifstar\@setpdfxst\@setpdfxns}
+\newcommand\@setpdfxst[2][CGATSTR001]{
+ \global\@EmbedICCtrue
+ \@setpdfx{#1}{#2}
+}
+\newcommand\@setpdfxns[2][CGATSTR001]{
+ \global\@EmbedICCfalse
+ \@setpdfx{#1}{#2}
+}
+%
+\newcommand\@setpdfx[2]{
+ \@tempTFfalse
+ \ifthenelse{\equal{#2}{off}}{
+ \@tempTFtrue
+ \global\@pdfxSETofftrue
+ \global\@pdfxISofftrue
+ }{}
+ \ifthenelse{\equal{#2}{X-1a:2001}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-1}
+ \gdef\@PDFXversion{PDF/X-1a:2001}
+ \gdef\@PDFXconformance{PDF/X-1a:2001}
+ \global\@HasConformancetrue
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-1a:2003}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-1}
+ \gdef\@PDFXversion{PDF/X-1a:2003}
+ \gdef\@PDFXconformance{PDF/X-1a:2003}
+ \global\@HasConformancetrue
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-3:2002}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-3}
+ \gdef\@PDFXversion{PDF/X-3:2002}
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-3:2003}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-3}
+ \gdef\@PDFXversion{PDF/X-3:2003}
+ \global\pdfminorversion=4
+ }{}
+ \if@tempTF\else
+ \ClassError{novel}{Bad compliance argument for \string\SetPDFX}%
+ {Choose: X-1a:2001, X-1a:2003, X-3:2002, X-3:2003, off.}%
+ \fi
+ % Grab the file that defines the Output Intent information:
+ % File name format: novel-YourIntent.clo
+ % Setting: \SetPDFX[YourIntent]{compliance}
+ % Contents of file: See the above included Output Intent data.
+ \StrDel{#1}{\space}[\NPDFXOINS]
+ \IfFileExists{novel-\NPDFXOINS.clo}{\input{novel-\NPDFXOINS.clo}}{%
+ \ClassError{novel}{Bad Output Intent for \string\SetPDFX}%
+ {Use filename (without extension) of a file with *.clo extension. ^^J%
+ Filename must begin with novel- ^^J%
+ Example: File novel-FOGRA39.clo is called as [FOGRA39]. ^^J%
+ The file must be where TeX can find it. ^^J%
+ For contents of the file, see package documentation.}%
+ }{}%
+} % end \@setpdfx
+%
+\SetPDFX[CGATSTR001]{X-1a:2001} % Default.
+%%
+
+
+
+%% Neutralize file data settings:
+\gdef\@DisableFileDataSettings{% called by `novel.cls' \AtBeginDocument
+ \let\title\relax
+ \let\author\relax
+ \let\subtitle\relax
+ \LetLtxMacro\SetAuthor\relax
+ \LetLtxMacro\SetTitle\relax
+ \LetLtxMacro\SetSubtitle\relax
+ \LetLtxMacro\SetApplication\relax
+ \LetLtxMacro\SetProducer\relax
+ \LetLtxMacro\SetPDFX\relax
+}% end \@DisableFileDataSettings
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-FileData.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-Fonts.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Fonts.sty
new file mode 100644
index 0000000000..f35708f606
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Fonts.sty
@@ -0,0 +1,426 @@
+%%
+%% This is file `novel-Fonts.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Fonts.sty}%
+[2023/02/08 v1.80 LaTeX file (font settings and defaults)]
+%%
+
+
+%% Package `fontspec' was previously loaded by `\novel.cls'.
+
+
+%% INITIALIZATION
+%% ----------------------------------------------------------------------------
+% Fonts are chosen in Preamble using \Set commands. But they are not activated
+% until \AtEndPreamble. Until then, the basic TeX font families must be
+% temporarily specified, so that certain packages can load without compliant.
+% These are Latin Modern fonts, which are Open Type and will work, but are not
+% stylistically suitable for works of fiction. The only reason they are
+% used here, is because just about every TeX installation has them.
+\gdef\rmdefault{lmr} % Latin Modern Roman
+\gdef\sfdefault{lmss} % Latin Modern Sans
+\gdef\ttdefault{lmtt} % Latin Modern Mono
+% The following might become unnecessary if fontspec adds the capability to
+% disable keys. For now: Color and Opacity cannot be used as font features,
+% for a black/white printed book. Alas, fontspec over-rules xcolor.
+% So, this code over-rules fontspec:
+\gdef\@CheckFontspecFeatures#1{%
+ \@tempTFfalse%
+ \IfSubStr{#1}{Color}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{Colour}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{color}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{colour}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{Opacity}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{opacity}{\@tempTFtrue}{}%
+ \if@tempTF%
+ \ClassError{novel}{Color and Opacity forbidden as font features}%
+ {You defined a font, or added a font feature, with Color or Opacity. ^^J%
+ That is disallowed in `novel' class.}%
+ \fi%
+} % end \@CheckFontspecFeatures
+% Default font features (will be changed later):
+\defaultfontfeatures{} % reset
+\defaultfontfeatures{SmallCapsFeatures={Renderer=Basic},Ligatures=TeX,} % all
+\if@novrevert
+ \defaultfontfeatures[\rmfamily,\sffamily]%
+ {Kerning=On,Numbers=OldStyle,Ligatures=Common}
+\else
+ \defaultfontfeatures[\rmfamily,\sffamily]%
+ {Kerning=On,Numbers=OldStyle}
+\fi
+% Fake \microtypesetup until package loaded by \@ActivateFonts, \AtEndPreamble:
+\newif \if@MicrotypeSet
+\gdef\microtypesetup#1{
+ \gdef\@mymicrotypesetup{#1} % used in novel-Fonts.sty
+ \global\@MicrotypeSettrue
+}%
+%% end initialization
+
+
+%% SETTINGS FOR PARENT FONT, DESCENDANTS, OTHERS
+%% ----------------------------------------------------------------------------
+% In `novel' you do not \usepackage{font name} or \RequirePackage{font name}.
+% You do not directly write \renewcommand\rmdefault{font name}.
+% You do not directly use \setmainfont[features]{font name}.
+% Instead, `novel' requires a `parent font' to be set. The parent font is
+% the ancestor of the main (normal) font, and several other descendants.
+% The parent font features, if any, should be a minimal set that will be
+% applied to all descendants. For example, if the font has an an alternate
+% style for a particular letter, and you want to use it for all descendants,
+% then you would spedify that feature for the parent font.
+% For now, these settings are merely stored. Later, \AtEndPreamble,
+% the main (normal) font inherits the settings for the parent font.
+% Other descendants inherit those settings, with their own features added.
+% Anything not set by you, will have a suitable default set automatically.
+\newif \if@ParentFontSet
+\gdef\parentfontfeatures{}
+\gdef\parentfontname{}
+\DeclareDocumentCommand \SetParentFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \if@novrevert
+ \gdef\parentfontfeatures{#1,#3}
+ \else
+ \gdef\parentfontfeatures{Ligatures=Common,#1,#3}
+ \fi
+ \gdef\parentfontname{#2}
+ \global\@ParentFontSettrue
+}%
+\DeclareDocumentCommand \SetMasterFont { O{} m O{} } {% DEPRECATED
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\parentfontfeatures{#1,#3}
+ \gdef\parentfontname{#2}
+ \global\@ParentFontSettrue
+}%
+%
+% In a work of fiction, you probably do not need a sans or mono font.
+% But TeX expects you do have them. So, \AtEndPreamble, Libertinus Sans
+% and Libertinus Mono will be set as defaults, if you have those fonts.
+% Otherwise, Latin Modern Sans and Mono will be used, but they are not
+% well-suited to works of fiction.
+% If you wish to set your own sans and mono fonts, do it using standard
+% `fontspec' syntax. There is no special method in `novel' class:
+% \setsansfont[features]{font name}
+% \setmonofont[features]{font name}
+%
+% The headfont is used in headers and footers:
+\newif \if@HeadFontSet
+\gdef\@headfontfeatures{}
+\gdef\@headfontname{}
+\DeclareDocumentCommand \SetHeadFont { O{} m O{} } {% revised v 1.40.3
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@headfontfeatures{Numbers=Lining,%
+ WordSpace=\@looseheadword,#1,#3}% loose letters added in head/foot styles
+ \gdef\@headfontname{#2}
+ \global\@HeadFontSettrue
+}%
+% The chapter font is used by the \ChapterTitle{} command:
+\newif \if@ChapterFontSet
+\gdef\@chapterfontfeatures{}
+\gdef\@chapterfontname{}
+\DeclareDocumentCommand \SetChapterFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@chapterfontfeatures{Numbers=Lining,#1,#3}
+ \gdef\@chapterfontname{#2}
+ \global\@ChapterFontSettrue
+}%
+% The subch font is used by the \ChapterSubtitle{} command:
+\newif \if@SubchFontSet
+\gdef\@subchfontfeatures{}
+\gdef\@subchfontname{}
+\DeclareDocumentCommand \SetSubchFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@subchfontfeatures{Numbers=Lining,#1,#3}
+ \gdef\@subchfontname{#2}
+ \global\@SubchFontSettrue
+}%
+% The deco font is used for decorations and acronyms.
+% It must be NovelDeco.otf or a font based on NovelDeco.otf. No other!
+\newif \if@DecoFontSet
+\newif \if@HasDecoFont
+\gdef\@decofontfeatures{}
+\gdef\@decofontname{}
+\DeclareDocumentCommand \SetDecoFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@decofontname{#2}
+ \global\@DecoFontSettrue
+ \global\@HasDecoFonttrue
+ \newfontface\decofont[#1,#3]{#2}
+}%
+% For syntax consistency:
+\ExplSyntaxOn
+\cs_new_eq:NN \NewFontFamily \newfontfamily
+\cs_new_eq:NN \NewFontFace \newfontface
+\cs_new_eq:NN \SetSansFont \setsansfont
+\cs_new_eq:NN \SetMonoFont \setmonofont
+\cs_new_eq:NN \SetMathFont \setmathfont
+\cs_new_eq:NN \AddFontFeatures \addfontfeatures
+\cs_new_eq:NN \AddFontFeature \addfontfeatures
+\ExplSyntaxOff
+\gdef\@DropCapFont{} % until actually set, will be default main font
+\gdef\@DropCapColorModel{} % until actually set, using `xcolor' syntax
+\gdef\@DropCapColorValue{black} % until actually set, using `xcolor' syntax
+\gdef\NDC@charstyle{}
+% The argument to \SetDropCapFont is a user-defined `fontspec' font command.
+% Example syntax, using `fontspec' in LuaLaTeX:
+% Create font command, such as: \newfontface\mynicefont[options]{fontname}
+% Then: \SetDropCapFont{\mynicefont}
+\newif \if@HasDropCapFont
+\DeclareDocumentCommand \SetDropCapFont { m } {%
+ \@HasDropCapFonttrue%
+ \gdef\@DropCapFont{#1}%
+ \gdef\NDC@charstyle{%
+ #1%
+ \if@HasDropCapColor%
+ \ifthenelse{\equal{\@DropCapColorModel}{}}{%
+ \color{\@DropCapColorValue}%
+ }{%
+ \color[\@DropCapColorModel]{\@DropCapColorValue}%
+ }%
+ \fi%
+ }%
+}%
+% The argument(s) to \SetDropCapColor use `xcolor' syntax:
+% [colormodel]{value} OR {colorname}
+\newif \if@HasDropCapColor
+\DeclareDocumentCommand \SetDropCapColor { O{} m } {%
+ \@setdropcapcolor[#1]{#2}%
+}% end \SetDropCapColor
+\DeclareDocumentCommand \@setdropcapcolor { O{} m } {%
+ \global\@HasDropCapColortrue%
+ \gdef\@DropCapColorModel{#1}%
+ \gdef\@DropCapColorValue{#2}%
+ \renewcommand\NDC@charstyle{%
+ \@DropCapFont%
+ \ifthenelse{\equal{\@DropCapColorModel}{}}{%
+ \color{\@DropCapColorValue}%
+ }{%
+ \color[\@DropCapColorModel]{\@DropCapColorValue}%
+ }%
+ }%
+}% end \@setdropcapcolor
+% for convenience:
+\ExplSyntaxOn
+\cs_new_eq:NN \SetDropcapFont \SetDropCapFont
+\cs_new_eq:NN \SetDropcapColor \SetDropCapColor
+\ExplSyntaxOff
+%
+% A default math font (which presumably you do not need) is chosen here.
+% You may over-ride using `unicode-math' syntax \setmathfont in Preamble.
+\IfFontExistsTF{Libertinus Math}{ % stylistically consisent with novel text
+ \setmathfont[BoldFont={libertinusmath-regular.otf}]%
+ {libertinusmath-regular.otf}
+}{
+ \IfFontExistsTF{Latin Modern Math}{}{% default for package `unicode-math'
+ }{ % The following hack allows you to proceed without a real math font,
+ % (but then you cannot print math):
+ \IfFontExistsTF{NovelDeco.otf}{%
+ \setmathfont[BoldFont={NovelDeco.otf}]{NovelDeco.otf} % fake math feature
+ \ClassWarning{novel}{^^JIgnore this if you used \string\setmathfont. ^^J%
+ Did not find suitable default math font. Used NovelDeco.otf. ^^J%
+ But NovelDeco does not have real math symbols. ^^J%
+ Math notation will print incorrectly. No problem if no math. ^^J}%
+ }{}% if no NovelDeco, do nothing here
+ }
+}%
+%% end settings for parent font and others.
+
+
+%% CREATING NEW FONT FONT FEATURES
+%% ----------------------------------------------------------------------------
+% \CreateFontFeature{substitutions}{feature code}
+% Problem: Font has one or more alternate glyphs that you would like to use,
+% but they are not listed in a feature set for the font.
+% Solution: Create your own feature set, with \CreateFontFeature. The created
+% feature may then be used like a real feature, in any font definition.
+% The substitutions are a comma-separated list, char=char.alt and so forth.
+% For example, the following substitutions are syntactically OK:
+% emdash=emdah.alt, one=one.rev, ntilde=ntilde.03
+% If a substitution is not available in a particular font, it is ignored.
+% You have to look at the font in a font editor, to know what is available.
+% It is possible to make silly substitutions, such as a=b, five=three without
+% throwing an error, unless your code causes a cycle.
+% The most useful application of this command is to reach alternate emdash,
+% and alternate oldstyle one. Not every font has these.
+% The feature code is a 4-character pseudo- Open Type code, otherwise unused.
+% For example, the feature code might be myfs (my fake substitution)
+% but it cannot be a pre-defined code such as lnum or smcp. It may be
+% a style set such as ss03 if you are sure that the font in question
+% do not already have ss03 (but this is taking a chance).
+% Once defined, you may use it like this (for example):
+% \SetParentFont[RawFeature=+myfs]{fontname}
+% \NewFontFamily\myfake[RawFeature=+myfs]{fontname}
+% In the document body: {\addfontfeature{myfs} text}
+\DeclareDocumentCommand \CreateFontFeature { m m } {%
+ \IfEndWith{#1}{,}{\StrGobbleRight{#1}{1}[\@fakezero]}{\def\@fakezero{#1}}
+ \def\@fakeone{"\@fakezero"}
+ \StrSubstitute{\@fakeone}{=}{"]="}[\@fakeone]
+ \StrSubstitute{\@fakeone}{,}{",\space["}[\@fakeone]
+ \directlua{
+ fonts.handlers.otf.addfeature {
+ name = "#2",
+ type = "substitution",
+ data = {\@fakeone},
+ }
+ }
+} %
+%% end \CreateFontFeature. Above thanks to fontspec 2016.
+
+
+%% ACTIVATE FONTS \AtEndPreamble
+%% ----------------------------------------------------------------------------
+\gdef\@ActivateFonts{% called by `novel.cls' \AtEndPreamble
+ % We begin with the parent font:
+ \if@coverart
+ \SetParentFont{NovelDeco.otf}
+ \fi
+ \if@ParentFontSet\else
+ \ifthenelse{\equal{\rmdefault}{lmr}}{%
+ % At this point, if \rmdefault is lmr, it means the user did not choose
+ % a different font. Then, Libertinus Serif or Latin Modern Roman
+ % will be automatically set as \rmdefault, if available:
+ \IfFontExistsTF{Libertinus Serif}{ % preferred default
+ \if@novrevert % Version 1.52 behavior.
+ \SetParentFont[% Pre-1.80 default.
+ BoldFont=libertinusserif-semibold.otf,%
+ BoldItalicFont=libertinusserif-semibolditalic.otf,%
+ ]{Libertinus Serif}
+ \else % Version 1.80. Compiles faster wihout semibold.
+ \SetParentFont{Libertinus Serif}
+ \fi
+ }{ % backup default, if Libertinus Serif not available:
+ \SetParentFont[%
+ SmallCapsFont={Latin Modern Roman Caps}%
+ ]{Latin Modern Roman}% only because it comes with LaTeX
+ \let\scshape\oldscshape % or small caps won't work
+ \let\smcp\oldscshape % or small caps won't work
+ }%
+ }{% However, if \rmdefault is not lmr, it means the user chose the font.
+ % If the choice was made via \SetParentFont, no problem. But if done by
+ % incorrect method such as \setmainfont, \renewcommand\rmdefault,
+ % or \usepackage{fontname}, an error is thrown:
+ \if@ParentFontSet\else
+ \ClassError{novel}{Wrong command used to set main font}%
+ {You tried to define the main document font the wrong way. ^^J%
+ Bad: \string\renewcommand\string\rmdefault{font}\space ^^J%
+ Bad: \string\usepackage{font package}\space ^^J%
+ Bad: \string\RequirePackage{font package}\space ^^J%
+ Bad: \string\setmainfont[features]{font}\sapce ^^J%
+ Those are incorrect in `novel' class. ^^J%
+ Use \string\SetParentFont[features]{font}\space instead. ^^J%
+ See `novel' documentation.}%
+ \fi
+ }%
+ \fi % end \if@ParentFontSet
+ % Now we are ready for the main (normal) font, descending from parent font:
+ \setmainfont[\parentfontfeatures]{\parentfontname}
+ \let\mainfont\rmfamily\relax % backwards compatibility
+ % The headfont, which descends from parent font:
+ \if@HeadFontSet\else % default if not user-set:
+ \SetHeadFont[Letters=SmallCaps,\parentfontfeatures,Scale=0.92]%
+ {\parentfontname}
+ \fi
+ \newfontfamily\headfont[\@headfontfeatures]{\@headfontname}
+ % The chapter font, descending from parent font:
+ \if@ChapterFontSet\else % if no user-set font, default:
+ \SetChapterFont[\parentfontfeatures,Scale=1.6]{\parentfontname}
+ \fi
+ \newfontfamily\chapterfont[\@chapterfontfeatures]{\@chapterfontname}
+ % The subch font, descending from parent font:
+ \if@SubchFontSet\else % if no user-set font, default:
+ \SetSubchFont[\parentfontfeatures,Scale=1.2]{\parentfontname}
+ \fi
+ \newfontfamily\subchfont[\@subchfontfeatures]{\@subchfontname}
+ % The remaining fonts are not descendants of parent font:
+ % The mono font:
+ \ifthenelse{\equal{\ttdefault}{lmtt}}{% over-ride:
+ \IfFontExistsTF{Libertinus Mono}{ % if available
+ \setmonofont[%
+ ItalicFont={},% Doesn't have these.
+ BoldFont={},%
+ BoldItalicFont={},%
+ ]{Libertinus Mono}
+ }{
+ \setmonofont{Latin Modern Mono}% backup
+ }
+ }{} % User \setmonofont, so leave alone.
+ % The sans font:
+ \ifthenelse{\equal{\sfdefault}{lmss}}{ % override:
+ \IfFontExistsTF{Libertinus Sans}{ % if available
+ \setsansfont{Libertinus Sans}
+ }{
+ \setsansfont{Latin Modern Sans}% backup
+ }
+ }{} % User \setsansfont, so leave alone.
+ % The decofont must be NovelDeco.otf or a user modification of that font:
+ \if@DecoFontSet\else
+ \IfFontExistsTF{NovelDeco.otf}{
+ \SetDecoFont{NovelDeco}
+ }{} % if not available, this will be detected below
+ \fi
+ % Decorative glyphs, only in this font. Should not be re-set by user.
+ \if@HasDecoFont % NovelDeco or a user-defined alternative was found:
+ \newfontface\@decoglyph[%
+ \@decofontfeatures,%
+ ]{\@decofontname}
+ \newfontface\@decoglypha[%
+ \@decofontfeatures,RawFeature=+ss01,%
+ ]{\@decofontname}
+ \newfontface\@decoglyphb[%
+ \@decofontfeatures,RawFeature=+ss02,%
+ ]{\@decofontname}
+ \newfontface\@decoglyphc[%
+ \@decofontfeatures,RawFeature=+ss03,%
+ ]{\@decofontname}
+ \fi% end \if@HasDecoFont
+ \if@HasDecoFont
+ \NewFontFace\decodropcapfont[RawFeature=+dcap]{\@decofontname}
+ \else
+ \NewFontFace\decodropcapfont[\parentfontfeatures,Numbers=Lining]%
+ {\parentfontname}
+ \fi
+ \if@HasDropCapFont\else
+ \SetDropCapFont{\decodropcapfont} % default
+ \fi
+ % This provides default microtype settings, allows the user to over-ride,
+ % and hopefully prevents the user from choosing inappropriate settings:
+ \let\microtypesetup\relax % fake command no longer needed
+ \if@MicrotypeSet % true if user wrote \microtypesetup{} in Preamble
+ \IfSubStr{\@mymicrotypesetup}{config}{% user specified own config file
+ \gdef\@mymicrotypeset{\@mymicrotypesetup}
+ }{ % default to novel's config file
+ \gdef\@mymicrotypeset{%
+ config=novel-microtype,final,\@mymicrotypesetup}
+ }
+ \else % user did not write \microtypesetup{} in Preamble
+ \gdef\@mymicrotypeset{%
+ config=novel-microtype,final,stretch=20,shrink=20}
+ \fi
+ \if@mtoff
+ \providecommand\textls[2][]{##2} % echoes its mandatory argument
+ \else
+ \RequirePackage[\@mymicrotypeset]{microtype}
+ \renewcommand\textls[2][]{##2} % nullifies the microtype command (problems)
+ \fi
+ % end microtypesetup
+%
+} % end \@ActivateFonts, called by `novel.cls' \AtEndPreamble.
+%%
+
+
+%%
+\endinput
+%%
+%% End of file `novel-Fonts.sty'
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-Footnotes.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Footnotes.sty
new file mode 100644
index 0000000000..5465b0b70b
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Footnotes.sty
@@ -0,0 +1,431 @@
+%%
+%% This is file `novel-Footnotes.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Footnotes.sty}%
+[2023/02/08 v1.80 LaTeX file (commands for footnotes and endnotes)]
+%%
+
+
+
+%% Markers (superscript, subscripts):
+\newtoggle{@usesymbolmark} % true when footnote markers are symbolic
+\newtoggle{@realmarker} % true when OT features sups, sinf, subs requested
+%
+
+
+%% superscripts and subscripts
+\let\subs\relax
+\let\sups\relax
+\let\textsuperscript\relax
+\let\textsubscript\relax
+% Perhaps superscripts and subscripts (scientific) are in the font, or not.
+% Problem: The best fonts have these characters at size/weight designed
+% to mingle with normal size. But many fonts merely scaled characters,
+% which will be too light at the small size.
+% The unstarred version of these commands use the Open Type features when
+% they are present, then faking (auto scale/raise) if features not present.
+% The starred version just fakes, without regard for features.
+%
+
+% Note that the effect of these commands continues, not just one-shot:
+\gdef\realmarker{\global\toggletrue{@realmarker}} % anywhere in text
+\gdef\fakemarker{\global\togglefalse{@realmarker}} % anywhere in text
+\newlength\@hoAhl % height of Ahl, locally measured and set when needed
+%%
+\ExplSyntaxOn
+%
+\DeclareDocumentCommand \sups { m } {%
+ \iftoggle{@realmarker}{%
+ \fontspec_if_feature:nTF {sups}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=Superior}\smash{#1}}%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi\charscale[0.7,0pt,0.5\@hoAhl]{#1}%
+ }%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{Numbers=Lining}\charscale[0.7,0pt,0.5\@hoAhl]{#1}}%
+ }%
+}% end \sups
+%
+\DeclareDocumentCommand \subs { m } {%
+ \iftoggle{@realmarker}{%
+ \fontspec_if_feature:nTF {sinf}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=ScientificInferior}\smash{#1}}%
+ }{%
+ \fontspec_if_feature:nTF {subs}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=Inferior}\smash{#1}}%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi\charscale[0.7,0pt,-0.2\@hoAhl]{#1}%
+ }%
+ }%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{Numbers=Lining}\charscale[0.7,0pt,-0.2\@hoAhl]{#1}}%
+ }%
+}% end \subs
+%
+\cs_new_eq:NN \textsuperscript \sups
+\cs_new_eq:NN \textsubscript \subs
+\ExplSyntaxOff
+%%
+
+
+
+% \SetMarkerStyle does two things.
+% Option real: OT features sups, sinf, subs requested. Fake if not available.
+% Option fake: Always fake OT features sups, sinf, subs.
+% Mandatory: asterisk, dagger, number. Pertains to footnote markers only.
+% No matter real or fake, the asterisk symbol is always real, and the
+% dagger, dbldagger, and section (when used as footnote markers)
+% are always partially faked.
+\newcommand\SetMarkerStyle[2][real]{
+ \def\@goodfnm{no}
+ \ifthenelse{\equal{#2}{asterisk}}{%
+ \def\@goodfnm{yes}\global\toggletrue{@usesymbolmark}%
+ \gdef\@myfnsymbols{*}}{}
+ \ifthenelse{\equal{#2}{dagger}}{%
+ \def\@goodfnm{yes}\global\toggletrue{@usesymbolmark}%
+ \gdef\@myfnsymbols{†}}{}
+ \ifthenelse{\equal{#2}{number}}{%
+ \def\@goodfnm{yes}\global\togglefalse{@usesymbolmark}}{}
+ \def\@goodfnk{no}
+ \ifthenelse{\equal{#1}{real}\OR\equal{#1}{}}{%
+ \def\@goodfnk{yes}\global\toggletrue{@realmarker}}{}
+ \ifthenelse{\equal{#1}{fake}}{%
+ \def\@goodfnk{yes}\global\togglefalse{@realmarker}}{}
+ \ifthenelse{\equal{\@goodfnm}{no}\OR\equal{\@goodfnk}{no}}{%
+ \ClassError{novel}{Bad choice for \string\SetMarkers}%
+ {Optional: real, fake. Required: asterisk, dagger, number.}%
+ }{}
+}
+\LetLtxMacro{\SetMarkers}{\SetMarkerStyle} % backward compatibilty pre-v1.40.3.
+%
+\SetMarkerStyle[real]{asterisk} % default
+%%
+
+
+
+%% FOOTNOTES
+%% ----------------------------------------------------------------------------
+% In `novel' class, you may place footnotes at the botom of the textblock.
+% The markers may be symbolic (default begins with asterisk), or
+% set so that the asterisk is not used, or the markers may be numbers,
+% If symbolic, they will be automatically reset by ChapterStart.
+% You can manually reset them at any time.
+% You can also make a non-marked footnote, which does not increment the count.
+
+
+% Lengths used to tweak vertical position of symbolic (text) footnote markers:
+\newlength\@twast % tweaks asterisk
+\newlength\@twdag % tweaks dagger
+\newlength\@twdbldag % tweaks double dagger
+\newlength\@twsect % tweaks section mark
+\newlength\@tweight % tweaks 8, reliably the tallest digit
+
+
+%% footnotesize is calculated by layout, based on normal font size and skip.
+%% It is used only for actual footnotes!
+
+%
+\newcounter{@fnsymbolcount} % counter, footenote symbolic markers
+ \setcounter{@fnsymbolcount}{1}
+\newcounter{@fnnumbercount} % counter, footnote numerical markers
+ \setcounter{@fnnumbercount}{1}
+\newcounter{@rnnumbercount} % counter, endnote markers (always numerical)
+ \setcounter{@rnnumbercount}{1}
+\newcounter{@maxfnsymbol} % max footnote symbol count before recycle
+%
+\gdef\ResetFootnote{% symbols or numbers
+ \setcounter{@fnsymbolcount}{1}%
+ \setcounter{@fnnumbercount}{1}%
+}
+\gdef\ResetFootnoteSymbol{\setcounter{@fnsymbolcount}{1}} % only symbols
+\gdef\Resetendnote{\setcounter{@rnnumbercount}{1}}
+%
+\newtoggle{@usenomark} % when true: no mark, no increment count
+\newtoggle{@placedfootnotenumber} % true if any numerical footnote placed
+%
+\let\@myoldfootnote\footnote\relax % copies the original definition
+\let\footnote\relax % so it can be re-defined, below
+%
+\gdef\@fourem{% length of rule separating footnotes from main text
+ \vspace{-\nbs}%
+ \noindent\strut\smash{\rule[-2pt]{0.33\textwidth}{0.05\@SetFontSize}}%
+}
+\let\footnoterule\@fourem
+%
+
+
+% \@makefnmark applies to the footnote marker in the flow of main text:
+\gdef\@makefnmark{\iftoggle{@usenomark}{}{\@getfnmark}}
+%
+\long\gdef\@makefntext#1{% the actual footnote, at bottom of textblock
+ \iftoggle{@usenomark}%
+ {\forceindent#1}%
+ {\forceindent\@getbotfnmark\,#1}%
+} % end \@makefntext
+% Now re-define \footnote:
+\newcommand\footnote[2][]{%
+ \ifthenelse{\equal{#1}{0}}{%
+ \global\toggletrue{@usenomark}%
+ }{%
+ \global\togglefalse{@usenomark}%
+ }%
+ \gdef\footnoterule{\vfill\@fourem}%
+ \begingroup%
+ \def\footnotesize{% Not gdef. Local to footnote. Calculated during layout.
+ \@setfontsize\footnotesize{\@myfootnotesizeN pt}{\@myfootnoteskipN pt}%
+ }%
+ \unskip\@myoldfootnote{#2}%
+ \endgroup%
+} % end \footnote
+%
+% \@rollfnsymbol prevents running out of symbolic markers:
+\gdef\@rollfnsymbol{%
+ \stepcounter{@fnsymbolcount}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{\value{@maxfnsymbol}}}{%
+ \setcounter{@fnsymbolcount}{1}%
+ }{}%
+} % end \@rollfnsymbol
+%
+% \@getfnmark places a footnote marker in the running text.
+% The marker depends upon whether it should be a number or a symbol.
+% If the latter, then it depends on whether the symbols include asterisks.
+% And, it depends upon the current count for that type of marker.
+\gdef\@getfnmark{%
+ \iftoggle{@usesymbolmark}%
+ {%
+ \global\togglefalse{@placedfootnotenumber}%
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{%
+ \charscale[1,0pt,-\@twast]{*}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{%
+ \charscale[0.8,0pt,-\@twdag]{†}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{%
+ \charscale[0.8,0pt,-\@twsect]{§}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{%
+ \charscale[1,0pt,-\@twast]{**}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{%
+ \charscale[0.8,0pt,-\@twdag]{††}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{7}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{8}}{%
+ \charscale[0.8,0pt,-\@twsect]{§§}%
+ }{}%
+ }{}%
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{%
+ \charscale[0.8,0pt,-\@twdag]{†}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{%
+ \charscale[0.8,0pt,-\@twsect]{§}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{%
+ \charscale[0.8,0pt,-\@twdag]{††}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{%
+ \charscale[0.8,0pt,-\@twsect]{§§}%
+ }{}%
+ }{}%
+ }{%
+ \global\toggletrue{@placedfootnotenumber}%
+ \sups{\arabic{@fnnumbercount}}%
+ }%
+} % end \@getfnmark
+%
+% \@getbotfnmark places the marker in front of the actual footnote,
+% towards the bottom of the textblock. It duplicates the marker used in
+% running text, but is not elevated. Then, it increments the relevant count.
+% Note that (unlike some other TeX document classes) this marker is at
+% the indent, so that the footnote text is farther inward than the indent.
+% This is the preferred style.
+\gdef\@getbotfnmark{%
+ \iftoggle{@usesymbolmark}%
+ {%
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{*}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{†}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{§}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{**}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{††}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{7}}{‡‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{8}}{§§}{}%
+ }{}%
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{†}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{§}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{††}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{‡‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{§§}{}%
+ }{}%
+ \@rollfnsymbol%
+ }{%
+ \textrm{\arabic{@fnnumbercount}.}%
+ \stepcounter{@fnnumbercount}%
+ }%
+} %end \@getbotfnmark
+%
+%% end footnotes
+
+
+
+%% ENDNOTES
+%% ----------------------------------------------------------------------------
+% \endnote only places a marker. It does not store a note for later use.
+% Any argument is non-printing. So \endnote{ancestry of yada} does not print
+% anything other than the endnote marker number, and does not save
+% `ancestry of Yada' for later use. The argument is a self-memo, so that you
+% remember why you want an endnote there, when you look at the source.
+% Following \endnote or \endnotetext with [ will produce an error.
+% Reason: Confuses novel's commands with those from banned `endnote' package.
+% Whenever \endnote is used, the marker number and page is added to a list,
+% and the list is typed into the log file after the document ends. That way,
+% you can hunt down where the endnotes markers were placed.
+\newtoggle{@gotendnotes} % true if \endnote used
+%
+\long\gdef\@endnotelist{}
+\newcounter{@endnotecount}
+%
+\def\@addendnote{%
+ \global\toggletrue{@gotendnotes}%
+ \stepcounter{@endnotecount}\sups{\arabic{@endnotecount}}%
+ \long\edef\@endnotelist{%
+ \@endnotelist\space (\arabic{@endnotecount},p.\thepage)%
+ }%
+}
+\def\@nendnote#1{\@addendnote}
+\def\@nenspace{\@addendnote\space}
+\def\@nenerror{%
+ \ClassError{novel}{\string\endnote\space cannot be followed by [ character}%
+ {To avoid possible confusion with similar command from other packages, ^^J%
+ you may not follow \string\endnote\space with [ character. ^^J%
+ However, you may do \string\endnote\string{\string}[ if desired.}%
+}
+\def\@ndospace{\@ifnextchar[\@nenerror\@nenspace}
+\def\endnote{\@ifnextchar\bgroup\@nendnote\@ndospace}
+%%
+% \endnotetext{ID}{text} where ID is (usually) the endnote number.
+% If ID is other than space or tilde, it prints at left margin, followed by
+% period. Then the entire text is block-indented. Only one paragraph allowed.
+% If ID is space or empty, then the entire text is block-indented. This is
+% the method for continuing a prior endnote to a new paragraph. The text
+% may begin with \forceindent, according to your needs.
+\def\@nentexterror{%
+ \ClassError{novel}{\string\endnotetext\space cannot be followed by [ character}%
+ {To avoid possible confusion with similar command from other packages, ^^J%
+ you may not follow \string\endnotetext\space with [ character. ^^J%
+ This command takes two mandatory arguments. No optional argument.}%
+}
+%
+\newcommand\nentext[2]{%
+ \ifthenelse{\equal{#1}{\space}\OR\equal{#1}{}}%
+ {\noindent\hangindent=\parindent\flexbox{\space}#2\par}%
+ {\noindent\hangindent=\parindent\flexbox{\lnum{#1}. }#2\par}%
+}
+% In case the user inadvertently uses systax from `endnotes' package:
+\def\endnotetext{\@ifnextchar[\@nentexterror\nentext}
+%
+%% end endnotes
+
+
+%% See novel.cls for the accompanying \AtBeginDocument routine.
+
+
+%% Pertains to some standard LaTeX footnote code:
+\AtBeginShipout{\gdef\@fnafter{}}
+%%
+
+
+\gdef\@ActivateFootnotes{% called by `novel.cls' \AtBeginDocument
+ % Pertains to novel-footnotes.sty:
+ \LetLtxMacro\SetMarkerStyle\relax
+ \gsetlength\footnotesep{0.8\nbs}
+ % Adjusted position of footnote markers. Must wait for main font size:
+ \gsetlength\@twast{\heightof{*}-\normalAringheight}
+ \gsetlength\@twdag{\heightof{†}}
+ \gsetlength\@twdag{0.8\@twdag-\normalAringheight}
+ \gsetlength\@twdbldag{\heightof{‡}}
+ \gsetlength\@twdbldag{0.8\@twdbldag-\normalAringheight}
+ \gsetlength\@twsect{\heightof{§}}
+ \gsetlength\@twsect{0.8\@twsect-\normalAringheight}
+ \gsetlength\@tweight{\heightof{8}}%
+ \gsetlength\@tweight{0.8\@tweight-\normalAringheight}%
+ % Must wait to see how \SetFootnoteMarker was used:
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{\setcounter{@maxfnsymbol}{8}}{}
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{\setcounter{@maxfnsymbol}{6}}{}
+ % Values to be used by footnotes:
+ \FPdiv{\@myFontScale}{\strip@pt\@SetFontSize}{12}
+ % Substitute for \footnotesize, but only works for actual footnotes,
+ % about 10pt with similarly reduced skip:
+ \FPmul{\@myfootnotesizeN}{\@myFontScale}{10}
+ \FPround{\@myfootnotesizeN}{\@myfootnotesizeN}{2}
+ \FPmul{\@myfootnoteskipN}{\@myFontScale}{\strip@pt\nbs}
+ \FPmul{\@myfootnoteskipN}{\@myfootnoteskipN}{0.84}
+ \FPround{\@myfootnoteskipN}{\@myfootnoteskipN}{2}
+}% end \@ActivateFootnotes
+
+
+
+
+
+
+%% ATENDDOCUMENT
+%% ----------------------------------------------------------------------------
+%% Write a list of endnote (number,page) into log file,
+% and Big Bad Warning if numerical footnotes and endnotes both used:
+\AtEndDocument{%
+ \iftoggle{@gotendnotes}{%
+ \typeout{^^JClass `novel' Alert: You placed endnotes (number,page): ^^J%
+ \@endnotelist ^^J}%
+ }{}
+ %
+ \iftoggle{@placedfootnotenumber}{%
+ \iftoggle{@gotendnotes}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! You used numbered footnotes ^^J%
+ and numbered endnotes. Better change to symbolic footnotes! ^^J}%
+ }{}
+ }{}%
+}% end \AtEndDocument
+%%
+
+
+%%
+\endinput
+%%
+%% end of file `novel-Footnotes.sty'
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-HeadFootStyles.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-HeadFootStyles.sty
new file mode 100644
index 0000000000..4e003edd15
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-HeadFootStyles.sty
@@ -0,0 +1,498 @@
+%%
+%% This is file `novel-HeadFootStyles.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-HeadFootStyles.sty}%
+[2023/02/08 v1.80 LaTeX file (header and footer layouts and styles)]
+%%
+
+
+
+%% File `novel-LayoutSettings.sty' reserved space for header/footer,
+%% but did not place anything there. In this file, `fancyhdr' syntax
+%% defines the layout. The layout are not activated until
+%% \AtEndPreamble, and only if the user did not already define the layout
+%% in the Preamble.
+
+\gdef\@HeadFootStyle{1} % default: header but not footer
+\gdef\@VersoEmblem{} % no default emblem
+\gdef\@RectoEmblem{} % no default emblem
+
+
+%% SET HEADER/FOOTER STYLE AND RESERVE SPACE FOR HEADER/FOOTER
+%% ----------------------------------------------------------------------------
+% There are several pre-configured header/footer styles, addressing every
+% situation likely to be seen in popular fiction. The style details are
+% coded, using `fancyhdr' syntax, in novel-HeadFootStyles.sty.
+% If you wish to create a custom head/foot style, you must first choose
+% one of the pre-configured styles, then customize it. That way,
+% the layout engine knows whether header or footer are present.
+\newif \if@StyledHeader % true if user-customized header using \fancyhead
+\newif \if@StyledFooter % true if user-customized footer using \fancyfoot
+%
+\gdef\SetHeadFootStyle#1{%
+ \if@coverart
+ \gdef\@HeadFootStyle{0} % required: no header/footer for coverart
+ \ifthenelse{\equal{#1}{0}}{}{%
+ \ClassWarning{novel}{^^JClass option `coverart' does not %
+ allow header/footer. Ignored. ^^J}
+ }%
+ \else
+ \@tempTFfalse
+ \ifthenelse{\equal{#1}{0}}{%
+ \global\@HasHeaderfalse\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{1}}{%
+ \global\@HasHeadertrue\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{2}}{%
+ \global\@HasHeaderfalse\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{3}}{%
+ \global\@HasHeaderfalse\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{4}}{%
+ \global\@HasHeadertrue\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{5}}{%
+ \global\@HasHeadertrue\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{6}}{%
+ \global\@HasHeadertrue\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ % Ensure that user choice was on the allowed list:
+ \if@tempTF\else
+ \ClassError{novel}{Invalid choice for \string\SetHeadFootStyle}%
+ {\string\SetHeadFootStyle\space needs choice of 0,1,2,3,4,5,6, ^^J%
+ even if you wish to customize using fancyhdr syntax.}%
+ \fi
+ \gdef\@HeadFootStyle{#1}
+ \fi
+}%
+\SetHeadFootStyle{1} % default, header only
+\let\SetHeadStyle\SetHeadFootStyle\relax % deprecated
+%
+% \HeadJump is a number from 1 to 3 (may be decimal). It measures the
+% distance from baseline of header text, to first baseline of main text,
+% then divides by the normal baseline.
+% So, a \HeadJump of 1 means that the header text is positioned exactly
+% one line above main text (unlikely). A value of 2 skips a whole line.
+% The default value is 1.5, which is often used in popular fiction.
+% No matter what value is set, it will be re-set to 0 later, if the
+% choice of head/foot style does not have a header.
+% Likewise for \FootJump, measuring from baseline of lowermost main text,
+% to baseline of footer text.
+\gdef\SetHeadJump#1{%
+ \IfDecimal{#1}{%
+ \FPiflt{#1}{1}
+ \ClassError{novel}{\string\SetHeadJump\space must be at least 1}%
+ {\string\SetHeadJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \FPifgt{#1}{3}
+ \ClassError{novel}{\string\SetHeadJump\space must not exceed 3}%
+ {\string\SetHeadJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \gdef\@HeadJump{#1}
+ }{%
+ \ClassError{novel}{Unable to parse \string\SetHeadJump\space argument}%
+ {Needs integer or decimal, but not ending in decimal point or comma. ^^J%
+ Must be a number from 1 to 3, but may not be a macro.}%
+ }%
+}
+\SetHeadJump{1.5} % default
+%
+\gdef\SetFootJump#1{%
+ \IfDecimal{#1}{%
+ \FPiflt{#1}{1}
+ \ClassError{novel}{\string\SetFootJump\space must be at least 1}%
+ {\string\SetFootJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \FPifgt{#1}{3}
+ \ClassError{novel}{\string\SetFootJump\space must not exceed 3}%
+ {\string\SetFootJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \gdef\@FootJump{#1}
+ }{%
+ \ClassError{novel}{Unable to parse \string\SetFootJump\space argument}%
+ {Needs integer or decimal, but not ending in decimal point or comma. ^^J%
+ Must be a number from 1 to 3, but may not be a macro.}%
+ }%
+}
+\SetFootJump{1.5} % default
+%
+%% end set style and reserve space for header/footer.
+
+
+%% Used in novel-headfootstyles.sty:
+% \SetLooseHead looseness factor (fontspec LetterSpace) 0=tight, 50=default
+\gdef\SetLooseHead#1{
+ \FPdiv{\@loosehead}{#1}{10} % change method fontspec w/ microtype
+ \FPmin{\@looseheadN}{\@loosehead}{50} % don't want numbers too loose
+ \FPdiv{\@looseheadword}{\@loosehead}{30} %
+ \FPadd{\@looseheadword}{\@looseheadword}{1} %
+}
+\SetLooseHead{50}
+%%
+
+%
+% See docs for what these emblems do, if used:
+\newcommand\SetEmblems[2]{ % verso, recto
+ \gdef\@VersoEmblem{{\headfont #1}}
+ \gdef\@RectoEmblem{{\headfont #2}}
+}
+\let\SetEmblem\SetEmblems% for convenience
+% If you want something fancier than \thepage:
+\gdef\SetPageNumberStyle#1{% no small caps, so lowercase roman preserved
+ \gdef\pagenumberstyle{{\addfontfeature{Letters=ResetAll}#1}}
+}
+\SetPageNumberStyle{\thepage}% no small caps
+% See novel.cls for the accompanying AtBeginDocument routine.
+
+
+%% INITIALIZE FANCYHDR
+%% ----------------------------------------------------------------------------
+% Earlier, space was reserved for header/footer, but the content of
+% headers and footers was not specified. Now, package `fancyhdr'
+% will be used to create the content.
+% Start by loading package `fancyhdr' and blanking everything:
+\RequirePackage{fancyhdr}
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO,CE,CO]{}
+% It might be useful to know whether something is being placed in main text,
+% or within a header/footer. A new boolean is created, which is only true
+% when within a header or footer. You can define macros so that they test
+% this boolean.
+% To make this work, \fancyhead and \fancyfoot are re-defined:
+\newtoggle{@inheadfoot} % true within header or footer
+\LetLtxMacro{\@myfancyhead}{\fancyhead}
+\LetLtxMacro{\@myfancyfoot}{\fancyfoot}
+\renewcommand\fancyhead[2][]{%
+ \global\@StyledHeadertrue%
+ \@myfancyhead[#1]{\toggletrue{@inheadfoot}{\normalsize #2}}% not global
+}
+\renewcommand\fancyfoot[2][]{%
+ \global\@StyledFootertrue%
+ \FPsub{\@footraise}{\@FootJump}{1}%
+ \FPmul{\@footraise}{-\@footraise}{\strip@pt\nbs}%
+ \@myfancyfoot[#1]{%
+ \toggletrue{@inheadfoot}% not global
+ \stake\smash{\raisebox{\@footraise pt}{\normalsize #2}}%
+ }%
+}
+%% end initialize fancyhdr.
+
+
+%% THISPAGESTYLE COMMANDS
+%% ----------------------------------------------------------------------------
+% Re-define \thispagestyle based on layout. When it requests only the page
+% number, decide what to do based on this command and whether footer is used:
+\newif \if@ThisPageStyle % true if \thispagestyle declared for current page
+\newif \if@DeleteCSline % true when using @dropfolioinside
+\AtBeginShipout{% re-sets when page done
+ \global\@DeleteCSlinefalse%
+ \global\@ThisPageStylefalse%
+}
+\LetLtxMacro{\@myTempTPS}{\thispagestyle}
+%
+\gdef\thispagestyle#1{%
+ \global\@ThisPageStyletrue%
+ \@tempTFfalse%
+ % Style `fancy' is same as normal style:
+ \ifthenelse{\equal{#1}{fancy}}{%
+ \@tempTFtrue%
+ \@myTempTPS{fancy}%
+ }{}%
+ % Style `empty' has no visible content in header or footer.
+ % This style is pre-defined, so no need to re-define it here.
+ \ifthenelse{\equal{#1}{empty}}{%
+ \@tempTFtrue%
+ \@myTempTPS{empty}%
+ }{}%
+ % Style `footer' has no visible content in header.
+ % If the normal style has a footer, it will be used as-is. However, if the
+ % normal style does not have a footer, then (unlike the above style)
+ % the page number will not be placed at bottom; as with style `empty'.
+ \ifthenelse{\equal{#1}{footer}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else\@myTempTPS{empty}%
+ \fi%
+ }{}%
+ % Style `forcenumber' is rarely used. If the normal style has a footer,
+ % it will be used as-is (presumably contains the page number), and there
+ % will be no visible content in the header.
+ % But if there is no normal footer, then the outside portion of the header
+ % is printed. No other portion of the header. Presumably the page number
+ % is located at the outside of the header.
+ \ifthenelse{\equal{#1}{forcenumber}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else\@myTempTPS{@forcenumber}%
+ \fi%
+ }{}%
+ % Style `dropfoliobeneath': There will be no visible content in header.
+ % If the normal style has a footer, it will be used as-is. This assumes
+ % that the page number is contained in the footer, the usual case.
+ % If the normal style has no footer, then the page number will be centered
+ % within the lower margin, at the position where an exta line would be.
+ % Thus, pagination of the main text is unaffected.
+ % Since the number is closer than usual to the page bottom edge, you must
+ % ensure that it does not intrude into the unsafe zone (where printers
+ % prohibit any printable matter). TeX cannot check this for you. However,
+ % you can define an Unsafe Zone, and inspect placement of the number
+ % in draft mode.
+ % Styles `plain*' and `fancyplain*' (with asterisk) are aliases.
+ \ifthenelse{\equal{#1}{dropfoliobeneath}%
+ \OR \equal{#1}{plain*} \OR \equal{#1}{fancyplain*}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else%
+ \@myTempTPS{@dropfoliobeneath}%
+ \typeout{^^JClass `novel' Alert: Page no. \thepage\space in margin. ^^J%
+ Review layout to ensure that this is within the Safe Area. ^^J%
+ }%
+ \fi%
+ }{}%
+ % Style `dropfolioinside': There will be no visible content in header.
+ % If the normal style has a footer, it will be used as-is. This assumes
+ % that the page number is contained in the footer, the usual case.
+ % If the normal style has not footer, then the page number will be centered
+ % where the last line of main text would ordinarily be. No extra gap.
+ % That may cause the (former) last line of main text to flow to the top of
+ % the next page, and so forth. However, if this page style is used on
+ % a page with ChapterStart, then the height of ChapterStart will be
+ % automatically reduced by one line, so that there is no repagination.
+ % Styles `plain', `fancyplain', `dropfolio', and `dropfoliolater' are aliases
+ % for `dropfolioinside'. I couldn't make up my mind regarding the
+ % command name. For compatibility, all these do the same thing.
+ \ifthenelse{\equal{#1}{dropfolioinside}%
+ \OR \equal{#1}{plain} \OR \equal{#1}{fancyplain}%
+ \OR \equal{#1}{dropfolio} \OR \equal{#1}{dropfoliolater}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else%
+ \global\@DeleteCSlinetrue%
+ \enlargethispage{-\nbs}%
+ \@myTempTPS{@dropfolioinside}%
+ \fi%
+ }{}%
+ % Verify that an allowable choice was made:
+ \if@tempTF\else%
+ \ClassError{novel}{^^JPage \thepage\space has \string\thispagestyle ^^J%
+ but its argument is not on the list of choices. See docs. ^^J}%
+ \fi%
+} % end \thispagestyle.
+%
+\let\dropfolionow\relax % compatibility with earlier version.
+%
+% Here are the thispagestyle definitions:
+\fancypagestyle{@footer}{ % blanks header, but leaves footer as-is
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+}
+\fancypagestyle{@dropfolioinside}{ % page number where last line would be
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO]{}
+ \fancyfoot[CO,CE]{%
+ \raisebox{\dimexpr\@FootJump\nbs}{\@lspagenum\pagenumberstyle}%
+ }
+}
+\fancypagestyle{@dropfoliobeneath}{ % page number in margin below text
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO]{}
+ \fancyfoot[CO,CE]{%
+ \raisebox{\dimexpr\@FootJump\nbs-\nbs}{\@lspagenum\pagenumberstyle}%
+ }
+}
+\fancypagestyle{@forcenumber}{ % if has header but not footer
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyfoot[LO,RE,LE,RO,CE,CO]{}
+}
+%% end \thispagestyle commands.
+
+
+%%
+\gdef\@lshftext{\headfont\addfontfeature{LetterSpace=\@loosehead}}
+\gdef\@lspagenum{\headfont\addfontfeature{LetterSpace=\@looseheadN}}
+%%
+
+% Content of header text (if present) can be changed at any time within
+% the body, using the following commands. If not used, then
+% Verso is initialized to \theauthor and Recto is initialized to \thetitle
+% AtBeginDocument, with adjustments to interword spacing.
+% If you wish, you may write the commands with empty arguments, in which case
+% the header still appears with page number (if present), but no text.
+%
+\gdef\NewVersoHeadText#1{\gdef\versoheadtext{#1}}
+\let\SetVersoHeadText\NewVersoHeadText\relax % for convenience
+\let\RenewVersoHeadText\NewVersoHeadText\relax % for convenience
+%
+\gdef\NewRectoHeadText#1{\gdef\rectoheadtext{#1}}
+\LetLtxMacro\SetRectoHeadText\NewRectoHeadText\relax % for convenience
+\LetLtxMacro\RenewRectoHeadText\NewRectoHeadText\relax % for convenience
+%
+%%
+
+
+%% See AtBeginDocument routine in novel.cls:
+%% ----------------------------------------------------------------------------
+\gdef\@ActivateHeadFootStyles{ % called AtBeginDocument by novel.cls
+ % Pre-configured header/footer styles, unless user over-rode them:
+ % \versoheadtext is initialized to \theauthor
+ % \rectoheadtext is initialized to \thetitle
+ \@ifundefined{versoheadtext}{
+ \NewVersoHeadText{\theauthor}
+ }{}
+ \@ifundefined{rectoheadtext}{
+ \NewRectoHeadText{\thetitle}
+ }{}
+ %
+ % ---------------------------------------------------------------------------
+ % IF YOU ARE WRITING YOUR OWN HEADER/FOOTER LAYOUT:
+ % Look here for the pre-defined layouts, for use as models.
+ % Note that if you write \fancyhead or \fancyfoot in the Preamble,
+ % that sets the \@StyledHeader flag, so these codes do not over-ride yours.
+ % \@lshftext loosens text tracking.
+ % \@lspagenum loosens page number tracking, like \@lshftext but capped
+ % at a maximum looseness.
+ \ifthenelse{\equal{\@HeadFootStyle}{1}}{ % default
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyhead[CE]{\@lshftext\versoheadtext}
+ \fancyhead[CO]{\@lshftext\rectoheadtext}
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{2}}{
+ \global\@StyledHeaderfalse
+ \if@StyledFooter\else
+ \fancyfoot[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyfoot[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{3}}{
+ \if@StyledFooter\else
+ \fancyfoot[CO,CE]{\@lspagenum\pagenumberstyle}
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{4}}{
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ \hspace{1em}%
+ {\@lshftext\versoheadtext}%
+ }
+ \fancyhead[RO]{%
+ {\@lshftext\rectoheadtext}%
+ \hspace{1em}%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{5}}{
+ \if@StyledHeader\else
+ \fancyhead[CE]{\@lshftext\versoheadtext}
+ \fancyhead[CO]{\@lshftext\rectoheadtext}
+ \fi
+ \if@StyledFooter\else
+ \fancyfoot[CO,CE]{%
+ {\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{6}}{
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyhead[RE]{\@lshftext\versoheadtext}
+ \fancyhead[LO]{\@lshftext\rectoheadtext}
+ \fi
+ }{}
+ % END MODELS FOR WRITING YOUR OWN.
+ %
+ % END PRE-DEFINED LAYOUTS AND STYLES.
+ % ---------------------------------------------------------------------------
+ %
+ % Now put `fancyhdr' to work:
+ \pagestyle{fancy} % default unless over-ridden by \thispagestyle{}
+ %
+} % end \@ActivateHeadFootStyles
+%
+%%
+
+
+%% Neutralize settings that cannot be used after Preamble:
+\gdef\@DisableHeadFootSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetHeadFootStyle\relax
+ \LetLtxMacro\SetHeadStyle\relax
+ \LetLtxMacro\SetHeadJump\relax
+ \LetLtxMacro\SetFootJump\relax
+ \LetLtxMacro\SetLooseHead\relax
+}% end \@DisableHeadFootSettings
+%%
+
+% The following settings can continue to be re-issued after \begin{document}:
+% \SetEmblems also \SetEmblem
+% \SetPageNumberStyle
+% \SetVersoHeadText also \New and \Renew
+% \SetRectoHeadText also \New and \Renew
+
+
+%%
+\endinput
+%%
+%% End of file `novel-HeadFootStyles.sty'
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-Images.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Images.sty
new file mode 100644
index 0000000000..206f130565
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Images.sty
@@ -0,0 +1,565 @@
+%%
+%% This is file `novel-Images.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Images.sty}%
+[2023/02/08 v1.80 LaTeX file (image placement)]
+%%
+
+
+%% In `novel', images are handled with a view to preserving uniform line grid.
+%% Normally, a work of fiction has no (or very few) images within the main
+%% body of text. Images are more likely on display pages (such as title page)
+%% or in chapter starts, or maps.
+
+%% There are two ways to place an image: inline, or float.
+%% Inline image does not occupy its own block, but mingles with flowing text.
+%% Float image occupies its own block, which will be placed where the command
+%% is written, if it fits on that page. If it doesn't fit, then it will be
+%% placed at the top of the following page. Surrounding text will be
+%% typeset so at to not leave a big gap. Althouth TeX allows several
+%% options for positioning a float, `novel' only allows one method.
+
+%% Be sure to read the separate documentation about how to prepare images.
+%% In general: (1) png or jpg only. (2) Flattened, no transparency.
+%% (3) 300dpi (grayscale) or 600dpi (black/white) are industry norms.
+%% (4) Image file must contain its resolution. (5) Exact size, without scaling.
+%% (6) No private metadata. (7) Be sure grayscale is 1-channel, not rgb gray.
+
+
+%% Luacode and related macro thanks to user Marcel Krüger,
+%% at tex.stackexchange.com.
+\RequirePackage{luacode}
+\begin{luacode*}
+ function check_colorspaces(allowed_colorspace, name)
+ local doc = epdf.open(name);
+ if doc == nil then
+ tex.sprint(luatexbase.catcodetables['latex-package'],
+ "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
+ return;
+ else
+ for pageno=1,doc:getNumPages() do
+ local xobjs= doc:getCatalog():getPage(pageno):getResourceDict():lookup("XObject");
+ if not xobjs:isNull() then
+ for i=1,xobjs:dictGetLength() do
+ xobjDict = xobjs:dictGetVal(i):streamGetDict()
+ if xobjDict:lookup('Subtype'):getName() == 'Image' then
+ if not allowed_colorspace[xobjDict:lookup('ColorSpace'):getName()] then
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
+ return
+ end
+ end
+ end
+ end
+ end
+ end
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
+ return;
+end
+\end{luacode*}
+%
+\newcommand\PDFHasDisallowedColorspaceTF[1]{%
+ \directlua{check_colorspaces({DeviceCMYK=true, DeviceGray=true},"\luaescapestring{#1}")}%
+}
+%%
+%%
+\begin{luacode*}
+ function utf16to8(u16str)
+ local result = ""
+ local i = 1
+ if #u16str % 2 == 1 then
+ print("ERROR")
+ return
+ end
+ while i < #u16str do
+ local high, low = u16str:byte(i, i + 1)
+ i = i + 2
+ local current = bit32.replace(low, high, 8, 8)
+ if bit32.band(high, 0xFC) == 0xD8 then
+ current = bit32.replace(0, current, 10, 10)
+ if i > #u16str then
+ print("ERROR")
+ return
+ end
+ high, low = u16str:byte(i, i + 1)
+ i = i + 2
+ current = bit32.replace(current, bit32.replace(low, high, 8, 8), 0, 10) + 0x10000
+ elseif bit32.band(high, 0xFC) == 0xDC then
+ print("ERROR")
+ return
+ end
+ result = result .. unicode.utf8.char(current)
+ end
+ return result
+ end
+ function normalize_string(str)
+ if str:sub(1,2) == "\xFE\xFF" then
+ return utf16to8(str:sub(3,-3))
+ else
+ return str
+ end
+ end
+ function check_pdf_info(name, field, expected)
+ local doc = epdf.open(name);
+ if doc == nil then
+ tex.sprint(luatexbase.catcodetables['latex-package'],
+ "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
+ else
+ local producer = doc:getDocInfo():dictLookup(field)
+ if not producer:isNull() and normalize_string(producer:getString()) == expected then
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
+ else
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
+ end
+ end
+ end
+\end{luacode*}
+\newcommand\PDFVerifyInfoFieldTF[3]{\directlua{check_pdf_info("\luaescapestring{#1}", "\luaescapestring{#2}", "\luaescapestring{#3}")}}
+%%
+
+
+%%
+\LetLtxMacro\@scriptincludepdf\includepdf\relax
+\providecommand\includepdf[2][]{}
+\renewcommand\includepdf[2][]{% from package `pdfpages'
+ \ClassError{novel}{Cannot use \string\includepdf\space command}%
+ {You can use novel-scripts `makegray' and `makebw' to convert pdf %%J%
+ to a raster jpg or png, suitable for placement as an image.}%
+}
+\gdef\ScriptCoverImage#1{%
+ \if@coverart%
+ \PDFVerifyInfoFieldTF{#1}{NSprocessed}{true}%
+ {\@scriptincludepdf{#1}}%
+ {\ClassError{novel}{Book cover pdf must be pre-processed by novel-scripts}%
+ {Each pdf processed by novel-scripts is marked internally. ^^J%
+ Your cover artwork pdf is unmarked. Use `makecmykpdf' script.}%
+ }%
+ \else%
+ \ClassError{novel}{Cannot use \string\ScriptCoverImage\space in interior}%
+ {\string\ScriptCoverImage\space only with `coverart' class option.}%
+ \fi%
+} %
+%%
+
+
+% Pertains to images:
+\newlength\imagewidth
+\newlength\imageheight
+\newlength\imagehoffset
+\newlength\imagevoffset
+\newlength\@imagewidth
+\newlength\@imageheight
+\newlength\@imagehoffset
+\newlength\@imagevoffset
+\newlength\@mytotalht
+\newif \if@UsingNovelCommand % true within \InlineImage etc.
+%%
+\gdef\imagestarred{false}
+\gdef\imagefilename{unknown}
+\setkeys{Gin}{draft=false} % always shows the image, not a box outline
+\LetLtxMacro\novel@sub@inclgr\includegraphics\relax
+\if@coverart\else % Need to allow it, for possible use by \includepdf in cover.
+ \renewcommand\includegraphics[2][]{%
+ \ClassError{novel}{Direct use of \string\includegraphics\space forbidden}%
+ {You may only place images using commands specific to `novel' class. ^^J%
+ See `novel' documentation, section 7.}%
+ }
+\fi
+%
+\newcommand\@TestImageExtension[1]{%
+ \@tempTFfalse%
+ \IfEndWith{#1}{.png}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.PNG}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.jpg}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.JPG}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.jpeg}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.JPEG}{\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Image format `#1' not allowed, page \thepage}%
+ {Image `#1' has file type not allowed in `novel' class. ^^J%
+ Must have file extension png, jpg, jpeg (or capitalized). ^^J%
+ Others such as pdf, bmp, tiff, eps, svg, jp2, jbig, are not allowed. ^^J%
+ The file extension is mandatory. Provide it, if missing.}%
+ \fi%
+} %
+%%
+
+
+%% INLINE IMAGE
+%% ----------------------------------------------------------------------------
+% \InlineImage[xoffset,yoffset]{imagename.png} or jpg
+% As the name implies, an inline image is used within the flow of text, rather
+% than in its own block. It may be used in main body, header, and footer.
+% Macros such as \imagefilename, \imagewidth, etc.
+% are only set or re-set when the image in in the body. That prevents an
+% intervening header/footer image from over-writing values set by%
+% the most recent body image.
+% Without offsets, the image is positioned with is left edge at the cursor,
+% and its top edge at the text baseline. Positive offsets are right and up.
+% If improperly positioned, the image can overlie (obscure) text that was
+% previously placed. This is rarely desirable and may be flagged by
+% some print services, because it looks wrong.
+% The image will underlie anything that follows. This may be used as a
+% special effect, if allowed by the print service (probably OK).
+% With the un-starred command, the image occupies its natural cursor width.
+% With the starred command, the image occupies zero cursor width, so that
+% anything following will overlie it.
+\DeclareDocumentCommand \InlineImage { s O{0pt} m }{%
+ \@TestImageExtension{#3}%
+ \@tempTFfalse%
+ \if@pdfxSEToff%
+ \@tempTFtrue%
+ \else%
+ \IfSubStr*{\@UnknownImages}{#3}{\@tempTFtrue}{}%
+ \IfSubStr*{\@AllGoodImages}{#3}{\@tempTFtrue}{}%
+ \fi%
+ \if@tempTF\else\@NovelInspectImage{#3}\fi%
+ \StrDel{#2}{\space}[\@myila]%
+ \StrCut{\@myila}{,}{\@myilxa}{\@myilya}%
+ \ifthenelse{\equal{\@myilxa}{} \OR \equal{\@myilxa}{0}}{%
+ \def\@myilx{0pt}}{\def\@myilx{\@myilxa}%
+ }%
+ \ifthenelse{\equal{\@myilya}{} \OR \equal{\@myilya}{0}}{%
+ \def\@myily{0pt}}{\def\@myily{\@myilya}%
+ }%
+ \iftoggle{@inheadfoot}{}{\gdef\imagefilename{#3}}% for possible later use
+ \global\@UsingNovelCommandtrue%
+ \gdef\@mygraphic{\novel@sub@inclgr{#3}}%
+ \gdef\@mygraphicname{#3}%
+ \setlength\@imagewidth{\widthof{\@mygraphic}}%
+ \global\@imagewidth=\@imagewidth%
+ \iftoggle{@inheadfoot}{}{\setlength\imagewidth{\@imagewidth}}%
+ \setlength\@imageheight{\heightof{\@mygraphic}}%
+ \global\@imageheight=\@imageheight%
+ \iftoggle{@inheadfoot}{}{%
+ \setlength\imageheight{\@imageheight}%
+ \global\imageheight=\imageheight%
+ }%
+ %
+ \setlength\@imagehoffset{\@myilx}%
+ \IfBeginWith{\@myily}{b}{%
+ \StrDel[1]{\@myily}{b}[\temp@adjVoffseta]%
+ \ifthenelse{\equal{\temp@adjVoffseta}{} \OR \equal{\temp@adjVoffseta}{0}}{%
+ \def\temp@adjVoffset{0pt}}{\def\temp@adjVoffset{\temp@adjVoffseta}%
+ }%
+ \setlength\@imagevoffset{\temp@adjVoffset}%
+ }{%
+ \setlength\@imagevoffset{-\@imageheight}%
+ \addtolength\@imagevoffset{\@myily}%
+ }%
+ %
+ \IfBooleanTF{#1}%
+ % starred:
+ {%
+ \iftoggle{@inheadfoot}{}{\gdef\imagestarred{true}}%
+ \makebox[0pt][l]{%
+ \hspace{\@imagehoffset}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }%
+ }%
+ % unstarred:
+ {%
+ \iftoggle{@inheadfoot}{}{\gdef\imagestarred{false}}%
+ \hspace{\@imagehoffset}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }% end IfBooleanTF{#1}
+ \iftoggle{@inheadfoot}{}{\setlength\imagehoffset{\@imagehoffset}}%
+ \iftoggle{@inheadfoot}{}{\setlength\imagevoffset{\@imagevoffset}}%
+ \global\@UsingNovelCommandfalse%
+} %
+% end Inline Image
+%%
+
+
+%% FLOAT IMAGE (centered unless offset)
+%% ----------------------------------------------------------------------------
+% \FloatImage[floatmethod,xoffset,yoffset]{yourimagename.png} % or jpg
+% This is a substitute for other floats. Does not require `float' package.
+% Default: [ht,0pt,\nfs].
+% Method ht attempts to place the image where the code is written. But if it
+% doesn't fit on that page, it will float to the top of the next page.
+% Method b attempts to place the image on the bottom of the page where the
+% code is written. If not, it floats to the bottom of the next page.
+% Allowed float methods: ht hb t b. Equivalent to LaTeX floats with !.
+% Parsing the optional argument: comma-separated values, ignoring space.
+% May be empty before or between commas.
+% Example: [,,2em] is read as default method, xoffset 0pt, yoffset 2em.
+% Example: [b] is valid, because a single value is read as method.
+\providecommand*\floatlocation[2]{\@namedef{fps@#1}{#2}}
+\floatlocation{figure}{!ht} % default
+\gdef\ftype@figure{1} % mystery TeX code
+\DeclareDocumentCommand \FloatImage { s O{ht} m } {% starred not in use
+ \iftoggle{@inheadfoot}{%
+ \ClassError{novel}{Cannot use \string\FloatImage\space in header/footer}%
+ {Header footer allow \string\InlineImage, but not \string\FloatImage.}%
+ }{}%
+ \@TestImageExtension{#3}%
+ \@tempTFfalse%
+ \if@pdfxSEToff%
+ \@tempTFtrue%
+ \else%
+ \IfSubStr*{\@UnknownImages}{#3}{\@tempTFtrue}{}%
+ \IfSubStr*{\@AllGoodImages}{#3}{\@tempTFtrue}{}%
+ \fi%
+ \if@tempTF\else\@NovelInspectImage{#3}\fi%
+ % Sadly, parsing with `xstring' involves roundabout code:
+ \StrDel{#2}{\space}[\@tempArgs]%
+ \StrCut{\@tempArgs}{,}{\@tempArgA}{\@tempArgX}%
+ \StrCut{\@tempArgX}{,}{\@tempArgB}{\@tempArgC}%
+ \ifthenelse{\equal{\@tempArgA}{}}{%
+ \def\@tempArgAa{ht}%
+ }{%
+ \def\@tempArgAa{\@tempArgA}%
+ }%
+ \ifthenelse{\equal{\@tempArgB}{0}\OR\equal{\@tempArgB}{}}{%
+ \def\@tempArgBb{0pt}%
+ }{%
+ \def\@tempArgBb{\@tempArgB}%
+ }%
+ \ifthenelse{\equal{\@tempArgC}{0}\OR\equal{\@tempArgC}{}}{%
+ \def\@tempArgCc{0pt}%
+ }{%
+ \def\@tempArgCc{\@tempArgC}%
+ }%
+ \StrDel{\@tempArgAa}{!}[\@tempArgAa]%
+ \@tempTFfalse%
+ \ifthenelse{\equal{\@tempArgAa}{ht}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{hb}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{t}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{b}}{\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassWarning{novel}{Incorrect position for \string\FloatImage, ^^J%
+ page \thepage. Default position ht substituted.}%
+ \fi%
+ \floatlocation{figure}{!\@tempArgAa}% enable current float method
+ %\vfil% One l.
+ \@float{figure}%
+ \@FloatImage{\@tempArgBb}{\@tempArgCc}{#3}%
+ \end@float\par%
+ \floatlocation{figure}{!ht}% restore default float method
+ \null%
+ \vspace{0.01pt plus 0pt minus 0.02pt} % caulk
+} %
+%
+
+%% Environment @floatimagegap. Only used by \@FloatImage command.
+% Creates a gap at fixed height, regardless of content.
+% Needs to compensate for prior line depth.
+\newcounter{@gaplines} % passes the argument down to environment end
+\DeclareDocumentEnvironment {@floatimagegap} { m } {%
+ \par%
+ \null%
+ \vspace*{-\nbs}%
+ \begin{textblock*}{\textwidth}[0,0](0pt,0pt)%
+ \setcounter{@gaplines}{#1}%
+ \strut\par%
+ \vspace*{-\nbs}%
+}{% close the environment:
+ \end{textblock*}%
+ \par%
+ \vspace*{#1\nbs}%
+} %
+%%
+\DeclareDocumentCommand \@FloatImage { m m m }{% DO NOT CALL DIRECTLY
+ \global\@UsingNovelCommandtrue%
+ \gdef\@mygraphic{\novel@sub@inclgr[scale=\@TMratio]{#3}}%
+ \gdef\@mygraphicname{#3}%
+ \gsetlength\@imagewidth{\widthof{\@mygraphic}}%
+ \gsetlength\@imageheight{\heightof{\@mygraphic}}%
+ \setlength\@imagehoffset{#1}%
+ \setlength\@imagevoffset{#2-\@imageheight+\normalXheight}%
+ \setlength\@mytotalht{\@imageheight+0.3\nbs}%
+ \FPdiv{\@mytotalhtN}{\strip@pt\@mytotalht}{\strip@pt\nbs}%
+ \FPadd{\@mytotalhtN}{\@mytotalhtN}{0.5}% round upward
+ \FPround{\@mytotalhtN}{\@mytotalhtN}{0}% to integer
+ \FPmin{\@allowmyoverflow}{\@mytotalhtN}{\@LinesPerPage}% not exceeding lpp
+ % If a full-page image is too tall for a page, standard TeX float will
+ % delay it until the time that floats are cleared, typically by \clearpage.
+ % That would probably be at the end of a chapter.
+ % In `novel' this behavior is hacked. Regardless of the image's actual
+ % height, it is treated as if its height does not exceed whatever will
+ % fit on a single page. Then, a full-page float will appear at the first
+ % opportunity, rather than being delayed. As a consquence, an oversized
+ % full-page float may overflow into the footer or bottom margin.
+ % To fix that (if it matters), you need to edit the image in graphics.
+ \begin{@floatimagegap}{\@allowmyoverflow}%
+ \vspace*{-\nfs}%
+ \null%
+ {\centering%
+ \makebox[0pt][l]{%
+ \hspace{\dimexpr\@imagehoffset-0.5\@imagewidth}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }%
+ \par%
+ }%
+ \end{@floatimagegap}%
+ \global\@UsingNovelCommandfalse%
+} %
+% end Float Image
+%%
+
+
+%% WRAP IMAGE
+% This is a shim to `wrapfig' package. Since `novel' uses its own method for
+% placing images, environments defined in `wrapfig' cannot be used directly.
+% \WrapImage[position]{image} % default position r
+% Optional position is same as with `wrapfig':
+% l r o i places image "exactly here", left, right, outside, inside.
+% L R O I allows image to float.
+% Since novel's \InlineImage normally can be over-written by following text,
+% it needs an accompanying \rule to act as a strut.
+%
+\RequirePackage{wrapfig}
+%
+\DeclareDocumentCommand\WrapImage { O{r} m } {%
+ \begin{wrapfloat}{figure}{#1}{0pt}%
+ \InlineImage[0pt,\normalXheight]{#2}%
+ \rule[\dimexpr\normalXheight-\imageheight]{0pt}%
+ {\dimexpr\imageheight-\normalXheight+0.3\nfs}%
+ \end{wrapfloat}%
+}%
+\LetLtxMacro\wrapimage\WrapImage\relax
+% end Wrap Image.
+%%
+
+
+%% Read file bytes as plain text, for later parsing.
+% Output is comma-separated list of byte codes, decimal 0-255.
+% Returns -1 if requested start is more than file size.
+% Returns all bytes if requested number exceeds file size.
+% Does not test if file exists; error if not found.
+\DeclareDocumentCommand\novelgetbytes { m m m } {%
+ % filename, start byte number (0=beginning, e=up to end), number of bytes
+ \ifthenelse{\equal{#2}{e}}{% package xifthen
+ \long\edef\novelbytesare{%
+ \directlua{
+ inp = assert(io.open("#1", "rb"))
+ local e=inp:seek("end")
+ if #3>e+1 then
+ inp:seek("set")
+ local r=inp:read(e)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ else
+ local b=e-2-math.min(e,#3)
+ local w=1+math.min(e,#3)
+ inp:seek("set",b)
+ local r=inp:read(w)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ end
+ }%
+ }%
+ }{%
+ \long\edef\novelbytesare{%
+ \directlua{
+ inp = assert(io.open("#1", "rb"))
+ local e=inp:seek("end")
+ if #2>e then tex.sprint(-1) else
+ local w=math.min(#3,e-#2)
+ inp:seek("set",#2)
+ local r=inp:read(w)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ end
+ }%
+ }%
+ }%
+} % end @novelgetbytes
+
+%%
+% png bit depth is 8 for ordinary color or gray, 1 for b/w monochrome.
+% Although png allows more than 8, `novel' does not.
+\def\novelpngbitdepth#1{\novelgetbytes{#1}{24}{1}\novelbytesare}
+% png color type: 0=grayscale (incl. b/w).
+% `novel' only permits colortype 0 for non-color book interiors.
+% other: 2=rgb, 3=indexed rgb, 4=gray alpha, 6=rgb alpha.
+\def\novelpngcolortype#1{\novelgetbytes{#1}{25}{1}\novelbytesare}
+%%
+
+%%
+% Examine png or jpg image for novel-make as comment:
+% Known-good images, will not be inspected. Comma-separated list:
+\newcommand\SetKnownGoodImages[1]{
+ \gdef\@KnownGoodImages{#1}
+}
+\SetKnownGoodImages{} % default empty
+\gdef\@AllGoodImages{}
+\gdef\@UnknownImages{}
+%
+\gdef\@GatherGoodImages{% called \AtBeginDocument by `novel.cls'.
+ \let\SetKnownGoodImages\relax
+ \xdef\@AllGoodImages{\@KnownGoodImages\space \@AllGoodImages}
+ \if@pdfxSEToff
+ \xdef\@AllGoodImages{\@KnownGoodImages}
+ \xdef\@UnknownImages{}
+ \fi
+}
+% This is the (decimal) code string:
+\gdef\@novelmake{110,111,118,101,108,109,97,107,101}
+%
+\newcommand\@NovelInspectImage[1]{%
+ \StrRight{#1}{3}[\tempEXT]%
+ \ifthenelse{\equal{\tempEXT}{png} \OR \equal{\tempEXT}{PNG}}{%
+ \novelgetbytes{#1}{e}{256}%
+ }{% jpg or JPG:
+ \novelgetbytes{#1}{0}{256}%
+ }%
+ \IfSubStr{\novelbytesare}{\@novelmake}{%
+ \xdef\@AllGoodImages{\@AllGoodImages\space #1}%
+ }{%
+ \xdef\@UnknownImages{\@UnknownImages\space #1}%
+ }%
+}
+%%
+
+
+%% Called \AfterEndDocument by `novel.cls`:
+\long\gdef\@WarnUnknownImages{%
+ \@tempTFfalse%
+ \ifthenelse{\equal{\@UnknownImages}{}}{}{\@tempTFtrue}%
+ \if@pdfxSEToff\@tempTFfalse\fi%
+ \if@tempTF%
+ \typeout{^^JClass `novel' Alert: Some images not processed by scripts.^^J%
+ \space List of unprocessed images: \@UnknownImages ^^J%
+ \space Above list does not include any `known good' set by you. ^^J^^J}%
+ \ClassWarning{novel}{\@testintentional %
+ Some images may not meet PDF/X specifications. ^^J%
+ See near end of log file for `Some images not processed by scripts`. ^^J}%
+ \fi%
+}
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-Images.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-JC200103.clo b/macros/luatex/latex/novel/tex/lualatex/novel/novel-JC200103.clo
new file mode 100644
index 0000000000..7286dac7dc
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-JC200103.clo
@@ -0,0 +1,27 @@
+%%
+%% This is file `novel-JC200103.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+\ProvidesFile{novel-JC200103.clo}%
+[2023/02/08 any version. (novel Output Intent JC200103)]
+%%
+
+
+% Typically used in Japan.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+\gdef\@OIidentifier{JC200103} % also called "reference name"
+\gdef\@OIcondition{Japan Color 2001 Coated: Printing process definition: ISO 12647-2:2004, sheet-fed offset printing, positive plates, paper type 3 (coated, 105 gsm), screen frequency 69/cm.}
+\gdef\@OIinfo{Japan Color 2001 Coated}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{JapanColor2001Coated.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-JC200103.clo'
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-LayoutSettings.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-LayoutSettings.sty
new file mode 100644
index 0000000000..a9b2bb09e1
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-LayoutSettings.sty
@@ -0,0 +1,419 @@
+%%
+%% This is file `novel-LayoutSettings.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-LayoutSettings.sty}%
+[2023/02/08 v1.80 LaTeX file (layout settings)]
+%%
+
+
+%% Note that nearly all layout settings are pre-configured based on Trim Size.
+%% In general, these user commands may be used to over-ride the presets.
+
+
+
+%% SIZE-RELATED COMMANDS AVAILABLE IN PREAMBLE.
+%% ----------------------------------------------------------------------------
+%% Use if necessary for customization.
+%% If you like a class option that pre-sets these values,
+%% then you do not have to use any of these commands.
+%
+% Note: This class does not ask you to set the width/height of the textblock.
+% Instead, these values are automatically calculated from other dimensions.
+
+
+%% Trim Size is the finished width and height of the book (not thickness).
+% Books are (usually) manufactured to a small number of standard Trim Sizes.
+% The available choice of sizes will depend on your print service,
+% and may by limited by binding method, paper, or distribution channels.
+% These are NOT the usual TeX "paper size" choices, such as A4 or letterpaper.
+% In the U.S.A., 5.5in W x 8.5in H is very common for softcover fiction,
+% so it will (later) be set as default, unless you set your own.
+\newif \if@SetTrimSize % true if \SetTrimSize rather than defaults.
+\newlength\@TrimWidth
+\newlength\@TrimHeight
+\newcommand\SetTrimSize[2]{% width, height
+ \global\@SetTrimSizetrue
+ \gsetlength\@TrimWidth{#1}
+ \gsetlength\@TrimHeight{#2}
+}% end set trimsize
+%%
+
+
+%% Margins are measured from Trim Size inwards, always positive.
+% If the Media Size is larger than Trim Size, then the area beyond
+% the Trim Size is NOT margins. It is discarded scrap paper.
+% However, word processors (in general) do not understand the difference
+% between Trim Size and Media Size. So, if you are ever asked to
+% lay out the book in a word processor, using a standard (A4 or letter)
+% physical paper size, then you will be asked to set the "margins"
+% very wide, because the word processor margins include both
+% the finished book margins, and the discarded scrap paper.
+% In certain circumstances, text or images may intrude into the margin area.
+% This is not always an error, because it may be intentional.
+% Margins at top and bottom are relative to:
+% top of header, or top of textblock if no header;
+% bottom of footer, or bottom of textblock if no footer.
+% Inner margin generally greater than Outer, due to gutter.
+% Standard margins command ("TOBI, or not TOBI, that is the question."):
+\newif \if@SetMargins % true if \SetMargins rather than defaults.
+\newlength\@TopMargin
+\newlength\@OuterMargin
+\newlength\@BottomMargin
+\newlength\@InnerMargin
+\newcommand\SetMargins[4]{ % top, outer, bottom, inner
+ \global\@SetMarginstrue
+ \gsetlength\@TopMargin{#1}
+ \gsetlength\@OuterMargin{#2}
+ \gsetlength\@BottomMargin{#3}
+ \gsetlength\@InnerMargin{#4}
+}% end set margins
+\LetLtxMacro\SetMargin{\SetMargins}\relax % for those who mis-type
+%%
+
+
+%% Unsafe Zone (opposite of "safe area").
+% This feature only applies with class options `draft,shademargins'
+% and does NOT apply in `coverart'.
+% The purpose of margins is to confine the main text (and header/footer).
+% In `novel' (unlike most other TeX document classes) there is no provision
+% for marginal notes, because they are not used in popular fiction.
+% Yet there may be circumstances where you intentionally or accidentally
+% have text, or part of an image, placed or overflowing into a margin.
+% In PDF, even PDF/X, that is not a problem. It cannot read your mind.
+% However, every print service specifies a "safe area." All text, and
+% all images without bleed, must remain within the safe area.
+% The limits of the safe area are typically 0.125in to 0.5in inside the
+% Trim Size, depending on technology. This defines how close you may
+% place anything near the page edges.
+% In `novel' the opposite of the safe area is the "unsafe zone" (UZ).
+% So, the UZ lies just inside the perimeter of the Trim Size.
+% Each margin is at least as wide as its corresponding UZ.
+% Some print services use "minimum margin" to mean the UZ.
+% When you are in draft mode with `shademargins' class option,
+% the UZ (if it is set) will be displayed in dark gray.
+% Then, you can inspect the PDF for any intrusion into the UZ.
+% If you intrude into the UZ, there is no warning or error.
+% The UZ is strictly for visualization. There is no default setting.
+% If you do not set the UZ yourself, then no UZ will be displayed.
+% In any case, the final PDF is unaffected.
+\newif \if@UnsafeZone % true if \SetUnsafeZone used
+\newlength\@TopUZWidth
+\newlength\@OuterUZWidth
+\newlength\@BottomUZWidth
+\newlength\@InnerUZWidth
+\newcommand\SetUnsafeZone[4]{% top, outer, bottom, inner.
+ \global\@UnsafeZonetrue
+ \gsetlength\@TopUZWidth{#1}
+ \gsetlength\@OuterUZWidth{#2}
+ \gsetlength\@BottomUZWidth{#3}
+ \gsetlength\@InnerUZWidth{#4}
+} % end \SetUnsafeZone
+\LetLtxMacro\SetUnsafeZones{\SetUnsafeZone}\relax % for those who mis-type
+%%
+
+
+% PDF Media Size is already known to TeX as \paperwidth and \paperheight.
+% For this reason, there is no need to define additional lengths.
+% Sheet-fed printers use a small number of standard paper sizes.
+% Whether you use P.O.D. or print at home or office, your print job will
+% almost certainly be sheet-fed. After printing, the sheet is trimmed
+% to the specified Trim Size. Note that the sheet sizes used in
+% commercial printing are specialized for the purpose, and may be
+% different from the routine A4 and USletter sizes familiar to you.
+% In most cases (except for cover artwork), your PDF Media Size will be
+% exactly the same as the finished Trim Size. Placement of the Trim Size
+% onto a larger sheet of paper is done automatically at the print service,
+% a procedure known as "imposition." Several small Trim Sizes may be
+% printed onto a single sheet, in order to waste less paper in trimming.
+% In a few cases, the print service will ask you to provide a PDF that has
+% the Trim Size centered H/V within a larger Media Size.
+% Sometimes (especially for cover artwork), that's because you are
+% doing the imposition yourself. In other cases (especially for interiors)
+% it is because most of the files seen at the print service came from
+% word processors, where the writers (not knowing better) created layouts
+% on A4 or USletter with large "margins," rather than correct Trim Size.
+% Then, if you submit a file at actual Trim Size, it looks wrong,
+% not because it is wrong, but because it stands out from the crowd.
+% You may use \SetMediaSize to deal with this situation.
+% You do not need \SetMediaSize, if (as usual) it is identical to TrimSize.
+% Changing the Media Size does not affect Trim Size or internal page layout.
+% Class options `cropview' and `closecrop' (only in draft mode)
+% affect Media Size. See their descriptions below.
+%
+% \SetMediaSize{width}{height} usage:
+\newif \if@MediaSize % true if \SetMediaSize rather than default = Trim Size.
+\DeclareDocumentCommand\SetMediaSize { m m } {% width, height
+ \@MediaSizetrue
+ \gsetlength\paperwidth{#1}
+ \gsetlength\paperheight{#2}
+}% end \SetMediaSize
+%%
+
+
+%% Lines Per Page refers to the main textblock, not including header or footer.
+% If you do not set it, a suitable default will be based on other settings.
+% The number of lines is contrained by Trim Height, Margins, and normal em.
+% This is because the minimum \baselineskip must be 1.2x normal em size,
+% to avoid crowding of the text and variable line heights.
+% The check for constraint is done in file novel-CalculateLayout.sty.
+% The same check also verifies that the number is an integer >=10.
+\newif \if@LinesPerPage % true if \SetLinesPerPage rather than default.
+\newcommand\SetLinesPerPage[1]{
+ \IfInteger{#1}{}{%
+ \ClassError{novel}{\string\SetLinesPerPage\space must be integer >=10}%
+ {Do not write period, comma, or space within \string\SetLinesPerPage.}%
+ }
+ \FPiflt{#1}{10}
+ \ClassError{novel}{\string\SetLinesPerPage\ must be at least 10}%
+ {LinesPerPage were set or calculated at less than 10.}%
+ \fi
+ \global\@LinesPerPagetrue
+ \gdef\@LinesPerPage{#1}
+}% end set linesperpage
+%%
+
+
+%% \SetFontSize may be in any units, even decimals: 12.2pt, 11.5bp, etc.
+% Before external packages load, the font size is temporarily set to
+% 10pt at 13pt skip, so that moldy-oldie packages don't get confused.
+% Later, the size is changed to its actual value based on this command,
+% or on the defaults for Trim Size.
+\newif \if@FontSizeSet % true if \SetFontSize rather than default.
+\newlength\@SetFontSize
+\newcommand\SetFontSize[1]{
+ \global\@FontSizeSettrue
+ \gsetlength\@SetFontSize{#1}
+}% end set font size
+%%
+
+
+%% MISCELLANOUS SETTINGS. Mostly remove "glue". Best to leave as-is.
+%% ----------------------------------------------------------------------------
+% Standard TeX \hoffset and \voffset is not relative to the MediaBox, but is
+% relative to 1in from the top left corner of the MediaBox. Ouch.
+% When necessary, the 1in (72.27pt) is compensated in later calculations.
+\setlength\hoffset{0pt} % relative to 1in built-in offset at left
+\setlength\voffset{0pt} % relative to 1in built-in offset at top
+%
+\@twocolumnfalse
+\@twosidetrue
+\setlength\columnsep{12pt} % not needed, picked something at random
+\setlength\columnseprule{0pt}
+%
+\@mparswitchtrue % irrelevant
+\setlength\marginparwidth{0pt} % no marginal paragraphs allowed
+\setlength\marginparsep{0pt}
+\setlength\marginparpush{0pt}
+%
+\global\@topnum \z@
+\setlength\abovedisplayskip{0pt}
+\setlength\abovedisplayshortskip{0pt}
+\setlength\belowdisplayshortskip{0pt}
+\setlength\belowdisplayskip{0pt}
+\setlength\smallskipamount{0pt}
+\setlength\medskipamount{0pt}
+\setlength\bigskipamount{0pt}
+% `novel' uses grid setting. However, to allow for roundoff errors in
+% vertical position calculations, there is a tiny amount of wiggle room:
+\setlength\topsep{0pt}
+\setlength\partopsep{0pt}
+\setlength\parsep{0pt}
+\setlength\parskip{0pt}
+\setlength\floatsep{0pt}
+\setlength\textfloatsep{0pt}
+\setlength\dbltextfloatsep{0pt}
+\setlength\intextsep{0pt}
+% \topskip will be set as normal baselineskip, which must first be calculated.
+% That is done in novel-CalculateLayout.sty.
+\setlength\lineskip{0pt}
+\setlength\normallineskip{0pt}
+\setlength\lineskiplimit{-2pt} % allows some limited vertical clash
+\renewcommand\baselinestretch{1} % multiplier
+\widowpenalty 150 % same as TeX default
+\clubpenalty 150 % same as TeX default
+\@lowpenalty 51
+\@medpenalty 151
+\@highpenalty 301
+% Floats are limited, but just in case:
+\setcounter{topnumber}{2}
+\renewcommand\topfraction{.7}
+\setcounter{bottomnumber}{1}
+\renewcommand\bottomfraction{.3}
+\setcounter{totalnumber}{3}
+\renewcommand\textfraction{.2}
+\renewcommand\floatpagefraction{.5}
+\setcounter{dbltopnumber}{2}
+\renewcommand\dbltopfraction{.7}
+\renewcommand\dblfloatpagefraction{.5}
+%
+\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\normalfont\rmfamily}
+\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\normalfont\sffamily}
+\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\normalfont\ttfamily}
+\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\normalfont\bfseries}
+\DeclareOldFontCommand{\it}{\normalfont\itshape}{\normalfont\itshape}
+\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\normalfont\slshape}
+\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\normalfont\scshape}
+%
+\pagestyle{empty} % will be over-ridden by fancyhead in separate file
+\pagenumbering{arabic} % may be over-ridden in document
+\flushbottom % best for continuous text
+%
+%% End miscellaneous settings.
+
+
+
+%% FRONTMATTER, MAINMATTER. BUT NO BACKMATTER!
+%% ----------------------------------------------------------------------------
+%
+% See novel.cls for the AtBeginShipout routine.
+%
+% These do not have @ in name, so that they can be used in document body:
+\newif \ifWithinFrontmatter % true within frontmatter
+\newif \ifWithinMainmatter % true within mainmatter
+\def\frontmatter{ % starts page count and frontmatter count at 1.
+ \ifWithinFrontmatter
+ \ClassError{novel}{\string\frontmatter\ used more than once}%
+ {You issued \string\frontmatter\ more than once.}%
+ \fi
+ \ifWithinMainmatter
+ \ClassError{novel}{\string\frontmatter\ cannot follow \mainmatter}%
+ {In order: \string\frontmatter\ \string\mainmatter ^^J%
+ but you do not need both of them.}%
+ \fi
+ \global\WithinFrontmattertrue\global\WithinMainmatterfalse
+ \clearpage
+ \pagenumbering{roman}
+ \setcounter{page}{1}
+}
+%
+\def\mainmatter{ % restarts page to 1, arabic numbers; freeze frontpagecount
+ \ifWithinMainmatter
+ \ClassError{novel}{\string\mainmatter\ used more than once}%
+ {You issued \string\mainmatter\ more than once.}%
+ \fi
+ \cleartorecto
+ \global\WithinFrontmatterfalse\global\WithinMainmattertrue
+ \pagenumbering{arabic}
+ \setcounter{page}{1}
+}
+%
+\def\backmatter{\@ifstar\@backmatterst\@backmatterns}
+\def\@backmatterns{%
+ \cleartorecto%
+ \typeout{^^JClass `novel' Alert: \string\backmatter\space merely %
+ clears to recto. See docs. ^^J}%
+}
+\let\@backmatterst\@backmatterns
+%% end frontmatter, mainmatter. No backmatter!
+
+
+%% DISABLE OR NEUTRALIZE SOME STANDARD LATEX COMMANDS
+%% ----------------------------------------------------------------------------
+% The `novel' class disallows these commands, or neutralizes them by simply
+% repeating their arguments. In some cases, they request functionality that's
+% not implemented in `novel'. In other cases, functionality is part of core,
+% but would interfere with the `novel' emphasis on constant line skip.
+% You may redefine the commands using your own Preamble code (discouraged).
+%
+%%%%%\gdef\null{\hbox{\strut}} % May be important!
+%
+% Standard LaTeX font sizes are ineffective:
+\gdef\@noSizeCommand#1{\ClassWarning{novel}{%
+ Standard LaTeX font sizes are ineffective in `novel' class. ^^J%
+ Your use of command `#1' was ignored. ^^J}%
+}
+\gdef\@DisableFontSizes{% called by `novel.cls' \AtBeginDocument
+ \gdef\HUGE{\@noSizeCommand{HUGE}}
+ \gdef\Huge{\@noSizeCommand{Huge}}
+ \gdef\huge{\@noSizeCommand{huge}}
+ \gdef\LARGE{\@noSizeCommand{LARGE}}
+ \gdef\Large{\@noSizeCommand{Large}}
+ \gdef\large{\@noSizeCommand{large}}
+ \gdef\small{\@noSizeCommand{small}}
+ \gdef\footnotesize{\@noSizeCommand{footnotesize}}
+ \gdef\scriptsize{\@noSizeCommand{scriptsize}}
+ \gdef\tiny{\@noSizeCommand{tiny}}
+} %
+% In `novel' there is no academic organization.
+% All these do is echo the argument, if any:
+\long\gdef\part#1{#1}
+\long\gdef\chapter#1{#1}
+\long\gdef\section#1{#1}
+\long\gdef\subsection#1{#1}
+\long\gdef\subsubsection#1{#1}
+\long\gdef\paragraph#1{#1}
+\long\gdef\subparagraph#1{#1}
+\long\gdef\appendix#1{#1}
+% In some situations, the use will be interrupted:
+\DeclareDocumentCommand\@nodocommand { O{} +m } {%
+ \ClassError{novel}{No command or environment `#1' in this class}%
+ {Many academic layout commands or environments are disabled in `novel'.}%
+}
+\DeclareDocumentCommand\@sandboxonly { m } {%
+ \ClassError{novel}{ ^^J%
+ Command or environment `#1' only allowed in `sandbox' mode. ^^J%
+ See `novel' documentation 2.2. ^^J
+ The offending command may have been called by another macro.}%
+ {Fix your code. If you do not, then compile will fail or be unexpected.}%
+}
+% Here is the interruption list:
+\long\gdef\maketitle{\@nodocommand{maketitle}}
+\long\gdef\makeindex{\@nodocommand{makeindex}}
+\long\gdef\tableofcontents{\@nodocommand{tableofcontents}}
+\long\gdef\listoftables{\@nodocommand{listoftables}}
+\long\gdef\listoffigures{\@nodocommand{listoffigures}}
+\long\gdef\thebibliography{\@nodocommand{thebibliography}}
+\long\gdef\theindex{\@nodocommand{theindex}}
+\long\gdef\abstract{\@nodocommand{abstract}}
+\if@sandbox\else
+ \DeclareDocumentCommand\caption{}{\@sandboxonly{caption}}
+ \DeclareDocumentEnvironment{tabular}{s o +m}{\@sandboxonly{tabular}}{}
+ \DeclareDocumentEnvironment{table}{s o}{\@sandboxonly{table}}{}
+ \DeclareDocumentEnvironment{figure}{s o}{\@sandboxonly{figure}}{}
+ \DeclareDocumentEnvironment{itemize}{s}{\@sandboxonly{itemize}}{}
+ \DeclareDocumentEnvironment{enumerate}{s}{\@sandboxonly{enumerate}}{}
+ \DeclareDocumentEnvironment{description}{s}{\@sandboxonly{description}}{}
+ \DeclareDocumentEnvironment{labeling}{s}{\@sandboxonly{labeling}}{}
+\fi
+%
+\newif \if@OnTitlePage % not really useful
+\DeclareDocumentEnvironment{titlepage}{s}{%
+ \clearpage
+ \thispagestyle{empty}
+ \global\@OnTitlePagetrue
+}{
+ \clearpage
+ \global\@OnTitlePagefalse
+}
+%% end disable or neutralize.
+
+
+%% Neutralize settings commands:
+\gdef\@DisableLayoutSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetMediaSize\relax
+ \LetLtxMacro\SetTrimSize\relax
+ \LetLtxMacro\SetMargins\relax
+ \LetLtxMacro\SetLinesPerPage\relax
+ \LetLtxMacro\SetFontSize\relax
+ \LetLtxMacro\SetUnsafeZone\relax
+}% end \@DisableLayoutSettings
+%%
+
+
+%%
+\endinput
+%%
+%% End of file `novel-LayoutSettings.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-PostLayout.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-PostLayout.sty
new file mode 100644
index 0000000000..5096645cac
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-PostLayout.sty
@@ -0,0 +1,263 @@
+%%
+%% This is file `novel-PostLayout.sty', part of `novel' document class.
+%% Copyright 2017-2023 Robert Allgeyer.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-PostLayout.sty}%
+[2023/02/08 v1.80 LaTeX file (post-layout modifications)]
+%%
+
+%%
+%% This file is loaded \AtEndPreamble, which precedes \AtBeginDocument.
+%%
+
+
+
+% \@getPageXY is used by `shademargins' and `cropmarks' options.
+% The 72.27pt compensates for built-in 1in TeX offsets.
+% Position of left edge of TrimBox, rightwards from left edge of MediaBox:
+\newlength\Trim@Left
+% Position of bottom of TrimBox, upwards from bottom of MediaBox:
+\newlength\Trim@Bottom
+\gdef\@getPageXY{%
+ \ifodd\c@page% Adjusts for left-right margin switching, verso/recto,
+ % and also for horizontal position of TrimBox within MediaBox:
+ \gsetlength\Trim@Left{\oddsidemargin-\@InnerMargin+72.27pt}%
+ \else%
+ \gsetlength\Trim@Left{\evensidemargin-\@OuterMargin+72.27pt}%
+ \fi%
+ % Adjusts for vertical position of TrimBox within MediaBox:
+
+ \gsetlength\Trim@Bottom{0.5\paperheight-0.5\@TrimHeight+\hoffset}%
+
+}%
+%% end \@getPageXY.
+
+
+%% ACTIVATE CLOSECROP CLASS OPTION
+%% ----------------------------------------------------------------------------
+% The `closecrop' class option is only effective in draft mode.
+% It preserves the text layout, but removes most of the margin white space.
+% The resulting file is more easily readable on a hand-held device.
+% However, the cropped file is not suitable for distribution as an E-book,
+% as it is missing reflow information, marketing metadata, etc.
+\if@closecrop
+ \gsetlength\paperwidth{\textwidth+0.2in}
+ \if@HasHeader
+ \gsetlength\topmargin{-1in}
+ \else
+ \gsetlength\topmargin{-0.9in}
+ \fi
+ \if@HasFooter
+ \if@HasHeader
+ \gsetlength\paperheight{%
+ \textheight+\headsep+\headheight+\@FootJump\baselineskip+1pt%
+ }
+ \else
+ \gsetlength\paperheight{%
+ \textheight+\headsep+\headheight+\@FootJump\baselineskip+\@SetFontSize%
+ }
+ \fi
+ \else
+ \gsetlength\paperheight{\textheight+\headsep+\headheight+0.1in}
+ \fi
+\fi
+%% end closecrop
+
+
+%% ACTIVATE SHADEMARGINS CLASS OPTION (Includes Unsafe Zone)
+%% ----------------------------------------------------------------------------
+%% With class option `shademargins' (only effective in draft mode):
+% Based on code by Ulrike Fischer at tex.stackexchange.com, CC-by-sa-3.0:
+% 0.542763, 0.883215 and 0.949123 are unlikely user choices.
+% The re-defined \color command makes an exception for those values.
+\definecolor[named]{hingledingle}{gray}{1} % fake white, when white disallowed
+%
+\if@shademargins
+ % Margins are visualized by filling the TrimBox background with gray.
+ % Then, the rectangle defining the Englosed area is filled with white.
+ % Then header and/or footer are filled with a lighter gray background.
+ % Then Unsafe Zone (UZ) sits atop the other background fills, as darker gray.
+ % The UZ is constructed from four strips, one at each side.
+ \AddToShipoutPictureBG{% fills trim area with medium gray
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.883215}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom]{\@TrimWidth}{\@TrimHeight}%
+ }%
+ }%
+ %
+ \AddToShipoutPictureBG{% fills enclosed area with white
+ \@getPageXY%
+ \AtPageLowerLeft{\color{hingledingle}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\dimexpr\Trim@Bottom+\@BottomMargin]%
+ {\textwidth}{\dimexpr\@TrimHeight-\@TopMargin-\@BottomMargin}
+ }%
+ }%
+ \if@HasHeader% fills header (and its jump) with light gray
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.949123}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\Trim@Bottom+\@TrimHeight-\@TopMargin-\@HeadJump\nbs]%
+ {\@TrimWidth-\@OuterMargin-\@InnerMargin}{\@HeadJump\nbs}%
+ }%
+ }%
+ \fi%
+ %
+ \if@HasFooter% fills footer (and its jump) with light gray
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.949123}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\Trim@Bottom+\@BottomMargin]%
+ {\@TrimWidth-\@OuterMargin-\@InnerMargin}{\@FootJump\nbs}%
+ }%
+ }%
+ \fi%
+ %
+ \if@UnsafeZone% fills unsafe zones with dark gray
+ \AddToShipoutPictureBG{% top unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom+\@TrimHeight-\@TopUZWidth]%
+ {\@TrimWidth}{\@TopUZWidth}%
+ }%
+ }%
+ \AddToShipoutPictureBG{% outer unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth-\@OuterUZWidth}%
+ \rule[\Trim@Bottom]{\@OuterUZWidth}{\@TrimHeight}%
+ \else%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth-\@InnerUZWidth}%
+ \rule[\Trim@Bottom]{\@InnerUZWidth}{\@TrimHeight}%
+ \fi%
+ }%
+ }%
+ \AddToShipoutPictureBG{% bottom unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom]{\@TrimWidth}{\@BottomUZWidth}%
+ }%
+ }%
+ \AddToShipoutPictureBG{% inner unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \ifodd\c@page%
+ \rule[\Trim@Bottom]{\@InnerUZWidth}{\@TrimHeight}%
+ \else%
+ \rule[\Trim@Bottom]{\@OuterUZWidth}{\@TrimHeight}%
+ \fi%
+ }%
+ }%
+ \fi% end \if@UnsafeZone
+ %
+\fi % end \if@shademargins
+%
+%% end shademargins and unsafe zone
+
+
+%% LABEL DRAFT OPTION
+%% ----------------------------------------------------------------------------
+% Writes DRAFT inside upper left of TrimBox, when in draft mode.
+% This macro must go here, in order, so that the label is not over-shaded.
+\ifdraftdoc
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageUpperLeft{%
+ \raisebox{-\@SetFontSize}{\textbf{~DRAFT}}%
+ }%
+ }%
+\fi
+%% end label draft.
+
+
+%% ACTIVATE CROPMARKS CLASS OPTION
+%% ----------------------------------------------------------------------------
+% Cropmarks (trim marks, really) are not important in this document class.
+% That's because the targeted printing services generally do not want them.
+% But a minimal capability was easy to add. The far end of each mark is
+% 0.25in from the trim area. The close end is separated by 0.125in.
+% So the length of the marks essentially 1/8in. Width 0.25bp.
+% The marks are turned on using `cropmarks' class option.
+% When Media Size = Trim Size, cropmarks are disabled.
+% Too late for \@cropviewfalse; OK since CropBox already calculated properly.
+\ifthenelse{%
+ \dimtest{\@TrimWidth}{=}{\paperwidth} %
+ \AND \dimtest{\@TrimHeight}{=}{\paperheight}%
+}{\global\@cropmarksfalse}{}
+%
+\if@cropmarks% Cropmark begins 0.125in from TrimBox, ends 0.25in from TrimBox.
+ % H top left:
+ \AddToShipoutPictureBG{\@getPageXY%
+ \AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25in}%
+ \rule[0.5\paperheight+0.5\@TrimHeight]{0.25in-0.125in}{0.25bp}}}
+ % H bottom left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25in}%
+ \rule[\Trim@Bottom-0.5pt]{0.25in-0.125in}{0.25bp}}}
+ % H top right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth+0.125in}%
+ \rule[0.5\paperheight+0.5\@TrimHeight]{0.25in-0.125in}{0.25bp}}}
+ % H bottom right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth+0.125in}%
+ \rule[\Trim@Bottom-0.25bp]{0.25in-0.125in}{0.25bp}}}
+ % V top left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25bp}%
+ \rule[0.5\paperheight+0.5\@TrimHeight+0.125in]%
+ {0.25bp}{0.25in-0.125in}}}
+ % V bottom left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25bp}%
+ \rule[\Trim@Bottom-0.25in]{0.25bp}{0.25in-0.125in}}}
+ % V top right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth}%
+ \rule[0.5\paperheight+0.5\@TrimHeight+0.125in]%
+ {0.25bp}{0.25in-0.125in}}}
+ % V bottom right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth}%
+ \rule[\Trim@Bottom-0.25in]{0.25bp}{0.25in-0.125in}}}
+\fi
+%
+%% end cropmarks
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-PostLayout.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-Sandbox.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Sandbox.sty
new file mode 100644
index 0000000000..71b890738e
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-Sandbox.sty
@@ -0,0 +1,145 @@
+%%
+%% This is file `novel-Sandbox.sty', part of `novel' document class.
+%% Copyright 2017-2023 Robert Allgeyer.
+%%
+%% Material extracted from `article.cls', a LaTeX document class.
+%% Copyright 1993-2016
+%% The LaTeX3 Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Sandbox.sty}%
+[2023/02/08 v1.80 LaTeX file (used only with sandbox class option)]
+%%
+
+%%
+%% This file is only loaded when the `sandbox' document class is used.
+%% It provides support for tables, and a few other things that ordinarily
+%% would be prohibited in `novel' due to possible layout incompatibility.
+%%
+%% Normally, `novel' sets many glues and lengths to zero, to maintain line grid.
+%% But `sandbox', sets the glues to values typical of other document classes.
+%% So, not only can you construct tables, they will look as expected.
+%%
+
+
+
+
+\setlength\leftmargini {2.5em}
+\leftmargin \leftmargini
+\setlength\leftmarginii {2.2em}
+\setlength\leftmarginiii {1.87em}
+\setlength\leftmarginiv {1.7em}
+\setlength\leftmarginv {1em}
+\setlength\leftmarginvi {1em}
+\setlength \labelsep {.5em}
+\setlength \labelwidth{\leftmargini}
+\addtolength\labelwidth{-\labelsep}
+\@beginparpenalty -\@lowpenalty
+\@endparpenalty -\@lowpenalty
+\@itempenalty -\@lowpenalty
+\renewcommand\theenumi{\@arabic\c@enumi}
+\renewcommand\theenumii{\@alph\c@enumii}
+\renewcommand\theenumiii{\@roman\c@enumiii}
+\renewcommand\theenumiv{\@Alph\c@enumiv}
+\newcommand\labelenumi{\theenumi.}
+\newcommand\labelenumii{(\theenumii)}
+\newcommand\labelenumiii{\theenumiii.}
+\newcommand\labelenumiv{\theenumiv.}
+\renewcommand\p@enumii{\theenumi}
+\renewcommand\p@enumiii{\theenumi(\theenumii)}
+\renewcommand\p@enumiv{\p@enumiii\theenumiii}
+\newcommand\labelitemi{\textbullet}
+\newcommand\labelitemii{\normalfont\bfseries \textendash}
+\newcommand\labelitemiii{\textasteriskcentered}
+\newcommand\labelitemiv{\textperiodcentered}
+\newenvironment{description}
+ {\list{}{\labelwidth\z@ \itemindent-\leftmargin
+ \let\makelabel\descriptionlabel}}
+ {\endlist}
+\newcommand*\descriptionlabel[1]{\hspace\labelsep
+ \normalfont\bfseries #1}
+
+
+
+\setlength\tabcolsep{6pt}
+\setlength\arrayrulewidth{.4pt}
+\setlength\doublerulesep{2pt}
+\setlength\tabbingsep{\labelsep}
+
+
+\newcounter{figure}
+\renewcommand \thefigure {\@arabic\c@figure}
+\def\fps@figure{tbp}
+\def\ftype@figure{1}
+\def\ext@figure{lof}
+\def\fnum@figure{\figurename\nobreakspace\thefigure}
+
+\newenvironment{figure}
+ {\@float{figure}}
+ {\end@float}
+\newenvironment{figure*}
+ {\@float{figure}}
+ {\end@float}
+
+
+
+\newcounter{table}
+\renewcommand\thetable{\@arabic\c@table}
+\def\fps@table{tbp}
+\def\ftype@table{2}
+\def\ext@table{lot}
+\def\fnum@table{\tablename\nobreakspace\thetable}
+
+\newenvironment{table}
+ {\@float{table}}
+ {\end@float}
+\newenvironment{table*}
+ {\@float{table}}
+ {\end@float}
+
+
+
+\newlength\abovecaptionskip
+\newlength\belowcaptionskip
+
+\setlength\abovecaptionskip{\nbs}
+
+\setlength\belowcaptionskip{0pt}
+
+\long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \sbox\@tempboxa{#1: #2}%
+ \ifdim \wd\@tempboxa >\hsize
+ #1: #2\par
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
+
+
+
+
+
+
+
+\def\today{\ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year}
+
+
+
+\endinput
+
+%% end of file `novel-Sandbox.sty'.
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-TextMacros.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-TextMacros.sty
new file mode 100644
index 0000000000..23a6a8af9d
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-TextMacros.sty
@@ -0,0 +1,586 @@
+%%
+%% 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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-TextMacros.sty}%
+[2023/02/08 v1.80 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'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-microtype.cfg b/macros/luatex/latex/novel/tex/lualatex/novel/novel-microtype.cfg
new file mode 100644
index 0000000000..e9076d5593
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-microtype.cfg
@@ -0,0 +1,252 @@
+%%
+%% This is file `novel-microtype.cfg', part of `novel' document class.
+%% Modified from file `microtype.cfg' by Robert Allgeyer, 2017-2023.
+%%
+%% Original notice from `microtype.cfg' follows.
+%% Same license for `novel-microtype.cfg'.
+%%
+%% ------------------------------------------------------------------------
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version. The latest version of this license is in:
+%% http://www.latex-project.org/lppl.txt, and version 1.3c or later is part
+%% of all distributions of LaTeX version 2005/12/01 or later.
+%%
+%% ------------------------------------------------------------------------
+%%
+%% When modifying this file, also change the identification line below.
+%% ------------------------------------------------------------------------
+%%
+\ProvidesFile{novel-microtype.cfg}%
+[2023/02/08 any version. (default microtype configuration for novel class)]
+
+%%% ---------------------------------------------------------------------------
+%%% FONT SETS
+
+\DeclareMicrotypeSet{all}
+ { }
+
+\DeclareMicrotypeSet{allmath}
+ { }
+
+\DeclareMicrotypeSet{alltext}
+ { }
+
+\DeclareMicrotypeSet{allmath-nott}
+ { family = {rm*,sf*} }
+
+\DeclareMicrotypeSet{alltext-nott}
+ { family = {rm*,sf*} }
+
+\DeclareMicrotypeSet{basicmath}
+ { family = {rm*,sf*}, series = {md*} }
+
+\DeclareMicrotypeSet{basictext}
+ { family = {rm*,sf*}, series = {md*}, }
+
+\DeclareMicrotypeSet{smallcaps}
+ { shape = {sc*,si,scit} }
+
+\DeclareMicrotypeSet{normalfont}
+ { font = */*/*/*/* }
+
+%%% ---------------------------------------------------------------------------
+%%% DEFAULT SETS
+
+\DeclareMicrotypeSetDefault[protrusion]{alltext}
+\DeclareMicrotypeSetDefault[expansion] {basictext}
+\DeclareMicrotypeSetDefault[spacing] {basictext}
+\DeclareMicrotypeSetDefault[kerning] {alltext}
+\DeclareMicrotypeSetDefault[tracking] {smallcaps}
+
+%%% ---------------------------------------------------------------------------
+%%% FONT VARIANTS AND ALIASES
+
+\DeclareMicrotypeVariants{x,j,w,a,d,0,1}
+
+\DeclareMicrotypeAlias{lmr} {Latin Modern Roman}
+\DeclareMicrotypeAlias{lmm} {Latin Modern Math}
+
+%%% ---------------------------------------------------------------------------
+%%% INTERACTION WITH THE `babel' PACKAGE
+
+\DeclareMicrotypeBabelHook
+ {english,UKenglish,british,USenglish,american}
+ {kerning=, spacing=nonfrench}
+
+\DeclareMicrotypeBabelHook
+ {french,francais,acadian,canadien}
+ {kerning=french, spacing=}
+
+\DeclareMicrotypeBabelHook
+ {turkish}
+ {kerning=turkish, spacing=}
+
+%%% ---------------------------------------------------------------------------
+%%% CHARACTER INHERITANCE
+
+\DeclareCharacterInheritance
+ { encoding = * }
+ { A = {\`A,\'A,\^A,\~A,\"A,\r A,\k A,\u A},
+ a = {\`a,\'a,\^a,\~a,\"a,\r a,\k a,\u a},
+ C = {\'C,\c C,\v C},
+ c = {\'c,\c c,\v c},
+ D = {\v D,\DH},
+ d = {\v d,\dj},
+ E = {\`E,\'E,\^E,\"E,\k E,\v E},
+ e = {\`e,\'e,\^e,\"e,\k e,\v e},
+ G = {\u G},
+ g = {\u g},
+ I = {\`I,\'I,\^I,\"I,\.I},
+ i = {\`i,\'i,\^i,\"i,\i},
+ L = {\L,\'L,\v L},
+ l = {\l,\'l,\v l},
+ N = {\'N,\~N,\v N},
+ n = {\'n,\~n,\v n},
+ O = {\O,\`O,\'O,\^O,\~O,\"O,\H O},
+ o = {\o,\`o,\'o,\^o,\~o,\"o,\H o},
+ R = {\'R,\v R},
+ r = {\'r,\v r},
+ S = {\'S,\c S,\v S}, % \SS
+ s = {\'s,\c s,\v s},
+ T = {\c T,\v T},
+ t = {\c t,\v t},
+ U = {\`U,\'U,\^U,\"U,\H U,\r U},
+ u = {\`u,\'u,\^u,\"u,\H u,\r u},
+ Y = {\'Y,\"Y},
+ y = {\'y,\"y},
+ Z = {\'Z,\.Z,\v Z},
+ z = {\'z,\.z,\v z},
+ }
+
+%%% ---------------------------------------------------------------------------
+%%% TRACKING/LETTERSPACING
+
+\SetTracking
+ [ name = default,
+ no ligatures = {f, T} ]
+ { encoding = * }
+ { }
+
+%%% ---------------------------------------------------------------------------
+%%% EXPANSION
+
+\SetExpansion
+ [ name = default ]
+ { encoding = * }
+ {
+ A = 500, a = 700,
+ \AE = 500, \ae = 700,
+ B = 700, b = 700,
+ C = 700, c = 700,
+ D = 500, d = 700,
+ E = 700, e = 700,
+ F = 700,
+ G = 500, g = 700,
+ H = 700, h = 700,
+ K = 700, k = 700,
+ M = 700, m = 700,
+ N = 700, n = 700,
+ O = 500, o = 700,
+ \OE = 500, \oe = 700,
+ P = 700, p = 700,
+ Q = 500, q = 700,
+ R = 700,
+ S = 700, s = 700,
+ U = 700, u = 700,
+ W = 700, w = 700,
+ Z = 700, z = 700,
+ 2 = 700,
+ 3 = 700,
+ 6 = 700,
+ 8 = 700,
+ 9 = 700,
+ }
+
+
+
+%%% ---------------------------------------------------------------------------
+%%% PROTRUSION
+
+\SetProtrusion
+ [ name = default ]
+ { encoding = * }
+ {
+ A = {50,50},
+ \AE = {50,50},
+ F = { ,50},
+ J = {50, },
+ K = { ,50},
+ L = { ,50},
+ T = {50,50},
+ V = {50,50},
+ W = {50,50},
+ X = {50,50},
+ Y = {50,50},
+ k = { ,50},
+ r = { ,50},
+ v = {50,50},
+ w = {50,50},
+ x = {50,50},
+ y = { ,50},
+ 1 = {50,50},
+ 4 = {50,50},
+ 7 = {50,50},
+ . = { ,200},
+ {,}= { ,200},
+ : = { ,200},
+ ; = { ,200},
+ ! = { ,100},
+ ? = { ,100},
+ @ = {50,50},
+ ~ = {200,200},
+ \% = {50,50},
+ * = {200,200},
+ + = {200,200},
+ ( = {100, },
+ ) = { ,200},
+ / = {100,200},
+ - = {200,200},
+ \textendash = {200,200}, \textemdash = {150,150},
+ \textquoteleft = {200, }, \textquoteright = { ,200},
+ \textquotedblleft = {200, }, \textquotedblright = { ,200},
+ }
+
+
+\SetProtrusion
+ [ name = it-default, ]
+ { encoding = * ,
+ shape = {it,sl} }
+ {
+ . = { ,500},
+ {,}= { ,500},
+ : = { ,300},
+ ; = { ,300},
+ & = {50,50},
+ \% = {100, },
+ * = {200,200},
+ + = {150,200},
+ @ = {50,50},
+ ~ = {150,150},
+ ( = {200, },
+ ) = { ,200},
+ / = {100,200},
+ - = {300,300},
+ \textendash = {200,200}, \textemdash = {150,150},
+ \textquoteleft = {400,200}, \textquoteright = {400,200},
+ \textquotedblleft = {400,200}, \textquotedblright = {400,200},
+ \textbackslash = {100,200},
+ \quotesinglbase = {300,700}, \quotedblbase = {400,500},
+ \guilsinglleft = {400,400}, \guilsinglright = {300,500},
+ \guillemotleft = {300,300}, \guillemotright = {300,300},
+ \textexclamdown = {100, }, \textquestiondown = {200, },
+ \textbraceleft = {200,100}, \textbraceright = {200,200},
+ }
+
+
+
+\endinput
+%%
+%% End of file `novel-microtype.cfg'.
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-pdfx.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-pdfx.sty
new file mode 100644
index 0000000000..537ccf65c7
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-pdfx.sty
@@ -0,0 +1,517 @@
+%%
+%% This is file `novel-pdfx.sty', part of `novel' document class.
+%% Copyright (c) 2017-2023 Robert Allgeyer.
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% File `novel-pdfx.sty' uses code, directly copied or modified,
+%% from file `pdfx.sty', part of LaTeX package `pdfx': Copyright (c) 2015,
+%% CV Radhakrishnan, Han The Thanh, Ross Moore, Peter Selinger.
+%% Licensed LPPL 1.2+.
+%%
+%% ----------------------------------------------------------------------------
+%%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{novel-pdfx.sty}%
+[2023/02/08 v1.80 LaTeX file (PDF/X support for novel class)]
+% This package supports, and is part of, class `novel'.
+% No support for anything but LuaLaTeX.
+
+% DO NOT ATTEMPT TO USE OUTSIDE `NOVEL' DOCUMENT CLASS.
+% Reason: Other files in this class define stuff that is used here.
+
+%%
+%% This file is loaded \AtEndPreamble.
+%%
+
+
+%% Preliminary tests for cases forbidding PDF/X:
+\ifdraftdoc
+ \global\@pdfxISofftrue
+\fi
+\if@sandbox
+ \global\@pdfxISofftrue
+\fi
+%
+\gdef\@AlertNoPDFX{% called by `novel.cls' AtBeginDocument
+ \if@pdfxSEToff\else
+ \ifdraftdoc
+ \typeout{^^JClass `novel' Alert: No PDF/X in draft mode. ^^J%
+ Your document was processed with \string\SetPDFX{off}. ^^J}%
+ \fi
+ \if@sandbox
+ \typeout{^^JClass `novel' Alert: No PDF/X with sandbox option. ^^J%
+ Your document was processed with \string\SetPDFX{off}. ^^J}%
+ \fi
+ \fi
+} % end @AlertNoPDFX
+%%
+
+
+% Hyperref options for PDF/X with LuaLaTeX:
+\def\pdfx@pdfX@opts@luatex{%
+ draft,pdfpagemode=UseNone,bookmarks=false,hyperfootnotes=false,%
+ hyperindex=false,implicit=false,pdfversion=1.\the\pdfminorversion,%
+ pdfpagelabels=true,pageanchor=false,pdfstartview=}
+%
+\RequirePackage[\pdfx@pdfX@opts@luatex]{hyperref}
+%
+\hypersetup{pdfencoding=auto}
+\expandafter\ifx\csname KV@Hyp@psdextra\endcsname\relax\else
+ \hypersetup{psdextra}
+\fi
+\Hy@bookmarksfalse
+%
+\ifthenelse{\equal{\@title}{} \OR \equal{\@title}{ }}{%
+ \global\@HasTitlefalse}{\global\@HasTitletrue%
+}
+\ifthenelse{\equal{\@title}{IMPORTANT: Provide Book Title}}{%
+ \ClassWarning{novel}{^^JDid not provide title using \string\SetTitle. ^^J%
+ Default used: `IMPORTANT: Provide Book Title'. Be sure to change it! ^^J}%
+}{}%
+%
+% Sanity check: If title is missing at this step, then compliance must be off:
+\if@pdfxISoff\else
+ \if@HasTitle\else
+ \ClassError{novel}{PDF/X requires non-empty \string\SetTitle\space}%
+ {Unless \string\SetPDFX\space is off, must use \string\SetTitle\space ^^J%
+ with non-empty title. Blank space counts as empty.}%
+ \fi
+\fi
+%
+\if@HasTitle\else
+ \ClassWarning{novel}{^^JYour file has been compiled without standard ^^J%
+ PDF internal metadata, such as the title. This is allowable, and in ^^J%
+ some cases desirable. But in most cases it is not what you intended. ^^J%
+ If you want title and other metadata to be in PDF internal metadata, ^^J%
+ then you must place them prior to the \string\SetPDFX. ^^J}
+\fi
+%
+\expandafter\ifx\csname pdfresetpageorigin\endcsname\relax\else
+ \pdfresetpageorigin=0
+\fi
+\edef\pdfcreationdate{\pdfcreationdate}%
+\let\pdfx@mdfivesum\pdf@mdfivesum
+%
+
+
+
+%% CALCULATE AND SPECIFY CROPBOX AND TRIMBOX
+%% ----------------------------------------------------------------------------
+%%
+% The MediaBox is automatically provided, so there is no need to write
+% MediaBox in /pdfInfo (because it would be a duplicate).
+% TrimBox is always necessary for PDF/X.
+% Although CropBox is not necessary, it seems that it is often written
+% by professional PDF software. For that reason, and for proper centering
+% of TrimBox when MediaBox is larger, CropBox is created (= MediaBox).
+%
+\newcommand\@myMWN{\strip@pt\paperwidth}
+\FPmul{\@myMWN}{\@myMWN}{0.99626401}
+\FPround{\@myMWN}{\@myMWN}{3}
+\FPclip{\@myMWN}{\@myMWN}
+\newcommand\@myMHN{\strip@pt\paperheight}
+\FPmul{\@myMHN}{\@myMHN}{0.99626401}
+\FPround{\@myMHN}{\@myMHN}{3}
+\FPclip{\@myMHN}{\@myMHN}
+\newcommand\@myTWN{\strip@pt\@TrimWidth}
+\FPmul{\@myTWN}{\@myTWN}{0.99626401}
+\FPround{\@myTWN}{\@myTWN}{3}
+\newcommand\@myTHN{\strip@pt\@TrimHeight}
+\FPmul{\@myTHN}{\@myTHN}{0.99626401}
+\FPround{\@myTHN}{\@myTHN}{3}
+%
+\FPsub{\@myTWorigin}{\@myMWN}{\@myTWN}
+\FPmul{\@myTWorigin}{\@myTWorigin}{0.5}
+\FPround{\@myTWorigin}{\@myTWorigin}{3}
+\FPadd{\@myTWcorner}{\@myTWorigin}{\@myTWN}
+\FPround{\@myTWcorner}{\@myTWcorner}{3}
+\FPsub{\@myTHorigin}{\@myMHN}{\@myTHN}
+\FPmul{\@myTHorigin}{\@myTHorigin}{0.5}
+\FPround{\@myTHorigin}{\@myTHorigin}{3}
+\FPadd{\@myTHcorner}{\@myTHorigin}{\@myTHN}
+\FPround{\@myTHcorner}{\@myTHcorner}{3}
+%
+\FPclip{\@myTWorigin}{\@myTWorigin}
+\FPclip{\@myTWcorner}{\@myTWcorner}
+\FPclip{\@myTHorigin}{\@myTHorigin}
+\FPclip{\@myTHcorner}{\@myTHcorner}
+%
+\newcommand\novel@CropBox{%
+ \if@cropview%
+ /CropBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
+ \else%
+ /CropBox[0\space0\space\@myMWN\space\@myMHN]%
+ \fi%
+}
+%
+\newcommand\novel@TrimBox{%
+ /TrimBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
+}
+%
+% BleedBox, only for cover art. Same size as MediaBox.
+\newcommand\novel@BleedBox{%
+ \if@coverart%
+ /BleedBox[0\space0\space\@myMWN\space\@myMHN]%
+ \fi%
+}
+%
+\begingroup\edef\next{%
+\endgroup\pdfpageattr{\novel@CropBox^^J\novel@BleedBox^^J\novel@TrimBox}}\next
+%
+%% End calculate and specify TrimBox.
+
+
+
+%% GENERAL PDF INTERNAL METADATA PREPARATION
+%% ----------------------------------------------------------------------------
+%
+% Create hashes that will be used for uuid data. Does not need to be fancy:
+\edef\xmp@docid{\pdfx@mdfivesum{jobname.pdf}}
+\edef\xmp@instid{\pdfx@mdfivesum{\pdfcreationdate}}
+%
+%% End general PDF in internal metadata preparation.
+
+
+
+%% PREPARATION OF XMP METADATA
+%% ----------------------------------------------------------------------------
+%% Data prepared here, will later be inserted into the XMP packet template,
+%% then the processed template will be incuded in the PDF.
+%% XMP metadata is in utf-8 encoding.
+%
+% Make the XMP look pretty:
+\def\pad@ii{\space\space}
+\def\pad@iv{\pad@ii\pad@ii}
+\def\pad@vi{\pad@iv\pad@ii}
+\def\pad@viii{\pad@vi\pad@ii}
+\def\pad@x{\pad@viii\pad@ii}
+\def\pad@xii{\pad@x\pad@ii}
+\def\pad@xiv{\pad@xii\pad@ii}
+\def\pad@xvi{\pad@xiv\pad@ii}
+\def\pad@xviii{\pad@xvi\pad@ii}
+\def\pad@xx{\pad@xviii\pad@ii}
+\def\pad@xxxii{\pad@xvi\pad@xvi}
+\def\pad@lxiv{\pad@xxxii\pad@xxxii}
+\def\pad@cxxviii{\pad@lxiv\pad@lxiv}
+\def\pad@cclvi{\pad@cxxviii\pad@cxxviii}
+\def\pad@dxii{\pad@cclvi\pad@cclvi}
+%
+% Frankly, I am not sure if all this rigamarole is necessary, but it works!
+% Here, portions of XMP code are prepared. Later, they will be inserted
+% into the XMP packet template.
+\gdef\@titleString{
+ \pad@vi<dc:title>^^J
+ \pad@viii<rdf:Alt>^^J
+ \pad@x<rdf:li xml:lang="x-default">\@title</rdf:li>^^J
+ \pad@viii</rdf:Alt>^^J
+ \pad@vi</dc:title>^^J
+}
+%
+\ifthenelse{\equal{\@author}{}}{
+ \gdef\@authorString{}
+}{
+ \gdef\@authorString{
+ \pad@vi<dc:creator>^^J
+ \pad@viii<rdf:Bag>^^J
+ \pad@x<rdf:li>\@author</rdf:li>^^J
+ \pad@viii</rdf:Bag>^^J
+ \pad@vi</dc:creator>^^J
+ }
+}
+%
+\def\@documentID{uuid:\xmp@docid}
+\def\@instanceID{uuid:\xmp@instid}
+%
+\def\@pdfVersion{1.\the\pdfminorversion}
+%
+\if@pdfxISoff
+ \gdef\@verconfString{}%
+\else
+ \gdef\@verconfString{
+ \pad@vi<pdfx:GTS_PDFXVersion>\@PDFXversion</pdfx:GTS_PDFXVersion>^^J
+ \if@HasConformance
+ \pad@vi<pdfx:GTS_PDFXConformance>%
+ \@PDFXconformance</pdfx:GTS_PDFXConformance>^^J
+ \fi
+ }
+\fi
+%
+\if@pdfxISoff
+ \gdef\@pdfidString{}%
+\else
+ \gdef\@pdfidString{
+ \pad@vi<pdfxid:GTS_PDFXVersion>\@PDFXversion</pdfxid:GTS_PDFXVersion>^^J
+ }
+\fi
+%
+\ifthenelse{\equal{\@novelApplication}{} \OR \equal{\@novelApplication}{ }}{
+ \gdef\@applicationString{}%
+}{
+ \gdef\@applicationString{\pad@vi<xmp:CreatorTool>%
+ \@novelApplication</xmp:CreatorTool>^^J}%
+}
+%
+\ifthenelse{\equal{\@novelProducer}{} \OR \equal{\@novelProducer}{ }}{
+ \gdef\@producerString{}%
+}{
+ \gdef\@producerString{\pad@vi<pdf:Producer>%
+ \@novelProducer</pdf:Producer>^^J}%
+}
+%
+% Calculation of Dates and Times, which must be in a specific format.
+% Each time you process to PDF, the current date/time is used,
+% for all of the several metadata date/time strings.
+\def\xmp@cDate{\pdfx@getYear}
+{\catcode`\D=12 \catcode`\:=12
+ \gdef\pdfx@getYear D:#1#2#3#4{\edef\pdfx@xYear{#1#2#3#4}\pdfx@getMonth}
+}
+\def\pdfx@getMonth#1#2{\edef\pdfx@xMonth{#1#2}\pdfx@getDay}
+\def\pdfx@getDay#1#2{\edef\pdfx@xDay{#1#2}\pdfx@getHour}
+\def\pdfx@getHour#1#2{\edef\pdfx@xHour{#1#2}\pdfx@getMin}
+\def\pdfx@getMin#1#2{\edef\pdfx@xMin{#1#2}\pdfx@getSec}
+\def\pdfx@getSec#1#2{\edef\pdfx@xSec{#1#2}\pdfx@getTZh}
+\def\pdfx@getTZh{\futurelet\pdfx@next\pdfx@getTzh@branches}
+%
+{\catcode`\@=11 \catcode`\Z=12 \catcode`\+=12 \catcode`\-=12 % ends below
+\gdef\pdfx@getTzh@branches{%
+ \ifx\pdfx@next Z\let\pdfx@getTzbranch\pdfx@getTznozone
+ \else\ifx\pdfx@next +\let\pdfx@getTzbranch\pdfx@getTzplus
+ \else\ifx\pdfx@next -\let\pdfx@getTzbranch\pdfx@getTzminus
+ \else\let\pdfx@getTzbranch\pdfx@getTzerror
+ \fi\fi\fi \pdfx@getTzbranch }
+%
+\catcode`\0=12
+\gdef\pdfx@getTznozone Z#1\pdfx@getTzend{%
+ \edef\pdfx@xTzh{+00}\edef\pdfx@xTzm{00}}
+\gdef\pdfx@getTzplus +#1'#2'#3\pdfx@getTzend{%
+ \edef\pdfx@xTzh{+#1}\edef\pdfx@xTzm{#2}%
+ \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
+\gdef\pdfx@getTzminus -#1'#2'#3\pdfx@getTzend{%
+ \edef\pdfx@xTzh{-#1}\edef\pdfx@xTzm{#2}%
+ \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
+%
+\expandafter\ifx\csname pdfcreationdate\endcsname\relax
+\else
+ \expandafter\expandafter\expandafter\xmp@cDate\pdfcreationdate''\pdfx@getTzend
+ \xdef\pdfx@convDate{\pdfx@xYear\pdfx@xMonth\pdfx@xDay\pdfx@xHour
+ \pdfx@xMin\pdfx@xSec\pdfx@xTzh'\pdfx@xTzm'}%
+ \xdef\xmp@cDate{\pdfx@xYear-\pdfx@xMonth-\pdfx@xDay
+ T\pdfx@xHour:\pdfx@xMin:\pdfx@xSec\pdfx@xTzh:\pdfx@xTzm}%
+\fi
+}% End of \catcode`\@=11 etc.
+\let\@modifyDate\xmp@cDate
+\let\@createDate\xmp@cDate
+\let\@metadataDate\xmp@cDate
+% End dates and times.
+%
+%% End Prepare XMP metadata.
+
+
+
+%% WRITE THE XMP METADATA, UNLESS PDF/X IS OFF OR NO TITLE
+%%-----------------------------------------------------------------------------
+%% Inserts the prepared XMP metadata into XMP packet template, then writes
+%% the result at the start of the PDF, right now, before the document.
+%
+\if@pdfxISoff\else
+ \if@HasTitle
+ \begingroup
+ \makeatletter
+ \input{novel-xmppacket.sty}
+ \global\let\@xmpData\@xmpPacket % from the above file
+ \begingroup
+ \pdfcompresslevel=0
+ \immediate\pdfobj stream attr {/Type /Metadata /Subtype /XML} {\@xmpData}
+ \pdfcatalog{/Metadata \the\pdflastobj\space 0 R}
+ \endgroup
+ \endgroup
+ % Creates external xml file, if requested:
+ \if@wantXMPasXML
+ \newwrite\file
+ \immediate\openout\file=\jobname-XMPasXML.xml
+ \immediate\write\file{<?xml version="1.0" encoding="UTF-8" %
+ standalone="yes" ?>^^J}
+ \immediate\write\file{<!-- Ignore any message about not having style %
+ information. That is normal. -->^^J}
+ \immediate\write\file{<!-- Your viewer's font must be able to display %
+ any characters used in the XMP. -->^^J}
+ \immediate\write\file{<!-- For example, if your XMP has Cyrillic, %
+ then you need a Cyrillic-capable font. -->^^J}
+ \immediate\write\file{<!-- Any decorations (such as dashes in front of %
+ lines) are added by the viewer. Not in XMP. -->^^J}
+ \immediate\write\file{<!-- Note: xpacket begin="" contains the invisible %
+ 3-byte utf-8 BOM within its quotes. -->^^J}
+ \immediate\write\file{<!-- The above xml declaration, and these %
+ comments, are not part of the XMP packet. -->^^J}
+ \immediate\write\file{\@xmpData^^J}
+ \closeout\file
+ \fi
+ \fi
+\fi
+%
+%
+%% End write the XMP metadata.
+
+
+
+%% PREPARE PDF /INFO METADATA
+%% ----------------------------------------------------------------------------
+%% PDF /Info is another form of metadata, older than XMP but still used.
+%% It is NOT in utf-8 encoding. Depending on content, one of two encodings
+%% will be automatically used: PDFDoc encoding if metadata uses only
+%% characters within Latin-1, or utf-16 if metadata is not within Latin-1.
+%% Either way, the input was utf-8 before processing.
+%% In principle, PDF /Info is obsolete whenever PDF/X is used, because
+%% XMP metadata is supposed to prevail through the printing workflow.
+%% In practice, things don't always work that way. So, unless your PDF
+%% has no metadata, essential items are re-encoded and copied to PDF /Info.
+%% Other than encoding, XMP metadata and PDF /Info must be exactly the same.
+%% All of those issues are handled automatically here.
+%% The result is written at the end of the PDF, after the document.
+%
+% Macro for massaging encodings:
+\def\@infotopdfstring#1#2{%
+ \ifx#2\@empty
+ \global\let#1\empty
+ \else
+ \begingroup
+ \hypersetup{pdfencoding=auto}%
+ \pdfstringdef#1{#2}%
+ \endgroup
+ \fi
+}
+% Now, massage the metadata:
+\@infotopdfstring{\@infotitle}{\@title}
+\@infotopdfstring{\@infoauthor}{\@author}
+\@infotopdfstring{\@infoapplication}{\@novelApplication}
+\@infotopdfstring{\@infoproducer}{\@novelProducer}
+%
+%% End prepare PDF /Info.
+
+
+
+%% WRITE THE OUTPUT INTENT, UNLESS PDFX IS OFF.
+%% ----------------------------------------------------------------------------
+% Data for CGATS TR 001, FOGRA39, and JC200103 are in file novel-FileData.sty.
+\if@pdfxISoff\else
+ \begingroup
+ \edef\@pctchar{\expandafter\@gobble\string\%} % Escaped in TeX, not PDF.
+ \edef\@bchar{\expandafter\@gobble\string\\} % For use as escape, below.
+ \edef\0{\string\0} % Not sure why, but it works.
+ \edef\({\string\(} % PDF Catalog requires escaped parentheses.
+ \edef\){\string\)} % PDF Catalog requires escaped parentheses.
+ \catcode`\_ 12 % The icc file name might contain underscores.
+ %
+ \if@EmbedICC
+ \IfFileExists{\@OIprofile}{%
+ \immediate\pdfobj stream attr{/N 4} file{\@OIprofile}%
+ \edef\OBJ@OI{\the\pdflastobj\space 0 R}%
+ }{%
+ \ClassError{novel}{Requested icc color profile not found}%
+ {You used the starred \string\SetPDFX*\space which embeds the ^^J%
+ associated icc color profile. But the file could not be located. ^^J%
+ If necessary, put it in the same folder as your *.tex document. ^^J%
+ Incidentally: Do you really need to embed the profile?}%
+ }
+ \fi
+ \ifthenelse{\equal{\@OIcondition}{}}{
+ \edef\@OIconditionString{}%
+ }{
+ \edef\@OIconditionString{/OutputCondition (\@OIcondition)}%
+ }
+ \ifthenelse{\equal{\@OIidentifier}{}}{
+ \edef\@OIidentifierString{}%
+ }{
+ \edef\@OIidentifierString{/OutputConditionIdentifier (\@OIidentifier)}%
+ }
+ \ifthenelse{\equal{\@OIinfo}{}}{
+ \edef\@OIinfoString{}%
+ }{
+ \edef\@OIinfoString{/Info (\@OIinfo)}%
+ }
+ \ifthenelse{\equal{\@OIregistry}{}}{
+ \edef\@OIregistryString{}%
+ }{
+ \edef\@OIregistryString{/RegistryName (\@OIregistry)}%
+ }
+ \pdfcatalog{%
+ /OutputIntents [ <<%
+ /Type/OutputIntent%
+ /S/GTS_PDFX%
+ \@OIconditionString%
+ \@OIidentifierString%
+ \@OIinfoString%
+ \@OIregistryString%
+ \if@EmbedICC/DestOutputProfile \OBJ@OI\fi%
+ >> ]%
+ }%
+ \endgroup
+\fi
+%
+%% End write the output intent.
+
+
+
+%% DISABLE HYPERREF OPTIONS
+%%-----------------------------------------------------------------------------
+%% Prevents changes that will cause an incompatibility.
+%
+\Hy@DisableOption{pdfauthor}%
+\Hy@DisableOption{pdftitle}%
+\Hy@DisableOption{pdfsubject}%
+\Hy@DisableOption{pdfcreator}%
+\Hy@DisableOption{pdfcreationdate}%
+\Hy@DisableOption{pdfmoddate}%
+\Hy@DisableOption{pdfproducer}%
+\Hy@DisableOption{pdfkeywords}%
+%
+%% End disable hyperref options.
+
+
+
+%% PREPARE PDF/Info
+%% ----------------------------------------------------------------------------
+\gdef\@ActivatePDFInfo{% called by `novel.cls' \AtBeginDocument
+ \if@HasTitle
+ \pdfinfo{
+ \ifx\@infotitle\@empty\else /Title(\@infotitle)\fi
+ \ifx\@infoauthor\@empty\else /Author(\@infoauthor)\fi
+ \ifx\@infoapplication\@empty\else /Creator(\@infoapplication)\fi
+ \ifx\@pdfcreationdate\@empty
+ /CreationDate(D:\pdfx@convDate)%
+ \else
+ /CreationDate(\@pdfcreationdate)%
+ \fi
+ \ifx\@pdfmoddate\@empty
+ /ModDate(D:\pdfx@convDate)%
+ \else
+ /ModDate(\@pdfmoddate)%
+ \fi
+ \ifx\@infoproducer\@empty\else /Producer(\@infoproducer)\fi%
+ /Trapped/False%
+ \if@pdfxISoff\else
+ /GTS_PDFXVersion(\@PDFXversion)%
+ \if@HasConformance /GTS_PDFXConformance(\@PDFXconformance)\fi%
+ \fi
+ }
+ \fi
+}%
+%% End \@ActivatePDFInfo.
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-pdfx.sty'.
+
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel-xmppacket.sty b/macros/luatex/latex/novel/tex/lualatex/novel/novel-xmppacket.sty
new file mode 100644
index 0000000000..006c5f777e
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel-xmppacket.sty
@@ -0,0 +1,111 @@
+%%
+%% This is file `novel-xmppacket.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, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% The descriptive properties of the namespaces, and the general format of XMP,
+%% are public standards released by Adobe Systems Incorporated.
+%% See http://www.adobe.com/products/xmp.html
+%%
+%% ----------------------------------------------------------------------------
+%%
+%%
+\ProvidesFile{novel-xmppacket.sty}%
+[2023/02/08 any version. (novel XMP packet template)]
+%%
+
+
+
+% This packet uses utf-8 BOM.
+% The catcodes allow # _ ~ $ % & to be used as ordinary characters.
+% \edef and \let get rid of escape backslashes in front of those characters.
+% NO COMMENTS AFTER THIS! Until \endgroup.
+
+
+
+
+
+\begingroup
+\catcode`\¤=12\relax
+\lccode`\¤="FEFF
+\lowercase{\gdef\@novelBOM{¤}}
+\catcode`\#=12
+\catcode`\_=12
+\catcode`\~=12
+\catcode`\$=12
+\catcode`\%=12
+\catcode`\&=12
+
+\edef\@pctchar{\expandafter\@gobble\string\%}
+\let\%\@pctchar
+\edef\@hashchar{\expandafter\@gobble\string\#}
+\let\#\@hashchar
+\edef\@ampchar{\expandafter\@gobble\string\&amp;}
+\let\&\@ampchar
+\edef\@dollarchar{\expandafter\@gobble\string\$}
+\let\$\@dollarchar
+\edef\@underchar{\expandafter\@gobble\string\_}
+\let\_\@underchar
+\edef\@tildechar{\expandafter\@gobble\string\~}
+\let\~\@tildechar
+
+\xdef\@xmpPacket{<?xpacket begin="\@novelBOM" id="W5M0MpCehiHzreSzNTczkc9d"?>^^J
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04\pad@iv\pad@iv">^^J
+\pad@ii<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:xmp="http://ns.adobe.com/xap/1.0/">^^J
+\pad@vi<xmp:ModifyDate>\@modifyDate</xmp:ModifyDate>^^J
+\pad@vi<xmp:CreateDate>\@createDate</xmp:CreateDate>^^J
+\@applicationString
+\pad@vi<xmp:MetadataDate>\@metadataDate</xmp:MetadataDate>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:dc="http://purl.org/dc/elements/1.1/">^^J
+\pad@vi<dc:format>application/pdf</dc:format>^^J
+\@titleString
+\@authorString
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">^^J
+\pad@vi<xmpMM:DocumentID>\@documentID</xmpMM:DocumentID>^^J
+\pad@vi<xmpMM:InstanceID>\@instanceID</xmpMM:InstanceID>^^J
+\pad@vi<xmpMM:RenditionClass>default</xmpMM:RenditionClass>^^J
+\pad@vi<xmpMM:VersionID>1</xmpMM:VersionID>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdf="http://ns.adobe.com/pdf/\@pdfVersion/">^^J
+\@producerString
+\pad@vi<pdf:Trapped>False</pdf:Trapped>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdfx="http://ns.adobe.com/pdfx/\@pdfVersion/">^^J
+\@verconfString
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/">^^J
+\@pdfidString
+\pad@iv</rdf:Description>^^J
+\pad@ii</rdf:RDF>^^J
+</x:xmpmeta>^^J
+\pad@dxii
+<?xpacket end="w"?>}
+\endgroup
+
+
+% OK to use comments now.
+%%
+\endinput
+%%
+%% End of file `novel-xmppacket.sty'.
+
diff --git a/macros/luatex/latex/novel/tex/lualatex/novel/novel.cls b/macros/luatex/latex/novel/tex/lualatex/novel/novel.cls
new file mode 100644
index 0000000000..0d894e1fdf
--- /dev/null
+++ b/macros/luatex/latex/novel/tex/lualatex/novel/novel.cls
@@ -0,0 +1,643 @@
+%%
+%% This is file `novel.cls', LuaLaTeX `novel' document class.
+%% Copyright 2017-2023 Robert Allgeyer.
+%% Contact: Username `rallg' on GitHub and stackexchange. `RobtAll' on CTAN.
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+% Actually needs LuaLaTeX, at least version 0.95 from TeXLive 2016.
+\ProvidesClass{novel}[2023/02/08 v1.80 LaTeX document class]
+%%
+%% Version 1.80: Minor changes. Class option `revert' for 1.5.2 behavior.
+
+
+%% DESCRIPTION:
+%% ----------------------------------------------------------------------------
+%% Class `novel' is designed for print fiction: novels or short stories.
+%% It cannot be used for e-books or for journal publication.
+%% It is not suitable for most non-fiction, because routine academic features
+%% such as bibiography and automatic sectioning are defeated.
+%%
+%% There are pre-configured layouts for the most commonly used choices of
+%% trim size (finished book width and height), and internal layout consistent
+%% with fiction. The user can over-ride the pre-configured settings.
+%%
+%% The class will automatically create PDF/X compliant files upon request,
+%% using a self-contained command structure. Results have been tested.
+%%
+%% LuaLaTeX is required, and input files must be encoded utf-8.
+%%
+%% Fonts are loaded by luaotfload and fontspec, and massaged by microtype.
+%% For best results, use modern Open Type fonts, or TrueType fonts.
+%%
+%% The Libertinus font family, fork of [Linux] Libertine/Biolinum, is default.
+%% An included custom font, NovelDeco.otf, is used for special purposes.
+%%
+
+
+%% REQUIRE LUATEX and do some preliminary setup.
+%% ----------------------------------------------------------------------------
+%% These are not user settings.
+%
+\RequirePackage{ifluatex} % LuaTeX is required. Not XeTeX, dvips, or pdfTeX.
+\RequirePackage{ifxetex} % For occasional hacks (hiss, boo).
+\RequirePackage{luatex85} % Needed for compatibility with LuaTeX 0.95 etc.
+\RequirePackage{pdftexcmds} % compatibility
+\ifluatex
+ % New with TeXlive 2016. Removes unnecessary File Data:
+ \pdfvariable suppressoptionalinfo 511 % writes only ID to PDF Catalog
+\else
+ \ClassError{novel}{Must compile with LuaLaTeX 0.95+}%
+ {Sorry, LuaLaTeX only. No pdfTeX, dvips, or XeTeX.^^J%
+ Command line: lualatex your-document.tex}
+\fi
+\pdfimageresolution=300 % default dpi if image does not say
+%
+\RequirePackage{etoolbox} % general good stuff
+\RequirePackage{xifthen} % improved ifthenelse handling
+\RequirePackage{xstring} % parses strings
+\RequirePackage{fp} % used everywhere for math calculations
+\RequirePackage{xfp} % more math calculations
+\RequirePackage{keyval} % used by drop cap
+\FPmessagesfalse % eliminates numerous friendly messages from the log
+%
+\pdfminorversion=3 % might be reset later, depending on settings
+\gdef\thepdfminorversion{\pdfminorversion} % compatibility
+%
+\RequirePackage{silence} % Used here:
+% hyperref draft mode is always on, even when novel is not in draft mode:
+\WarningFilter{hyperref}{Draft mode on} % So, get rid of the hyperref warning.
+% Prevent complaints about no protrusion list for cmr, cmm, etc. in decimal pt:
+\WarningFilter{microtype}{I cannot find a protrusion list} % It's not there!
+%
+\WarningsOff[Fancyhdr,fancyhdr] % complains about headheight when no header
+\RequirePackage[relative]{textpos} % for inserting images
+\RequirePackage{calc} % allows length expression calculations
+\RequirePackage{atbegshi} % in oberdiek bundle. For one-page header changes. Also used by hyperref.
+\RequirePackage{letltxmacro} % in oberdiek bundle. For re-defining some macros
+\RequirePackage{xparse} % for writing cool-looking commands
+%
+% In addition, the following packages are required, but not loaded yet.
+% They must wait for something else to happen first. Then they will be loaded
+% with suitable arguments, when the time comes:
+% fontspec -- in novel-LayoutSettings.sty
+% unicode-math -- in novel-LayoutSettings.sty
+% microtype -- in novel-Fonts.sty
+% hyperref -- in novel-pdfx.sty
+% fancyhdr -- in novel.HeadFootStyles.sty
+% xcolor -- lower in this page
+% adjustbox -- lower on this page
+% eso-pic -- lower on this page
+% lipsum -- lower on this page
+%%
+
+
+\newlength\@tempLength % scratch length for local calculations
+\newif \if@tempTF % scratch boolean for local tests
+
+
+%% Global lengths are often passed around in `novel'.
+%% But \setlength is not always global in effect.
+%% This code defines a global command.
+%% Via Heiko Oberdiek at tex.stackexchange.com:
+\gdef\gsetlength#1#2{% #1 is the length command, #2 is the length value
+ \begingroup%
+ \setlength\skip@{#2}% Local assignment to a TeX scratch register.
+ \global#1=\skip@% Global assignment to #1
+ \endgroup% \skip@ is restored by end of group.
+}% end \gsetlength
+%%
+
+
+%% Process document class options.
+%% ----------------------------------------------------------------------------
+% Allowed option list:
+% draft xml shademargins cropmarks cropview closecrop
+% coverart sandbox unblock mtoff test revert
+% Yes, I realize that this could have been done another way, but I want
+% to issue error messages from `novel' rather than (say) `keyval':
+\gdef\@mycol{\@classoptionslist}
+\StrDel{\@mycol}{ }[\@mycol]
+\StrDel{\@mycol}{,}[\@mycol]
+\StrDel{\@mycol}{revert}[\@mycol]
+\StrDel{\@mycol}{draft}[\@mycol]
+\StrDel{\@mycol}{xml}[\@mycol]
+\StrDel{\@mycol}{shademargins}[\@mycol]
+\StrDel{\@mycol}{graytext}[\@mycol] % Obsolete. Now always allows graytext.
+\StrDel{\@mycol}{greytext}[\@mycol] % See above.
+\StrDel{\@mycol}{cropmarks}[\@mycol]
+\StrDel{\@mycol}{cropview}[\@mycol]
+\StrDel{\@mycol}{closecrop}[\@mycol]
+\StrDel{\@mycol}{coverart}[\@mycol]
+\StrDel{\@mycol}{unblock}[\@mycol]
+\StrDel{\@mycol}{mtoff}[\@mycol]
+\StrDel{\@mycol}{test}[\@mycol]
+\StrDel{\@mycol}{sandbox}[\@mycol]
+%
+\ifthenelse{\equal{\@mycol}{}}{}{
+ \ClassWarning{novel}{^^JUnrecognized class option: \@mycol. ^^J%
+ The unrecognized option was ignored! ^^J%
+ Note that font size, document size, and language ^^J%
+ are not `novel' class options. See documentation. ^^J}%
+}
+% Version 1.80 has minor tweaks. Option `revert' for version 1.52 behavior.
+\newif \if@novrevert
+\DeclareOption{revert}{\@novreverttrue}
+% If used, option `draft' shows overflow rule.
+\newif \ifdraftdoc
+\setlength\overfullrule{0pt}
+\DeclareOption{draft}{
+ \setlength\overfullrule{6pt}
+ \draftdoctrue
+ \ClassWarning{novel}{^^JCompiled with draft mode. Not for final release! ^^J}
+}
+\newif \ifmsdoc % manuscript, always false. Compatibility with other packages.
+% If used, option `xml' creates a file `\jobname-XMPasXML.xml` that contains
+% the XMP metadata with an xml declaration and comments at top.
+% Only works when \SetPDFX is not `off'. Note that you do not need to use
+% this option to get PDF/X. It is only for your own usage.
+\newif \if@wantXMPasXML
+\DeclareOption{xml}{\@wantXMPasXMLtrue}
+\DeclareOption{xmp}{ % in case you mis-type.
+ \ClassError{novel}{No class option `xmp'. Use `xml'}%
+ {There is no class option named `xmp'. It is `xml'.}
+}
+% Option `shademargins' does just that. Ignored unless in draft mode.
+\newif \if@shademargins
+\DeclareOption{shademargins}{\@shademarginstrue}
+%
+\newif \if@graytext % remains here for backwards compatibility
+\@graytexttrue % Always true.
+%
+% Usually you do NOT want crop (trim) marks!
+\newif \if@cropmarks
+\DeclareOption{cropmarks}{\@cropmarkstrue}
+% PDF viewers display CropBox, which normally is identical to MediaBox.
+% Option `cropview', sets CropBox to TrimBox instead, so that's all you see.
+% Only makes a difference when MediaBox is larger than TrimBox.
+% Ignored unless in draft mode.
+\newif \if@cropview
+\DeclareOption{cropview}{\@cropviewtrue}
+% With `closecrop', the TrimSize and margins are re-sized, to preserve the
+% live area, but with reduced margins on all sides (same for verso/recto).
+% This option is available only in draft mode, and disables shademargins.
+% The purpose is to create a PDF that is more easily read on a handheld device,
+% so you can think about edits while traveling. It is NOT an e-book, since
+% it has no hyperlinks and is missing some features that an e-book should have.
+\newif \if@closecrop
+\DeclareOption{closecrop}{\@cropviewtrue\@closecroptrue}
+% This is used to create a 1-page file with no text, just an image.
+% Option coverart. Intended purpose is PDF/X for novel cover.
+\newif \if@coverart
+\DeclareOption{coverart}{\@coverarttrue}
+% Option unblock, for developer use only.
+% Normally, a number of packages known to be incompatible with `novel'
+% are blocked from loading. If the user tries to get them via \usepackage
+% or \RequirePackage, or if they are called within some other loaded package,
+% then compile halts with an error. The `unblock' option turns off blocking,
+% and allows incompatible packages to load. Use only at own risk!
+\newif \if@novelunblock % For developer use.
+\DeclareOption{unblock}{\@novelunblocktrue}
+% Option mtoff. Primarily for developer use.
+% With mtoff, the microtype package is not loaded.
+\newif \if@mtoff
+\DeclareOption{mtoff}{\@mtofftrue}
+% Option test. Primarily for developer use.
+\newif \if@testsuite
+\DeclareOption{test}{\@testsuitetrue}
+%
+% Option sandbox. for artwork and tables. Max 4 pages.
+\newif \if@sandbox
+\DeclareOption{sandbox}{\@sandboxtrue}
+%
+%% Note that document size and normal font size are not class options.
+%% They are set by commands in the Preamble, and have default values.
+%
+\ProcessOptions\relax
+% Disable some options, depending on compatibilities:
+\ifdraftdoc\else
+ \global\@shademarginsfalse
+ \global\@cropviewfalse
+ \global\@closecropfalse
+\fi
+%
+\if@testsuite
+ \gdef\@testintentional{Test suite intentionally generates this warning. ^^J}
+\else
+ \gdef\@testintentional{}
+\fi
+%
+\if@cropview
+ \global\@cropmarksfalse
+\fi
+%
+\if@closecrop
+ \global\@cropviewtrue
+ \global\@shademarginsfalse
+ \global\@cropmarksfalse
+\fi
+%
+\if@coverart
+ \global\draftdocfalse
+ \global\@shademarginsfalse
+ \global\@cropviewfalse
+ \global\@closecropfalse
+ \global\@sandboxfalse
+\fi
+%
+\if@sandbox
+ % Thanks to user Compholio at stackexchange.com:
+ \newcounter{sandboxcount}
+ \ifx\latex@outputpage\@undefined\relax%
+ \global\let\latex@outputpage\@outputpage%
+ \fi%
+ \gdef\@outputpage{%
+ \addtocounter{sandboxcount}{1}%
+ \ifnum\value{sandboxcount}>4\relax% no output after 4 pages
+ \else%
+ \latex@outputpage%
+ \fi%
+ }%
+ \AtEndPreamble{%
+ \gdef\@title{untitled interior artwork}%
+ }%
+ \AfterEndPreamble{%
+ \ifdraftdoc\else\thispagestyle{empty}\fi%
+ }%
+\fi
+%% end class options
+
+
+\RequirePackage{noindentafter} % for unindented chapter and scene starts
+\RequirePackage{changepage} % provides block indents, etc. Do not use strict!
+\RequirePackage{magaz} % special treatment of first lines
+
+
+%% Activate xcolor, adjustbox, and eso-pic:
+%% ----------------------------------------------------------------------------
+% The final book must be black/white and gray only, for all text.
+% Interior images must be raster black/white or grayscale. See documentation.
+% Vector graphics are strongly discouraged, in any case.
+% In draft mode only, the `shademargins' option requires `grayscale',
+% which will be temporarily enabled, even if not specifically requested.
+%
+\RequirePackage[gray,hyperref]{xcolor}
+%
+% adjustbox and eso-pic cannot precede xcolor.
+\RequirePackage{adjustbox} % for scaling and moving
+\RequirePackage{eso-pic} % background effects in draft mode
+\RequirePackage{pdfpages} % only used for pdf pre-processed by novel-scripts
+%% end activate xcolor and adjustbox
+
+
+%% Temporary normal font size, baselineskip, and fontspec
+%% ----------------------------------------------------------------------------
+%% This normalsize is temporary, so that packages can load without complaint.
+%% It will be modified later, during layout calculations.
+%% Actual default font size will be 11pt-12pt, with 11.4pt average.
+%% The small temporary size is to ensure that overly-large struts and skips
+%% are not created prior to page layout calculation.
+\gdef\@TentativeEmN{10}
+\gdef\@TentativeBLSkipN{13}
+\renewcommand\normalsize{%
+ \@setfontsize\normalsize{\@TentativeEmN}{\@TentativeBLSkipN}%
+}
+\normalsize
+\RequirePackage[no-math]{fontspec} % For LuaLaTeX. NOT package `fontenc'.
+% The `novel' class is not intended for math. But TeX assumes you do math,
+% so it needs a math font, whether you like it or not.
+\RequirePackage{unicode-math}
+%% end temporary normal point size, baselineskip, and fontspec.
+
+
+%% Define commands used for File Data, including PDF/X Settings.
+%% ----------------------------------------------------------------------------
+%% As used here, `File Data' refers to PDF metadata as found in PDF/Info
+%% and in XMP. This class does not write it to the PDF Catalog.
+\RequirePackage{novel-FileData}
+%%
+
+
+%% Physical Layout Commands and Settings.
+%% ----------------------------------------------------------------------------
+%% Define user commands that over-ride class option pre-configured settings.
+%% Also sets a variety of miscellaneous lengths:s \parsep, \parindent, etc.
+\RequirePackage{novel-LayoutSettings}
+
+
+%% Language support.
+%% ----------------------------------------------------------------------------
+\RequirePackage{polyglossia}
+\setdefaultlanguage[variant=american]{english} % may be changed by user
+%% end language support.
+
+
+%% Additional Macros, Loaded in Preamble.
+%% ----------------------------------------------------------------------------
+\RequirePackage{novel-Fonts} % font settings and defaults
+\if@coverart\else\RequirePackage{lipsum}\fi % generates dummy text for examples
+\RequirePackage{novel-DropCap}
+% Macros for use in document body:
+\RequirePackage{novel-TextMacros}
+% Standard header footer styles, based on `fancyhdr':
+% Each pre-configured style will set these booleans true or false:
+\newif\if@HasHeader \newif\if@HasFooter
+\RequirePackage{novel-HeadFootStyles}
+% Chapter and Scene styles:
+\RequirePackage{novel-ChapterScene}
+% Image placement:
+\RequirePackage{novel-Images}
+% Footnotes and endnotes:
+\RequirePackage{novel-Footnotes}
+%%
+
+
+%% For convenience, from `article' class.
+%% ----------------------------------------------------------------------------
+\newenvironment{verse}{% Not very useful.
+ \let\\\@centercr
+ \list{}{%
+ \itemsep\z@
+ \itemindent -\parindent%
+ \listparindent\itemindent
+ \rightmargin \leftmargin
+ \advance\leftmargin \parindent%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%%
+\newenvironment{quotation}{% Not very useful.
+ \list{}{%
+ \listparindent \parindent%
+ \itemindent \listparindent
+ \rightmargin \leftmargin
+ \parsep \z@%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%%
+\newenvironment{quote}{% Not very useful.
+ \list{}{%
+ \rightmargin\leftmargin%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%
+%% end convenience.
+
+
+
+%% Special features of test suite (for developers and error reporting)
+%% ----------------------------------------------------------------------------
+% Files `novel-testsuite.tex' and `novel-testimage.png' are within the novel
+% documentation extras folder. To run the test suite, copy these files to
+% a writeable location (such as your home directory) and compile there.
+\newcommand\testsuiteoops[1]{%
+ \ClassError{novel}{#1 missing}{Install the necessary file(s).}%
+}
+\if@testsuite
+ \IfFontExistsTF{libertinusserif-regular.otf}{}{%
+ \testsuiteoops{`libertinus' fonts}%
+ }
+ \IfFileExists{lmodern.sty}{}{\testsuiteoops{`lmodern' package}}
+ \IfFileExists{novel-testimage.png}{}{\testsuiteoops{`novel-testimage.png'}}
+ \NewFontFamily\mustbelibertinus{Libertinus Serif}
+ \NewFontFamily\mustbelmodern{Latin Modern Roman}
+\fi
+%% end special features of test suite.
+
+
+%% \AtEndPreamble sets defaults, calculates layout, and writes PDF/X
+%% ----------------------------------------------------------------------------
+% This is prior to \AtBeginDocument, and ensures that the results are available
+% prior to any \AtBeginDocument routines from user macros or loaded packages.
+\AtEndPreamble{
+ \@ActivateFonts % in `novel-Fonts.sty'
+ \RequirePackage{novel-CalculateLayout} % may load novel-ChangeLayout.sty
+ \RequirePackage{novel-PostLayout} % calculates shademargins, cropmarks, etc.
+ \RequirePackage{novel-pdfx}% also provides an \AtBeginDocument macro
+ \@GetInitialYpos% in `novel-TextMacros.sty
+}%
+%% end AtEndPreamble
+
+
+%% Messages that may be issued by \AtBeginDocument routines:
+%% ----------------------------------------------------------------------------
+%
+%% Dealing with known incompatible packages:
+\gdef\really@no#1#2#3{ % cannot be used, even with unblock or sandbox
+ \@ifpackageloaded{#1}{%
+ \ClassError{novel}{Sorry, package `#1' cannot be used in `novel' class}%
+ {No exceptions. You are out of luck. ^^J%
+ Reason: `novel' has #2 ^^J%
+ See `novel' HTML documentation, section #3. ^^J%
+ Note: The offending package may have been loaded by another package.}%
+ }{}%
+} %
+%
+%% Command or environment native to LuaLaTeX, but banned except in sandbox:
+\gdef\@OnlySandbox#1{%
+ \ClassError{novel}{Use of `#1' page \thepage\space requires sandbox}%
+ {`novel' class prohibits command or environment `#1' ^^J%
+ unless you use class option `sandbox'. See documentation.}%
+}
+%
+%% Package can be used, but Alert:
+\gdef\alert@nodisp#1{%
+ \@ifpackageloaded{#1}{%
+ \typeout{^^JClass `novel' Alert: Beware of package #1. ^^J%
+ Commands from this package may cause mis-positioning in main text. ^^J%
+ Maybe, maybe not. Best if usage is confined to display pages. ^^J}%
+ }%
+}
+%
+%% Dealing with blocked packages, allowed with `unblock':
+\if@novelunblock
+ \gdef\sorry@no#1{} % no package-specific errors, when unblock
+ \ClassWarning{novel}{Using `unblock' class option, at your own risk. ^^J%
+ The `unblock' option is for developer use, not production documents. ^^J%
+ If the unblocked packages and commands cause problems, ^^J%
+ they are not bugs. Do not report them. You have been warned. ^^J%
+ Perhaps your document will compile without error, and perhaps the ^^J%
+ results are OK. But in other cases, unexpected typesetting results. ^^J}%
+\else % package-specific errors, when no unblock
+ \gdef\sorry@no#1{
+ \@ifpackageloaded{#1}{%
+ \ClassError{novel}{Sorry, package `#1' cannot be used in `novel' class}%
+ {See `novel' HTML documentation, regarding `sandbox' option. ^^J%
+ Note: The offending package may have been loaded by another package.}%
+ }{}%
+ } %
+\fi
+%
+\gdef\@needsandboxmsg{%
+ \ClassError{novel}{Need `sandbox' for picture, figure, table environments}%
+ {You cannot use picture, figure, or table environments in `novel' unless ^^J%
+ you use the `sandbox' document class option. See docs.}%
+}
+%% end messages.
+
+
+%% \AtBeginDocument finishes the setup
+%% ----------------------------------------------------------------------------
+%
+\AtBeginDocument{ %
+ \@RedefineParapos % in `novel-TextMacros.sty'
+ \@ActivateTextLengths % in `novel-TextMacros.sty'
+ \@ActivateDropCaps % in `novel-DropCaps.sty'
+ \@ActivateChapterScene % in `novel-ChapterScene.sty'
+ \@ActivateHeadFootStyles % in file `novel-HeadFootStyles.sty'
+ \@AlertNoPDFX % in file `novel-pdfx.sty'
+ \@ActivatePDFInfo % in file `novel-pdfx.sty'
+ \@ActivateTextMacros % in `novel-TextMacros.sty'
+ \@ActivateFootnotes % in `novel-Footnotes.sty'
+ \@DisableFontSizes % in file `novel-LayoutSettings.sty'
+ \@DisableLayoutSettings % in file `novel-LayoutSettings.sty'
+ \@DisableFileDataSettings % in file `novel-FileData.sty'
+ \@DisableChapterSceneSettings % in file `novel-ChapterScene.sty'
+ \@RedefineBreakpos % in file `novel-ChapterScene.sty'
+ \@DisableHeadFootSettings % in file `novel-HeadFootStyles.sty'
+ \@GatherGoodImages % in file `novel-Images.sty'.
+ % List of always-blocked packages (not exhaustive, since TeX has so many):
+ \really@no{geometry}{its own layout commands.}{4}
+ \really@no{pdfx}{built-in PDF/X capability.}{3.4}
+ \really@no{xmpincl}{built-in PDF/X capability.}{3.4}
+ \really@no{hyperxmp}{built-in PDF/X capability.}{3.4}
+ \really@no{pdfxmult}{built-in PDF/X capability.}{3.4}
+ \really@no{inputenc}{utf-8 encoding always.}{1.2.1}
+ \really@no{fontenc}{`fontspec' and utf-8 encoding always.}{1.2.1, 1.2.3}
+ \really@no{biblatex}{no bibiography capability.}{1.2.5}
+ \really@no{showkeys}{an incompatible layout method.}{1.2.5}
+ \really@no{booktabs}{no capability for this, due to printer specs.}{3.4}
+ \really@no{pax}{no capability for this, due to printer specs.}{3.4}
+ \really@no{bookmark}{focus on paper books, not e-books.}{(top of file)}
+ \really@no{endnotes}{limited, built-in endnote methods.}{6.5}
+ \really@no{acronym}{focus on paper books, not e-books.}{(top of file)}
+ \really@no{embedfile}{incompatible print requirements.}{(top of file)}
+ \really@no{makeidx}{an incompatible layout method.}{1.2.5}
+ \really@no{gridset}{a command name conflict.}{4}
+ % Potential problem packages, allowed in sandbox or with unblock:
+ \if@sandbox
+ \RequirePackage{novel-Sandbox}
+ \else
+ \gdef\mplibcode{\@OnlySandbox{mplibcode}}
+ % Related to floats:
+ \sorry@no{floatflt}
+ \sorry@no{floatfig}
+ \sorry@no{flafter}
+ \sorry@no{float}
+ \sorry@no{morefloats}
+ \sorry@no{endfloat}
+ \sorry@no{placeins}
+ % Related to footnotes and endnotes:
+ \sorry@no{footmisc}
+ \sorry@no{footnote}
+ \sorry@no{manyfoot}
+ % Related to tables:
+ \sorry@no{multirow}
+ \sorry@no{tabu}
+ \sorry@no{tabularx}
+ \sorry@no{tabulary}
+ \sorry@no{longtable}
+ % Related to lists:
+ \sorry@no{array}
+ \sorry@no{easylist}
+ \sorry@no{listings}
+ \sorry@no{numitem}
+ \sorry@no{tasks}
+ % Related to graphics or layout:
+ \sorry@no{pagegrid}
+ \sorry@no{subfig}
+ \sorry@no{lpic}
+ \sorry@no{pinlabel}
+ \sorry@no{overpic}
+ \sorry@no{caption}
+ \sorry@no{sidecap}
+ \sorry@no{subcaption}
+ \sorry@no{paracol}
+ \sorry@no{scrextend}
+ \sorry@no{exsheets}
+ \sorry@no{eqparbox}
+ \sorry@no{colortbl}
+ \sorry@no{tikz}
+ \sorry@no{pstricks}
+ \sorry@no{xypic}
+ \sorry@no{xfig}
+ \sorry@no{pgfcalendar}
+ \sorry@no{pgfpages}
+ \sorry@no{pst-pdf}
+ \sorry@no{auto-pst-pdf}
+ \sorry@no{epstopdf}
+ \sorry@no{pdftricks}
+ \sorry@no{pdftricks2}
+ \sorry@no{mpgraphics}
+ \sorry@no{pict2e}
+ \sorry@no{picman}
+ \sorry@no{scalerel}
+ \sorry@no{pmgraph}
+ \sorry@no{reflectgraphics}
+ \fi % end sandbox.
+ % Alert packages, might cause minor layout problems, not enough to block:
+ \alert@nodisp{nth}
+ \alert@nodisp{engord}
+ \alert@nodisp{ulem}
+ \alert@nodisp{soul}
+ % end list of Alert packages.
+ % Package `pagegrid' interacts with `shademargins' and `draft' options:
+ \@ifpackageloaded{pagegrid}{ % that is, if permitted by sandbox or unblock
+ \ifdraftdoc
+ \if@shademargins
+ \ClassWarning{novel}{^^JGrid from `pagegrid' is concealed. ^^J%
+ Document class option `shademargins' over-writes page grid. ^^J%
+ To see the grid, use `draft' but not `shademargins'. ^^J}
+ \else\fi
+ \else
+ \ClassError{novel}{Package `pagegrid' needs `draft' mode}%
+ {Package `pagegrid' only with document class option `draft'.}%
+ \fi
+ }{} % end if pagegrid
+}% end \AtBeginDocument
+%%
+
+
+%% AtEndDocument adds one or two blank pages, required by printers.
+% Also writes list of inspected, good images to aux, for later use:
+\AtEndDocument{%
+ \if@coverart\else%
+ \if@sandbox\else%
+ \immediate\write\@auxout{%
+ \string\xdef\string\@AllGoodImages{\@AllGoodImages}^^J%
+ \string\xdef\string\@UnknownImages{\@UnknownImages}^^J%
+ }%
+ \cleartoend% adds 1 or 2 blanks, for final verso blank
+ \fi%
+ \fi%
+}
+%%
+
+
+%% AfterEndDocument writes final message:
+\AfterEndDocument{
+ \@WarnUnknownImages % in `novel-Images.sty'.
+}
+%%
+
+
+
+%%
+%% End of file `novel.cls'
+