diff options
author | Norbert Preining <norbert@preining.info> | 2024-02-24 03:01:46 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-02-24 03:01:46 +0000 |
commit | f325bd88d1d4db13f51277bc59c8ff8814e937bc (patch) | |
tree | e39af6619c91d812dd93cb57d25149da5a84d801 /macros | |
parent | e7a321bba289c40f39563c19bbeac355f7c0eeeb (diff) |
CTAN sync 202402240301
Diffstat (limited to 'macros')
99 files changed, 5154 insertions, 547 deletions
diff --git a/macros/latex/contrib/colorist/colorart.cls b/macros/latex/contrib/colorist/colorart.cls index dbea4b818c..ff1cf130b1 100644 --- a/macros/latex/contrib/colorist/colorart.cls +++ b/macros/latex/contrib/colorist/colorart.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {colorart} - {2024/02/20} {} + {2024/02/23} {} {A colorful article style} \tl_const:Nn \l__colorclass_base_class_tl { article } diff --git a/macros/latex/contrib/colorist/colorbook.cls b/macros/latex/contrib/colorist/colorbook.cls index 4566530a3a..81e6a6188f 100644 --- a/macros/latex/contrib/colorist/colorbook.cls +++ b/macros/latex/contrib/colorist/colorbook.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {colorbook} - {2024/02/20} {} + {2024/02/23} {} {A colorful book style} \tl_const:Nn \l__colorclass_base_class_tl { book } diff --git a/macros/latex/contrib/colorist/colorist-fancy.sty b/macros/latex/contrib/colorist/colorist-fancy.sty index 0674eb014d..15b7995abb 100644 --- a/macros/latex/contrib/colorist/colorist-fancy.sty +++ b/macros/latex/contrib/colorist/colorist-fancy.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {colorist-fancy} - {2024/02/20} {} + {2024/02/23} {} {The fancy style of colorist} \IfPackageLoadedTF { colorist } {} @@ -730,7 +730,7 @@ heading_suffix "}\n" } \newtheoremstyle{simple-var} {}{} - { \bool_if:NTF \l__colorist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__colorist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {0pt} { @@ -750,7 +750,7 @@ heading_suffix "}\n" {\color{main-text!50!paper}\thmnote{\hspace{.4em} \colorist_insert_l_mathparen: #3 \colorist_insert_r_mathparen: }}\nobreakspace\nobreakspace{\normalfont\textcolor{main-text!27!paper}{---}}\nobreakspace\nobreakspace} \newtheoremstyle{simple-var} {}{} - { \bool_if:NTF \l__colorist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__colorist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {0pt} {{\thmname{#1}\nobreakspace\thmnumber{#2}} @@ -784,7 +784,7 @@ heading_suffix "}\n" } \newtheoremstyle{basic-var} {}{} - { \bool_if:NTF \l__colorist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__colorist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {}{} {0pt} { @@ -803,7 +803,7 @@ heading_suffix "}\n" \thmnote{\normalfont\sffamily\color{main-text}\nobreakspace \colorist_insert_l_mathparen: #3 \colorist_insert_r_mathparen: }} \newtheoremstyle{basic-var} {0pt}{0pt} - { \bool_if:NTF \l__colorist_emphasis_theorem_bool { \itshape } { \normalfont } }{0pt} + { \bool_if:NTF \l__colorist_emphasize_theorem_bool { \itshape } { \normalfont } }{0pt} {}{\;}{0.25em} {{\thmname{#1}\nobreakspace\thmnumber{\textup{#2}}} \thmnote{\normalfont\sffamily\color{main-text}\nobreakspace \colorist_insert_l_mathparen: #3 \colorist_insert_r_mathparen: }} @@ -959,15 +959,15 @@ heading_suffix "}\n" \else \reversemarginpar \fi - \colorist_mpar_adjust:n {-.33em} + \colorist_mpar_adjust:n {\dimexpr.5em-8pt\relax} \marginnote{ \colorist_icon_ideabulb:w [0.3] {orange} \bool_if:NTF \l__colorist_is_book_bool { - \hspace*{-.2em} + \hspace*{-2pt} } { - \hspace*{-.5em} + \hspace*{-5pt} } } \normalmarginpar diff --git a/macros/latex/contrib/colorist/colorist.sty b/macros/latex/contrib/colorist/colorist.sty index 68044afbc8..0b4c2b9dd8 100644 --- a/macros/latex/contrib/colorist/colorist.sty +++ b/macros/latex/contrib/colorist/colorist.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {colorist} - {2024/02/20} {} + {2024/02/23} {} {A colorful style for articles and books} \keys_define:nn { colorist } @@ -70,10 +70,10 @@ , indent lists .dim_set:N = \l__colorist_item_indentation_dim , indent lists .default:n = { \parindent } - , emphasis-theorems .bool_set:N = \l__colorist_emphasis_theorem_bool - , emphasis-theorems .initial:n = { false } - , emphasis~theorems .bool_set:N = \l__colorist_emphasis_theorem_bool - , emphasis theorems .bool_set:N = \l__colorist_emphasis_theorem_bool + , emphasize-theorems .bool_set:N = \l__colorist_emphasize_theorem_bool + , emphasize-theorems .initial:n = { false } + , emphasize~theorems .bool_set:N = \l__colorist_emphasize_theorem_bool + , emphasize theorems .bool_set:N = \l__colorist_emphasize_theorem_bool , theorem-in-new-line .bool_set:N = \l__colorist_theorem_in_new_line_bool , theorem-in-new-line .initial:n = { false } diff --git a/macros/latex/contrib/crefthe/crefthe-doc.pdf b/macros/latex/contrib/crefthe/crefthe-doc.pdf Binary files differindex 524854ddd9..664da1ba34 100644 --- a/macros/latex/contrib/crefthe/crefthe-doc.pdf +++ b/macros/latex/contrib/crefthe/crefthe-doc.pdf diff --git a/macros/latex/contrib/crefthe/crefthe-doc.tex b/macros/latex/contrib/crefthe/crefthe-doc.tex index 39ccd9c191..a6d2dae2b7 100644 --- a/macros/latex/contrib/crefthe/crefthe-doc.tex +++ b/macros/latex/contrib/crefthe/crefthe-doc.tex @@ -121,7 +121,7 @@ \begin{document} \def\PackageVersion{2023/11/11} -\def\PackageSubVersion{} +\def\PackageSubVersion{a} \title{\crefthepackage{}\\\smallskip\itshape Cross referencing with proper definite articles} \author{Jinwen XU} diff --git a/macros/latex/contrib/crefthe/crefthe.sty b/macros/latex/contrib/crefthe/crefthe.sty index 51d2e5fbd2..3dd1c8e027 100644 --- a/macros/latex/contrib/crefthe/crefthe.sty +++ b/macros/latex/contrib/crefthe/crefthe.sty @@ -12,7 +12,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {crefthe} - {2023/11/11} {} + {2023/11/11a} {} {Cross referencing with proper definite articles} \keys_define:nn { crefthe } diff --git a/macros/latex/contrib/minimalist/README.md b/macros/latex/contrib/minimalist/README.md index 93ddc3fadc..4e46eb1e0a 100644 --- a/macros/latex/contrib/minimalist/README.md +++ b/macros/latex/contrib/minimalist/README.md @@ -11,13 +11,20 @@ It mainly consists of two parts. - Main part: - - `minimalist.sty` : interface of the main style - - `minimalist-default.sty` : the default style - - `minimalist-classical.sty` : the style "classical" - - `minimalist-flow.sty` : the style "flow" - - `minimalist-plain.sty` : the style "plain" - - `minimalist-stream.sty` : the style "stream" - - ... and more styles to come (currently on schedule: "modern") + - `minimalist.sty` : *interface of the main style* + - `minimalist-plain.sty` : *the style "plain"* + - The best choice for formal usage. + - `minimalist-default.sty` : *the default style* + - Slightly fancier than the plain style. + - `minimalist-flow.sty` : *the style "flow"* + - Suitable for writing course notes: sections and theorems are numbered together to create a storytelling atmosphere; proofs are colored by default. + - `minimalist-stream.sty` : *the style "stream"* + - Numbers are placed in the left margin; sections and theorems are numbered together to gain a streamlined feeling. + - `minimalist-classical.sty` : *the style "classical"* + - Originated in the typewriter style, now modernized. + - `minimalist-classicthesis.sty` + - Use your favorite design of [ClassicThesis](https://ctan.org/pkg/classicthesis) (and its carefully designed styles such as [ArsClassica](https://ctan.org/pkg/arsclassica)), while still have access to the features provided here, such as preconfigured theorem environments, multilingual support, enhanced author info block, etc. + - ... and more styles to come (currently on schedule: "elegant", "french", "modern", "typewriter") - `minimart.cls` : class for typesetting articles - `minimbook.cls` : class for typesetting books diff --git a/macros/latex/contrib/minimalist/minimalist-classical.sty b/macros/latex/contrib/minimalist/minimalist-classical.sty index 9b0dc1f76e..908de05e44 100644 --- a/macros/latex/contrib/minimalist/minimalist-classical.sty +++ b/macros/latex/contrib/minimalist/minimalist-classical.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist-classical} - {2024/02/20} {} + {2024/02/23} {} {The "classical" style of minimalist} \IfPackageLoadedTF { minimalist } {} @@ -769,7 +769,7 @@ heading_suffix "}\n" } \newtheoremstyle{simple-var} {.5\baselineskip}{.5\baselineskip} - { \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {\newline} { @@ -794,7 +794,7 @@ heading_suffix "}\n" } \newtheoremstyle{simple-var} {.5\baselineskip}{.5\baselineskip} - { \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {0pt} { @@ -864,13 +864,19 @@ heading_suffix "}\n" \SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + \bool_if:NT \l__minimalist_colored_proof_bool { - \hook_gput_code:nnn { env/proof/begin } { minimalist } + \clist_map_inline:nn { proof, proof* } { - \Hy@SaveLastskip - \color{ \l__minimalist_colored_proof_tl } - \Hy@RestoreLastskip + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } } } @@ -1144,6 +1150,7 @@ heading_suffix "}\n" %% Special adjustment %%================================ + \endinput %% %% End of file `minimalist/minimalist-classical.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist-classicthesis.sty b/macros/latex/contrib/minimalist/minimalist-classicthesis.sty new file mode 100644 index 0000000000..f22987b5a2 --- /dev/null +++ b/macros/latex/contrib/minimalist/minimalist-classicthesis.sty @@ -0,0 +1,679 @@ +%% +%% This is file `minimalist/minimalist-classicthesis.sty', +%% generated with the docstrip utility. +%% +%% Copyright (C) 2021-2024 by Jinwen XU +%% +%% This is part of the minimalist class series. +%% +%% 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. +%% +\NeedsTeXFormat{LaTeX2e}[2022-06-01] +\ProvidesExplPackage + {minimalist-classicthesis} + {2024/02/23} {} + {The "classicthesis" style of minimalist} + +\IfPackageLoadedTF { minimalist } {} + { + \msg_new:nnn { \@currname } + { minimalist-not-loaded } + { "#1"~is~an~internal~style~of~"minimalist".~To~use~it,~you~must~load~the~package~"minimalist"~first. } + \msg_warning:nnx { \@currname } { minimalist-not-loaded } { \@currname } + \endinput + } + +\bool_new:N \l__minimalist_colored_proof_bool +\bool_set_true:N \l__minimalist_colored_proof_bool +\tl_if_eq:NnTF \l__minimalist_colored_proof_tl { * } + { + \bool_set_false:N \l__minimalist_colored_proof_bool + } + { + \tl_if_eq:NnT \l__minimalist_colored_proof_tl { false } + { + \bool_set_false:N \l__minimalist_colored_proof_bool + } + } + +%%================================ +%% Title fonts +%%================================ +\RequirePackage { relsize } +\RequirePackage { anyfontsize } + +\cs_new:Nn \minimalist_bfseries: {} +\cs_new:Nn \minimalist_sffamily: {} +\cs_new:Nn \minimalist_scshape: {} + +\hook_gput_code:nnn { begindocument } { minimalist } + { + \@ifpackageloaded{classicthesis-arsclassica} + { + \cs_set:Nn \minimalist_sffamily: { \sffamily } + } + { + \cs_set:Nn \minimalist_sffamily: {} + } + } + +\tl_new:N \g_minimalist_title_font_common_tl + +\tl_new:N \g_minimalist_title_font_part_tl +\tl_new:N \g_minimalist_title_font_chapter_tl +\tl_new:N \g_minimalist_title_font_section_tl +\tl_new:N \g_minimalist_title_font_subsection_tl +\tl_new:N \g_minimalist_title_font_subsubsection_tl +\tl_new:N \g_minimalist_title_font_paragraph_tl + +\tl_gset:Nn \g_minimalist_title_font_part_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl } +\tl_gset:Nn \g_minimalist_title_font_chapter_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl \minimalist_scshape: } +\tl_gset:Nn \g_minimalist_title_font_section_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl \minimalist_scshape: } +\tl_gset:Nn \g_minimalist_title_font_subsection_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl \minimalist_scshape: } +\tl_gset:Nn \g_minimalist_title_font_subsubsection_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl } +\tl_gset:Nn \g_minimalist_title_font_paragraph_tl { \minimalist_bfseries:\minimalist_sffamily: \g_minimalist_title_font_common_tl \minimalist_scshape: } + +\bool_if:NF \l__minimalist_fast_bool + { + \RequirePackage { tikz } + \ExplSyntaxOff + \usetikzlibrary{calc,shadings} + \ExplSyntaxOn + \RequirePackage { tikzpagenodes } % For `current page text area` + } + + + +%%================================ +%% Blank page +%%================================ +\projlib_langauge_define_multilingual_text:Nn \bl@nkpagetext + { + , EN = This~page~is~intentionally~left~blank + , FR = Cette~page~est~intentionnellement~laissée~vide + , DE = Diese~Seite~wurde~absichtlich~leer~gelassen + , IT = Questa~pagina~è~stata~lasciata~vuota~intenzionalmente + , PT = Esta~página~foi~intencionalmente~deixada~em~branco + , BR = Esta~página~foi~intencionalmente~deixada~em~branco + , ES = Esta~página~ha~sido~intencionalmente~dejada~en~blanco + , CN = \ziju{0.2} æ¤é¡µä¸ºæœ‰æ„留为空白 + , TC = \ziju{0.2} æ¤é 為有æ„留為空白 + , JP = ã“ã®ãƒšãƒ¼ã‚¸ã¯æ„図的ã«ç©ºç™½ã«ã—ã¦ã‚ã‚Šã¾ã™ + , RU = Ðта~Ñтраница~намеренно~оÑтавлена~пуÑтой + } +\renewcommand{\cleardoublepage}{ + \relax + \clearpage + \if@twoside\ifodd\c@page\relax\else + \thispagestyle{empty} + \hook_gput_next_code:nn { shipout/background } + { + \put(0.5\paperwidth,-0.5\paperheight){ + \makebox[0pt]{\large\color{main-text!10!paper}\g_minimalist_title_font_common_tl\bl@nkpagetext}} + } + \null\newpage\fi\fi +} + +%%================================ +%% Index +%%================================ +\RequirePackage { imakeidx } +\makeindex[intoc] + +\RequirePackage { silence } +\ExplSyntaxOff +\WarningFilter{latex}{Writing or overwriting file} +\begin{filecontents*}[overwrite]{\jobname.mst} +delim_0 "\\IndexDotfill " % Filler between section heading and page number +delim_1 "\\IndexDotfill " % Filler between subsection heading and page number +headings_flag 1 +heading_prefix "\\IndexHeading{" +heading_suffix "}\n" +\end{filecontents*} +\ExplSyntaxOn + +\projlib_langauge_define_multilingual_text:Nn \index_symbols_name + { + , EN = Symbols + , FR = Symboles + , DE = Symbole + , IT = Simboli + , PT = SÃmbolos + , BR = SÃmbolos + , ES = SÃmbolos + , CN = ç¬¦å· + , TC = 符號 + , JP = è¨˜å· + , RU = Символы + } + +\newcommand*{\IndexDotfill} + { + \null\nobreak + \leaders \hbox to .67em {\hss \textcolor{main-text!15!paper}{.} \hss} \hskip1em plus1fill + } +\newcommand*{\IndexLinebreak} + { + \nobreakspace\textcolor{main-text!45!paper}{\raisebox{.4ex}{.}\raisebox{.2ex}{.}} + \item\hspace*{\hangindent} + \textcolor{main-text!45!paper}{\raisebox{.45ex}{.}\raisebox{.25ex}{.}}\: + \unskip + } + +\newcommand*{\IndexHeading}[1] + { + \str_if_eq:nnTF { #1 } { Symbols } + { \tl_set:Nn \l_tmpa_tl { \index_symbols_name } } + { \tl_set:Nn \l_tmpa_tl { #1 } } + \centerline{ \minimalist_sffamily: { \l_tmpa_tl } } + \nopagebreak + \par + \vspace{.3\baselineskip} + } + +\renewcommand*{\indexspace} + { + \par + \vspace{2pc plus .5pc minus .3pc} + } + +\bool_new:N \l__minimalist_if_first_subitem_bool +\renewcommand*{\@idxitem} + { + \par\hangindent40\p@ + \bool_set_true:N \l__minimalist_if_first_subitem_bool + } +\renewcommand*{\subitem} + { + \par\hangindent40\p@ + \bool_if:NT \l__minimalist_if_first_subitem_bool + { + \nobreak + \bool_set_false:N \l__minimalist_if_first_subitem_bool + } + \hspace*{20\p@} + } + +\hook_gput_code:nnn { begindocument/before } { minimalist } + { + \bool_if:NF \l__minimalist_fast_bool + { + \hook_gput_code:nnn { cmd/printindex/before } { minimalist } { \bookmarksetup{startatroot} } + } + \hook_gput_code:nnn { cmd/printindex/before } { minimalist } { \LocallyStopLineNumbers } + \hook_gput_code:nnn { cmd/printindex/after } { minimalist } { \ResumeLineNumbers } + } + +%%================================ +%% Draft mark +%%================================ +\RequirePackage { projlib-draft } + +%%================================ +%% Theorems +%%================================ +\RequirePackage { mathtools } +\RequirePackage { amsthm } + +\tl_const:Nn \c_minimalist_l_mathparen_latin_tl { $($ } +\tl_const:Nn \c_minimalist_r_mathparen_latin_tl { $)$ } +\tl_const:Nn \c_minimalist_l_mathparen_cjk_tl { \!\,( } +\tl_const:Nn \c_minimalist_r_mathparen_cjk_tl { )\!\, } +\cs_new:Nn \minimalist_insert_l_mathparen: + { + \tl_use:c { c_minimalist_l_mathparen_ \l_projlib_language_current_languagetype_tl _tl } + } +\cs_new:Nn \minimalist_insert_r_mathparen: + { + \tl_use:c { c_minimalist_r_mathparen_ \l_projlib_language_current_languagetype_tl _tl } + } + +%% Change equation numbers to gray +\def\tagform@#1{\maketag@@@{\textcolor{.!39!paper}{(\ignorespaces#1\unskip\@@italiccorr)}}} + +\PassOptionsToPackage { nopatch = eqnum } { microtype } + +\def\simpleqedsymbol{ + \makebox[1em]{\rlap{\textcolor{.!12!paper}{\rule[-0.1em]{.95em}{.95em}}}{\kern.07em\raisebox{.07em}{\textcolor{paper}{\rule[-0.1em]{.81em}{.81em}}}\kern.07em}}} +\DeclareRobustCommand{\simpleqed}{% + \ifmmode \quad\hbox{\simpleqedsymbol} + \else + \leavevmode\unskip\penalty9999 \hbox{}\nobreak\hfill + \quad\hbox{\simpleqedsymbol}% + \fi +} + +\bool_if:NTF \l__minimalist_theorem_in_new_line_bool + { + \newtheoremstyle{simple} + {.75\baselineskip}{} + { + \normalfont + \parindent=0pt + \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip + }{} + {\normalfont}{} + {0pt} + { + \rlap{\vbox{\hbox{\parbox{\linewidth}{ + {\thmname{#1}\thmnumber{\nobreakspace #2}} + {\color{.!50!paper}\thmnote{\hspace{.4em} \minimalist_insert_l_mathparen: #3 \minimalist_insert_r_mathparen: }} + }}\hbox{\strut}\vspace{0pt}}} + \bool_if:NT \l__minimalist_theorem_with_qed_bool + { + \pushQED{\simpleqed} + } + } + \newtheoremstyle{simple-var} + {.75\baselineskip}{} + { + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } + \parindent=0pt + \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip + }{} + {\normalfont}{} + {0pt} + { + \rlap{\vbox{\hbox{\parbox{\linewidth}{ + {\thmname{#1}\thmnumber{\nobreakspace #2}} + {\color{.!50!paper}\thmnote{\hspace{.4em} \minimalist_insert_l_mathparen: #3 \minimalist_insert_r_mathparen: }} + }}\hbox{\strut}\vspace{0pt}}} + \bool_if:NT \l__minimalist_theorem_with_qed_bool + { + \pushQED{\simpleqed} + } + } + } + { + \newtheoremstyle{simple} + {}{} + { + \normalfont + \parindent=0pt + \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip + }{} + {\normalfont}{} + {0pt} + { + {\thmname{#1}\thmnumber{\nobreakspace #2}} + {\color{.!50!paper}\thmnote{\hspace{.4em} \minimalist_insert_l_mathparen: #3 \minimalist_insert_r_mathparen: }} + \minimalist_bfseries:\minimalist_sffamily: . + \nobreakspace\nobreakspace + % {\normalfont\textcolor{.!27!paper}{---}} + \bool_if:NT \l__minimalist_theorem_with_qed_bool + { + \pushQED{\simpleqed} + } + } + \newtheoremstyle{simple-var} + {}{} + { + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } + \parindent=0pt + \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip + }{} + {\normalfont}{} + {0pt} + { + {\thmname{#1}\thmnumber{\nobreakspace #2}} + {\color{.!50!paper}\thmnote{\hspace{.4em} \minimalist_insert_l_mathparen: #3 \minimalist_insert_r_mathparen: }} + \minimalist_bfseries:\minimalist_sffamily: . + \nobreakspace\nobreakspace + % {\normalfont\textcolor{.!27!paper}{---}} + \bool_if:NT \l__minimalist_theorem_with_qed_bool + { + \pushQED{\simpleqed} + } + } + } + +\theoremstyle{simple} + +\bool_if:NT \l__minimalist_theorem_with_qed_bool + { + \def\@endtheorem{\popQED\endtrivlist\@endpefalse} + } + +\newcommand{\customqedsymbol}{ + \makebox[1em]{\color{.!27!paper}\rule[-0.1em]{.95em}{.95em}}} +\let\qedsymbol\customqedsymbol + +%% Special treatments for the Q.E.D. symbol +\def\noQED{\let\popQED\relax} +\let\noqed\noQED +\def\proofless{\pushQED{\qed}} + +\bool_if:NTF \l__minimalist_fast_bool + { + \RequirePackage { hyperref } + \hypersetup { draft } + } + { + \RequirePackage { hyperref } + \RequirePackage { bookmark } + \hypersetup{ hidelinks, linktoc = all } + \bookmarksetup{ numbered } + \renewcommand\Hy@numberline[1]{#1.~} + % https://tex.stackexchange.com/a/1821 + % Add the bookmark of ToC + \bool_if:NTF \l__minimalist_is_book_bool + { + \hook_gput_code:nnn { cmd/tableofcontents/before } { minimalist } + { + \if@openright\cleardoublepage\else\clearpage\fi + \pdfbookmark[0]{\contentsname}{toc} + } + } + { + \hook_gput_code:nnn { cmd/tableofcontents/before } { minimalist } + { + \pdfbookmark[1]{\contentsname}{toc} + } + } + } + + +\PassOptionsToPackage + { + theorem-style = { + theorem = simple-var, lemma = simple-var, proposition = simple-var, corollary = simple-var, property = simple-var, axiom = simple-var, construction = simple-var, + theorems = simple-var, lemmas = simple-var, propositions = simple-var, corollaries = simple-var, properties = simple-var, axioms = simple-var, constructions = simple-var, + theorem-with-name = simple-var, + } + } { projlib-theorem } + +\RequirePackage { projlib-theorem } + +\SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } + +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + +\bool_if:NT \l__minimalist_colored_proof_bool + { + \clist_map_inline:nn { proof, proof* } + { + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } + } + } + + +\exp_args:No \SetTheorem { \c_projlib_theorem_supported_clist, theorem-with-name } + { + name style = { + , heading style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + } + } + +\SetTheorem { remark } + { + name style = { + , heading style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + } + } + +\bool_if:NF \l__projlib_theorem_complexname_bool + { + \exp_args:No \SetTheorem { \c_projlib_theorem_supported_clist, theorem-with-name } + { + name style = { + , crefname style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + , Crefname style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textsc + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + , numbering style = { + \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + } + } + + \SetTheorem { remark } + { + name style = { + , crefname style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + , Crefname style = { + , english = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , french = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , ngerman = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , italian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , portuguese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , brazilian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , spanish = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl\textit + , schinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , tchinese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , japanese = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + , russian = \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + , numbering style = { + \minimalist_bfseries:\minimalist_sffamily:\g_minimalist_title_font_common_tl + } + } + } + } + +\PassOptionsToPackage { many } { tcolorbox } +\RequirePackage { tcolorbox } +\bool_if:NT \l__minimalist_fast_bool { \tcbstartdraftmode } + + +\NewDocumentEnvironment { emphasis } { } + { + \LocallyStopLineNumbers + \enlargethispage{2mm} + \begin{tcolorbox} + [ + enhanced ~ jigsaw, breakable, oversize, + % nobeforeafter, + left = .5em, right=0mm, top=0.5mm, bottom=0mm, boxrule=0pt, + colback=main-text!2!paper, frame ~ hidden, + borderline ~ west = {.3em} {0mm} {main-text!25!paper}, + arc = 0.2mm, + ] + } + { + \end{tcolorbox} + \ResumeLineNumbers + } + + +%%================================ +%% Title block style +%%================================ +\bool_if:NTF \l__minimalist_is_book_bool + { + \hook_gput_code:nnn { package/projlib-author/after } { minimalist } + { + \tl_gset:Nn \g__projlib_author_font_author_tl { \normalfont \minimalist_scshape: } + \tl_gset:Nn \g__projlib_author_font_institute_tl { \large \normalfont } + \tl_gset:Nn \g__projlib_author_font_address_tl { \large \normalfont \itshape } + \tl_gset:Nn \g__projlib_author_font_curraddr_tl { \large \normalfont \itshape } + \tl_gset:Nn \g__projlib_author_font_email_tl { \large \normalfont \ttfamily } + } + + \RequirePackage { projlib-titlepage } + \RenewDocumentCommand \maketitle { O{} } + { + \LocallyStopLineNumbers + \ProjLibTitlePage [ style = simple, #1 ] + { + , title = \@title + , author = \@author + , date = \@date + } + \ResumeLineNumbers + } + } + { + \renewcommand{\@maketitle} + { + \LocallyStopLineNumbers + \begin{center} + \let\footnote\thanks + {\minimalist_sffamily:\Large\@title}\\\bigskip + \color{main-text!80!paper} + {\small\minimalist_scshape:\@author} + \par\smallskip\vspace{-\parskip} + {\small\@date} + \end{center} + \projlib_author_if_content_empty:nT { \@date } { \medskip } + \medskip\par + \ResumeLineNumbers + } + + +%%================================ +%% Abstract style +%%================================ + \renewenvironment{abstract} + { + \LocallyStopLineNumbers + \vspace{-.5\baselineskip} + \begin{center} + { \small\spacedlowsmallcaps{\abstractname} }\\ + \vspace{-.3\baselineskip} + \begin{minipage}[t]{.833\textwidth} + \vspace{0pt} + \color{main-text!80!paper} + \footnotesize + \parindent=2em + } + { + \end{minipage} + \end{center} + \medskip + \ResumeLineNumbers + } + +%%================================ +%% Keyword environment +%%================================ + \DefineMultilingualText { \keywordname } + { + EN = Keywords , + FR = Mots~clés , + DE = Schlüsselwörter , + IT = Parole~chiave , + PT = Palavras~chave , + BR = Palavras~chave , + ES = Palabras~clave , + CN = å…³é”®è¯ , + TC = é—œéµè©ž , + JP = ã‚ーワード , + RU = Ключевые~Ñлова , + } + + \newenvironment{keyword}{ + \LocallyStopLineNumbers + \vspace{-.75\baselineskip} + \begin{center} + { \small\spacedlowsmallcaps{\keywordname} }\\ + \vspace{-.3\baselineskip} + \begin{minipage}[t]{.833\textwidth} + \vspace{0pt} + \color{main-text!80!paper} + \footnotesize + \parindent=2em + \begin{center} + }{ + \end{center} + \end{minipage} + \end{center} + \medskip + \ResumeLineNumbers + } + } % end of \bool_if:NTF \l__minimalist_is_book_bool + +%%================================ +%% Simulate features of amsart +%%================================ +\PassOptionsToPackage { amsfashion } { projlib-author } +\RequirePackage { projlib-author } + +%%================================ +%% Special adjustment +%%================================ + +%%================================ +%% Load the main design +%%================================ +\hook_gput_code:nnn { begindocument/before } { minimalist } + { + \RequirePackage { classicthesis } + } + +\endinput +%% +%% End of file `minimalist/minimalist-classicthesis.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist-default.sty b/macros/latex/contrib/minimalist/minimalist-default.sty index 32d64df661..ea3aa22eb9 100644 --- a/macros/latex/contrib/minimalist/minimalist-default.sty +++ b/macros/latex/contrib/minimalist/minimalist-default.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist-default} - {2024/02/20} {} + {2024/02/23} {} {The default style of minimalist} \IfPackageLoadedTF { minimalist } {} @@ -756,7 +756,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {.75\baselineskip}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -797,7 +797,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -875,13 +875,19 @@ heading_suffix "}\n" \SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + \bool_if:NT \l__minimalist_colored_proof_bool { - \hook_gput_code:nnn { env/proof/begin } { minimalist } + \clist_map_inline:nn { proof, proof* } { - \Hy@SaveLastskip - \color{ \l__minimalist_colored_proof_tl } - \Hy@RestoreLastskip + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } } } @@ -1152,6 +1158,7 @@ heading_suffix "}\n" \crefformat { subsubsection } { \nobreak \crefthemark { \crefthe_retrieve_space: } \nobreak #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } \labelcrefformat { subsubsection } { #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } + \endinput %% %% End of file `minimalist/minimalist-default.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist-flow.sty b/macros/latex/contrib/minimalist/minimalist-flow.sty index 671ceef5c2..737d61eaa9 100644 --- a/macros/latex/contrib/minimalist/minimalist-flow.sty +++ b/macros/latex/contrib/minimalist/minimalist-flow.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist-flow} - {2024/02/20} {} + {2024/02/23} {} {The "flow" style of minimalist} \IfPackageLoadedTF { minimalist } {} @@ -767,7 +767,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {.75\baselineskip}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -805,7 +805,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -880,13 +880,19 @@ heading_suffix "}\n" \SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + \bool_if:NT \l__minimalist_colored_proof_bool { - \hook_gput_code:nnn { env/proof/begin } { minimalist } + \clist_map_inline:nn { proof, proof* } { - \Hy@SaveLastskip - \color{ \l__minimalist_colored_proof_tl } - \Hy@RestoreLastskip + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } } } @@ -1158,6 +1164,7 @@ heading_suffix "}\n" \crefformat { subsubsection } { \nobreak \crefthemark { \crefthe_retrieve_space: } \nobreak #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } \labelcrefformat { subsubsection } { #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } + \endinput %% %% End of file `minimalist/minimalist-flow.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist-plain.sty b/macros/latex/contrib/minimalist/minimalist-plain.sty index 577f4b24e1..761cc4f258 100644 --- a/macros/latex/contrib/minimalist/minimalist-plain.sty +++ b/macros/latex/contrib/minimalist/minimalist-plain.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist-plain} - {2024/02/20} {} + {2024/02/23} {} {The "plain" style of minimalist} \IfPackageLoadedTF { minimalist } {} @@ -730,7 +730,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {.75\baselineskip}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -771,7 +771,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-var} {}{} { - \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } + \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } \parindent=0pt \parskip=.3333\baselineskip plus .0667\baselineskip minus .0833\baselineskip }{} @@ -849,13 +849,19 @@ heading_suffix "}\n" \SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + \bool_if:NT \l__minimalist_colored_proof_bool { - \hook_gput_code:nnn { env/proof/begin } { minimalist } + \clist_map_inline:nn { proof, proof* } { - \Hy@SaveLastskip - \color{ \l__minimalist_colored_proof_tl } - \Hy@RestoreLastskip + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } } } @@ -1118,6 +1124,7 @@ heading_suffix "}\n" %% Special adjustment %%================================ + \endinput %% %% End of file `minimalist/minimalist-plain.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist-stream.sty b/macros/latex/contrib/minimalist/minimalist-stream.sty index cef220e623..51acfcbb7f 100644 --- a/macros/latex/contrib/minimalist/minimalist-stream.sty +++ b/macros/latex/contrib/minimalist/minimalist-stream.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist-stream} - {2024/02/20} {} + {2024/02/23} {} {The "stream" style of minimalist} \IfPackageLoadedTF { minimalist } {} @@ -836,7 +836,7 @@ heading_suffix "}\n" } \newtheoremstyle{simple-newline-var} {-.2\baselineskip plus 2pt minus .1\baselineskip}{.3\baselineskip plus 2pt minus .1\baselineskip} - { \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {0pt} { @@ -858,7 +858,7 @@ heading_suffix "}\n" } \dim_new:N \l_minimalist_space_before_inline_theorem_dim -\AtBeginDocument +\hook_gput_code:nnn { begindocument } { minimalist } { \dim_set:Nn \l_minimalist_space_before_inline_theorem_dim { @@ -889,7 +889,7 @@ heading_suffix "}\n" \newtheoremstyle{simple-inline-var} % {.3\baselineskip plus 2pt minus .1\baselineskip}{.3\baselineskip plus 2pt minus .1\baselineskip} {\l_minimalist_space_before_inline_theorem_dim}{\l_minimalist_space_before_inline_theorem_dim} - { \bool_if:NTF \l__minimalist_emphasis_theorem_bool { \itshape } { \normalfont } }{} + { \bool_if:NTF \l__minimalist_emphasize_theorem_bool { \itshape } { \normalfont } }{} {\normalfont}{} {0pt} { @@ -1003,13 +1003,19 @@ heading_suffix "}\n" \SetTheorem { proof, proof* } { qed-symbol = { \customqedsymbol } } +\hook_gput_code:nnn { env/proof/begin } { minimalist } { \let\simpleqed\relax } +\hook_gput_code:nnn { env/proof*/begin } { minimalist } { \let\simpleqed\relax } + \bool_if:NT \l__minimalist_colored_proof_bool { - \hook_gput_code:nnn { env/proof/begin } { minimalist } + \clist_map_inline:nn { proof, proof* } { - \Hy@SaveLastskip - \color{ \l__minimalist_colored_proof_tl } - \Hy@RestoreLastskip + \hook_gput_code:nnn { env/ #1 /begin } { minimalist } + { + \Hy@SaveLastskip + \color{ \l__minimalist_colored_proof_tl } + \Hy@RestoreLastskip + } } } @@ -1248,6 +1254,7 @@ heading_suffix "}\n" \crefformat { subsubsection } { \nobreak \crefthemark { \crefthe_retrieve_space: } \nobreak #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } \labelcrefformat { subsubsection } { #2 \minimalist_apply_title_numbering_style_static:n {#1} #3 } + \endinput %% %% End of file `minimalist/minimalist-stream.sty'. diff --git a/macros/latex/contrib/minimalist/minimalist.sty b/macros/latex/contrib/minimalist/minimalist.sty index 9b50bd5349..034a9cc8c6 100644 --- a/macros/latex/contrib/minimalist/minimalist.sty +++ b/macros/latex/contrib/minimalist/minimalist.sty @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplPackage {minimalist} - {2024/02/20} {} + {2024/02/23} {} {A simple and clear style for articles and books} \keys_define:nn { minimalist } @@ -81,10 +81,10 @@ , indent lists .dim_set:N = \l__minimalist_item_indentation_dim , indent lists .default:n = { \parindent } - , emphasis-theorems .bool_set:N = \l__minimalist_emphasis_theorem_bool - , emphasis-theorems .initial:n = { false } - , emphasis~theorems .bool_set:N = \l__minimalist_emphasis_theorem_bool - , emphasis theorems .bool_set:N = \l__minimalist_emphasis_theorem_bool + , emphasize-theorems .bool_set:N = \l__minimalist_emphasize_theorem_bool + , emphasize-theorems .initial:n = { false } + , emphasize~theorems .bool_set:N = \l__minimalist_emphasize_theorem_bool + , emphasize theorems .bool_set:N = \l__minimalist_emphasize_theorem_bool , theorem-in-new-line .bool_set:N = \l__minimalist_theorem_in_new_line_bool , theorem-in-new-line .initial:n = { false } @@ -120,6 +120,8 @@ } \ProcessKeyOptions [ minimalist ] +\PassOptionsToPackage { dvipsnames } { xcolor } + \bool_new:N \l__minimalist_is_book_bool \cs_if_exist:cTF { c@chapter } { diff --git a/macros/latex/contrib/minimalist/minimart.cls b/macros/latex/contrib/minimalist/minimart.cls index f208d3ccd6..67411f25a8 100644 --- a/macros/latex/contrib/minimalist/minimart.cls +++ b/macros/latex/contrib/minimalist/minimart.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {minimart} - {2024/02/20} {} + {2024/02/23} {} {A simple and clear article style} \tl_const:Nn \l__minimclass_base_class_tl { article } diff --git a/macros/latex/contrib/minimalist/minimbook.cls b/macros/latex/contrib/minimalist/minimbook.cls index c36dc2b239..727572c73a 100644 --- a/macros/latex/contrib/minimalist/minimbook.cls +++ b/macros/latex/contrib/minimalist/minimbook.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {minimbook} - {2024/02/20} {} + {2024/02/23} {} {A simple and clear book style} \tl_const:Nn \l__minimclass_base_class_tl { book } diff --git a/macros/latex/contrib/se2thesis/CHANGELOG.md b/macros/latex/contrib/se2thesis/CHANGELOG.md index ed9739a1ba..600f16953b 100644 --- a/macros/latex/contrib/se2thesis/CHANGELOG.md +++ b/macros/latex/contrib/se2thesis/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to ## [Unreleased] +## [v3.3.1] – 2024–02–23 + +### Changed +- Make the citations in the margin appear in ACM style, too. +- Make sidenotes appear right ragged. + ## [v3.3.0] – 2024–02–22 ### Added @@ -19,7 +25,7 @@ and this project adheres to chapter. - Add thesis-type option `phdeng` for a doctoral degree in engineering. -### Changed +### Changed - The default citation style, when setting `biblatex=true` while loading the `se2packages` package is now `numeric` based on the ACM numeric style instead @@ -27,8 +33,6 @@ and this project adheres to See [issue #7](https://github.com/se2p/se2thesis/issues/7) for a discussion on the general decision. -### Changed - ## [v3.2.0] – 2023–09–12 ### Changed @@ -172,6 +176,7 @@ These changes might be breaking changes! ### Added - First official release +[v3.3.1]: https://github.com/se2p/se2thesis/compare/v3.3.1...v3.3.0 [v3.3.0]: https://github.com/se2p/se2thesis/compare/v3.3.0...v3.2.0 [v3.2.0]: https://github.com/se2p/se2thesis/compare/v3.2.0...v3.1.0 [v3.1.0]: https://github.com/se2p/se2thesis/compare/v3.1.0...v3.0.0 diff --git a/macros/latex/contrib/se2thesis/se2colors.dtx b/macros/latex/contrib/se2thesis/se2colors.dtx index 35bd60d0d3..97d57ee682 100644 --- a/macros/latex/contrib/se2thesis/se2colors.dtx +++ b/macros/latex/contrib/se2thesis/se2colors.dtx @@ -231,7 +231,7 @@ % % Identify the package and give the overall version information. % \begin{macrocode} -\ProvidesExplPackage {se2colors} {2024-02-22} {3.3.0} +\ProvidesExplPackage {se2colors} {2024-02-23} {3.3.1} {A colour support package for the se2thesis bundle} % \end{macrocode} % diff --git a/macros/latex/contrib/se2thesis/se2fonts.dtx b/macros/latex/contrib/se2thesis/se2fonts.dtx index 4f127a4cc3..938c24d1f7 100644 --- a/macros/latex/contrib/se2thesis/se2fonts.dtx +++ b/macros/latex/contrib/se2thesis/se2fonts.dtx @@ -151,7 +151,7 @@ % % Identify the package and give the overall version information. % \begin{macrocode} -\ProvidesExplPackage {se2fonts} {2024-02-22} {3.3.0} +\ProvidesExplPackage {se2fonts} {2024-02-23} {3.3.1} {A font-selection support package for the se2thesis bundle} % \end{macrocode} % diff --git a/macros/latex/contrib/se2thesis/se2packages.dtx b/macros/latex/contrib/se2thesis/se2packages.dtx index 92c1771a92..8e29a96906 100644 --- a/macros/latex/contrib/se2thesis/se2packages.dtx +++ b/macros/latex/contrib/se2thesis/se2packages.dtx @@ -443,7 +443,7 @@ % % Identify the package and give the overall version information. % \begin{macrocode} -\ProvidesExplPackage {se2packages} {2024-02-22} {3.3.0} +\ProvidesExplPackage {se2packages} {2024-02-23} {3.3.1} {Supporting packages for the se2thesis bundle} % \end{macrocode} % @@ -822,7 +822,7 @@ } { biblatex } \RequirePackage{biblatex} \RequirePackage{ragged2e} - \RequirePackage[mark=arabic,shape=up]{sidenotesplus} + \RequirePackage[mark=arabic,shape=up,Ragged]{sidenotesplus} \newbibmacro{cite:authoryear}{% \printtext[labelnumberwidth]{% @@ -830,13 +830,10 @@ }% \setunit{\addspace}% \printnames{labelname}% - \setunit{\printdelim{nameyeardelim}}% - \begingroup - \DeclareFieldFormat{date}{\mkbibparens{##1}}% - \printdate - \endgroup - \setunit*{\addcomma\space}%%% NEW - \printfield[title]{labeltitle}%%% NEW + \setunit{\labelnamepunct}\newblock% + \usebibmacro{year}% + \newunit% + \printfield[title]{labeltitle} } \newrobustcmd*{\makebibmarginnote}[1]{% diff --git a/macros/latex/contrib/se2thesis/se2thesis-master-thesis-example.pdf b/macros/latex/contrib/se2thesis/se2thesis-master-thesis-example.pdf Binary files differindex 4750e14e31..cdfb050e29 100644 --- a/macros/latex/contrib/se2thesis/se2thesis-master-thesis-example.pdf +++ b/macros/latex/contrib/se2thesis/se2thesis-master-thesis-example.pdf diff --git a/macros/latex/contrib/se2thesis/se2thesis.dtx b/macros/latex/contrib/se2thesis/se2thesis.dtx index 832c1bf225..9bb167399c 100644 --- a/macros/latex/contrib/se2thesis/se2thesis.dtx +++ b/macros/latex/contrib/se2thesis/se2thesis.dtx @@ -586,7 +586,7 @@ % % Identify the class and give the overall version number. % \begin{macrocode} -\ProvidesExplClass {se2thesis} {2024-02-22} {3.3.0} +\ProvidesExplClass {se2thesis} {2024-02-23} {3.3.1} {A thesis class for the Chair of Software Engineering II} % \end{macrocode} % @@ -1619,7 +1619,7 @@ % We provide the following English translations. % % \begin{macrocode} -\ProvideDictionaryFor{English}{se2translations}[2024/02/22] +\ProvideDictionaryFor{English}{se2translations}[2024/02/23] \ProvideDictTranslation{abstract}{abstract} \ProvideDictTranslation{Abstract}{Abstract} \ProvideDictTranslation{acknowledgement}{acknowledgement} @@ -1670,7 +1670,7 @@ % We provide the following German translations. % % \begin{macrocode} -\ProvideDictionaryFor{German}{se2translations}[2024/02/22] +\ProvideDictionaryFor{German}{se2translations}[2024/02/23] \ProvideDictTranslation{abstract}{Zusammenfassung} \ProvideDictTranslation{Abstract}{Zusammenfassung} \ProvideDictTranslation{acknowledgement}{Danksagung} diff --git a/macros/latex/contrib/se2thesis/se2thesis.pdf b/macros/latex/contrib/se2thesis/se2thesis.pdf Binary files differindex dcc165ba6a..e83e4eeb21 100644 --- a/macros/latex/contrib/se2thesis/se2thesis.pdf +++ b/macros/latex/contrib/se2thesis/se2thesis.pdf diff --git a/macros/latex/contrib/tagpdf/README.md b/macros/latex/contrib/tagpdf/README.md index 0635cfcf85..63cec98476 100644 --- a/macros/latex/contrib/tagpdf/README.md +++ b/macros/latex/contrib/tagpdf/README.md @@ -1,6 +1,6 @@ #tagpdf — A package to create tagged pdf -Packageversion: 0.98v -Packagedate: 2024/02/04 +Packageversion: 0.98w +Packagedate: 2024/02/22 Author: Ulrike Fischer, LaTeX Project Team ## License diff --git a/macros/latex/contrib/tagpdf/ex-AF-file.pdf b/macros/latex/contrib/tagpdf/ex-AF-file.pdf index 337e15047b..10e04d0ab6 100644 --- a/macros/latex/contrib/tagpdf/ex-AF-file.pdf +++ b/macros/latex/contrib/tagpdf/ex-AF-file.pdf @@ -1,11 +1,11 @@ %PDF-2.0 %ÌÕÁÔÅØÐÄÆ 22 0 obj -<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20240204162433+01'00') /Size 151 /CheckSum (D20ACE377A277C4B52E563C8711AFF51) >> /Length 151 >> +<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20240222232227+01'00') /Size 151 /CheckSum (CEB22652C4F993D3F2F770C724E63275) >> /Length 151 >> stream %% LaTeX2e file `example-input-file.tex' %% generated by the `filecontents' environment -%% from source `ex-AF-file' on 2024/02/04. +%% from source `ex-AF-file' on 2024/02/22. %% Additional info! @@ -15,7 +15,7 @@ endobj << /Type /Filespec /AFRelationship /Unspecified /F <FEFF006500780061006D0070006C0065002D0069006E007000750074002D00660069006C0065002E007400650078> /UF <FEFF006500780061006D0070006C0065002D0069006E007000750074002D00660069006C0065002E007400650078> /EF<</F 22 0 R/UF 22 0 R>> >> endobj 25 0 obj -<< /Subtype /text#2Fplain/Type /EmbeddedFile /Params<</ModDate (D:20240204) >> /Length 19 >> +<< /Subtype /text#2Fplain/Type /EmbeddedFile /Params<</ModDate (D:20240222) >> /Length 19 >> stream Bär with teh shirt endstream @@ -24,7 +24,7 @@ endobj << /Type /Filespec /AFRelationship /Supplement /F <FEFF007400610067002D0041004600660069006C00650031002E007400780074> /UF <FEFF007400610067002D0041004600660069006C00650031002E007400780074> /EF<</F 25 0 R/UF 25 0 R>> >> endobj 28 0 obj -<< /Subtype /text#2Fplain/Type /EmbeddedFile /Params<</ModDate (D:20240204) >> /Length 4 >> +<< /Subtype /text#2Fplain/Type /EmbeddedFile /Params<</ModDate (D:20240222) >> /Length 4 >> stream Duck endstream @@ -242,17 +242,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:24:54+01:00</rdf:li> + <rdf:li>2024-02-22T23:22:47+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-AF-file.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:24:54+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:24:54+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:24:54+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:22:47+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:22:47+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:22:47+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:38d5a844-2217-4081-87cc-b2129dc357a6</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:46bb877d-d422-42b6-852c-1e35e1836535</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:922cc914-e255-45d0-8c41-0a693aaec20c</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -347,7 +347,7 @@ endobj << /Type /Namespace /NS (https://www.latex-project.org/ns/book/2022) /RoleMapNS 18 0 R >> endobj 19 0 obj -<< /Type /Namespace /NS (data:,86B8CC4-5278-3FD8-2A39-38BA676A5FDD) >> +<< /Type /Namespace /NS (data:,822344F4-764-B054-F214-EFA7E5F05397) >> endobj 8 0 obj [ 9 0 R 11 0 R 13 0 R 15 0 R 17 0 R 19 0 R ] @@ -449,7 +449,7 @@ endobj << /Type /Catalog /Pages 36 0 R /MarkInfo 37 0 R/Lang (de-DE)/Metadata 31 0 R/StructTreeRoot 5 0 R >> endobj 46 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162454+01'00')/ModDate (D:20240204162454+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232247+01'00')/ModDate (D:20240222232247+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 47 @@ -501,7 +501,7 @@ xref 0000020698 00000 n 0000020816 00000 n trailer -<< /Size 47 /Root 45 0 R /Info 46 0 R /ID [ <10D35F6F0AFD0725784B9221741EEDF1> <10D35F6F0AFD0725784B9221741EEDF1> ] >> +<< /Size 47 /Root 45 0 R /Info 46 0 R /ID [ <9D6A0157460D27414440104FDAADEEF0> <9D6A0157460D27414440104FDAADEEF0> ] >> startxref 21039 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-alt-actualtext.pdf b/macros/latex/contrib/tagpdf/ex-alt-actualtext.pdf Binary files differindex 3688c60cbd..823bf35058 100644 --- a/macros/latex/contrib/tagpdf/ex-alt-actualtext.pdf +++ b/macros/latex/contrib/tagpdf/ex-alt-actualtext.pdf diff --git a/macros/latex/contrib/tagpdf/ex-attribute.pdf b/macros/latex/contrib/tagpdf/ex-attribute.pdf index b70311cc2e..7e5c805831 100644 --- a/macros/latex/contrib/tagpdf/ex-attribute.pdf +++ b/macros/latex/contrib/tagpdf/ex-attribute.pdf @@ -216,17 +216,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:25:54+01:00</rdf:li> + <rdf:li>2024-02-22T23:23:43+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-attribute.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:25:54+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:25:54+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:25:54+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:23:43+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:23:43+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:23:43+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:7a9cf910-1c19-429a-8f24-339c62d8a57f</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:56507ade-9637-4af9-8b4e-db0a75fca225</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:065f0cda-84f8-4a6e-8389-031fc1a6106d</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -449,7 +449,7 @@ endobj << /Type /Catalog /Pages 26 0 R /MarkInfo 27 0 R/Lang (de_DE)/Metadata 21 0 R/StructTreeRoot 5 0 R >> endobj 38 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/Title (Title)/CreationDate (D:20240204162554+01'00')/ModDate (D:20240204162554+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/Title (Title)/CreationDate (D:20240222232343+01'00')/ModDate (D:20240222232343+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 39 @@ -493,7 +493,7 @@ xref 0000017720 00000 n 0000017838 00000 n trailer -<< /Size 39 /Root 37 0 R /Info 38 0 R /ID [ <5C6A3964C54F6EE4C18E93DFDB746F1D> <5C6A3964C54F6EE4C18E93DFDB746F1D> ] >> +<< /Size 39 /Root 37 0 R /Info 38 0 R /ID [ <1A03E1D431E20C44F3C40BCA13F7CA44> <1A03E1D431E20C44F3C40BCA13F7CA44> ] >> startxref 18075 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-formula-problem.pdf b/macros/latex/contrib/tagpdf/ex-formula-problem.pdf index f8cd961bef..abecb1df8e 100644 --- a/macros/latex/contrib/tagpdf/ex-formula-problem.pdf +++ b/macros/latex/contrib/tagpdf/ex-formula-problem.pdf @@ -239,17 +239,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:26:24+01:00</rdf:li> + <rdf:li>2024-02-22T23:24:12+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-formula-problem.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:26:24+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:26:24+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:26:24+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:24:12+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:24:12+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:24:12+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:8eb2ce1d-b2ec-440a-8bc2-73733eb3eeb0</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:b93eb6f7-df10-41e5-8954-2e1480c6450e</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:96efc9b7-a599-4aad-8efa-a4a6f3bb1a83</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>2</prism:pageCount> </rdf:Description> @@ -425,7 +425,7 @@ endobj << /Type /Catalog /Pages 16 0 R /MarkInfo 23 0 R/Lang (de-DE)/Metadata 19 0 R/StructTreeRoot 5 0 R >> endobj 33 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162624+01'00')/ModDate (D:20240204162624+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232412+01'00')/ModDate (D:20240222232412+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 34 @@ -464,7 +464,7 @@ xref 0000018886 00000 n 0000019004 00000 n trailer -<< /Size 34 /Root 32 0 R /Info 33 0 R /ID [ <A419CA6154416AC1B76F3FCC85B8ED2E> <A419CA6154416AC1B76F3FCC85B8ED2E> ] >> +<< /Size 34 /Root 32 0 R /Info 33 0 R /ID [ <8B9D540F4DC33CE1434F842EF4863C9C> <8B9D540F4DC33CE1434F842EF4863C9C> ] >> startxref 19227 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-list.pdf b/macros/latex/contrib/tagpdf/ex-list.pdf index 1d1e99d3d4..ea24cdcef6 100644 --- a/macros/latex/contrib/tagpdf/ex-list.pdf +++ b/macros/latex/contrib/tagpdf/ex-list.pdf @@ -210,17 +210,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:26:54+01:00</rdf:li> + <rdf:li>2024-02-22T23:24:42+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-list.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:26:54+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:26:54+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:26:54+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:24:42+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:24:42+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:24:42+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:4c749825-1de7-414c-879f-29e4d0bef66e</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:953ef2d0-e619-4cff-8823-dd0e50200ab4</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:2fc1dbf9-e70e-4fc2-8fbe-fff091ce17c3</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -653,7 +653,7 @@ endobj << /Type /Catalog /Pages 54 0 R /MarkInfo 55 0 R/Lang (en-US)/Metadata 48 0 R/StructTreeRoot 5 0 R >> endobj 72 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162654+01'00')/ModDate (D:20240204162654+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232442+01'00')/ModDate (D:20240222232442+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 73 @@ -731,7 +731,7 @@ xref 0000029592 00000 n 0000029710 00000 n trailer -<< /Size 73 /Root 71 0 R /Info 72 0 R /ID [ <919034DA36C84F01F9BD978C4647D563> <919034DA36C84F01F9BD978C4647D563> ] >> +<< /Size 73 /Root 71 0 R /Info 72 0 R /ID [ <F14FE069DE252BEC3560BBB4553379B6> <F14FE069DE252BEC3560BBB4553379B6> ] >> startxref 29933 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-mc-manual-para-split-obsolete.pdf b/macros/latex/contrib/tagpdf/ex-mc-manual-para-split-obsolete.pdf index 6e6b51cce8..cb9740d022 100644 --- a/macros/latex/contrib/tagpdf/ex-mc-manual-para-split-obsolete.pdf +++ b/macros/latex/contrib/tagpdf/ex-mc-manual-para-split-obsolete.pdf @@ -243,17 +243,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:27:21+01:00</rdf:li> + <rdf:li>2024-02-22T23:25:08+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-mc-manual-para-split-obsolete.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:27:21+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:27:21+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:27:21+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:25:08+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:25:08+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:25:08+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:c33d64b4-96ec-4e48-8f27-0b3edc831547</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:f55806bc-d889-4918-8fed-972dca883fe4</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:2fed5a6c-01de-4c90-8a51-19fd520415a3</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>2</prism:pageCount> </rdf:Description> @@ -413,7 +413,7 @@ endobj << /Type /Catalog /Pages 14 0 R /Lang (en-US)/Metadata 15 0 R >> endobj 25 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162721+01'00')/ModDate (D:20240204162721+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232508+01'00')/ModDate (D:20240222232508+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 26 @@ -444,7 +444,7 @@ xref 0000023897 00000 n 0000023978 00000 n trailer -<< /Size 26 /Root 24 0 R /Info 25 0 R /ID [ <7D716B199BC4F3135271DDE3C3416149> <7D716B199BC4F3135271DDE3C3416149> ] >> +<< /Size 26 /Root 24 0 R /Info 25 0 R /ID [ <0C901AF132BA870423F64B7A9333C038> <0C901AF132BA870423F64B7A9333C038> ] >> startxref 24201 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-softhyphen.pdf b/macros/latex/contrib/tagpdf/ex-softhyphen.pdf index 2c2939934d..45d200a8d5 100644 --- a/macros/latex/contrib/tagpdf/ex-softhyphen.pdf +++ b/macros/latex/contrib/tagpdf/ex-softhyphen.pdf @@ -210,17 +210,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:27:46+01:00</rdf:li> + <rdf:li>2024-02-22T23:25:33+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-softhyphen.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:27:46+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:27:46+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:27:46+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:25:33+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:25:33+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:25:33+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:aa82e685-4098-469d-861c-3c45dfc700c7</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:2a630ad7-ee3c-44e5-8ab2-730213a2c266</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:220ecb1a-1ca6-4b81-8426-907f7c14c789</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -393,7 +393,7 @@ endobj << /Type /Catalog /Pages 19 0 R /MarkInfo 20 0 R/Lang (en-US)/Metadata 14 0 R/StructTreeRoot 5 0 R >> endobj 30 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162746+01'00')/ModDate (D:20240204162746+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232533+01'00')/ModDate (D:20240222232533+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 31 @@ -429,7 +429,7 @@ xref 0000018116 00000 n 0000018234 00000 n trailer -<< /Size 31 /Root 29 0 R /Info 30 0 R /ID [ <C281A9B95B5DD286F378F77B0F085479> <C281A9B95B5DD286F378F77B0F085479> ] >> +<< /Size 31 /Root 29 0 R /Info 30 0 R /ID [ <09007091BD82F7217F0AE2883B15CE9E> <09007091BD82F7217F0AE2883B15CE9E> ] >> startxref 18457 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-spaceglyph-listings.pdf b/macros/latex/contrib/tagpdf/ex-spaceglyph-listings.pdf index aa5f7113ce..6066138ec2 100644 --- a/macros/latex/contrib/tagpdf/ex-spaceglyph-listings.pdf +++ b/macros/latex/contrib/tagpdf/ex-spaceglyph-listings.pdf @@ -210,17 +210,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:28:10+01:00</rdf:li> + <rdf:li>2024-02-22T23:25:56+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-spaceglyph-listings.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:28:10+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:28:10+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:28:10+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:25:56+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:25:56+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:25:56+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:acdc2435-bf29-4e54-8d09-1c9b6dc32038</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:69467ac3-e2d3-481a-84aa-be8b39fc3381</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:8de9f9de-17f8-4963-8fc9-32008bdcce27</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -354,7 +354,7 @@ endobj << /Type /Catalog /Pages 15 0 R /MarkInfo 16 0 R/Lang (en-US)/Metadata 10 0 R/StructTreeRoot 5 0 R >> endobj 26 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162810+01'00')/ModDate (D:20240204162810+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232556+01'00')/ModDate (D:20240222232556+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 27 @@ -386,7 +386,7 @@ xref 0000015484 00000 n 0000015602 00000 n trailer -<< /Size 27 /Root 25 0 R /Info 26 0 R /ID [ <C9D1E5D71A55A1B1B3D6141FABBBD89F> <C9D1E5D71A55A1B1B3D6141FABBBD89F> ] >> +<< /Size 27 /Root 25 0 R /Info 26 0 R /ID [ <B48001748D24B04769B6E82AE43AEDC6> <B48001748D24B04769B6E82AE43AEDC6> ] >> startxref 15825 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-structure-obsolete.pdf b/macros/latex/contrib/tagpdf/ex-structure-obsolete.pdf index 7ed1e6242f..5a4b2b37f1 100644 --- a/macros/latex/contrib/tagpdf/ex-structure-obsolete.pdf +++ b/macros/latex/contrib/tagpdf/ex-structure-obsolete.pdf @@ -210,17 +210,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:28:36+01:00</rdf:li> + <rdf:li>2024-02-22T23:26:20+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-structure-obsolete.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:28:36+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:28:36+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:28:36+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:26:20+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:26:20+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:26:20+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:bf5e4a2b-cfa9-4fc5-878c-8f9d2ee95445</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:a23ea6f7-ae97-45e7-82e8-052481d4b120</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:3eeee032-14a3-4af9-8f50-e80ac4a9a8e4</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -526,7 +526,7 @@ endobj << /Type /Catalog /Pages 26 0 R /MarkInfo 27 0 R/Lang (en-US)/Metadata 20 0 R/StructTreeRoot 5 0 R >> endobj 43 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162836+01'00')/ModDate (D:20240204162836+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232620+01'00')/ModDate (D:20240222232620+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 44 @@ -575,7 +575,7 @@ xref 0000023426 00000 n 0000023544 00000 n trailer -<< /Size 44 /Root 42 0 R /Info 43 0 R /ID [ <B60BBC4CC0F003088722E1DA52185908> <B60BBC4CC0F003088722E1DA52185908> ] >> +<< /Size 44 /Root 42 0 R /Info 43 0 R /ID [ <8C6DD20E978698F0DE752E546A93C3E9> <8C6DD20E978698F0DE752E546A93C3E9> ] >> startxref 23767 %%EOF diff --git a/macros/latex/contrib/tagpdf/ex-tagpdf-template.pdf b/macros/latex/contrib/tagpdf/ex-tagpdf-template.pdf index f06bd1838d..1bbc8c530d 100644 --- a/macros/latex/contrib/tagpdf/ex-tagpdf-template.pdf +++ b/macros/latex/contrib/tagpdf/ex-tagpdf-template.pdf @@ -210,17 +210,17 @@ stream </dc:language> <dc:date> <rdf:Seq> - <rdf:li>2024-02-04T16:29:02+01:00</rdf:li> + <rdf:li>2024-02-22T23:26:46+01:00</rdf:li> </rdf:Seq> </dc:date> <dc:format>application/pdf</dc:format> <dc:source>ex-tagpdf-template.tex</dc:source> <xmp:CreatorTool>LaTeX</xmp:CreatorTool> - <xmp:CreateDate>2024-02-04T16:29:02+01:00</xmp:CreateDate> - <xmp:ModifyDate>2024-02-04T16:29:02+01:00</xmp:ModifyDate> - <xmp:MetadataDate>2024-02-04T16:29:02+01:00</xmp:MetadataDate> + <xmp:CreateDate>2024-02-22T23:26:46+01:00</xmp:CreateDate> + <xmp:ModifyDate>2024-02-22T23:26:46+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2024-02-22T23:26:46+01:00</xmp:MetadataDate> <xmpMM:DocumentID>uuid:f320abfc-f6ab-4d12-8719-d176f4d947cf</xmpMM:DocumentID> - <xmpMM:InstanceID>uuid:09e3ba2b-d440-481c-84c5-ec325f7e692b</xmpMM:InstanceID> + <xmpMM:InstanceID>uuid:0724bd50-3cc7-47a7-8c40-a7b4df91a045</xmpMM:InstanceID> <prism:complianceProfile>three</prism:complianceProfile> <prism:pageCount>1</prism:pageCount> </rdf:Description> @@ -306,7 +306,7 @@ endobj << /Type /Namespace /NS (https://www.latex-project.org/ns/book/2022) /RoleMapNS 18 0 R >> endobj 19 0 obj -<< /Type /Namespace /NS (data:,742A6FB5-B116-EDEB-CE34-2B5E2DFF57D0) >> +<< /Type /Namespace /NS (data:,D23E8AA3-3C3B-E3B-C789-DBEFB598C460) >> endobj 8 0 obj [ 9 0 R 11 0 R 13 0 R 15 0 R 17 0 R 19 0 R ] @@ -398,7 +398,7 @@ endobj << /Type /Catalog /Pages 31 0 R /MarkInfo 32 0 R/Lang (en-US)/Metadata 26 0 R/StructTreeRoot 5 0 R >> endobj 42 0 obj -<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240204162902+01'00')/ModDate (D:20240204162902+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> +<< /Producer (luahbtex-1.17.0)/Creator (LaTeX)/CreationDate (D:20240222232646+01'00')/ModDate (D:20240222232646+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.17.0 (TeX Live 2023)) >> endobj xref 0 43 @@ -407,10 +407,10 @@ xref 0000000003 00000 f 0000000004 00000 f 0000000010 00000 f -0000014807 00000 n +0000014806 00000 n 0000012015 00000 n 0000012225 00000 n -0000014242 00000 n +0000014241 00000 n 0000012867 00000 n 0000000012 00000 f 0000012935 00000 n @@ -423,30 +423,30 @@ xref 0000013875 00000 n 0000014153 00000 n 0000000000 00000 f -0000014303 00000 n -0000014400 00000 n -0000014487 00000 n -0000014574 00000 n -0000014673 00000 n +0000014302 00000 n +0000014399 00000 n +0000014486 00000 n +0000014573 00000 n +0000014672 00000 n 0000000020 00000 n 0000011869 00000 n 0000011734 00000 n 0000011500 00000 n -0000017428 00000 n -0000017782 00000 n +0000017427 00000 n +0000017781 00000 n 0000011979 00000 n 0000012056 00000 n 0000012188 00000 n 0000012804 00000 n -0000014944 00000 n -0000016385 00000 n -0000015031 00000 n -0000016606 00000 n -0000017582 00000 n -0000017844 00000 n -0000017962 00000 n +0000014943 00000 n +0000016384 00000 n +0000015030 00000 n +0000016605 00000 n +0000017581 00000 n +0000017843 00000 n +0000017961 00000 n trailer -<< /Size 43 /Root 41 0 R /Info 42 0 R /ID [ <308775A820C8CCFDD397720B69A96080> <308775A820C8CCFDD397720B69A96080> ] >> +<< /Size 43 /Root 41 0 R /Info 42 0 R /ID [ <7984D150CB27BF39829D2CAE888D8E38> <7984D150CB27BF39829D2CAE888D8E38> ] >> startxref -18185 +18184 %%EOF diff --git a/macros/latex/contrib/tagpdf/tagpdf-backend.dtx b/macros/latex/contrib/tagpdf/tagpdf-backend.dtx index 8d0ba2593e..e4078dbb6e 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-backend.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-backend.dtx @@ -47,13 +47,13 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{implementation} % \begin{macrocode} %<@@=tag> %<*luatex> -\ProvidesExplFile {tagpdf-luatex.def} {2024-02-04} {0.98v} +\ProvidesExplFile {tagpdf-luatex.def} {2024-02-22} {0.98w} {tagpdf~driver~for~luatex} % \end{macrocode} % \section{Loading the lua} @@ -97,6 +97,12 @@ \lua_now:e { ltx.@@.tables.\cs_to_str:N#1 = {} } } +\cs_set_protected:Npn \@@_prop_new_linked:N #1 + { + \prop_new_linked:N #1 + \lua_now:e { ltx.@@.tables.\cs_to_str:N#1 = {} } + } + \cs_set_protected:Npn \@@_seq_new:N #1 { @@ -158,8 +164,8 @@ local ProvidesLuaModule = { name = "tagpdf", - version = "0.98v", --TAGVERSION - date = "2024-02-04", --TAGDATE + version = "0.98w", --TAGVERSION + date = "2024-02-22", --TAGDATE description = "tagpdf lua code", license = "The LATEX Project Public License 1.3c" } @@ -636,7 +642,7 @@ if tex.outputmode == 0 then else -- assume a dvips variant function @@_backend_create_bmc_node (tag) local bmcnode = nodenew("whatsit","special") - bmcnode.data = "ps:SDict begin mark/"..tag.." BMC pdfmark end" + bmcnode.data = "ps:SDict begin mark/"..tag.." /BMC pdfmark end" return bmcnode end end @@ -672,7 +678,7 @@ if tex.outputmode == 0 then else -- assume a dvips variant function @@_backend_create_bdc_node (tag,dict) local bdcnode = nodenew("whatsit","special") - bdcnode.data = "ps:SDict begin mark/"..tag.."<<"..dict..">> BDC pdfmark end" + bdcnode.data = "ps:SDict begin mark/"..tag.."<<"..dict..">> /BDC pdfmark end" return bdcnode end end @@ -699,7 +705,7 @@ end % \begin{macrocode} local function @@_pdf_object_ref (name) local tokenname = 'c__pdf_backend_object_'..name..'_int' - local object = token.create(tokenname).index..' 0 R' + local object = token.create(tokenname).mode ..' 0 R' return object end ltx.@@.func.pdf_object_ref=@@_pdf_object_ref diff --git a/macros/latex/contrib/tagpdf/tagpdf-checks.dtx b/macros/latex/contrib/tagpdf/tagpdf-checks.dtx index c95b9d8bcb..9dfa7f3539 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-checks.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-checks.dtx @@ -48,7 +48,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \section{Commands} @@ -71,7 +71,7 @@ % \cs{tag_if_box_tagged:N}\Arg{box} % \end{syntax} % This tests if a box contains tagging commands. -% It relies currently on that the code that saved the box correctly set +% It relies currently on that the code, that saved the box, correctly sets % the command \verb+\l_tag_box_\int_use:N #1_tl+ to a positive value. % The LaTeX commands will do that automatically % at some time but it is in the responsability of the user to @@ -306,7 +306,7 @@ % Message if an attribute i sunknown. % \end{function} % -% \begin{function}{role-missing,role-unknown,role-unknown-tag,role-tag,new-tag, +% \begin{function}{role-missing,role-unknown,role-unknown-tag,role-unknown-NS,role-tag,new-tag, % role-parent-child,role-remapping} % Messages related to role mapping. % \end{function} @@ -327,7 +327,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-checks-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-checks-code} {2024-02-22} {0.98w} {part of tagpdf - code related to checks, conditionals, debugging and messages} %</header> % \end{macrocode} @@ -500,12 +500,13 @@ % \end{macro} % % \subsection{Roles} -% \begin{macro}{role-missing,role-unknown,role-unknown-tag} +% \begin{macro}{role-missing,role-unknown,role-unknown-tag,role-unknown-NS} % Warning message if either the tag or the role is missing % \begin{macrocode} \msg_new:nnn { tag } {role-missing} { tag~#1~has~no~role~assigned } \msg_new:nnn { tag } {role-unknown} { role~#1~is~not~known } \msg_new:nnn { tag } {role-unknown-tag} { tag~#1~is~not~known } +\msg_new:nnn { tag } {role-unknown-NS} { \tl_if_empty:nTF{#1}{Empty~NS}{NS~#1~is~not~known} } % \end{macrocode} % \end{macro} % \begin{macro}{role-parent-child} diff --git a/macros/latex/contrib/tagpdf/tagpdf-code.pdf b/macros/latex/contrib/tagpdf/tagpdf-code.pdf Binary files differindex 8cb02cff58..b639df8b25 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-code.pdf +++ b/macros/latex/contrib/tagpdf/tagpdf-code.pdf diff --git a/macros/latex/contrib/tagpdf/tagpdf-data.dtx b/macros/latex/contrib/tagpdf/tagpdf-data.dtx index 2088a66c60..9addb5955a 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-data.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-data.dtx @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % This files contains a various data files which are read in @@ -58,9 +58,10 @@ % \section{The LaTeX namespace} % This is the main new namespace. It is bound to change a lot! % It lists the new tag, the rolemap and the namespace of the rolemap. +% latex-lab has also a namespace module, which takes precendence! % \begin{macrocode} %<*ns-latex> -%% \ProvidesExplFile {tagpdf-ns-latex.def} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-ns-latex.def} {2024-02-22} {0.98w} %% {latex} {https://www.latex-project.org/ns/dflt/2022}{} title, Title, pdf2, part, Title, pdf2, @@ -92,7 +93,7 @@ text, P, pdf2, % It is bound to change % \begin{macrocode} %<*ns-latex-book> -%% \ProvidesExplFile {tagpdf-ns-latex-book.def} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-ns-latex-book.def} {2024-02-22} {0.98w} %% {latex-book} {https://www.latex-project.org/ns/book/2022}{} chapter, H1,pdf2, section, H2,pdf2, @@ -106,7 +107,7 @@ subparagraph, H6,pdf2, % \section{The pdf namespace data} % \begin{macrocode} %<*ns-pdf> -%% \ProvidesExplFile {tagpdf-ns-pdf.def} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-ns-pdf.def} {2024-02-22} {0.98w} %% {pdf} {http://iso.org/pdf/ssn}{} StructTreeRoot,StructTreeRoot,pdf,D, Document,Document,pdf,D, @@ -174,7 +175,7 @@ Strong,Span,pdf,I, % \section{The pdf 2.0 namespace data} % \begin{macrocode} %<*ns-pdf2> -%% \ProvidesExplFile {tagpdf-ns-pdf2.def} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-ns-pdf2.def} {2024-02-22} {0.98w} %% {pdf2} {http://iso.org/pdf2/ssn}{} StructTreeRoot,StructTreeRoot,pdf2,D, Document,Document,pdf2,D, @@ -231,7 +232,7 @@ Strong,Strong,pdf2,I, % \section{The mathml namespace data} % \begin{macrocode} %<*ns-mathml> -%% \ProvidesExplFile {tagpdf-ns-mathml.def} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-ns-mathml.def} {2024-02-22} {0.98w} % {mathml}{http://www.w3.org/1998/Math/MathML}{} abs,abs,mathml, and,and,mathml, @@ -466,7 +467,7 @@ xor,xor,mathml, % This will perhaps change in future. % \begin{macrocode} %<*parent-child> -%% \ProvidesExplFile {tagpdf-parent-child.csv} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-parent-child.csv} {2024-02-22} {0.98w} ,,,StructTreeRoot,Document,Art,Part,Div,Sect,BlockQuote,NonStruct,TOC,TOCI,Index,Private,Quote,Note,Reference,BibEntry,P,Hn,H,Lbl,Code,Span,Link,Annot,Form,Ruby,RB,RT,RP,Warichu,WT,WP,L,LI,LBody,Table,TR,TH,TD,THead,TBody,TFoot,Caption,Figure,Formula,MC Document,both,document level,1,0..n,∅,‡,‡,∅,0..n,‡,∅,∅,∅,0..n,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅ Art,1.7,grouping,∅,0..n,∅,‡,‡,0..n,0..n,‡,∅,∅,∅,0..n,∅,0..n,∅,∅,∅,0..1,0..1,∅,∅,∅,0..n,0..n,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,0..n,∅,∅,0..n,0..n,∅,∅,∅,0..n,0..n,∅,∅ @@ -521,7 +522,7 @@ MC,both,---,∅,∅,∅,∅,∅,∅,0..n,‡,∅,∅,∅,0..n,0..n,0..n,0..n,0.. % This will perhaps change in future. % \begin{macrocode} %<*parent-child-2> -%% \ProvidesExplFile {tagpdf-parent-child-2.csv} {2024-02-04} {0.98v} +%% \ProvidesExplFile {tagpdf-parent-child-2.csv} {2024-02-22} {0.98w} ,,,StructTreeRoot,Document,DocumentFragment,Art,Part,Div,Sect,Aside,BlockQuote,NonStruct,TOC,TOCI,Index,Private,Title,Sub,Quote,Note,Reference,BibEntry,P,Hn,H,Lbl,Code,Em,Strong,Span,Link,Annot,Form,Ruby,RB,RT,RP,Warichu,WT,WP,FENote,L,LI,LBody,Table,TR,TH,TD,THead,TBody,TFoot,Caption,Figure,Formula,math,mathml,Artifact,MC Document,both,document level,1,0..n,0..n,∅,‡,‡,∅,0..n,0..n,‡,∅,∅,∅,0..n,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,0..n,∅ DocumentFragment,2.0,document level,∅,0..n,0..n,0..n,‡,‡,0..n,0..n,0..n,‡,∅,∅,∅,0..n,∅,∅,∅,∅*,∅,∅,∅,∅,∅,∅,∅*,∅,∅,∅,∅*,∅*,∅,∅,∅,∅,∅,∅,∅,∅,∅*,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅,∅*,∅,∅,∅,∅,0..n,∅ diff --git a/macros/latex/contrib/tagpdf/tagpdf-mc-generic.dtx b/macros/latex/contrib/tagpdf/tagpdf-mc-generic.dtx index fe6e98b82b..0d86e3e3e4 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-mc-generic.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-mc-generic.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \end{documentation} @@ -55,11 +55,11 @@ % \begin{macrocode} %<@@=tag> %<*generic> -\ProvidesExplPackage {tagpdf-mc-code-generic} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-mc-code-generic} {2024-02-22} {0.98w} {part of tagpdf - code related to marking chunks - generic mode} %</generic> %<*debug> -\ProvidesExplPackage {tagpdf-debug-generic} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-debug-generic} {2024-02-22} {0.98w} {part of tagpdf - debugging code related to marking chunks - generic mode} %</debug> % \end{macrocode} diff --git a/macros/latex/contrib/tagpdf/tagpdf-mc-luacode.dtx b/macros/latex/contrib/tagpdf/tagpdf-mc-luacode.dtx index e53dc629d9..3ea053fc1a 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-mc-luacode.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-mc-luacode.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{implementation} % The code is splitted into three parts: code shared by all engines, @@ -86,11 +86,11 @@ % \begin{macrocode} %<@@=tag> %<*luamode> -\ProvidesExplPackage {tagpdf-mc-code-lua} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-mc-code-lua} {2024-02-22} {0.98w} {tagpdf - mc code only for the luamode } %</luamode> %<*debug> -\ProvidesExplPackage {tagpdf-debug-lua} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-debug-lua} {2024-02-22} {0.98w} {part of tagpdf - debugging code related to marking chunks - lua mode} %</debug> % \end{macrocode} diff --git a/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx b/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx index c38d7b8e2f..17027222f3 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \section{Public Commands} @@ -181,7 +181,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-mc-code-shared} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-mc-code-shared} {2024-02-22} {0.98w} {part of tagpdf - code related to marking chunks - code shared by generic and luamode } %</header> @@ -240,7 +240,7 @@ % key: absolute number of the mc (tagmcabs)\\ % value: the structure number the mc is in % \begin{macrocode} -\@@_prop_new:N \g_@@_mc_parenttree_prop +\@@_prop_new_linked:N \g_@@_mc_parenttree_prop % \end{macrocode} % \end{variable} % diff --git a/macros/latex/contrib/tagpdf/tagpdf-roles.dtx b/macros/latex/contrib/tagpdf/tagpdf-roles.dtx index 47a1f40bcc..052b805193 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-roles.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-roles.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \begin{function} @@ -98,7 +98,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-roles-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-roles-code} {2024-02-22} {0.98w} {part of tagpdf - code related to roles and structure names} %</header> % \end{macrocode} @@ -505,11 +505,16 @@ { \msg_info:nnn { tag }{new-tag}{#1} } - \prop_get:cnN { g_@@_role_NS_#4_class_prop } {#3}\l_@@_tmpa_tl - \quark_if_no_value:NT \l_@@_tmpa_tl - { - \tl_set:Nn\l_@@_tmpa_tl{--UNKNOWN--} - } + \prop_if_exist:cTF + { g_@@_role_NS_#4_class_prop } + { + \prop_get:cnN { g_@@_role_NS_#4_class_prop } {#3}\l_@@_tmpa_tl + \quark_if_no_value:NT \l_@@_tmpa_tl + { + \tl_set:Nn\l_@@_tmpa_tl{--UNKNOWN--} + } + } + { \tl_set:Nn\l_@@_tmpa_tl{--UNKNOWN--} } \@@_role_alloctag:nnV {#1}{#2}\l_@@_tmpa_tl % \end{macrocode} % Do not remap standard tags. TODO add warning? @@ -579,15 +584,24 @@ %#3 tlvar which hold the role tag %#4 tlvar which hold the name of the target NS { - \prop_get:cnNTF {g_@@_role_NS_#2_prop} {#1}\l_@@_tmpa_tl - { - \tl_set:Ne #3 {\exp_last_unbraced:NV\use_i:nn \l_@@_tmpa_tl} - \tl_set:Ne #4 {\exp_last_unbraced:NV\use_ii:nn \l_@@_tmpa_tl} - } - { - \tl_set:Nn #3 {#1} - \tl_set:Nn #4 {#2} - } + \prop_if_exist:cTF {g_@@_role_NS_#2_prop} + { + \prop_get:cnNTF {g_@@_role_NS_#2_prop} {#1}\l_@@_get_tmpc_tl + { + \tl_set:Ne #3 {\exp_last_unbraced:NV\use_i:nn \l_@@_get_tmpc_tl} + \tl_set:Ne #4 {\exp_last_unbraced:NV\use_ii:nn \l_@@_get_tmpc_tl} + } + { + \msg_warning:nnn { tag } {role-unknown-tag} { #1 } + \tl_set:Nn #3 {#1} + \tl_set:Nn #4 {#2} + } + } + { + \msg_warning:nnn { tag } {role-unknown-NS} { #2 } + \tl_set:Nn #3 {#1} + \tl_set:Nn #4 {#2} + } } \cs_generate_variant:Nn \@@_role_get:nnNN {VVNN} } @@ -1106,20 +1120,27 @@ \tl_set:Nn \l_@@_tmpa_tl {#1} } { - \prop_get:cnNTF - { g_@@_role_NS_#2_prop } - {#1} - \l_@@_tmpa_tl - { - \tl_set:Ne \l_@@_tmpa_tl {\tl_head:N\l_@@_tmpa_tl} - \tl_if_empty:NT\l_@@_tmpa_tl - { - \tl_set:Nn \l_@@_tmpa_tl {#1} - } - } - { - \tl_set:Nn \l_@@_tmpa_tl {\q_no_value} - } + \prop_if_exist:cTF { g_@@_role_NS_#2_prop } + { + \prop_get:cnNTF + { g_@@_role_NS_#2_prop } + {#1} + \l_@@_tmpa_tl + { + \tl_set:Ne \l_@@_tmpa_tl {\tl_head:N\l_@@_tmpa_tl} + \tl_if_empty:NT\l_@@_tmpa_tl + { + \tl_set:Nn \l_@@_tmpa_tl {#1} + } + } + { + \tl_set:Nn \l_@@_tmpa_tl {\q_no_value} + } + } + { + \msg_warning:nnn { tag } {role-unknown-NS} { #2} + \tl_set:Nn \l_@@_tmpa_tl {\q_no_value} + } } % \end{macrocode} % and the same for the child @@ -1131,20 +1152,27 @@ \tl_set:Nn \l_@@_tmpb_tl {#3} } { - \prop_get:cnNTF - { g_@@_role_NS_#4_prop } - {#3} - \l_@@_tmpb_tl + \prop_if_exist:cTF { g_@@_role_NS_#4_prop } { - \tl_set:Ne \l_@@_tmpb_tl { \tl_head:N\l_@@_tmpb_tl } - \tl_if_empty:NT\l_@@_tmpb_tl - { - \tl_set:Nn \l_@@_tmpb_tl {#3} - } + \prop_get:cnNTF + { g_@@_role_NS_#4_prop } + {#3} + \l_@@_tmpb_tl + { + \tl_set:Ne \l_@@_tmpb_tl { \tl_head:N\l_@@_tmpb_tl } + \tl_if_empty:NT\l_@@_tmpb_tl + { + \tl_set:Nn \l_@@_tmpb_tl {#3} + } + } + { + \tl_set:Nn \l_@@_tmpb_tl {\q_no_value} + } } - { + { + \msg_warning:nnn { tag } {role-unknown-NS} { #4} \tl_set:Nn \l_@@_tmpb_tl {\q_no_value} - } + } } % \end{macrocode} % and now get the relation @@ -1239,7 +1267,8 @@ % tag-namespace (rolemap-key), % role (rolemap-key), % role-namespace (rolemap-key), -% add-new-tag (setup-key)} +% role/new-tag (setup-key), +% add-new-tag (deprecated)} % \begin{macrocode} \keys_define:nn { @@ / tag-role } { @@ -1251,8 +1280,8 @@ \keys_define:nn { @@ / setup } { - mathml-tags .bool_gset:N = \g_@@_role_add_mathml_bool - ,add-new-tag .code:n = + role/mathml-tags .bool_gset:N = \g_@@_role_add_mathml_bool + ,role/new-tag .code:n = { \keys_set_known:nnnN {@@/tag-role} @@ -1298,6 +1327,14 @@ \l_@@_role_role_namespace_tmpa_tl } } + ,role/map-tags .choice: + ,role/map-tags/false .code:n = { \socket_assign_plug:nn { tag/struct/tag } {latex-tags} } + ,role/map-tags/pdf .code:n = { \socket_assign_plug:nn { tag/struct/tag } {pdf-tags} } +% \end{macrocode} +% deprecated names +% \begin{macrocode} + , mathml-tags .bool_gset:N = \g_@@_role_add_mathml_bool + , add-new-tag .meta:n = {role/new-tag={#1}} } %</package> % \end{macrocode} diff --git a/macros/latex/contrib/tagpdf/tagpdf-space.dtx b/macros/latex/contrib/tagpdf/tagpdf-space.dtx index 00ca1c28e0..9555e43500 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-space.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-space.dtx @@ -46,14 +46,16 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} -% \begin{function}{interwordspace (setup-key)} +% \begin{function}{activate/space (setup-key),interwordspace (deprecated)} % This key allows to activate/deactivate the real space chars if the engine supports % it. The allowed values are |true|, |on|, |false|, |off|. +% The old name of the key |interwordspace| is still supported but deprecated. % \end{function} -% \begin{function}{show-spaces (setup-key)} +% \begin{function}{show-spaces (deprecated)} +% This key is deprecated. Use |debug/show=spaces| instead. % This key works only with luatex and shows with small red % bars where spaces have been inserted. This is only for debugging and % is not completly reliable (and change affect other literals and tagging), so it @@ -64,7 +66,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-space-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-space-code} {2024-02-22} {0.98w} {part of tagpdf - code related to real space chars} %</header> % \end{macrocode} @@ -73,17 +75,29 @@ % support real space chars. Most of the code for luatex which uses attributes % is in the lua code, here are only the keys. % -% \begin{macro}{interwordspace (setup-key),show-spaces (setup-key)} +% \begin{macro}{activate/spaces (setup-key),interwordspace (deprecated),show-spaces (deprecated)} % \begin{macrocode} %<*package> \keys_define:nn { @@ / setup } - { - interwordspace .choices:nn = { true, on } + { + activate/spaces .choice:, + activate/spaces/true .code:n = { \msg_warning:nne {tag}{sys-no-interwordspace}{\c_sys_engine_str} }, - interwordspace .choices:nn = { false, off } + activate/spaces/false .code:n= { \msg_warning:nne {tag}{sys-no-interwordspace}{\c_sys_engine_str} }, - interwordspace .default:n = true, - show-spaces .bool_set:N = \l_@@_showspaces_bool + activate/spaces .default:n = true, + debug/show/spaces .code:n = {\bool_set_true:N \l_@@_showspaces_bool}, + debug/show/spacesOff .code:n = {\bool_set_false:N \l_@@_showspaces_bool}, +% \end{macrocode} +% deprecated versions: +% \begin{macrocode} + interwordspace .choices:nn = {true,on}{\keys_set:nn{@@/setup}{activate/spaces={true}}}, + interwordspace .choices:nn = {false,off}{\keys_set:nn{@@/setup}{activate/spaces={false}}}, + interwordspace .default:n = {true}, + show-spaces .choice:, + show-spaces/true .meta:n = {debug/show=spaces}, + show-spaces/false .meta:n = {debug/show=spacesOff}, + show-spaces .default:n = true } \sys_if_engine_pdftex:T { @@ -92,19 +106,17 @@ \pdfglyphtounicode{space}{0020} \keys_define:nn { @@ / setup } { - interwordspace .choices:nn = { true, on } { \pdfinterwordspaceon }, - interwordspace .choices:nn = { false, off }{ \pdfinterwordspaceon }, - interwordspace .default:n = true, - show-spaces .bool_set:N = \l_@@_showspaces_bool + activate/spaces/true .code:n = { \pdfinterwordspaceon }, + activate/spaces/false .code:n = { \pdfinterwordspaceoff }, + activate/spaces .default:n = true, } } { \keys_define:nn { @@ / setup } { - interwordspace .choices:nn = { true, on, false, off } + activate/spaces .choices:nn = { true, false } { \msg_warning:nnn {tag}{sys-no-interwordspace}{dvi} }, - interwordspace .default:n = true, - show-spaces .bool_set:N = \l_@@_showspaces_bool + activate/spaces .default:n = true, } } } @@ -114,25 +126,22 @@ { \keys_define:nn { @@ / setup } { - interwordspace .choices:nn = - { true, on } + activate/spaces .choice:, + activate/spaces/true .code:n = { \bool_gset_true:N \g_@@_active_space_bool \lua_now:e{ltx.@@.func.markspaceon()} }, - interwordspace .choices:nn = - { false, off } + activate/spaces/false .code:n = { \bool_gset_false:N \g_@@_active_space_bool \lua_now:e{ltx.@@.func.markspaceoff()} }, - interwordspace .default:n = true, - show-spaces .choice:, - show-spaces / true .code:n = + activate/spaces .default:n = true, + debug/show/spaces .code:n = {\lua_now:e{ltx.@@.trace.showspaces=true}}, - show-spaces / false .code:n = + debug/show/spacesOff .code:n = {\lua_now:e{ltx.@@.trace.showspaces=nil}}, - show-spaces .default:n = true } } % \end{macrocode} diff --git a/macros/latex/contrib/tagpdf/tagpdf-struct.dtx b/macros/latex/contrib/tagpdf/tagpdf-struct.dtx index 2e8b69d7e5..3cdced94d1 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-struct.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-struct.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \section{Public Commands} @@ -254,9 +254,9 @@ % must be declared first in \cs{tagpdfsetup}. % \end{function} % \subsection{Setup keys} -% \begin{function}{newattribute (setup-key)} +% \begin{function}{role/new-attribute (setup-key), newattribute (deprecated)} % \begin{syntax} -% newattribute = \Arg{name}\Arg{Content} +% role/new-attribute = \Arg{name}\Arg{Content} % \end{syntax} % This key can be used in the setup command \cs{tagpdfsetup} and allow to declare a % new attribute, which can be used as attribute or attribute class. @@ -264,9 +264,9 @@ % \begin{verbatim} % \tagpdfsetup % { -% newattribute = +% role/new-attribute = % {TH-col}{/O /Table /Scope /Column}, -% newattribute = +% role/new-attribute = % {TH-row}{/O /Table /Scope /Row}, % } % \end{verbatim} @@ -285,7 +285,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-struct-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-struct-code} {2024-02-22} {0.98w} {part of tagpdf - code related to storing structure} %</header> % \end{macrocode} @@ -464,7 +464,7 @@ % It is currently used by the toc-tagging and sec-tagging code. % \begin{macrocode} %</package> -%<base>\prop_new:N \g_@@_struct_dest_num_prop +%<base>\prop_new_linked:N \g_@@_struct_dest_num_prop %<*package> % \end{macrocode} % \end{variable} @@ -474,7 +474,7 @@ % at the end to point to structured related with this destination. % As this is probably need in other places too, it is not only a toc-variable. % \begin{macrocode} -\prop_new:N \g_@@_struct_ref_by_dest_prop +\prop_new_linked:N \g_@@_struct_ref_by_dest_prop % \end{macrocode} % \end{variable} % @@ -1113,6 +1113,33 @@ % This are the keys for the user commands. % we store the tag in a variable. But we should be careful, it is only reliable % at the begin. +% +% This socket is used by the tag key. It allows to switch between +% the latex-tabs and the standard tags. +% \begin{macrocode} +%<*package> +\socket_new:nn { tag/struct/tag }{1} +\socket_new_plug:nnn { tag/struct/tag }{ latex-tags } + { + \seq_set_split:Nne \l_@@_tmpa_seq { / } {#1/\prop_item:Ne\g__tag_role_tags_NS_prop{#1}} + \tl_gset:Ne \g_@@_struct_tag_tl { \seq_item:Nn\l_@@_tmpa_seq {1} } + \tl_gset:Ne \g_@@_struct_tag_NS_tl{ \seq_item:Nn\l_@@_tmpa_seq {2} } + \@@_check_structure_tag:N \g_@@_struct_tag_tl + } + +\socket_new_plug:nnn { tag/struct/tag }{ pdf-tags } + { + \seq_set_split:Nne \l_@@_tmpa_seq { / } {#1/\prop_item:Ne\g_@@_role_tags_NS_prop{#1}} + \tl_gset:Ne \g_@@_struct_tag_tl { \seq_item:Nn\l_@@_tmpa_seq {1} } + \tl_gset:Ne \g_@@_struct_tag_NS_tl{ \seq_item:Nn\l_@@_tmpa_seq {2} } + \@@_role_get:VVNN \g_@@_struct_tag_tl\g_@@_struct_tag_NS_tl\l_@@_tmpa_tl\l_@@_tmpb_tl + \tl_gset:Ne \g_@@_struct_tag_tl {\l_@@_tmpa_tl} + \tl_gset:Ne \g_@@_struct_tag_NS_tl{\l_@@_tmpb_tl} + \@@_check_structure_tag:N \g_@@_struct_tag_tl + } +\socket_assign_plug:nn { tag/struct/tag } {latex-tags} +% \end{macrocode} + % \begin{macro} % { % label (struct-key), @@ -1128,7 +1155,6 @@ % E (struct-key) % } % \begin{macrocode} -%<*package> \keys_define:nn { @@ / struct } { label .tl_set:N = \l_@@_struct_key_label_tl, @@ -1152,10 +1178,7 @@ parent .default:n = {-1}, tag .code:n = % S property { - \seq_set_split:Nne \l_@@_tmpa_seq { / } {#1/\prop_item:Ne\g__tag_role_tags_NS_prop{#1}} - \tl_gset:Ne \g_@@_struct_tag_tl { \seq_item:Nn\l_@@_tmpa_seq {1} } - \tl_gset:Ne \g_@@_struct_tag_NS_tl{ \seq_item:Nn\l_@@_tmpa_seq {2} } - \@@_check_structure_tag:N \g_@@_struct_tag_tl + \socket_use:nn { tag/struct/tag }{#1} }, title .code:n = % T property { @@ -1905,7 +1928,7 @@ % \section{Attributes and attribute classes} % \begin{macrocode} %<*header> -\ProvidesExplPackage {tagpdf-attr-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-attr-code} {2024-02-22} {0.98w} {part of tagpdf - code related to attributes and attribute classes} %</header> % \end{macrocode} @@ -1921,7 +1944,7 @@ % |\g_@@_attr_class_used_seq| will hold the attributes which have been used as % class name. % |\l_@@_attr_value_tl| is used to build the attribute array or key. -% Everytime an attribute is used for the first time, and object is created +% Every time an attribute is used for the first time, and object is created % with its content, the name-object reference relation is stored in % |\g_@@_attr_objref_prop| % \begin{macrocode} @@ -1933,9 +1956,9 @@ % \end{macrocode} % \end{variable} % \subsection{Commands and keys} -% \begin{macro}{\@@_attr_new_entry:nn,newattribute (setup-key)} +% \begin{macro}{\@@_attr_new_entry:nn,role/new-attribute (setup-key), newattribute (deprecated)} % This allows to define attributes. Defined attributes -% are stored in a global property. |newattribute| expects +% are stored in a global property. |role/new-attribute| expects % two brace group, the name and the content. The content typically % needs an |/O| key for the owner. An example look like % this. @@ -1945,9 +1968,9 @@ % \begin{verbatim} % \tagpdfsetup % { -% newattribute = +% role/new-attribute = % {TH-col}{/O /Table /Scope /Column}, -% newattribute = +% role/new-attribute = % {TH-row}{/O /Table /Scope /Row}, % } % \end{verbatim} @@ -1957,13 +1980,21 @@ \prop_gput:Nen \g_@@_attr_entries_prop {\pdf_name_from_unicode_e:n{#1}}{#2} } - + +\cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} \keys_define:nn { @@ / setup } { - newattribute .code:n = + role/new-attribute .code:n = { \@@_attr_new_entry:nn #1 } +% \end{macrocode} +% deprecated name +% \begin{macrocode} + ,newattribute .code:n = + { + \@@_attr_new_entry:nn #1 + }, } % \end{macrocode} % \end{macro} diff --git a/macros/latex/contrib/tagpdf/tagpdf-tree.dtx b/macros/latex/contrib/tagpdf/tagpdf-tree.dtx index 3f16beff6d..ef7bcd3f1a 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-tree.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-tree.dtx @@ -47,13 +47,13 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{implementation} % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-tree-code} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-tree-code} {2024-02-22} {0.98w} {part of tagpdf - code related to writing trees and dictionaries to the pdf} %</header> % \end{macrocode} diff --git a/macros/latex/contrib/tagpdf/tagpdf-user.dtx b/macros/latex/contrib/tagpdf/tagpdf-user.dtx index ac7144dab6..65a0811c14 100644 --- a/macros/latex/contrib/tagpdf/tagpdf-user.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf-user.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Version 0.98v, released 2024-02-04} +% \date{Version 0.98w, released 2024-02-22} % \maketitle % \begin{documentation} % \section{Setup commands} @@ -60,8 +60,8 @@ % % \begin{function}{activate (setup-key)} % And additional setup key which combine the other activate keys -% |activate-mc|, |activate-tree|, |activate-struct| and additionally -% add a document structure. +% |activate/mc|, |activate/tree|, |activate/struct| and additionally +% adds a document structure. % \end{function} % % \begin{function}{\tag_tool:n,\tagtool} @@ -109,7 +109,7 @@ % \end{syntax} % These are direct wrappers around |\tag_struct_begin:n|, % |\tag_struct_end:| and |\tag_struct_use:n|. -% The commands and their argument are documentated in the \pkg{tagpdf-struct} module. +% The commands and their argument are documented in the \pkg{tagpdf-struct} module. % \end{function} @@ -183,22 +183,24 @@ % pdftex. % \end{function} % -% \subsection{Paratagging} +% \subsection{Tagging of paragraphs} % -% This is a first try to make use of the new paragraph hooks in a current LaTeX to +% This makes use of the paragraph hooks in LaTeX to % automate the tagging of paragraph. It requires sane paragraph nesting, % faulty code, e.g. a missing |\par| at the end of a low-level vbox can highly % confuse the tagging. The tags should be carefully checked if this is used. % -% \begin{function}{paratagging (setup-key),paratagging-show (setup-key)} +% \begin{function}{para/tagging (setup-key),paratagging-show (deprecated),paratagging (deprecated)} % \begin{syntax} -% |paratagging| = |true|\verb+|+|false|\\ -% |paratagging-show| = |true|\verb+|+|false|\\ +% |para/tagging| = |true|\verb+|+|false|\\ +% |debug/show=para|\\ +% |debug/show=paraOff| % \end{syntax} -% This keys can be used in |\tagpdfsetup| and enable/disable paratagging. -% |paratagging-show| puts small red numbers at the begin and end of a paragraph. +% The |para/tagging| key can be used in |\tagpdfsetup| and enable/disables tagging +% of paragraphics. +% |debug/show=para| puts small colored numbers at the begin and end of a paragraph. % This is meant as a debugging help. The number are boxes and have a (tiny) height, -% so they can affect typesetting. +% so they can affect typesetting. % \end{function} % % \begin{function}{\tagpdfparaOn,\tagpdfparaOff} @@ -223,17 +225,21 @@ % \end{function} % % \subsection{Header and footer} -% Header and footer are automatically excluded from tagging. This can -% be disabled with the following key. +% Header and footer are automatically tagged as artifact: +% They are surrounded by an artifact-mc and inside tagging is stopped. % If some real content is in the header and % footer, tagging must be restarted there explicitly. -% The key accepts the values |true| which surrounds the header with an artifact -% mc-chunk, |false| which disables the automatic tagging, and |pagination| which +% The behaviour can be changed with the following key. +% The key accepts the values |true| (the default), +% |false| which disables the header tagging code. This can be useful +% if the page style is empty (it then avoids empty mc-chunks) or +% if the head and foot should be tagged in some special way. +% The last value, |pagination|, is like |true| but % additionally adds an artifact structure with an pagination attribute. % -% \begin{function}{exclude-header-footer (setup-key)} +% \begin{function}{page/exclude-header-footer (setup-key)} % \begin{syntax} -% |exclude-header-footer| = |true|\verb+|+|false|\verb+|+pagination +% |page/exclude-header-footer| = |true|\verb+|+|false|\verb+|+pagination % \end{syntax}% % \end{function} @@ -264,7 +270,7 @@ % \end{syntax} % \end{function} -% The next \LaTeX{} will use special sockets for the tagging. +% The next \LaTeX{} (2024-06-01) will use special sockets for the tagging. % % These sockets will use names starting % with \texttt{tagsupport/}. Usually, these sockets have exactly two @@ -303,7 +309,7 @@ % \begin{macrocode} %<@@=tag> %<*header> -\ProvidesExplPackage {tagpdf-user} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-user} {2024-02-22} {0.98w} {tagpdf - user commands} %</header> % \end{macrocode} @@ -664,7 +670,7 @@ %<*package> % \end{macrocode} % \subsection{Document structure} -% \begin{macro}{\g_@@_root_default_tl,activate (setup-key),activate-socket (setup-key)} +% \begin{macro}{\g_@@_root_default_tl,activate (setup-key),activate/socket (setup-key)} % \begin{macrocode} \tl_new:N\g_@@_root_default_tl \tl_gset:Nn\g_@@_root_default_tl {Document} @@ -674,11 +680,11 @@ \keys_define:nn { @@ / setup} { - activate-socket .bool_set:N = \l_@@_active_socket_bool, + activate/socket .bool_set:N = \l_@@_active_socket_bool, activate .code:n = { \keys_set:nn { @@ / setup } - { activate-mc,activate-tree,activate-struct,activate-socket } + { activate/mc,activate/tree,activate/struct,activate/socket } \tl_gset:Nn\g_@@_root_default_tl {#1} }, activate .default:n = Document @@ -879,17 +885,49 @@ % \end{macrocode} %\begin{macro} % { -% paratagging (setup-key), -% paratagging-show (setup-key), -% paratag (setup-key), -% paratag (tool-key), -% unittag (tool-key), -% para-flattened (tool-key), +% para/tagging (setup-key), +% para/tag (setup-key), +% para/maintag (setup-key), +% para/tagging (tool-key), +% para/tag (tool-key), +% para/maintag (tool-key), +% para/flattened (tool-key), +% unittag (deprecated), +% para-flattened (deprecated), +% paratagging (deprecated), +% paratagging-show (deprecated), +% paratag (deprecated), % } -% These keys enable/disable locally paratagging, and the debug modus. -% It can affect the typesetting if |paratagging-show| is used. The small numbers -% are boxes and they have a (small) height. The |paratag| key sets the tag used by -% the next automatic paratagging, it can also be changed with |\tag_tool:n| +% These keys enable/disable locally paratagging. +% Paragraphs are typically tagged with two structure: A main structure +% around the whole paragraph, and inner structures around the various chunks. +% Debugging can be +% activated locally with |debug/show=para|, this can affect the typesetting +% as the small numbers +% are boxes and they have a (small) height. Debugging can be deactivated +% with |debug/show=paraOff| +% The |para/tag| key sets the tag used by +% the inner structure, |para/maintag| the tag of the outer structure, +% both can also be changed with |\tag_tool:n| +% \begin{macrocode} +\keys_define:nn { @@ / setup } + { + para/tagging .bool_set:N = \l_@@_para_bool, + debug/show/para .code:n = {\bool_set_true:N \l_@@_para_show_bool}, + debug/show/paraOff .code:n = {\bool_set_false:N \l_@@_para_show_bool}, + para/tag .tl_set:N = \l_@@_para_tag_tl, + para/maintag .tl_set:N = \l_@@_para_main_tag_tl, + para/flattened .bool_set:N = \l_@@_para_flattened_bool + } +\keys_define:nn { tag / tool} + { + para/tagging .bool_set:N = \l_@@_para_bool, + para/tag .tl_set:N = \l_@@_para_tag_tl, + para/maintag .tl_set:N = \l_@@_para_main_tag_tl, + para/flattened .bool_set:N = \l_@@_para_flattened_bool + } +% \end{macrocode} +% the deprecated names % \begin{macrocode} \keys_define:nn { @@ / setup } { @@ -899,6 +937,7 @@ } \keys_define:nn { tag / tool} { + para .bool_set:N = \l_@@_para_bool, paratag .tl_set:N = \l_@@_para_tag_tl, unittag .tl_set:N = \l_@@_para_main_tag_tl, para-flattened .bool_set:N = \l_@@_para_flattened_bool @@ -1133,11 +1172,6 @@ %<*package> \renewcommand\tagpdfparaOn {\bool_set_true:N \l_@@_para_bool} \renewcommand\tagpdfparaOff{\bool_set_false:N \l_@@_para_bool} -\keys_define:nn { tag / tool} - { - para .bool_set:N = \l_@@_para_bool, - para-flattened .bool_set:N = \l_@@_para_flattened_bool, - } % \end{macrocode} % \end{macro} % @@ -1248,34 +1282,38 @@ } % \end{macrocode} % And now the keys -% \begin{macro}{exclude-header-footer (setup-key)} +% \begin{macro}{page/exclude-header-footer (setup-key),exclude-header-footer (deprecated)} % \begin{macrocode} \keys_define:nn { @@ / setup } { - exclude-header-footer .choice:, - exclude-header-footer / true .code:n = + page/exclude-header-footer .choice:, + page/exclude-header-footer / true .code:n = { \cs_set_eq:NN \@@_hook_kernel_before_head: \@@_exclude_headfoot_begin: \cs_set_eq:NN \@@_hook_kernel_before_foot: \@@_exclude_headfoot_begin: \cs_set_eq:NN \@@_hook_kernel_after_head: \@@_exclude_headfoot_end: \cs_set_eq:NN \@@_hook_kernel_after_foot: \@@_exclude_headfoot_end: }, - exclude-header-footer / pagination .code:n = + page/exclude-header-footer / pagination .code:n = { \cs_set:Nn \@@_hook_kernel_before_head: { \@@_exclude_struct_headfoot_begin:n {pagination} } \cs_set:Nn \@@_hook_kernel_before_foot: { \@@_exclude_struct_headfoot_begin:n {pagination} } \cs_set_eq:NN \@@_hook_kernel_after_head: \@@_exclude_struct_headfoot_end: \cs_set_eq:NN \@@_hook_kernel_after_foot: \@@_exclude_struct_headfoot_end: }, - exclude-header-footer / false .code:n = + page/exclude-header-footer / false .code:n = { \cs_set_eq:NN \@@_hook_kernel_before_head: \prg_do_nothing: \cs_set_eq:NN \@@_hook_kernel_before_foot: \prg_do_nothing: \cs_set_eq:NN \@@_hook_kernel_after_head: \prg_do_nothing: \cs_set_eq:NN \@@_hook_kernel_after_foot: \prg_do_nothing: }, - exclude-header-footer .default:n = true, - exclude-header-footer .initial:n = true + page/exclude-header-footer .default:n = true, + page/exclude-header-footer .initial:n = true, +% \end{macrocode} +% deprecated name +% \begin{macrocode} + exclude-header-footer .meta:n = { page/exclude-header-footer = {#1} } } % \end{macrocode} % \end{macro} diff --git a/macros/latex/contrib/tagpdf/tagpdf.bib b/macros/latex/contrib/tagpdf/tagpdf.bib index c4a48b605b..2f2cc7c293 100644 --- a/macros/latex/contrib/tagpdf/tagpdf.bib +++ b/macros/latex/contrib/tagpdf/tagpdf.bib @@ -1,8 +1,9 @@ @online{pdfreference, title= {PDF Reference, sixth edition}, author={{Adobe Systems Incorporated}}, -url = {https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf}, -year = {2006} +url = {https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf}, +year = {2006}, +urldate={2024-02-17}, } @book{pdfspec-iso32000-1, @@ -10,8 +11,8 @@ year = {2006} title={Document management -- Portable document format -- Part 1: PDF 1.7}, date={2008-07-01}, edition={1}, - url={https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf}, - urldate={2021-04-18}, + url={https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf}, + urldate={2024-02-17}, } @@ -34,22 +35,28 @@ year = {2006} url={https://www.iso.org/obp/ui/#iso:std:iso:32000:-2:ed-2:v1:en}, urldate={2021-04-18}, } -@online{pac3, -title = {PDF Accessibility Checker (PAC 3)}, -author= {{Zugang für alle -- Schweizerische Stiftung zur behindertengerechten Technologienutzung}}, -url = {http://www.access-for-all.ch/ch/pdf-werkstatt/pdf-accessibility-checker-pac.html}, -urldate ={2018-07-05}} +@online{pac2024, +title = {PDF Accessibility Checker (PAC 2024)}, +url = {https://pac.pdf-accessibility.org/}, +urldate ={2024-02-17}} @online{verapdf, title = {veraPDF}, author={{veraPDF consortium}}, -url = {http://verapdf.org/} +url = {https://verapdf.org/} } @online{ngpdf, title = {Next-Generation PDF}, author={{Dual Lab}}, -url = {http://ngpdf.com/} +url = {https://ngpdf.com} +} + +@online{mathexamples, +title = {MathML Associated Files Examples}, +author={\LaTeX\ Project}, +url = {https://github.com/latex3/tagging-project/discussions/56}, +urldate={2024-02-19} } @online{tugaccess, @@ -57,3 +64,22 @@ title={PDF accessibility and PDF standards}, author= {{TeX User Group}}, url= {https://tug.org/twg/accessibility/} } + +@inproceedings{todasoifferdeims2024, +author={Roman Toda and Jing Mu and Youqiang Wu and Neil Soiffer}, +title = {PDF Document Object Model Support for Math}, +year={2024}, +booktitle = {The 5th International Workshop on Digitization and E-Inclusion in Mathematics and Science 2024}, +publisher = {The DEIMS2024 Organizing Committee}, +url={https://workshop.sciaccess.net/deims2024/DEIMS2024_Proceedings.zip} +} + +@inproceedings{mittelbachfischerdeims2024, +author={Frank Mittelbach und Ulrike Fischer}, +title = {Enhancing LATEX to Automatically Produce Tagged and +Accessible PDF}, +year={2024}, +booktitle = {The 5th International Workshop on Digitization and E-Inclusion in Mathematics and Science 2024}, +publisher = {The DEIMS2024 Organizing Committee}, +url={https://workshop.sciaccess.net/deims2024/DEIMS2024_Proceedings.zip} +} diff --git a/macros/latex/contrib/tagpdf/tagpdf.dtx b/macros/latex/contrib/tagpdf/tagpdf.dtx index ad8f1950f9..15b5548d58 100644 --- a/macros/latex/contrib/tagpdf/tagpdf.dtx +++ b/macros/latex/contrib/tagpdf/tagpdf.dtx @@ -42,34 +42,37 @@ % in debugging messages to allow to follow the nesting. % \end{function} % -% \begin{function}{activate-space (setup-key)} -% |activate-space| activates the additional parsing needed for -% interword spaces. It is not documented, the parsing is currently -% implicitly activated by the known key |interwordspace|, as the code will -% perhaps move to some other place, now that it is better separated. +% \begin{function}{activate/spaces (setup-key)} +% |activate/spaces| activates the additional parsing needed for +% interword spaces. It replaces the deprecated key |interwordspace|. % \end{function} % -% \begin{function}{activate-mc (setup-key), -% activate-tree (setup-key), -% activate-struct (setup-key), -% activate-all (setup-key)} -% Keys to activate the various tagging steps +% \begin{function}{activate/mc (setup-key), +% activate/tree (setup-key), +% activate/struct (setup-key), +% activate/all (setup-key), +% activate-mc (deprecated), +% activate-tree (deprecated), +% activate-struct (deprecated), +% activate-all (deprecated), +% } +% Keys to activate the various tagging steps. % \end{function} -%\begin{function}{no-struct-dest (setup-key)} +%\begin{function}{activate/struct-dest (setup-key),no-struct-dest (deprecated)} % The key allows to suppress the creation of structure destinations % \end{function} % -% \begin{function}{log (setup-key)} -% The |log| takes currently the values |none|, |v|, |vv|, |vvv|, |all|. +% \begin{function}{debug/log (setup-key)} +% The |debug/log| key takes currently the values |none|, |v|, |vv|, |vvv|, |all|. % More details are in \texttt{tagpdf-checks}. % \end{function} % -% \begin{function}{tagunmarked (setup-key)} +% \begin{function}{activate/tagunmarked (setup-key), tagunmarked (deprecated) } % This key allows to set if (in luamode) unmarked text should be % marked up as artifact. The initial value is true. % \end{function} % -% \begin{function}{tabsorder (setup-key)} +% \begin{function}{page/tabsorder (setup-key), tabsorder (deprecated)} % This sets the tabsorder on a page. The values are |row|, |column|, |structure| (default) % or |none|. Currently this is set more or less globally. More finer control can be % added if needed. @@ -84,7 +87,7 @@ % \begin{macrocode} %<@@=tag> %<*package> -\ProvidesExplPackage {tagpdf} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf} {2024-02-22} {0.98w} { A package to experiment with pdf tagging } \bool_if:nF @@ -110,7 +113,7 @@ % \end{macrocode} %<*debug> % \begin{macrocode} -\ProvidesExplPackage {tagpdf-debug} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-debug} {2024-02-22} {0.98w} { debug code for tagpdf } \@ifpackageloaded{tagpdf}{}{\PackageWarning{tagpdf-debug}{tagpdf~not~loaded,~quitting}\endinput} % \end{macrocode} @@ -133,7 +136,7 @@ % we define a base package with dummy functions % \begin{macrocode} %<*base> -\ProvidesExplPackage {tagpdf-base} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdf-base} {2024-02-22} {0.98w} {part of tagpdf - provide base, no-op versions of the user commands } %</base> % \end{macrocode} @@ -278,7 +281,7 @@ % commands, the struct-boolean activates the storing of the structure data. % In a normal document all should be active, the split is only there for % debugging purpose. -% Structure destination will be activated automatically if pdf version 2.0 is detected, +% Structure destination will be activated automatically, % but with the boolean struct-dest-boolean one can suppress them. % Also we assume currently that they are set only at begin document. But % if some control passing over groups are needed they could be perhaps @@ -329,10 +332,10 @@ \cs_generate_variant:Nn \pdf_object_ref:n {e} \cs_generate_variant:Nn \pdfannot_dict_put:nnn {nne} \cs_generate_variant:Nn \pdffile_embed_stream:nnn {nee,oee} -\cs_generate_variant:Nn \prop_gput:Nnn {Nee,Nen} -\cs_generate_variant:Nn \prop_put:Nnn {Nee} -\cs_generate_variant:Nn \prop_item:Nn {No,Ne} -\cs_generate_variant:Nn \seq_set_split:Nnn{Nne} +\cs_generate_variant:Nn \prop_gput:Nnn {Nee,Nen} %** unneeded +\cs_generate_variant:Nn \prop_put:Nnn {Nee} %** unneeded +\cs_generate_variant:Nn \prop_item:Nn {No,Ne} %** unneeded +\cs_generate_variant:Nn \seq_set_split:Nnn{Nne} %** unneeded \cs_generate_variant:Nn \str_set_convert:Nnnn {Nonn, Noon, Nnon } \cs_generate_variant:Nn \clist_map_inline:nn {on} % \end{macrocode} @@ -340,6 +343,7 @@ % \section{Label and Reference commands} % To ease transition to properties we setup internal definition. They can be replaced % by the property definitions once that is released. +% %** do it! % \begin{macro}{\@@_property_new:nnnn,\@@_property_gset:nnnn,\@@_property_ref:nnn} % At first a command to define new properties % \begin{macrocode} @@ -425,6 +429,7 @@ % \begin{macro} % { % \@@_prop_new:N +% ,\@@_prop_new_linked:N % ,\@@_seq_new:N % ,\@@_prop_gput:Nnn % ,\@@_seq_gput_right:Nn @@ -435,6 +440,7 @@ % } % \begin{macrocode} \cs_set_eq:NN \@@_prop_new:N \prop_new:N +\cs_set_eq:NN \@@_prop_new_linked:N \prop_new_linked:N \cs_set_eq:NN \@@_seq_new:N \seq_new:N \cs_set_eq:NN \@@_prop_gput:Nnn \prop_gput:Nnn \cs_set_eq:NN \@@_seq_gput_right:Nn \seq_gput_right:Nn @@ -539,78 +545,103 @@ % % % \section{Keys for tagpdfsetup} - +% % TODO: the log-levels must be sorted % % \begin{macro} % { -% activate-space (setup-key), -% activate-mc (setup-key), -% activate-tree (setup-key), -% activate-struct (setup-key), -% activate-all (setup-key), -% no-struct-dest (setup-key), +% activate/mc (setup-key), +% activate/tree (setup-key), +% activate/struct (setup-key), +% activate/all (setup-key), +% activate/struct-dest (setup-key), % } % Keys to (globally) activate tagging. -% |activate-space| activates the additional parsing needed for -% interword spaces. It is not documented, the parsing is currently -% implicitly activated by the known key |interwordspace|, as the code will -% perhaps move to some other place, now that it is better separated. -% |no-struct-dest| allows to suppress structure destinations. +% |activate/spaces| activates the additional parsing needed for +% interword spaces. It is defined in tagpdf-space. +% |activate/struct-dest| allows to activate or suppress structure destinations. % \begin{macrocode} %<*package> \keys_define:nn { @@ / setup } { - activate-space .bool_gset:N = \g_@@_active_space_bool, + activate/mc .bool_gset:N = \g_@@_active_mc_bool, + activate/tree .bool_gset:N = \g_@@_active_tree_bool, + activate/struct .bool_gset:N = \g_@@_active_struct_bool, + activate/all .meta:n = + {activate/mc={#1},activate/tree={#1},activate/struct={#1}}, + activate/all .default:n = true, + activate/struct-dest .bool_gset:N = \g_@@_active_struct_dest_bool, +% \end{macrocode} +% old, deprecated names +% \begin{macrocode} activate-mc .bool_gset:N = \g_@@_active_mc_bool, activate-tree .bool_gset:N = \g_@@_active_tree_bool, activate-struct .bool_gset:N = \g_@@_active_struct_bool, activate-all .meta:n = - {activate-mc={#1},activate-tree={#1},activate-struct={#1}}, + {activate/mc={#1},activate/tree={#1},activate/struct={#1}}, activate-all .default:n = true, - no-struct-dest .bool_gset_inverse:N = \g_@@_active_struct_dest_bool, - % \end{macrocode} + no-struct-dest .bool_gset_inverse:N = \g_@@_active_struct_dest_bool, +% \end{macrocode} +% \end{macro} +% \begin{macro}{debug/show (setup-key)} +% Subkeys/values are defined in various other places. +% \begin{macrocode} + debug/show .choice:, +% \end{macrocode} % \end{macro} -% \begin{macro}{log (setup-key)} +% \begin{macro}{debug/log (setup-key), debug/uncompress (setup-key), log (deprecated), uncompress (deprecated)} % The |log| takes currently the values |none|, |v|, |vv|, |vvv|, |all|. % The description of the log levels is in tagpdf-checks. % \begin{macrocode} - log .choice:, - log / none .code:n = {\int_set:Nn \l_@@_loglevel_int { 0 }}, - log / v .code:n = + debug/log .choice:, + debug/log / none .code:n = {\int_set:Nn \l_@@_loglevel_int { 0 }}, + debug/log / v .code:n = { \int_set:Nn \l_@@_loglevel_int { 1 } \cs_set_protected:Nn \@@_check_typeout_v:n { \iow_term:e {##1} } }, - log / vv .code:n = {\int_set:Nn \l_@@_loglevel_int { 2 }}, - log / vvv .code:n = {\int_set:Nn \l_@@_loglevel_int { 3 }}, - log / all .code:n = {\int_set:Nn \l_@@_loglevel_int { 10 }}, + debug/log / vv .code:n = {\int_set:Nn \l_@@_loglevel_int { 2 }}, + debug/log / vvv .code:n = {\int_set:Nn \l_@@_loglevel_int { 3 }}, + debug/log / all .code:n = {\int_set:Nn \l_@@_loglevel_int { 10 }}, + debug/uncompress .code:n = { \pdf_uncompress: }, +% \end{macrocode} +% deprecated but still needed as the documentmetadata key argument uses it. +% \begin{macrocode} + log .meta:n = {debug/log={#1}}, + uncompress .code:n = { \pdf_uncompress: }, % \end{macrocode} % \end{macro} -% \begin{macro}{tagunmarked (setup-key)} +% \begin{macro}{activate/tagunmarked (setup-key),tagunmarked (deprecated)} % This key allows to set if (in luamode) unmarked text should be % marked up as artifact. The initial value is true. % \begin{macrocode} - tagunmarked .bool_gset:N = \g_@@_tagunmarked_bool, - tagunmarked .initial:n = true, + activate/tagunmarked .bool_gset:N = \g_@@_tagunmarked_bool, + activate/tagunmarked .initial:n = true, +% \end{macrocode} +% deprecated name +% \begin{macrocode} + tagunmarked .bool_gset:N = \g_@@_tagunmarked_bool, % \end{macrocode} % \end{macro} -% \begin{macro}{tabsorder (setup-key)} +% \begin{macro}{page/tabsorder (setup-key),tabsorder (deprecated)} % This sets the tabsorder on a page. The values are |row|, |column|, |structure| (default) % or |none|. Currently this is set more or less globally. More finer control can be % added if needed. % \begin{macrocode} - tabsorder .choice:, - tabsorder / row .code:n = + page/tabsorder .choice:, + page/tabsorder / row .code:n = \pdfmanagement_add:nnn { Page } {Tabs}{/R}, - tabsorder / column .code:n = + page/tabsorder / column .code:n = \pdfmanagement_add:nnn { Page } {Tabs}{/C}, - tabsorder / structure .code:n = + page/tabsorder / structure .code:n = \pdfmanagement_add:nnn { Page } {Tabs}{/S}, - tabsorder / none .code:n = + page/tabsorder / none .code:n = \pdfmanagement_remove:nn {Page} {Tabs}, - tabsorder .initial:n = structure, - uncompress .code:n = { \pdf_uncompress: }, + page/tabsorder .initial:n = structure, +% \end{macrocode} +% deprecated name +% \begin{macrocode} + tabsorder .meta:n = {page/tabsorder={#1}}, } % \end{macrocode} % \end{macro} diff --git a/macros/latex/contrib/tagpdf/tagpdf.pdf b/macros/latex/contrib/tagpdf/tagpdf.pdf Binary files differindex bbd66f6ce5..86868f1382 100644 --- a/macros/latex/contrib/tagpdf/tagpdf.pdf +++ b/macros/latex/contrib/tagpdf/tagpdf.pdf diff --git a/macros/latex/contrib/tagpdf/tagpdf.tex b/macros/latex/contrib/tagpdf/tagpdf.tex index 054d511baa..c08c8406d9 100644 --- a/macros/latex/contrib/tagpdf/tagpdf.tex +++ b/macros/latex/contrib/tagpdf/tagpdf.tex @@ -10,14 +10,14 @@ \DocumentMetadata { % comment the following line to compile an untagged documentation: - testphase=phase-III, + testphase={phase-III,title,table}, pdfversion=2.0,lang=en-UK,pdfstandard=a-4,pdfstandard=ua-2 %uncompress } \DebugBlocksOff \makeatletter -\def\UlrikeFischer@package@version{0.98v} -\def\UlrikeFischer@package@date{2024-02-04} +\def\UlrikeFischer@package@version{0.98w} +\def\UlrikeFischer@package@date{2024-02-22} \makeatother \documentclass[bibliography=totoc,a4paper]{article} @@ -36,7 +36,8 @@ \usepackage[noparboxrestore]{marginnote} \reversemarginpar - +\usepackage{booktabs} +\setlength\belowcaptionskip{10pt} \usepackage{tcolorbox} \usepackage{tikz} @@ -282,9 +283,11 @@ One must check how good the accessibility is \emph{practically}. Syntax validation and formal standard validation can be done for example with -preflight of the (non-free) Adobe Acrobat. It can also be done also with the -free \PDF{} Accessibility Checker (PAC~2021) \parencite{pac3}. There is also -the validator veraPDF \parencite{verapdf}. A rather new and quite useful tool +preflight of the (non-free) Adobe Acrobat. It can also be done +(only for PDF 1.7 and older) also with the +free \PDF{} Accessibility Checker (PAC~2024) \parencite{pac2024}. There is also +the validator veraPDF \parencite{verapdf} which can also handle PDF 2.0 files. +A quite useful tool is \enquote{Next Generation PDF} \parencite{ngpdf}, a browser application which converts a tagged PDF to html, allows to inspect its structure and also to edit the structure. For PDF~2.0 files there is also a checker based on the @@ -337,7 +340,7 @@ improvements and new features in the \LaTeX\ kernel, the latex-lab bundle and the \PDF\ management code and is now much better. Only a few structures---mostly some from currently unsupported packages--- still need manual tagging. But sadly the output of the validators don't quite reflect -the improvements. The documentation uses now \PDF~2.0 and PAC~3 can't handle +the improvements. The documentation uses now \PDF~2.0 and PAC~2024 can't handle this, it claims that the file is damaged. The Adobe validator has a bug and doesn't like the (valid) use of the \texttt{Lbl} tag for the section numbers (see figure~\ref{fig:adobe}). @@ -396,7 +399,7 @@ some text When loading \pkg{tagpdf} through the \texttt{testphase} keys, it is automatically activated. To deactivate it while still retaining all the other new code from the latex-lab testphase files, -use in the preamble |\tagpdfsetup{activate-all=false}|. You can additionally also deactivate the +use in the preamble |\tagpdfsetup{activate/all=false}|. You can additionally also deactivate the paratagging and the interword space code. To suppress the loading of the package altogether you can try @@ -461,74 +464,70 @@ This command setups the general behavior of the package. The command should be normally used only in the preamble (for a few keys it could also make sense to change them in the document). -The key-val list understands the following keys: +The key-val list understands at least the following keys. More keys are defined in some of the latex-lab module, see table~\ref{tab:setupkey} for an overview which also includes older, now deprecated names. + +\begin{table} +\caption{Overview over keys for \cs{tagpdfsetup}}\label{tab:setupkey} +\input{tagpdfsetup-keys} +\end{table} \begin{description} -\item[\PrintKeyName{activate-all}] Boolean, initially false. Activates +\item[\PrintKeyName{activate/all}] Boolean, initially false. Activates everything, that's normally the sensible thing to do. -\item [\PrintKeyName{activate}] Like |activate-all|, +\item [\PrintKeyName{activate}] Like |activate/all|, \emph{additionally} is opens at begin document a structure with |\tagstructbegin| and closes it at end document. The key accepts as value a tag name which is used as the tag of the structure. The default value is |Document|. -\item[\PrintKeyName{activate-mc}] Boolean, initially false. Activates +\item[\PrintKeyName{activate/mc}] Boolean, initially false. Activates the code related to marked content. -\item[\PrintKeyName{activate-struct}] Boolean, initially +\item[\PrintKeyName{activate/struct}] Boolean, initially false. Activates the code related to structures. Should be used only - if \PrintKeyName{activate-mc} has been used too. + if \PrintKeyName{activate/mc} has been used too. -\item[\PrintKeyName{no-struct-dest}] Starting with version 0.93 +\item[\PrintKeyName{activate/struct-dest}] Boolean, initially true. + Starting with version 0.93 \pkg{tagpdf} will create automatically structure destinations (see - section~\ref{sec:struct-dest} if \pkg{hyperref} is used, if the - engine supports it and if the pdf version is 2.0. With this key this + section~\ref{sec:struct-dest} if \pkg{hyperref} is used and if the + engine supports it. With this key this can be suppressed. -\item[\PrintKeyName{activate-tree}] Boolean, initially +\item[\PrintKeyName{activate/tree}] Boolean, initially false. Activates the code related to trees. Should be used only if the two other keys has been used too. -\item[\PrintKeyName{add-new-tag}] Allows to define new tag names, see - section \ref{sec:new-tag} for a description. - -\item[\PrintKeyName{interwordspace}] Choice key, possible values are - \PrintKeyName{true}/""\PrintKeyName{on} and - \PrintKeyName{false}/\PrintKeyName{off}. The key +\item[\PrintKeyName{activate/spaces}] Boolean. The key activates/deactivates the insertion of space glyphs, see section~\ref{sec:spacechars}. In the luamode it only works if at - least \PrintKeyName{activate-mc} has been used. + least \PrintKeyName{activate/mc} has been used. + The old name of the key |interwordspace| is still supported but deprecated. -\item[\PrintKeyName{log}] Choice key, possible values - \PrintKeyName{none}, \PrintKeyName{v}, \PrintKeyName{vv}, - \PrintKeyName{vvv}, \PrintKeyName{all}. Setups the log level. - Changing the value affects currently mostly the luamode: - \enquote{higher} values gives more messages in the log. The current - levels and messages have been setup in a quite ad-hoc manner and - will need improvement. -\item[\PrintKeyName{newattribute}] This key takes two arguments and +\item[\PrintKeyName{role/new-tag}] Allows to define new tag names, see + section \ref{sec:new-tag} for a description. + +\item[\PrintKeyName{role/new-attribute}] This key takes two arguments and declares an attribute. See \ref{sec:attributes}. + +\item[\PrintKeyName{role/map-tags}] This key allows to remap the structure +tags. Currently it supports only two values: |false| (the default) and |pdf| which +maps all tags to their standard PDF role, e.g. |itemize| will be mapped to |L|. -\item[\PrintKeyName{show-spaces}] Boolean.\sidenote{luamode} That's a - debug option, it helps in lua mode to see where space glyph will be - inserted if \PrintKeyName{interwordspace} is activated. -\item[\PrintKeyName{paratagging}] Boolean. This activate/deactivates +\item[\PrintKeyName{para/tagging}] Boolean. This activate/deactivates the automatic tagging of paragraphs, see \ref{sec:paratagging} for more background. It uses the \texttt{para/begin} and - \texttt{para/end} hooks of the newest \LaTeX{} version (2021-05-01). + \texttt{para/end} hooks. With more tagging support conditions will be added, that means the code is bound to change! Paragraphs can appear in many unexpected places and the code can easily break, so there is also an option to see where such paragraphs are: -\item[\PrintKeyName{paratagging-show}] Boolean. This - activate/deactivates small red and green numbers in the places where - the paratagging hook code is used. -\item[\PrintKeyName{paratag}] String. This key changes the second tag +\item[\PrintKeyName{para/tag}] String. This key changes the second tag used by the paratagging code. The default tag is \texttt{text}, a \LaTeX{} specific tag that is role mapped to \texttt{P}. A useful local setting here can be \texttt{NonStruct}, which creates a @@ -536,7 +535,14 @@ The key-val list understands the following keys: recommended to use the newer \cs{tagtool} command described below instead of \cs{tagpdfsetup}. -\item[\PrintKeyName{tabsorder}] Choice key, possible values are +\item[\PrintKeyName{para/maintag}] String. This key changes the first tag + used by the paratagging code. The default tag is \texttt{text-unit}, a + \LaTeX{} specific tag that is role mapped to \texttt{Part}. + For local changes it is + recommended to use the newer \cs{tagtool} command described below + instead of \cs{tagpdfsetup}. + +\item[\PrintKeyName{page/tabsorder}] Choice key, possible values are \PrintKeyName{row}, \PrintKeyName{column}, \PrintKeyName{structure}, \PrintKeyName{none}. This decides if a \verb+/Tabs+ value is written to the dictionary of the page objects. Not really needed for @@ -544,7 +550,7 @@ The key-val list understands the following keys: accessibility checks. So I added it. Currently the tabsorder is the same for all pages. Perhaps this should be changed \ldots. -\item[\PrintKeyName{tagunmarked}] Boolean,\sidenote{luamode} initially +\item[\PrintKeyName{activate/tagunmarked}] Boolean,\sidenote{luamode} initially true. When this boolean is true, the lua code will try to mark everything that has not been marked yet as an artifact. The benefit is that one doesn't have to mark up every deco rule oneself. The @@ -553,10 +559,36 @@ The key-val list understands the following keys: annotations etc. See also section~\ref{sec:lazy} for a discussion about automatic tagging. -\item[\PrintKeyName{uncompress}] Sets both the \PDF{} compresslevel +\item[\PrintKeyName{debug/uncompress}] Sets both the \PDF{} compresslevel and the \PDF{} objcompresslevel to 0 and so allows to inspect the - \PDF{}. + \PDF{}. No really useful anymore as this can also + be set in \cs{DocumentMetadata}. +\item[\PrintKeyName{debug}] This keys knows a number of sub-keys to + set various debug options. + \begin{description} + \item[\PrintKeyName{debug/show}] This takes a comma list of keywords: + + \texttt{spaces}/\texttt{spacesOff}: \sidenote{luamode} + That helps in lua mode to see where space glyph will be + inserted if \PrintKeyName{activate/spaces} is activated. + This can also be activated with the now deprecated key |show-spaces| + + \texttt{para}/\texttt{paraOff}: This (locally) + activates/deactivates small red and green numbers in the places where + the paratagging hook code is used. + + + \item[\PrintKeyName{debug/log}] Choice key, possible values + \PrintKeyName{none}, \PrintKeyName{v}, \PrintKeyName{vv}, + \PrintKeyName{vvv}, \PrintKeyName{all}. Setups the log level. + Changing the value affects currently mostly the luamode: + \enquote{higher} values gives more messages in the log. The current + levels and messages have been setup in a quite ad-hoc manner and + will need improvement. + + + \end{description} \end{description} @@ -576,18 +608,18 @@ should be used as the implementation will change to improve the speed. Currently the following arguments are supported \begin{description} -\item[\PrintKeyName{para}] Boolean. It will replace the +\item[\PrintKeyName{para/tagging}] Boolean. It will replace the \cs{tagpdfparaOn} and \cs{tagpdfparaOff} command. -\item[\PrintKeyName{unittag}] String. It allows to change the outer +\item[\PrintKeyName{para/maintag}] String. It allows to change the outer tag used in the following automatically tagged paragraphs. The setting is local. -\item[\PrintKeyName{paratag}] String. It allows to change the inner +\item[\PrintKeyName{para/tag}] String. It allows to change the inner tag used in the following automatically tagged paragraphs. The setting is local. -\item[\PrintKeyName{para-flattened}] Boolean. If set it will suppress +\item[\PrintKeyName{para/flattened}] Boolean. If set it will suppress the outer structure in the automatic paratagging. This should be applied to the start and end hook in the same way! The setting is local. @@ -992,7 +1024,7 @@ The key-val list understands the following keys: The\sidenote{lua mode only} lua mode will mark up everything unmarked as \texttt{artifact=notype}. You can suppress this behavior by setting the - tagpdfsetup key \texttt{tagunmarked} to false. See section + tagpdfsetup key \texttt{activate/tagunmarked} to false. See section \ref{ssec:setup}. \item[\PrintKeyName{stash}] Normally marked content will be stored in the @@ -1382,9 +1414,30 @@ commands are used: \subsubsection{Math} +Math is still a problem but some progress has been made. +To tag math you have to surround it with a \texttt{Formula} structure. But the content of such a structure is handled by readers as a black box so additional data is needed for accessibility. + +There are a number of theoretical options here: +\begin{enumerate} +\item One can add an alternative text (\texttt{/Alt}) or an \texttt{/ActualText} +to the structure element either some text manually provided by the author or (with +the math module in the latex-lab bundle) the \LaTeX-source). +\item One can add an alternative text (\texttt{/Alt} or \texttt{/ActualText}) +to the MC-chunks. +\item One can build inside the \texttt{Formula} structure element a tree with MathML structure elements --- with PDF 2.0 this not require to declare new tags as the MathML name space is built-in. +\item One can in PDF 2.0 attach a MathML file and/or the \LaTeX-source as associated file to the \texttt{Formula} structure (or to one or more MC-chunks). +\end{enumerate} +The question is how these work in reality. + +Option 1 and 2 give not too bad results +with a screen reader, but can +require manual work and if you are unlucky the reader drops +important part of the math (like punctuation symbols). +Exploring the equation is not possible. -Math is a problem. I have seen an example where \emph{every single +Option 3 creates many structure elements. +E.g. I have seen an example where \emph{every single symbol} has been marked up with tags from MathML along with an \texttt{/ActualText} entry and an entry with alternate text which describes how to read the symbol. The \PDF{} then looked like this @@ -1403,19 +1456,20 @@ If this is really the way to go one would need some script to add the mark-up as doing it manually is too much work and would make the source unreadable -- at least with pdflatex and the generic mode. In lua mode is it possible to hook into the \texttt{mlist\_to\_hlist} -callback and add marker automatically. Some first implementation is -done by Marcel Krüger in the luamml project. - -But I'm not sure that this is the best way to do math. It looks rather +callback and add marker automatically. Some first implementation in this direction +has been done by Marcel Krüger in the luamml project. But up-to-now it was not possible +to test the usability of this approach: With the exception of the html derivation +with ngpdf no PDF-viewer/screen reader combination +seems to make use of such structures. +I'm not sure anyway that this is the best way to do math. It looks rather odd that a document should have to tell a screen reader in such detail -how to read an equation. It would be much more efficient, sensible and -flexible if a complete representation of the equation in mathML could -be stored in the \PDF{} and the task how to read this aloud delegated -to the screen reader. As \PDF{}~2.0 introduced associated files it is -probable that this will be the way to go but more investigations are -needed here. +how to read an equation. -See also section~\ref{sec:alt} for some more remarks and tests. +The last option 4 has been implemented in the math module in the \texttt{latex-lab} +bundle. Here happily a proof of +concept was possible: With development versions of foxit and the NVDA reader +it was possible to access an attached MathML and get speech output from it \cite{todasoifferdeims2024,mittelbachfischerdeims2024}. See also \cite{mathexamples} for some +examples and section~\ref{sec:alt} for some more remarks and tests. \subsubsection{Split paragraphs}\label{sec:splitpara} @@ -1448,7 +1502,7 @@ Pellentesque scelerisque sit amet, lacus.\tagmcend \end{taglstlisting} -Starting with version 0.92 there is code which tries to resolve this +Starting with version 0.92 there is code which resolves this problem. Basically it works like this: every mc-command issues a mark command (actually two slightly different). When the page is built in the output routine this mark commands are inspected and from them @@ -1461,14 +1515,13 @@ TUG~2021 \enquote{Taming the beast — Advances in paragraph tagging Please note \begin{itemize} -\item The code requires a \pkg{pdfmanagement-testphase} version v0.95i or newer. - \item Typically you will need more compilations than previously, don't rely on the rerun messages, but if something looks wrong rerun. \item The code relies on that related |\tagmcbegin| and |\tagmcend| are in the same boxing level. If one is in a box (which hides the - marks) and the other in the main galley, things will go wrong. + marks) and the other in the main galley, things will go wrong (\texttt{longtable} + is for example problematic). \end{itemize} \subsubsection{Automatic tagging of paragraphs}\label{sec:paratagging} @@ -1570,8 +1623,8 @@ of your own you must declare them. E.g. this declares two new types \begin{taglstlisting} \tagpdfsetup{ - add-new-tag = TAB/P, - add-new-tag = FIG/P, + role/new-tag = TAB/P, + role/new-tag = FIG/P, } \end{taglstlisting} @@ -1616,8 +1669,8 @@ nesting defines the level of a sectioning heading. The flat version is more \LaTeX-like and it is rather straightforward to patch \verb+\chapter+, \verb+\section+ and so on to insert the appropriates \texttt{H\ldots} start and end markers. The xml-like tree is more difficult -to automate. If such a tree is wanted I would recommend to use -- like the -context format -- explicit commands to start and end a sectioning unit. +to automate. It has been implemented in the sec module in latex-lab, but can break +if sectioning commands are hidden inside boxes. @@ -1861,7 +1914,7 @@ classes to a structure. To use such attributes you must at first declare it in \verb+\tagpdfsetup+ -with the key \texttt{newattribute}. This key takes two argument, a name and +with the key \texttt{role/new-attribute}. This key takes two argument, a name and the content of the attribute. The name should be a sensible key name, it is converted to a pdf name with \verb+\pdf_name_from_unicode_e:n+, so slashes and spaces are allow. The content should be a dictionary without the @@ -1871,9 +1924,9 @@ bracket. \begin{taglstlisting} \tagpdfsetup { - newattribute = + role/new-attribute = {TH-col}{/O /Table /Scope /Column}, - newattribute = + role/new-attribute = {TH-row}{/O /Table /Scope /Row}, } \end{taglstlisting} @@ -2112,10 +2165,10 @@ types or are \enquote{role mapped} to such a standard type. Such a role mapping is a simple key-value in the RoleMap dictionary. So instead of |H1| the type |section| could be used. The role mapping -can then be declared with the |add-new-tag| key: +can then be declared with the |role/new-tag| key: \begin{taglstlisting} - \tagpdfsetup{add-new-tag = section/H1} + \tagpdfsetup{role/new-tag = section/H1} \end{taglstlisting} In PDF 2.0 the situation is a bit more complicated. At first PDF~2.0 @@ -2185,7 +2238,7 @@ and the following are new:\\ \end{enumerate} To allow to this more complicated setup the syntax of the -\texttt{add-new-tag} key has been extended. It now takes as argument +\texttt{role/new-tag} key has been extended. It now takes as argument a key-value list with the following keys. A normal document shouldn't need the extended syntax, the simple syntax |section/H1| should in most cases do the right thing. @@ -2220,8 +2273,8 @@ most cases do the right thing. this preserves the old syntax. So this two calls are equivalent: \begin{taglstlisting} - \tagpdfsetup{add-new-tag = section/H1} - \tagpdfsetup{add-new-tag = {tag=section,role=H1}} + \tagpdfsetup{role/new-tag = section/H1} + \tagpdfsetup{role/new-tag = {tag=section,role=H1}} \end{taglstlisting} \end{description} @@ -2253,7 +2306,8 @@ dictionary as a fallback for such processors. In PDF 2.0 mathml tags have their own name space and can be freely used. In PDF 1.7. they can only be used if they are rolemapped to a standard type. By default they are not added to the |/RoleMap| dictionary, but this can be -forced with |\tagpdfsetup{mathml-tags}|. Please note that this adds mathml at the end of the document and overwrites tag with the same name without warning. +forced with |\tagpdfsetup{role/mathml-tags}|. Please note that this adds mathml +at the end of the document and overwrites tags with the same name without warning. \section{Checking parent-child rules}\label{sec:parent-child} @@ -2331,7 +2385,7 @@ or reflowing the text to decide if a space is meant as a word boundary or e.g. as a kerning. Accessible document should use real space glyphs (U+0032) from a font in such places. -With the key \PrintKeyName{interwordspace} you can activate such space +With the key \PrintKeyName{activate/spaces} you can activate such space glyphs. With pdftex this will simply call the primitive @@ -2344,16 +2398,16 @@ function it can't be fine tuned or adapted. You can only turn it on and off and insert manually such a space glyph with \verb+\pdffakespace+. -With luatex (in luamode) |interwordspace| is implemented with a +With luatex (in luamode) |activate/spaces| is implemented with a lua-function which is inserted in two callbacks and marks up the places where it seems sensible to inter a space glyph. Later in the process the space glyphs are injected -- the code will take the glyph from the current font if this has a space glyph or switch to the default latin modern font. The current code works reasonable well in -normal text. |interwordspace| can be used without actually tagging a +normal text. |activate/spaces| can be used without actually tagging a document. -The key \PrintKeyName{show-spaces} will show lines at the places where +The key-value \PrintKeyName{debug/show=spaces} will show lines at the places where in lua mode spaces are inserted and so can help you to find problematic places. For listings -- which have a quite specific handling of spaces -- you can find a suggestion in the example @@ -2532,7 +2586,7 @@ To tag boxes that can be both (without tagging commands or with balanced tagging commands) the following strategy can be used: \begin{itemize} -\item when storing the box put around it a structure as need by the +\item when storing the box put around it a structure as needed by the tagged variant: \begin{verbatim} \tag_mc_end_push: % interrupt an open mc @@ -2727,7 +2781,7 @@ KOMA. On the other side it means that quite often one can omit the commands starting with |\uftag| will stay valid for some time but then be deprecated. -\item \textbf{Breaking change!} The argument of \texttt{newattribute} +\item \textbf{Breaking change!} The argument of \texttt{role/new-attribute} (old key name: \texttt{newattribute}) option should no longer add the dictionary bracket \verb+<<..>>+, they are added by the code. @@ -2823,10 +2877,10 @@ command. places, it also ate spaces in places where this wasn't expected. From now on both commands behave exactly like the expl3 versions. \item The lua-code to add real space glyphs has been separated from the - tagging code. This means that |interwordspace| now works also if + tagging code. This means that |activate/spaces| now works also if tagging is not active. \item The key |activate| has been added, it open the first structure, see - below. + above. \end{itemize} \subsection{Changes in version 0.92} @@ -2969,7 +3023,7 @@ cases building the structure should now need only two or three compilations. The new code requires a current pdfmanagement-testphase and is then used automatically if the new engines are detected. - +\subsection{} \printbibliography[heading=bibintoc] diff --git a/macros/latex/contrib/tagpdf/tagpdfdocu-patches.sty b/macros/latex/contrib/tagpdf/tagpdfdocu-patches.sty index 1c3bb95bf6..c294994dcb 100644 --- a/macros/latex/contrib/tagpdf/tagpdfdocu-patches.sty +++ b/macros/latex/contrib/tagpdf/tagpdfdocu-patches.sty @@ -1,5 +1,5 @@ %\RequirePackage[enable-debug]{expl3}[2018/06/14] -\ProvidesExplPackage {tagpdfdocu-patches} {2024-02-04} {0.98v} +\ProvidesExplPackage {tagpdfdocu-patches} {2024-02-22} {0.98w} {patches/commands for the tagpdf documentation} \RequirePackage{etoolbox,xpatch} diff --git a/macros/latex/contrib/tagpdf/tagpdfsetup-keys.tex b/macros/latex/contrib/tagpdf/tagpdfsetup-keys.tex new file mode 100644 index 0000000000..22d4c9a8d5 --- /dev/null +++ b/macros/latex/contrib/tagpdf/tagpdfsetup-keys.tex @@ -0,0 +1,70 @@ +%% Overview over tagpdfsetup keys +%% The keys are split in a number of key pathes. +\tagpdfsetup{table/header-rows=1} +\begin{tabular}{lllll} +\toprule +new key name & old key name & value &type & defined in \\\midrule + ??? & root-AF & string &code &tagpdf-struct\\[4pt]\midrule +%% activate key path +%% activate` is used for keys that enable +%% general, typically document wide tagging options +%% related to the PDF processing. + +activate & activate & boolean &meta & tagpdf \\ +activate/all & activate-all & boolean &meta & tagpdf\\ +activate/mc & activate-mc & boolean &bool & tagpdf\\ +activate/spaces & interwordspace & boolean &code & tagpdf-space\\ +activate/struct & activate-struct & boolean &bool & tagpdf\\ +activate/struct-dest & no-struct-dest&boolean &bool & tagpdf\\ +activate/tagunmarked& tagunmarked & boolean &bool & tagpdf\\ +activate/tree & activate-tree & boolean &bool & tagpdf\\[4pt]\midrule +% temporary until tagging-sockets are in the kernel: +% activate/socket & --- & boolean & bool & tagpdf\\ +%% role key path. For everything related to tag and attribute names +%% adds mathml to the global rolemap, should perhaps be default +role/mathml-tags & mathml-tags & boolean &bool & tagpdf-roles\\ +role/new-tag & add-new-tag & string &code & tagpdf-roles\\ +role/new-attribute&newattribute & string &code & tagpdf-struct\\ +% values: latex, pdf, default is latex, with pdf only PDF-tags are used +role/map-tags & --- & choice & code & tagpdf-roles\\[4pt]\midrule +%% debug key path +%% for logging and showing +debug/show &various &choice &code & various \\ +debug/show=para & paratagging-show& --- &code & tagpdf-user\\ +debug/show=paraOff& & --- &code & tagpdf-user\\ +debug/show=spaces & show-spaces & --- &code & tagpdf-spaces\\ +debug/show=spacesOff& --- & --- &code & tagpdf-spaces\\ +debug/log & log & choice &code & tagpdf \\ +debug/uncompress & uncompress & --- &code & tagpdf\\[4pt]\midrule +%% viewer key path. +%% viewer keys influence some display options in a pdf viewer. +%% There is an overlap with similar "non-tagging" options. +% TODO viewer/display-title +%% show mathml-files in attachment pane (old mathml-panel) +viewer/pane/mathml & --- & boolean &bool &latex-lab-math (dev)\\ +viewer/pane/mathsource& --- &boolean &bool &latex-lab-math (dev)\\[4pt]\midrule +%%% Document element keys +%% page key path +page/tabsorder &tabsorder & choice & code & tagpdf\\ +page/exclude-header-footer & exclude-header-footer &choice & code &tagpdf-user\\[4pt]\midrule +%% para key path +para/tagging ¶tagging &boolean &bool &tagpdf-user\\ +para/tag ¶tag &string &code &tagpdf-user\\ +para/maintag &--- &string &code &tagpdf-user\\ +para/flattened &--- &boolean &bool &tagpdf-user\\[4pt]\midrule +%% math key path +% use the /Alt key, currently clashes with mathml-AF in foxit, +% so false if mathml handling is activated +math/alt/use &--- &boolean &bool &latex-lab-math\\ +math/mathml/write-dummy & --- &--- &code &latex-lab-math\\ +% mathml source files: +math/mathml/sources &--- & clist &clist &latex-lab-math\\ +math/mathml/AF &--- &boolean &bool &latex-lab-math\\ +math/tex/AF & --- &boolean &bool &latex-lab-math\\[4pt]\midrule +% TODO math/alt/type = source|manual| (later) +%% table key path +% true/false/layout +table/tagging & table-tagging &choice &code &latex-lab-table\\ +table/header-rows & table-header-rows& clist &clist &latex-lab-table\\ +\bottomrule +\end{tabular} diff --git a/macros/luatex/generic/luaxml/README b/macros/luatex/generic/luaxml/README index 38ba699686..5df074c453 100644 --- a/macros/luatex/generic/luaxml/README +++ b/macros/luatex/generic/luaxml/README @@ -15,7 +15,11 @@ then clone this repository and run make install Please note that you will need [LDoc](http://stevedonovan.github.io/ldoc/manual/doc.md.html#Processing_Single_Modules) and -[dkjson](http://dkolf.de/src/dkjson-lua.fsl/home) Lua modules installed on your system. +[dkjson](http://dkolf.de/src/dkjson-lua.fsl/home) Lua modules installed on your system. You can install them using: + + $ luarocks install --local ldoc + $ luarocks install --local dkjso + License: ======== @@ -28,10 +32,11 @@ Author ------ Michal Hoftich Email: michal.h21@gmail.com -Version: v0.1q, 2021-10-06 +Version: v0.1r, 2024-02-23 Original authors: Paul Chakravarti and Manoel Campos (http://manoelcampos.com) If you are interested in the process of development you may observe https://github.com/michal-h21/LuaXML + diff --git a/macros/luatex/generic/luaxml/luaxml-cssquery.lua b/macros/luatex/generic/luaxml/luaxml-cssquery.lua index 14d1b66fdb..ebb29abb15 100644 --- a/macros/luatex/generic/luaxml/luaxml-cssquery.lua +++ b/macros/luatex/generic/luaxml/luaxml-cssquery.lua @@ -1,7 +1,12 @@ --- CSS query module for LuaXML -- @module luaxml-cssquery -- @author Michal Hoftich <michal.h21@gmail.com -local parse_query = require("luaxml-parse-query") +local parse_query +if kpse then + parse_query = require("luaxml-parse-query") +else + parse_query = require("luaxml.parse-query") +end -- the string.explode function is provided by LuaTeX -- this is alternative for stock Lua diff --git a/macros/luatex/generic/luaxml/luaxml-domobject.lua b/macros/luatex/generic/luaxml/luaxml-domobject.lua index a5c0d29fee..73689add5a 100644 --- a/macros/luatex/generic/luaxml/luaxml-domobject.lua +++ b/macros/luatex/generic/luaxml/luaxml-domobject.lua @@ -2,13 +2,26 @@ -- @module luaxml-domobject -- @author Michal Hoftich <michal.h21@gmail.com local dom = {} -local xml = require("luaxml-mod-xml") -local handler = require("luaxml-mod-handler") -local css_query = require("luaxml-cssquery") + +local xml +local handler +local css_query +if kpse then + xml = require("luaxml-mod-xml") + handler = require("luaxml-mod-handler") + css_query = require("luaxml-cssquery") +else + xml = require("luaxml.mod-xml") + handler = require("luaxml.mod-handler") + css_query = require("luaxml.cssquery") +end local void = {area = true, base = true, br = true, col = true, hr = true, img = true, input = true, link = true, meta = true, param = true} +-- support also upper case names +for k,v in pairs(void) do void[string.upper(k)] = true end + local escapes = { [">"] = ">", ["<"] = "<", @@ -266,6 +279,8 @@ local parse = function( for _, el in ipairs(current:get_children()) do if el:is_text() then text[#text+1] = el._text or "" + elseif el._type == "CDATA" then + text[#text+1] = el._text or "" elseif el:is_element() then text[#text+1] = el:get_text() end @@ -339,11 +354,12 @@ local parse = function( return el._parent end - --- Execute function on the current element and all it's children elements. + --- Execute function on the current element and all it's children nodes. + -- The differenct to DOM_Object:traverse_elements() is that it executes the function + -- also on text nodes and all other kinds of XML nodes. -- The traversing of child elements of a given node can be disabled when the executed -- function returns false. - -- @return nothing - function DOM_Object:traverse_elements( + function DOM_Object:traverse( fn, --- function which will be executed on the current element and all it's children current --- [optional] element to be selected ) @@ -353,17 +369,68 @@ local parse = function( current = self:root_node() end local status = true - if self:is_element(current) or self:get_node_type(current) == "ROOT"then - local status = fn(current) + local status = fn(current) + if current:is_element() or current:get_node_type() == "ROOT" then -- don't traverse child nodes when the user function return false if status ~= false then - for _, child in ipairs(self:get_children(current)) do - self:traverse_elements(fn, child) + for _, child in ipairs(current:get_children()) do + self:traverse(fn, child) end end end end + --- Execute function on the current element and all it's children elements. + --- The traversing of child elements of a given node can be disabled when the executed + -- function returns false. + -- @return nothing + function DOM_Object:traverse_elements( + fn, --- function which will be executed on the current element and all it's children + current --- [optional] element to be selected + ) + local current = current or self -- + current:traverse(function(node) + if node:is_element() or node:get_node_type() == "ROOT" then + fn(node) + end + end) + end + + --- Get table with the inner text of an element, every text node is a separate table item. + --- @return table + function DOM_Object:strings( + current --- [optional] element to be selected + ) + local strings = {} + local current = current or self + current:traverse(function(node) + if node:get_node_type() == "TEXT" then + table.insert(strings, node._text or "") + end + end) + return strings + end + + --- Get table with the inner text of an element -- leading and trailing spaces are removed and elements that contain only white space are ignored. + --- @return table + function DOM_Object:stripped_strings( + current --- [optional] element to be selected + ) + local current = current or self + local strings = current:strings() + local cleaned = {} + for k,v in ipairs(strings) do + v = v:gsub("^%s*", ""):gsub("%s*$", "") + if v ~= "" then + table.insert(cleaned, v) + end + end + return cleaned + end + + + + --- Execute function on list of elements returned by DOM_Object:get_path() function DOM_Object:traverse_node_list( nodelist --- table with nodes selected by DOM_Object:get_path() diff --git a/macros/luatex/generic/luaxml/luaxml-entities.lua b/macros/luatex/generic/luaxml/luaxml-entities.lua index 3296f5ff03..af7b7e7f5d 100644 --- a/macros/luatex/generic/luaxml/luaxml-entities.lua +++ b/macros/luatex/generic/luaxml/luaxml-entities.lua @@ -1,6 +1,11 @@ local M = {} local char = unicode and unicode.utf8.char or utf8.char -local named_entities = require "luaxml-namedentities" +local named_entities +if kpse then + named_entities = require "luaxml-namedentities" +else + named_entities = require "luaxml.namedentities" +end local hexchartable = {} local decchartable = {} diff --git a/macros/luatex/generic/luaxml/luaxml-mod-handler.lua b/macros/luatex/generic/luaxml/luaxml-mod-handler.lua index bc34e70c37..8a46f90a05 100644 --- a/macros/luatex/generic/luaxml/luaxml-mod-handler.lua +++ b/macros/luatex/generic/luaxml/luaxml-mod-handler.lua @@ -112,8 +112,16 @@ --@returns Returns a string representation of table local M = {} -local stack = require("luaxml-stack") -local entities = require("luaxml-entities") + +local stack +local entities +if kpse then + stack = require("luaxml-stack") + entities = require("luaxml-entities") +else + stack = require("luaxml.stack") + entities = require("luaxml.entities") +end local function showTable(t) local sep = '' diff --git a/macros/luatex/generic/luaxml/luaxml-mod-html.lua b/macros/luatex/generic/luaxml/luaxml-mod-html.lua new file mode 100644 index 0000000000..69e32b16e2 --- /dev/null +++ b/macros/luatex/generic/luaxml/luaxml-mod-html.lua @@ -0,0 +1,2047 @@ +-- Copyright Michal Hoftich, 2022 +-- HTML parser inspired by https://browser.engineering/html.html +-- but then redone using https://html.spec.whatwg.org/multipage/parsing.html +-- +-- There main purpose of this module is to create an useful DOM for later processing +-- using LuaXML functions. Either for cleanup, or for translation to output formats, +-- for example LaTeX. +-- +-- It should be possible to serialize DOM back to the original HTML code. +-- +-- We attempt to do some basic fixes, like to close paragraphs or list items that +-- aren't closed correctly in the original code. We don't fix tables or +-- formatting elements (see https://html.spec.whatwg.org/multipage/parsing.html#the-list-of-active-formatting-elements) +-- as these features don't seem necessary for the purpose of this module. We may change +-- this policy in the future, if it turns out that they are necessary. +-- +-- +local M = {} + +-- use local copies of utf8 functions +local ucodepoint = utf8.codepoint +local utfchar = utf8.char +local function uchar(codepoint) + if codepoint and codepoint > -1 then + return utfchar(codepoint) + end + return "" +end + +-- declare namespaces +local xmlns = { + HTML = "http://www.w3.org/1999/xhtml", + MathML = "http://www.w3.org/1998/Math/MathML", + SVG = "http://www.w3.org/2000/svg", + XLink = "http://www.w3.org/1999/xlink", + XML = "http://www.w3.org/XML/1998/namespace", + XMLNS = "http://www.w3.org/2000/xmlns/", +} + +-- we must make search tree for named entities, as their support +-- is quite messy +local named_entities +if kpse then + named_entities = require "luaxml-namedentities" +else + named_entities = require "luaxml.namedentities" +end + +local entity_tree = {children = {}} + +local function update_tree(tree, char) + local children = tree.children or {} + local current = children[char] or {} + children[char] = current + tree.children = children + return current +end + +-- loop over named entities and update tree +for entity, char in pairs(named_entities) do + local tree = entity_tree + for char in entity:gmatch(".") do + tree = update_tree(tree,char) + end + tree.entity = entity + tree.char = char +end + +local function search_entity_tree(tbl) + -- get named entity for the list of characters + local tree = entity_tree + for _,char in ipairs(tbl) do + if tree.children then + tree = tree.children[char] + if not tree then return nil end + else + return nil + end + end + -- print("tree", tree.char) + return tree +end + + +-- declare basic node types + +local Root = { + _type = "root", + xmlns = xmlns.HTML +} + +function Root:init() + local o = {} + setmetatable(o, self) + self.__index = self + self.__tostring = function (x) return "_ROOT" end + o.children = {} + return o +end + +function Root:add_child(node) + table.insert(self.children, node) +end + +local Doctype = { + _type = "doctype" +} +function Doctype:init(name, parent) + local o = {} + setmetatable(o, self) + self.__index = self + self.__tostring = function (x) + if x.data then + return "<!DOCTYPE " .. x.name .. " " .. x.data .. ">" + else + return "<!DOCTYPE " .. x.name .. ">" + end + end + self.add_child = Root.add_child + o.parent = parent + o.name = name + o.children = {} + return o +end + +function Doctype:add_data(data) + self.data = data +end + + +local Text = { + _type = "text" +} + +function Text:init(text, parent) + local o = {} + setmetatable(o, self) + self.__index = self + o.text = text + self.__tostring = function (x) return "'" .. x.text .. "'" end + self.add_child = Root.add_child + o.parent = parent + o.children = {} + return o +end + +local Comment = { + _type = "comment" +} + +function Comment:init(text, parent) + local o = {} + setmetatable(o, self) + self.__index = self + o.text = text + self.__tostring = function (x) return "<!--" .. x.text .. "-->" end + self.add_child = Root.add_child + o.parent = parent + o.children = {} + return o +end + + + +local Element = { + _type = "element" +} + +function Element:init(tag, parent) + local o = {} + setmetatable(o, self) + self.__index = self + -- tag can be table with unicode characters + if type(tag) == "table" then + o.tag = table.concat(tag) + else + o.tag = tag + end + self.__tostring = function(x) + local attr = {} + for _, el in ipairs(x.attr) do + -- handle attributes + local value + if el.value:match('"') then + value = "'" .. el.value .. "'" + else + value = '"' .. el.value .. '"' + end + attr[#attr+1] = el.name .. "=" .. value + end + local closing = ">" + if x.self_closing then + closing = " />" + end + if #attr > 0 then + return "<" .. x.tag .. " " .. table.concat(attr, " ") .. closing + else + return "<" .. x.tag .. closing + end + end + self.add_child = Root.add_child + o.children = {} + o.attr = {} + o.parent = parent + -- default xmlns + o.xmlns = xmlns.HTML + return o +end + +-- state machine functions + +-- each function takes HtmlParser as an argument +local HtmlStates = {} + +-- declare codepoints for more efficient processing +local less_than = ucodepoint("<") +local greater_than = ucodepoint(">") +local amperesand = ucodepoint("&") +local exclam = ucodepoint("!") +local question = ucodepoint("?") +local solidus = ucodepoint("/") +local equals = ucodepoint("=") +local quoting = ucodepoint('"') +local apostrophe = ucodepoint("'") +local semicolon = ucodepoint(";") +local hyphen = ucodepoint("-") +local dash = ucodepoint("-") +local numbersign = ucodepoint("#") +local smallx = ucodepoint("x") +local bigx = ucodepoint("X") +local right_square = ucodepoint("]") +local EOF = -1 -- special character, meaning end of stream +local null = 0 + +local function is_upper_alpha(codepoint) + if (64 < codepoint and codepoint < 91) then + return true + end +end +local function is_lower_alpha(codepoint) + if (96 < codepoint and codepoint < 123) then + return true + end +end + +local function is_alpha(codepoint) + -- detect if codepoint is alphanumeric + if is_upper_alpha(codepoint) or + is_lower_alpha(codepoint) then + return true + end + return false +end + + +local function is_numeric(codepoint) + if 47 < codepoint and codepoint < 58 then + return true + end +end + +local function is_upper_hex(codepoint) + if 64 < codepoint and codepoint < 71 then + return true + end +end + +local function is_lower_hex(codepoint) + if 96 < codepoint and codepoint < 103 then + return true + end +end + +local function is_hexadecimal(codepoint) + if is_numeric(codepoint) or + is_lower_hex(codepoint) or + is_upper_hex(codepoint) + then + return true + end +end + + +local function is_alphanumeric(codepoint) + return is_alpha(codepoint) or is_numeric(codepoint) +end + +local function is_space(codepoint) + -- detect space characters + if codepoint==0x0009 or codepoint==0x000A or codepoint==0x000C or codepoint==0x0020 then + return true + end + return false +end + +local function is_surrogate(codepoint) + return 0xD800 <= codepoint and codepoint <= 0xDFFF +end + + +character_entity_replace_table = { +[0x80] = 0x20AC, +[0x82] = 0x201A, +[0x83] = 0x0192, +[0x84] = 0x201E, +[0x85] = 0x2026, +[0x86] = 0x2020, +[0x87] = 0x2021, +[0x88] = 0x02C6, +[0x89] = 0x2030, +[0x8A] = 0x0160, +[0x8B] = 0x2039, +[0x8C] = 0x0152, +[0x8E] = 0x017D, +[0x91] = 0x2018, +[0x92] = 0x2019, +[0x93] = 0x201C, +[0x94] = 0x201D, +[0x95] = 0x2022, +[0x96] = 0x2013, +[0x97] = 0x2014, +[0x98] = 0x02DC, +[0x99] = 0x2122, +[0x9A] = 0x0161, +[0x9B] = 0x203A, +[0x9C] = 0x0153, +[0x9E] = 0x017E, +[0x9F] = 0x0178 +} + +local function fix_null(codepoint) + if codepoint == null then + return 0xFFFD + else + return codepoint + end +end + +HtmlStates.data = function(parser) + -- this is the default state + local codepoint = parser.codepoint + -- print("codepoint", parser.codepoint) + if codepoint == less_than then + -- start of tag + return "tag_open" + elseif codepoint == amperesand then + -- we must save the current state + -- what we will return to after entity + parser.return_state = "data" + return "character_reference" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + end + return "data" +end + +HtmlStates.tag_open = function(parser) + -- parse tag contents + local codepoint = parser.codepoint + if codepoint == exclam then + return "markup_declaration_open" + elseif codepoint == solidus then + return "end_tag_open" + elseif codepoint == question then + parser:start_token("comment",{data={}}) + return "bogus_comment" + elseif is_alpha(codepoint) then + local data = { + name = {}, + attr = {}, + current_attr_name = {}, + current_attr_value = {}, + self_closing = false + } + parser:start_token("start_tag", data) + return parser:tokenize("tag_name") + elseif codepoint == EOF then + parser:emit_character(">") + parser:emit_eof() + else + -- invalid tag + -- emit "<" and reconsume current character as data + parser:emit_character("<") + return parser:tokenize("data") + end +end + +HtmlStates.character_reference = function(parser) + -- parse HTML entities + -- initialize temp buffer + parser.temp_buffer = {"&"} + local codepoint = parser.codepoint + if is_alphanumeric(codepoint) then + return parser:tokenize("named_character_reference") + elseif codepoint == numbersign then + table.insert(parser.temp_buffer, uchar(codepoint)) + return "numeric_character_reference" + else + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + end + +end + +HtmlStates.named_character_reference = function(parser) + -- named entity parsing is pretty complicated + -- https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state + local codepoint = parser.codepoint + -- test if the current entity name is included in the named entity list + local search_table = {} + -- first char in temp buffer is &, which we don't want to lookup in the search tree + for i=2, #parser.temp_buffer do search_table[#search_table+1] = parser.temp_buffer[i] end + if codepoint == semicolon then + -- close named entity + local entity = search_entity_tree(search_table) + if entity and entity.char then + parser:add_entity(entity.char) + else + -- if the current name doesn't correspond to any named entity, flush everything into text + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + end + return parser.return_state + else + local char = uchar(codepoint) + -- try if the current entity name is in the named entity search tree + table.insert(search_table, char) + local entity = search_entity_tree(search_table) + if entity then + -- keep parsing name entity while we match a name + table.insert(parser.temp_buffer, char) + return "named_character_reference" + else + -- here this will be more complicated + if #search_table > 1 then + local token = parser.current_token + if token.type == "start_tag" and (codepoint == equals or is_alphanumeric(codepoint)) then + -- in attribute value, flush characters and retokenize + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + else + -- try to get entity for characters preceding the current character + table.remove(search_table) + local newentity = search_entity_tree(search_table) + if newentity and newentity.char then + parser:add_entity(newentity.char) + else + -- we need to find if parts of the current substring match a named entity + -- for example ¬it; -> ¬it; but ∉ -> ∉ + local rest = {} + -- loop over the table with characters, and try to find if it matches entity + for i = #search_table, 1,-1 do + local removed_char = table.remove(search_table) + -- + table.insert(rest, 1, removed_char) + newentity = search_entity_tree(search_table) + if newentity and newentity.char then + parser:add_entity(newentity.char) + parser.temp_buffer = rest + break + end + end + -- replace temporary buffer witch characters that followed the matched entity + parser:flush_temp_buffer() + end + return parser:tokenize(parser.return_state) + end + else + -- search table contains only the current character + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + end + end + end + +end + +HtmlStates.numeric_character_reference = function(parser) + -- this variable will hold the number + local codepoint = parser.codepoint + parser.character_reference_code = 0 + if codepoint == smallx or codepoint == bigx then + -- hexadecimal entity + table.insert(parser.temp_buffer, uchar(codepoint)) + return "hexadecimal_character_reference_start" + else + -- try decimal entity + return parser:tokenize("decimal_character_reference_start") + end + +end + +HtmlStates.hexadecimal_character_reference_start = function(parser) + local codepoint = parser.codepoint + if is_hexadecimal(codepoint) then + return parser:tokenize("hexadecimal_character_reference") + else + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + end +end + +HtmlStates.decimal_character_reference_start = function(parser) + local codepoint = parser.codepoint + if is_numeric(codepoint) then + return parser:tokenize("decimal_character_reference") + else + parser:flush_temp_buffer() + return parser:tokenize(parser.return_state) + end +end + + +HtmlStates.decimal_character_reference = function(parser) + local codepoint = parser.codepoint + -- helper functions for easier working with the character_reference_code + local function multiply(number) + parser.character_reference_code = parser.character_reference_code * number + end + local function add(number) + parser.character_reference_code = parser.character_reference_code + number + end + if is_numeric(codepoint) then + multiply(10) + add(codepoint - 0x30) + elseif codepoint == semicolon then + return "numeric_reference_end_state" + else + -- this adds current entity + parser:tokenize("numeric_reference_end_state") + -- now tokenize the current character + return parser:tokenize(parser.return_state) + end + return "decimal_character_reference" +end + +HtmlStates.hexadecimal_character_reference = function(parser) + local codepoint = parser.codepoint + -- helper functions for easier working with the character_reference_code + local function multiply(number) + parser.character_reference_code = parser.character_reference_code * number + end + local function add(number) + parser.character_reference_code = parser.character_reference_code + number + end + if is_numeric(codepoint) then + multiply(16) + add(codepoint - 0x30) + elseif is_upper_hex(codepoint) then + multiply(16) + add(codepoint - 0x37) + elseif is_lower_hex(codepoint) then + multiply(16) + add(codepoint - 0x57) + elseif codepoint == semicolon then + return "numeric_reference_end_state" + else + -- this adds current entity + parser:tokenize("numeric_reference_end_state") + -- now tokenize the current character + return parser:tokenize(parser.return_state) + end + return "hexadecimal_character_reference" +end + +HtmlStates.numeric_reference_end_state = function(parser) + -- in this state, we don't need to + local character = parser.character_reference_code + -- we need to clean invalid character codes + if character == 0x00 or + character > 0x10FFFF or + is_surrogate(character) + then + character = 0xFFFD + -- should we add special support for "noncharacter"? I think we can pass them to the output anyway + elseif character_entity_replace_table[character] then + character = character_entity_replace_table[character] + end + parser:add_entity(uchar(character)) + return parser.return_state +end + + +HtmlStates.markup_declaration_open = function(parser) + -- started by <! + -- we now need to find the following text, to find if we started comment, doctype, or cdata + local comment_pattern = "^%-%-" + local doctype_pattern = "^[Dd][Oo][Cc][Tt][Yy][Pp][Ee]" + local cdata_pattern = "^%[CDATA%[" + local start_pos = parser.position + local text = parser.body + if text:match(comment_pattern, start_pos) then + -- local _, newpos = text:find(comment_pattern, start_pos) + -- we need to ignore next few characters + parser.ignored_pos = start_pos + 1 + parser:start_token("comment", {data = {}}) + return "comment_start" + elseif text:match(doctype_pattern, start_pos) then + parser.ignored_pos = start_pos + 6 + parser:start_token("doctype", {name = {}, data = {}, force_quirks = false}) + return "doctype" + elseif text:match(cdata_pattern, start_pos) then + parser.ignored_pos = start_pos + 6 + local current_element = parser:current_node() + if current_element.xmlns == xmlns.HTML or not current_element.xmlns then + -- we change CDATA simply to comments + parser:start_token("comment", {data = {"[CDATA["}}) + return "bogus_comment" + else + -- we are in XML mode, this happens for included SVG or MathML + return "cdata_section" + end + else + parser:start_token("comment", {data = {}}) + return "bogus_comment" + end + -- local start, stop = string.find(parser.body, comment_pattern, parser.position) +end + + +HtmlStates.cdata_section = function(parser) + local codepoint = parser.codepoint + if codepoint == right_square then + return "cdata_section_bracket" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "cdata_section" + end +end + +HtmlStates.cdata_section_bracket = function(parser) + local codepoint = parser.codepoint + if codepoint == right_square then + return "cdata_section_end" + else + parser:emit_character("]") + return parser:tokenize("cdata_section") + end +end + +HtmlStates.cdata_section_end = function(parser) + local codepoint = parser.codepoint + if codepoint == right_square then + parser:emit_character("]") + return "cdata_section_end" + elseif codepoint == greater_than then + return "data" + else + parser:emit_character("]") + return parser:tokenize("cdata_section") + end +end + + +HtmlStates.comment_start = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + return "comment_start_dash" + elseif codepoint == greater_than then + parser:emit() + return "data" + else + return parser:tokenize("comment") + end +end + +HtmlStates.comment_start_dash = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + return "comment_end" + elseif codepoint == greater_than then + parser:emit() + return data + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", "-") + return parser:tokenize("comment") + end +end + +HtmlStates.comment = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == less_than then + parser:append_token_data("data", uchar(codepoint)) + return "comment_less_than" + elseif codepoint == hyphen then + return "comment_end_dash" + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", uchar(codepoint)) + end + return "comment" +end + +HtmlStates.comment_less_than = function(parser) + local codepoint = parser.codepoint + if codepoint == exclam then + parser:append_token_data("data", uchar(codepoint)) + return "comment_less_than_bang" + elseif codepoint == less_than then + parser:append_token_data("data", uchar(codepoint)) + return "comment_less_than" + else + return parser:tokenize("comment") + end +end + +HtmlStates.comment_less_than_bang = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + return "comment_less_than_bang_dash" + else + return parser:tokenize("comment") + end +end + +HtmlStates.comment_less_than_bang_dash = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + return "comment_less_than_bang_dash_dash" + else + return parser:tokenize("comment_end_dash") + end + +end + +HtmlStates.comment_less_than_bang_dash_dash = function(parser) + -- these comment states start to be ridiculous + local codepoint = parser.codepoint + if codepoint == greater_than or codepoint == EOF then + return parser:tokenize("comment_end") + else + return parser:tokenize("comment_end") + end +end + +HtmlStates.comment_end_dash = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + return "comment_end" + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", uchar(codepoint)) + return parser:tokenize("comment") + end +end + +HtmlStates.comment_end = function(parser) + local codepoint = parser.codepoint + if codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == exclam then + return "comment_end_bang" + elseif codepoint == hyphen then + parser:append_token_data("data", "-") + return "comment_end" + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", "--") + return parser:tokenize("comment") + end +end + +HtmlStates.comment_end_bang = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + parser:append_token_data("data", "--!") + return "comment_end_dash" + elseif codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", "--!") + return parser:tokenize("comment") + end +end + +HtmlStates.end_tag_open = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) then + local data = { + name = {} + } + parser:start_token("end_tag", data) + return parser:tokenize("tag_name") + elseif codepoint == greater_than then + return "data" + elseif codepoint == EOF then + parser:discard_token() + parser:emit_character("</") + parser:emit_eof() + else + data = { + data = {} + } + parser:start_token("comment", data) + return parser:tokenize("bogus_comment") + end +end + +HtmlStates.bogus_comment = function(parser) + -- started by <? + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == EOF then + parser:emit() + parser:emit_eof() + else + parser:append_token_data("data", uchar(codepoint)) + return "bogus_comment" + end +end + +local function doctype_eof(parser) + parser:set_token_data("force_quirks", true) + parser:emit() + parser:emit_eof() +end + +HtmlStates.doctype = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "before_doctype_name" + elseif codepoint == greater_than then + return parser:tokenize("before_doctype_name") + elseif codepoint == EOF then + doctype_eof(parser) + else + return parser:tokenize("before_doctype_name") + end +end + +HtmlStates.before_doctype_name = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if is_space(codepoint) then + return "before_doctype_name" + elseif codepoint == greater_than then + parser:set_token_data("force_quirks", true) + parser:emit() + return "data" + elseif codepoint == EOF then + doctype_eof(parser) + elseif is_upper_alpha(codepoint) then + -- add lowercase name + parser:append_token_data("name", uchar(codepoint + 0x20)) + return "doctype_name" + else + parser:append_token_data("name", uchar(codepoint)) + return "doctype_name" + end +end + +HtmlStates.doctype_name = function(parser) + + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if is_space(codepoint) then + return "after_doctype_name" + elseif codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == EOF then + doctype_eof(parser) + elseif is_upper_alpha(codepoint) then + -- add lowercase name + parser:append_token_data("name", uchar(codepoint + 0x20)) + return "doctype_name" + else + parser:append_token_data("name", uchar(codepoint)) + return "doctype_name" + end +end + +HtmlStates.after_doctype_name = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "after_doctype_name" + elseif codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == EOF then + doctype_eof(parser) + else + parser:append_token_data("data", uchar(codepoint)) + -- there are lot of complicated rules how to consume doctype, + -- but I think that for our purpose they aren't interesting. + -- so everything until EOF or > is consumed as token.data + return "consume_doctype_data" + end +end + +HtmlStates.consume_doctype_data = function(parser) + -- this state just reads everything inside doctype as data + local codepoint = parser.codepoint + if codepoint == greater_than then + parser:emit() + return "data" + elseif codepoint == EOF then + doctype_eof(parser) + else + parser:append_token_data("data", uchar(codepoint)) + return "consume_doctype_data" + end +end + +HtmlStates.tag_name = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + elseif is_upper_alpha(codepoint) then + local lower = string.lower(uchar(codepoint)) + parser:append_token_data("name", lower) + elseif codepoint==EOF then + parser:emit() + parser:emit_eof() + else + local char = uchar(codepoint) + parser:append_token_data("name", char) + end + return "tag_name" + +end + +HtmlStates.self_closing_tag = function(parser) + local codepoint = parser.codepoint + if codepoint == greater_than then + parser.current_token.self_closing = true + parser:emit() + return "data" + else + return parser:tokenize("before_attribute_name") + end +end + + +HtmlStates.before_attribute_name = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + -- ignore spacing + return "before_attribute_name" + elseif codepoint == solidus or codepoint == greater_than then + -- reconsume in after_attribute_name + return parser:tokenize("after_attribute_name") + elseif codepoint == equals then + -- ToDo: handle https://html.spec.whatwg.org/multipage/parsing.html#parse-error-unexpected-equals-sign-before-attribute-name + else + -- start new attribute + parser:start_attribute() + return parser:tokenize("attribute_name") + end +end + +HtmlStates.attribute_name = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) + or codepoint == solidus + or codepoint == greater_than + then + return parser:tokenize("after_attribute_name") + elseif codepoint == equals then + return "before_attribute_value" + elseif is_upper_alpha(codepoint) then + -- lowercase attribute names + local lower = string.lower(uchar(codepoint)) + parser:append_token_data("current_attr_name", lower) + return "attribute_name" + else + parser:append_token_data("current_attr_name", uchar(codepoint)) + return "attribute_name" + end +end + +HtmlStates.after_attribute_name = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "after_attribute_name" + elseif codepoint == equals then + return "before_attribute_value" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + else + parser:start_attribute() + return parser:tokenize("attribute_name") + end +end + +HtmlStates.before_attribute_value = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "before_attribute_value" + elseif codepoint == quoting then + return "attribute_value_quoting" + elseif codepoint == apostrophe then + return "attribute_value_apostrophe" + elseif codepoint == greater_than then + parser:emit() + return "data" + else + return parser:tokenize("attribute_value_unquoted") + end +end + +HtmlStates.attribute_value_quoting = function(parser) + local codepoint = parser.codepoint + if codepoint == quoting then + return "after_attribute_value_quoting" + elseif codepoint == amperesand then + parser.return_state = "attribute_value_quoting" + return "character_reference" + else + parser:append_token_data("current_attr_value", uchar(codepoint)) + return "attribute_value_quoting" + end +end + +HtmlStates.attribute_value_apostrophe = function(parser) + local codepoint = parser.codepoint + if codepoint == apostrophe then + return "after_attribute_value_quoting" + elseif codepoint == amperesand then + parser.return_state = "attribute_value_apostrophe" + return "character_reference" + else + parser:append_token_data("current_attr_value", uchar(codepoint)) + return "attribute_value_apostrophe" + end +end + +HtmlStates.attribute_value_unquoted = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == amperesand then + parser.return_state = "attribute_value_unquoted" + return "character_reference" + elseif codepoint == greater_than then + parser:emit() + return "data" + else + parser:append_token_data("current_attr_value", uchar(codepoint)) + return "attribute_value_unquoted" + end +end + +HtmlStates.after_attribute_value_quoting = function(parser) + local codepoint = parser.codepoint + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + else + return parser:tokenize("before_attribute_name") + end +end + +HtmlStates.rcdata = function(parser) + -- this is the default state + local codepoint = parser.codepoint + -- print("codepoint", parser.codepoint) + codepoint = fix_null(codepoint) + if codepoint == less_than then + -- start of tag + return "rcdata_less_than" + elseif codepoint == amperesand then + -- we must save the current state + -- what we will return to after entity + parser.return_state = "rcdata" + return "character_reference" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + end + return "rcdata" +end + +local function discard_rcdata_end_tag(parser, text) + parser:discard_token() + parser:emit_character(text) +end + +HtmlStates.rcdata_less_than = function(parser) + local codepoint = parser.codepoint + if codepoint == solidus then + return "rcdata_end_tag_open" + else + discard_rcdata_end_tag(parser, "<") + return parser:tokenize("rcdata") + end +end + +HtmlStates.rcdata_end_tag_open = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) then + parser:start_token("end_tag", {name={}}) + parser.temp_buffer = {} + return parser:tokenize("rcdata_end_tag_name") + else + discard_rcdata_end_tag(parser, "</") + return parser:tokenize("rcdata") + end +end + + + +HtmlStates.rcdata_end_tag_name = function(parser) + -- we need to find name of the currently opened tag + local parent = parser:get_parent() or {} + local opened_tag = parent.tag + local current_tag = table.concat(parser.current_token.name or {}) + local codepoint = parser.codepoint + if is_upper_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint + 0x20)) + -- insert current char to temp buffer + table.insert(parser.temp_buffer, uchar(codepoint)) + return "rcdata_end_tag_name" + elseif is_lower_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "rcdata_end_tag_name" + elseif opened_tag == current_tag then + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + end + else + discard_rcdata_end_tag(parser, "</" .. table.concat(parser.temp_buffer)) + parser.temp_buffer = {} + return parser:tokenize("rcdata") + end +end + +HtmlStates.rawtext = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == less_than then + return "rawtext_less_than" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "rawtext" + end +end + +HtmlStates.rawtext_less_than = function(parser) + local codepoint = parser.codepoint + if codepoint == solidus then + return "rawtext_end_tag_open" + else + parser:emit_character("<") + return parser:tokenize("rawtext") + end +end + +HtmlStates.rawtext_end_tag_open = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) then + parser:start_token("end_tag", {name={}}) + parser.temp_buffer = {} + return parser:tokenize("rawtext_end_tag_name") + else + parser:emit_character("</") + return parser:tokenize("rawtext") + end +end + +HtmlStates.rawtext_end_tag_name = function(parser) + -- we need to find name of the currently opened tag + local parent = parser:get_parent() or {} + local opened_tag = parent.tag + local current_tag = table.concat(parser.current_token.name or {}) + local codepoint = parser.codepoint + if is_upper_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint + 0x20)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "rawtext_end_tag_name" + elseif is_lower_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "rawtext_end_tag_name" + elseif opened_tag == current_tag then + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + end + else + discard_rcdata_end_tag(parser, "</" .. table.concat(parser.temp_buffer)) + parser.temp_buffer = {} + return parser:tokenize("rawtext") + end +end + +HtmlStates.script_data = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == less_than then + return "script_data_less_than" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data" + end +end + +HtmlStates.script_data_less_than = function(parser) + local codepoint = parser.codepoint + if codepoint == solidus then + parser.temp_buffer = {} + return "script_data_end_tag_open" + elseif codepoint == exclam then + parser:emit_character("<!") + return "script_data_escape_start" + else + parser:emit_character("<") + return parser:tokenize("script_data") + end +end + +HtmlStates.script_data_end_tag_open = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) then + parser:start_token("end_tag", {name={}}) + return parser:tokenize("script_data_end_tag_name") + else + parser:emit_character("</") + return parser:tokenize("script_data") + end +end + +HtmlStates.script_data_end_tag_name = function(parser) + -- we need to find name of the currently opened tag + local parent = parser:get_parent() or {} + local opened_tag = parent.tag + local current_tag = table.concat(parser.current_token.name or {}) + local codepoint = parser.codepoint + if is_upper_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint + 0x20)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_end_tag_name" + elseif is_lower_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_end_tag_name" + elseif opened_tag == current_tag then + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + end + else + discard_rcdata_end_tag(parser, "</" .. table.concat(parser.temp_buffer)) + parser.temp_buffer = {} + return parser:tokenize("script_data") + end + +end + +HtmlStates.script_data_escape_start = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_escape_start_dash" + else + parser:tokenize("script_data") + end +end + +HtmlStates.script_data_escape_start_dash = function(parser) + local codepoint = parser.codepoint + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_escaped_dash_dash" + else + parser:tokenize("script_data") + end + +end + + +HtmlStates.script_data_escaped = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_escaped_dash" + elseif codepoint == less_than then + return "script_data_escaped_less_than_sign" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data_escaped" + end +end + +HtmlStates.script_data_escaped_dash = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_escaped_dash_dash" + elseif codepoint == less_than then + return "script_data_escaped_less_than_sign" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data_escaped" + end + +end + +HtmlStates.script_data_escaped_dash_dash = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_escaped_dash_dash" + elseif codepoint == less_than then + return "script_data_escaped_less_than_sign" + elseif codepoint == greater_than then + parser:emit_character(">") + return "script_data" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data_escaped" + end + +end + +HtmlStates.script_data_escaped_less_than_sign = function(parser) + local codepoint = parser.codepoint + if codepoint == solidus then + parser.temp_buffer = {} + return "script_data_escaped_end_tag_open" + elseif is_alpha(codepoint) then + parser.temp_buffer = {} + parser:emit_character("<") + return parser:tokenize("script_data_double_escape_start") + else + parser:emit_character("<") + return parser:tokenize("script_data_escaped") + end +end + +HtmlStates.script_data_escaped_end_tag_open = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) then + parser:start_token("end_tag", {name={}}) + return parser:tokenize("script_data_escaped_end_tag_name") + else + parser:emit_character("</") + return parser:tokenize("script_data_escaped") + end +end + +HtmlStates.script_data_escaped_end_tag_name = function(parser) + -- we need to find name of the currently opened tag + local parent = parser:get_parent() or {} + local opened_tag = parent.tag + local current_tag = table.concat(parser.current_token.name or {}) + local codepoint = parser.codepoint + if is_upper_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint + 0x20)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_escaped_end_tag_name" + elseif is_lower_alpha(codepoint) then + parser:append_token_data("name", uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_escaped_end_tag_name" + elseif opened_tag == current_tag then + if is_space(codepoint) then + return "before_attribute_name" + elseif codepoint == solidus then + return "self_closing_tag" + elseif codepoint == greater_than then + parser:emit() + return "data" + end + else + discard_rcdata_end_tag(parser, "</" .. table.concat(parser.temp_buffer)) + parser.temp_buffer = {} + return parser:tokenize("script_data_escaped") + end +end + +HtmlStates.script_data_double_escape_start = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) or + codepoint == solidus or + codepoint == greater_than + then + local current_tag = table.concat(parser.current_token.name or {}) + parser:emit_character(uchar(codepoint)) + if current_tag == "script" then + return "script_data_double_escaped" + else + return "script_data_escaped" + end + elseif is_upper_alpha(codepoint) then + parser:emit_character(uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint) + 0x20) + return "script_data_double_escape_start" + elseif is_lower_alpha(codepoint) then + parser:emit_character(uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_double_escape_start" + else + return parser:tokenize("script_data_escaped") + end +end + +HtmlStates.script_data_double_escaped = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_double_escaped_dash" + elseif codepoint == less_than then + parser:emit_character("<") + return "script_data_double_escaped_less_than_sign" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data_double_escaped" + end +end + +HtmlStates.script_data_double_escaped_dash = function(parser) + local codepoint = parser.codepoint + codepoint = fix_null(codepoint) + if codepoint == hyphen then + parser:emit_character("-") + return "script_data_double_escaped_dash" + elseif codepoint == less_than then + parser:emit_character("<") + return "script_data_double_escaped_less_than_sign" + elseif codepoint == greater_than then + parser:emit_character(">") + return "script_data" + elseif codepoint == EOF then + parser:emit_eof() + else + parser:emit_character(uchar(codepoint)) + return "script_data_double_escaped" + end +end + +HtmlStates.script_data_double_escaped_less_than_sign = function(parser) + local codepoint = parser.codepoint + if codepoint == solidus then + parser:emit("/") + return "script_data_double_escape_end" + else + return parser:tokenize("script_data_double_escaped") + end +end + +HtmlStates.script_data_double_escape_end = function(parser) + local codepoint = parser.codepoint + if is_alpha(codepoint) or + codepoint == solidus or + codepoint == greater_than + then + local current_tag = table.concat(parser.current_token.name or {}) + parser:emit_character(uchar(codepoint)) + if current_tag == "script" then + return "script_data_escaped" + else + return "script_data_double_escaped" + end + elseif is_upper_alpha(codepoint) then + parser:emit_character(uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint) + 0x20) + return "script_data_double_escape_start" + elseif is_lower_alpha(codepoint) then + parser:emit_character(uchar(codepoint)) + table.insert(parser.temp_buffer, uchar(codepoint)) + return "script_data_double_escape_start" + else + return parser:tokenize("script_data_double_escaped") + end + +end + +-- formatting elements needs special treatment +local formatting_element_names ={ + a = true, b = true, big = true, code = true, em = true, font = true, i = true, nobr = true, s = true, small = true, strike = true, strong = true, tt = true, u = true +} +local function is_formatting_element(name) + return formatting_element_names[name] +end + +local special_elements = {} + +local special_elements_list = {"address", "applet", "area", "article", "aside", +"base", "basefont", "bgsound", "blockquote", "body", "br", "button", "caption", +"center", "col", "colgroup", "dd", "details", "dir", "div", "dl", "dt", +"embed", "fieldset", "figcaption", "figure", "footer", "form", "frame", +"frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", +"hr", "html", "iframe", "img", "input", "keygen", "li", "link", "listing", +"main", "marquee", "menu", "meta", "nav", "noembed", "noframes", "noscript", +"object", "ol", "p", "param", "plaintext", "pre", "script", "section", +"select", "source", "style", "summary", "table", "tbody", "td", "template", +"textarea", "tfoot", "th", "thead", "title", "tr", "track", "ul", "wbr", "xmp", +"mi","mo","mn","ms","mtext", "annotation-xml","foreignObject","desc", "title" +} + +for k,v in ipairs(special_elements_list) do + special_elements[v] = true +end + + +local function is_special(name) + return special_elements[name] +end + +-- these lists are used in HtmlParser:generate_implied_endtags() +local implied_endtags = {dd=true, dt=true, li = true, optgroup = true, option = true, p = true, rb = true, rp = true, rd = true, trc = true} +local implied_endtags_thoroughly = {dd=true, dt=true, li = true, optgroup = true, option = true, p = true, + rb = true, rp = true, rd = true, trc = true, caption = true, colgroup = true, tbody = true, td = true, + tfoot = true, th = true, thead = true, tr = true +} + +-- find if unfinished tags list contain a tag +-- it fails if any element from element_list is matched before that tag +local function is_in_scope(parser, target, element_list) + for i = #parser.unfinished, 1, -1 do + local node = parser.unfinished[i] + local tag = node.tag + if tag == target then + return true + elseif element_list[tag] then + return false + end + end + return false +end + +local particular_scope_elements = { applet = true, caption = true, html = true, table = true, td = true, + th = true, marquee = true, object = true, template = true, mi = true, mo = true, mn = true, + ms = true, mtext = true, ["annotation-xml"] = true, foreignObject = true, desc = true, title = true, +} + +local function is_in_particular_scope(parser, target) + return is_in_scope(parser, target, particular_scope_elements) +end + +-- derived scope lists +-- +-- list_item scope +local list_item_scope_elements = {ol = true, ul = true} +for k,v in pairs(particular_scope_elements) do list_item_scope_elements[k] = v end + +local function is_in_list_item_scope(parser, target) + return is_in_scope(parser, target, list_item_scope_elements) +end + +-- button scope +local button_scope_elements = {button = true} +for k,v in pairs(particular_scope_elements) do button_scope_elements[k] = v end + +local function is_in_button_scope(parser, target) + return is_in_scope(parser, target, button_scope_elements) +end + +-- table scope +local table_scope_elements = {html = true, table = true, template = true} + +local function is_in_table_scope(parser, target) + return is_in_scope(parser, target, table_scope_elements) +end + +-- select scope +local function is_in_select_scope(parser, target) + -- this scope is specific, because it supports all tags except two + for i = #parser.unfinished, 1, -1 do + local node = parser.unfinished[i] + local tag = node.tag + if tag == target then + return true + elseif tag == "optgroup" or tag == "option" then + -- only these two tags are supported + else + return false + end + end + return false +end + +-- List of active formatting elements +-- https://html.spec.whatwg.org/multipage/parsing.html#the-list-of-active-formatting-elements +-- we don't implement it yet, but maybe in the future. + + +local HtmlTreeStates = {} + + + + + + +local HtmlParser = {} + +function HtmlParser:init(body) + local o ={} + setmetatable(o, self) + self.__index = self + o.body = self:normalize_newlines(body) -- HTML string + o.position = 0 -- position in the parsed string + o.unfinished = {} -- insert Root node into the list of opened elements + o.Document = Root:init() + o.default_state = "data" -- default state machine state + o.state = o.default_state -- working state of the machine + o.return_state = o.default_state -- special state set by entities parsing + o.temp_buffer = {} -- keep temporary data + o.current_token = {type="start"} -- currently processed token + o.insertion_mode = "initial" -- tree construction state + o.head_pointer = nil -- pointer to the Head element + o.form_pointer = nil + o.active_formatting = {} -- list of active formatting elements + o.scripting_flag = false -- we will not support scripting + return o +end + +function HtmlParser:normalize_newlines(body) + -- we must normalize newlines + return body:gsub("\r\n", "\n"):gsub("\r", "\n") +end + +-- declare void elements +local self_closing_tags_list = {"area", "base", "br", "col", "embed", "hr", "img", "input", + "link", "meta", "param", "source", "track", "wbr"} + +local self_closing_tags = {} +for _,v in ipairs(self_closing_tags_list) do self_closing_tags[v] = true end + + + + +function HtmlParser:parse() + -- we assume utf8 input, you must convert it yourself if the source is + -- in a different encoding + self.text = {} + self.state = self.default_state + -- this should enable us to pass over some characters that we want to ignore + -- for example scripts, css, etc. + self.ignored_pos = -1 + for pos, ucode in utf8.codes(self.body) do + -- save buffer info and require the tokenize function + if pos > self.ignored_pos then + self.position = pos + self.codepoint = ucode + self.character = uchar(ucode) + self.state = self:tokenize(self.state) or self.state -- if tokenizer don't return new state, assume that it continues in the current state + end + end + return self:finish() +end + +function HtmlParser:tokenize(state) + local state = state or self.state + local ucode = self.codepoint + local text = self.text + + self.last_position = self.position + self.element_state = false + -- execute state machine object and return new state + local fn = HtmlStates[state] or function(parser) return self.default_state end + local newstate = fn(self) + -- this should enable changing state from elements that needs special treatment, like <script> or <style> + if self.element_state then return self.element_state end + -- print("newstate", newstate, state, uchar(ucode or 32)) + return newstate +end + +function HtmlParser:start_token(typ, data) + -- emit the previous token + -- self:emit() + data.type = typ + self.current_token = data +end + +function HtmlParser:discard_token() + self.current_token = {type="empty"} +end + + + +function HtmlParser:append_token_data(name, data) + -- append data to the current token + local token = self.current_token or {} + if token[name] and type(token[name]) == "table" then + table.insert(token[name], data) + end +end + +function HtmlParser:set_token_data(name, data) + local token = self.current_token or {} + token[name] = data +end + +function HtmlParser:flush_temp_buffer() + -- write stuff from the temp buffer back to the document + local token = self.current_token + if token.type == "start_tag" then + -- in start tag, entities can be only in attribute value + for _, char in ipairs(self.temp_buffer) do + table.insert(token.current_attr_value, char) + end + elseif self.return_state == "data" then + -- handle entities in text + for _, char in ipairs(self.temp_buffer) do + self:start_token("character", {char=char}) + self:emit() + end + end + self.temp_buffer = {} +end + +function HtmlParser:add_entity(char) + local token = self.current_token + if token.type == "start_tag" then + table.insert(token.current_attr_value, char) + else + self:start_token("character", {char=char}) + self:emit() + end + self.temp_buffer = {} +end + +function HtmlParser:emit(token) + -- state machine functions should use this function to emit tokens + local token = token or self.current_token + -- print("Emit", token.type) + local token_type = token.type + if token_type == "character" then + table.insert(self.text, token.char) + elseif token_type == "doctype" then + self:add_text() + self:add_doctype() + elseif token_type == "start_tag" then + self:add_text() + -- self:start_attribute() + self:start_tag() + -- print("Emit start tag", table.concat(token.name)) + -- save last attribute + elseif token_type == "end_tag" then + self:add_text() + self:end_tag() + -- print("Emit end tag", table.concat(token.name)) + elseif token_type == "comment" then + self:add_text() + self:add_comment() + -- self:start_attribute() + elseif token_type == "empty" then + + end + -- self.current_token = {type="empty"} +end + +function HtmlParser:emit_character(text) + self:start_token("character", {char=text}) + self:emit() +end + +function HtmlParser:emit_eof() + self:start_token("end_of_file", {}) + self:emit() +end + +function HtmlParser:get_parent() + -- return parent element + return self.unfinished[#self.unfinished] or self.Document +end + +function HtmlParser:close_element() + -- return parent element and remove it from the unfinished list + return table.remove(self.unfinished) +end + +function HtmlParser:add_text(text) + -- process current text node + local text = text + if not text then + text = self.text + end + if type(text) == "table" then + if #text > 0 then + text = table.concat(text) + end + end + if type(text) == "string" and text~="" then + local parent = self:get_parent() + local node = Text:init(text, parent) + parent:add_child(node) + end + self.text = {} +end + + +function HtmlParser:start_attribute() + local token = self.current_token or {} + if token.type == "start_tag" then + local attr_name = table.concat(token.current_attr_name) + local attr_value = table.concat(token.current_attr_value) or "" + if attr_name ~= "" then + -- token.attr[attr_name] = attr_value + table.insert(token.attr, {name = attr_name, value = attr_value}) + -- print("saving attribute", attr_name, attr_value) + end + self:set_token_data("current_attr_name", {}) + self:set_token_data("current_attr_value", {}) + end +end + +function HtmlParser:set_xmlns(node, parent) + -- handle xmlns + local in_attr = false + -- try to find xmlns in node's attributes first + for _, attr in ipairs(node.attr) do + if attr.name == "xmlns" then + node.xmlns = attr.value + in_attr = true + break + end + end + if not in_attr then + -- if we cannot find xmlns attribute, then use + -- xmlns from the parent element, or the default xmlns + local parent = self:get_parent() + node.xmlns = parent.xmlns or xmlns.HTML + end +end + +function HtmlParser:start_tag() + local token = self.current_token + if token.type == "start_tag" then + -- close all currently opened attributes + self:start_attribute() + -- initiate Element object, pass attributes and info about self_closing + local name = table.concat(token.name) + local parent = self:get_parent() + local node = Element:init(name, parent) + node.attr = token.attr + node.self_closing = token.self_closing + self:set_xmlns(node) + -- + if token.self_closing -- <img /> + or self_closing_tags[name] -- void elements + then + parent:add_child(node) + else + -- add to the unfinished list + table.insert(self.unfinished, node) + end + if name == "title" then + self.element_state = "rcdata" + elseif name == "style" then + self.element_state = "rawtext" + elseif name == "script" then + self.element_state = "script_data" + end + end +end + +function HtmlParser:end_tag() + -- close current opened element + local token = self.current_token + if token.type == "end_tag" then + if #self.unfinished==0 then return nil end + local node = self:close_element() + local parent = self:get_parent() + parent:add_child(node) + end +end + +function HtmlParser:add_comment() + local token = self.current_token + if token.type == "comment" then + self:start_attribute() + local parent = self:get_parent() + local text = table.concat(token.data) + local node = Comment:init(text, parent) + parent:add_child(node) + end +end + +function HtmlParser:add_doctype() + local token = self.current_token + if token.type == "doctype" then + self:start_attribute() + local parent = self:get_parent() + local name = table.concat(token.name) + local node = Doctype:init(name, parent) + if #token.data > 0 then + node:add_data(table.concat(token.data)) + end + parent:add_child(node) + end +end + +function HtmlParser:switch_insertion(name) + self.insertion_mode = name +end + +function HtmlParser:current_node() + return self:get_parent() +end + +function HtmlParser:adjusted_current_node() + -- we don't support this feature yet + -- https://html.spec.whatwg.org/multipage/parsing.html#adjusted-current-node + return self:current_node() +end + + +function HtmlParser:reset_insertion_mode() + -- https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately + local last = false + for position = #self.unfinished, 1, -1 do + local node = self.unfinished[position] + if position == 1 then last = true end + local name = node.tag + -- switch to insertion mode based on the current element name + -- there is lot of other cases, but we support only basic ones + -- we can support other insertion modes in the future + if name == "head" and last == true then + self:switch_insertion("in_head") + return + elseif name == "body" then + self:switch_insertion("in_body") + return + elseif name == "html" then + if self.head_pointer then + self:switch_insertion("before_head") + return + else + self:switch_insertion("after_head") + end + elseif last == true then + self:switch_insertion("in_body") + return + end + end + -- by default use in_body + self:switch_insertion("in_body") +end + + +-- https://html.spec.whatwg.org/multipage/parsing.html#closing-elements-that-have-implied-end-tags +function HtmlParser:generate_implied_endtags(included, ignored) + local included = included or implied_endtags + -- parser can pass list of elements that should be removed from the "included" list + local ignored = ignored or {} + for _, name in ipairs(ignored) do included[name] = nil end + local current = self:current_node() or {} + -- keep removing elements while they are in the "included" list + if included[current.tag] then + table.remove(self.unfinished) + self:generate_implied_endtags(ignored) + end +end + +function HtmlParser:finish() + -- tokenize without any real character + self.codepoint = EOF + self:tokenize(self.state) + -- self:emit() + self:add_text() + -- close all unfinished elements + if #self.unfinished == 0 then + -- add implicit html tag + self:start_tag("html") + end + while #self.unfinished > 0 do + local node = self:close_element() + local parent = self:get_parent() + parent:add_child(node) + end + -- return root element + return self.Document -- self:close_element() +end + +-- +M.Text = Text +M.Element = Element +M.HtmlParser = HtmlParser +M.HtmlStates = HtmlStates -- table with functions for particular parser states +M.self_closing_tags = self_closing_tags -- list of void elements +M.search_entity_tree = search_entity_tree +M.is_in_particular_scope = is_in_particular_scope +M.is_in_list_item_scope = is_in_list_item_scope +M.is_in_button_scope = is_in_button_scope +M.is_in_table_scope = is_in_table_scope +M.is_in_select_scope = is_in_select_scope + +return M diff --git a/macros/luatex/generic/luaxml/luaxml-namedentities.lua b/macros/luatex/generic/luaxml/luaxml-namedentities.lua index 9a26f448f6..0e6399ab13 100644 --- a/macros/luatex/generic/luaxml/luaxml-namedentities.lua +++ b/macros/luatex/generic/luaxml/luaxml-namedentities.lua @@ -40,7 +40,7 @@ return { ["nsqsube"]="â‹¢", ["Nacute"]="Ń", ["mcomma"]="⨩", -["ApplyFunction"]=utf8.char(8289), +["ApplyFunction"]=utf8.char(0x2061), ["rfisht"]="⥽", ["phmmat"]="ℳ", ["rarrw"]="â†", diff --git a/macros/luatex/generic/luaxml/luaxml-testxml.lua b/macros/luatex/generic/luaxml/luaxml-testxml.lua index 8231642116..056bde0ece 100644 --- a/macros/luatex/generic/luaxml/luaxml-testxml.lua +++ b/macros/luatex/generic/luaxml/luaxml-testxml.lua @@ -9,9 +9,18 @@ -- Initial Import -- -modxml = require('luaxml-mod-xml') -handler = require('luaxml-mod-handler') -pretty = require('luaxml-pretty') +local modxml +local handler +local pretty +if kpse then + modxml = require('luaxml-mod-xml') + handler = require('luaxml-mod-handler') + pretty = require('luaxml-pretty') +else + modxml = require('luaxml.mod-xml') + handler = require('luaxml.mod-handler') + pretty = require('luaxml.pretty') +end -- Defaults diff --git a/macros/luatex/generic/luaxml/luaxml-transform.lua b/macros/luatex/generic/luaxml/luaxml-transform.lua index d7631ac78e..b6841fea5f 100644 --- a/macros/luatex/generic/luaxml/luaxml-transform.lua +++ b/macros/luatex/generic/luaxml/luaxml-transform.lua @@ -4,8 +4,15 @@ -- code originaly comes from from https://github.com/michal-h21/luaxml-mathml -- -local domobject = require "luaxml-domobject" -local cssquery = require "luaxml-cssquery" +local domobject +local cssquery +if kpse then + domobject = require "luaxml-domobject" + cssquery = require "luaxml-cssquery" +else + domobject = require "luaxml.domobject" + cssquery = require "luaxml.cssquery" +end -- initialize CSS selector object local css = cssquery() @@ -49,14 +56,18 @@ local function process_text(text, parameters) -- process all Unicode characters and find if they should be replaced for _, char in utf8.codes(text) do -- construct new string with replacements or original char - t[#t+1] = unicodes[char] or utf8.char(char) + if verbatim then + t[#t+1] = utf8.char(char) + else + t[#t+1] = unicodes[char] or utf8.char(char) + end end local text = table.concat(t) if parameters.collapse_newlines==true then text = text:gsub("\n", " ") end -- verbatim can be set in parameters table. it prevent collapsing of spaces. - if not parameters.verbatim then + if not verbatim then text = text:gsub("(%s%s+)", function(a) return a:sub(1,1) end) end return text diff --git a/macros/luatex/generic/luaxml/luaxml.pdf b/macros/luatex/generic/luaxml/luaxml.pdf Binary files differindex 4f00cb6f69..f574a0a528 100644 --- a/macros/luatex/generic/luaxml/luaxml.pdf +++ b/macros/luatex/generic/luaxml/luaxml.pdf diff --git a/macros/luatex/generic/luaxml/luaxml.tex b/macros/luatex/generic/luaxml/luaxml.tex index 28539d898c..5031a0468e 100644 --- a/macros/luatex/generic/luaxml/luaxml.tex +++ b/macros/luatex/generic/luaxml/luaxml.tex @@ -7,7 +7,7 @@ \usepackage{framed} % Version is defined in the makefile, use default values when compiled directly \ifdefined\version\else -\def\version{v0.1q} +\def\version{v0.1r} \let\gitdate\date \fi \newcommand\modulename[1]{\subsection{#1}\label{sec:#1}} @@ -466,8 +466,8 @@ attributes. The parameters table can hold following values: \begin{description} - \item[verbatim] -- by default, spaces are collapsed. This is useful in general, but you may want to - keep spaces, for example in program listings. Set \texttt{verbatim=true} in this case. + \item[verbatim] -- used for source code listings and similar texts, that should keep their original formatting. + Special characters are not escaped, so you will want to transform the elements into verbatim or listings environment. \item[separator] -- when you select element by names (\verb|@<element name>|), you can use this parameter set the separator between possible multiple instances of the child element. \end{description} diff --git a/macros/luatex/latex/gitinfo-lua/README.md b/macros/luatex/latex/gitinfo-lua/README.md index 1abafbdc06..463e764fa1 100644 --- a/macros/luatex/latex/gitinfo-lua/README.md +++ b/macros/luatex/latex/gitinfo-lua/README.md @@ -1,5 +1,6 @@ # Gitinfo Lua ![CTAN Version](https://img.shields.io/ctan/v/gitinfo-lua) +[![build](https://github.com/Xerdi/gitinfo-lua/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Xerdi/gitinfo-lua/actions/workflows/build.yml) A LaTeX package which provides macros integrated with LuaTeX and the commandline tool `git`. diff --git a/macros/luatex/latex/gitinfo-lua/doc/git-scenario.sh b/macros/luatex/latex/gitinfo-lua/doc/git-scenario.sh index a3cfd179e9..423c2a7d0c 100755 --- a/macros/luatex/latex/gitinfo-lua/doc/git-scenario.sh +++ b/macros/luatex/latex/gitinfo-lua/doc/git-scenario.sh @@ -2,8 +2,6 @@ set -e -PROJECT_DIR="${1:-../../git-test-project}" - set_author() { git config user.name $1 git config user.email $2 @@ -23,15 +21,6 @@ charlie() { set_author 'Charlie' 'charlie@example.com' } -if [[ -d "${PROJECT_DIR}" ]]; then - rm -rf "${PROJECT_DIR}" -fi - -mkdir "${PROJECT_DIR}" -cd "${PROJECT_DIR}" - -git init - alice echo "# My project" > README.md @@ -53,7 +42,12 @@ bob curl https://raw.githubusercontent.com/github/gitignore/main/TeX.gitignore > .gitignore git add .gitignore -git commit -m "Add gitignore" --date="2017-08-06 12:03" +git commit -m "Add gitignore + +Get the TeX.gitignore from the gitignore repository and +use it for this project. + +From github" --date="2017-08-06 12:03" charlie diff --git a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf Binary files differindex da85914b1b..02edd681a7 100644 --- a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf +++ b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf diff --git a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex index 438f235b00..ef7781dd01 100644 --- a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex +++ b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex @@ -17,7 +17,7 @@ % gitinfo-cmd.lua and gitinfo-lua.lua \documentclass{ltxdoc} \usepackage[english]{babel} -\usepackage[titlepage,authors]{../tex/gitinfo-lua} +\usepackage[titlepage,authors]{gitinfo-lua} \usepackage{listings} \lstset{ @@ -314,11 +314,13 @@ latexmk -pvc -lualatex -shell-escape main \end{description} \end{lstlisting} \noindent - \newcommand\commitline[1]{\item #1} + \newcommand\commitline[2]{\item #1 + + #2} \newcommand\formatversion[3]{% \item[#1] \gittag[(taggerdate)(taggerdate:short)(authordate:short)]{printdate}{#1} \begin{itemize} - \forgitcommit[s]{commitline}{#3} + \forgitcommit[s,b]{commitline}{#3} \end{itemize}% }% \setlength{\fboxsep}{16pt}% diff --git a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua index 7e27bc05ba..5aa0dc56e5 100644 --- a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua +++ b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua @@ -41,7 +41,7 @@ function api:exec(command, do_caching, target_dir) local cmd = self.executable .. ' ' .. command local cwd = target_dir or self.cwd if cwd then - cmd = 'cd ' .. cwd .. ';' .. cmd + cmd = 'cd ' .. cwd .. ' && ' .. cmd end if do_caching then local found, result = cache:seek(cmd) diff --git a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua index a1c2a6988b..0f3a1315d3 100644 --- a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua +++ b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua @@ -23,8 +23,8 @@ end local module = { name = 'gitinfo-lua', info = { - version = '1.0.1', --TAGVERSION - date = '2024/02/12', --TAGDATE + version = '1.0.2', --TAGVERSION + date = '2024/02/23', --TAGDATE comment = "Git info Lua — Git integration with LaTeX", author = "Erik Nijenhuis", license = "free" @@ -45,7 +45,8 @@ local api = { ['{'] = '\\{', ['}'] = '\\}', ['~'] = '\\textasciitilde ', - ['%^'] = '\\textasciicircum ' + ['%^'] = '\\textasciicircum ', + ['\n'] = ' ' } } local mt = { @@ -73,6 +74,7 @@ end function api:escape_str(value) local buf = string.gsub(value, '\\', '\\textbackslash ') + buf = string.gsub(buf, "\n%s*\n+", "\\par ") for search, replace in pairs(self.escape_chars) do buf = string.gsub(buf, search, replace) end diff --git a/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty b/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty index 33fe5066c9..3f850a1146 100644 --- a/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty +++ b/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty @@ -16,7 +16,7 @@ % This work consists of the files gitinfo-lua.sty gitinfo-lua.pdf % gitinfo-cmd.lua and gitinfo-lua.lua \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{gitinfo-lua}[2024/02/12 1.0.1 Xerdi's Git Package] +\ProvidesPackage{gitinfo-lua}[2024/02/23 1.0.2 Xerdi's Git Package] \RequirePackage{luacode} diff --git a/macros/unicodetex/latex/einfart/README.md b/macros/unicodetex/latex/einfart/README.md index 5cb65cbe21..f8db51385d 100644 --- a/macros/unicodetex/latex/einfart/README.md +++ b/macros/unicodetex/latex/einfart/README.md @@ -21,6 +21,21 @@ Compared with usual document classes, it has the following features: - Support both the standard and the AMS writing fashion. - ... and much more... +## To get started + +Prepration: + +- Make sure that your TeX distribution is up-to-dated. +- Check the required fonts indicated below, and make sure that they are installed. + +Once prepared: + +- You may get started by looking at one of the [demo documents](https://github.com/Jinwen-XU/minimalist/tree/main/einfart/demo) that suits your need and edit the code there to get your own template. + +If you run into a problem, or if you would like some elements to be changed or improved: + +- Feel free to raise an issue or post a feature request via [the GitHub issue](https://github.com/Jinwen-XU/minimalist/issues). + ## Required fonts The current document class requires the following open-source fonts that are not included in the standard TeX collection: diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.pdf Binary files differnew file mode 100644 index 0000000000..ad2ebb4667 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.tex new file mode 100644 index 0000000000..7861bff8a8 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classical.tex @@ -0,0 +1,108 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = classical, + % use indent = false, + % title in boldface, + % title in scshape, + % title in sffamily, + % theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{Title of the article (demo of the style \textquote{classical})} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.pdf Binary files differnew file mode 100644 index 0000000000..b4c30ec463 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.tex new file mode 100644 index 0000000000..6879fb5a30 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-classicthesis.tex @@ -0,0 +1,108 @@ +\PassOptionsToPackage{ + % drafting=true, % print version information on the bottom of the pages + tocaligned=false, % the left column of the toc will be aligned (no indentation) + dottedtoc=false, % page numbers in ToC flushed right + style=arsclassica % classicthesis, arsclassica, linedheaders, plain +}{classicthesis} +\documentclass[a4paper, 11pt, + use style = classicthesis, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{\spacedallcaps{Title of the article}\\[.3\baselineskip](demo of the style \textquote{ClassicThesis})} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.pdf Binary files differnew file mode 100644 index 0000000000..08e4cb919a --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.tex new file mode 100644 index 0000000000..73c502b9e7 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-default.tex @@ -0,0 +1,107 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{Title of the article (demo of the default style)} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.pdf Binary files differnew file mode 100644 index 0000000000..475a2da1d8 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.tex new file mode 100644 index 0000000000..45c7f04829 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-flow.tex @@ -0,0 +1,108 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = flow, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{Title of the article (demo of the style \textquote{flow})} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.pdf Binary files differnew file mode 100644 index 0000000000..3dfd68e0ab --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.tex new file mode 100644 index 0000000000..ae9c139c9c --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-plain.tex @@ -0,0 +1,108 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + % use osf, + use style = plain, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{Title of the article (demo of the style \textquote{plain})} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.pdf b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.pdf Binary files differnew file mode 100644 index 0000000000..4edd164588 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.pdf diff --git a/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.tex b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.tex new file mode 100644 index 0000000000..b9d7230304 --- /dev/null +++ b/macros/unicodetex/latex/einfart/demo/einfart-demo-style-stream.tex @@ -0,0 +1,108 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = stream, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{einfart} +\usepackage{ProjLib} +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\title{Title of the article (demo of the style \textquote{stream})} +\author{Author One} +\address{Address of Author One} +\email{\href{mailto:author.one@email.com}{author.one@email.com}} +%% \thanks{The first author is indebted to...} +\author{Author Two} +\address{Address of Author Two} +\email{\href{mailto:author.two@email.com}{author.two@email.com}} +%% \thanks{The second author would like to thank the support of...} +\subjclass{XXXXX} +%% \keywords{AAA, BBB, CCC} +\date{\today[only-year-month]} +%% \date{\TheDate{2024-01}} + +\maketitle + +\begin{abstract} + Some abstract. \blindtext +\end{abstract} + +\begin{keyword} + AAA, BBB, CCC +\end{keyword} + +\tableofcontents + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof*}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof*} + +\blinddocument + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/einfart/einfart.cls b/macros/unicodetex/latex/einfart/einfart.cls index 2146ce094d..7daea1ac7e 100644 --- a/macros/unicodetex/latex/einfart/einfart.cls +++ b/macros/unicodetex/latex/einfart/einfart.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {einfart} - {2024/02/20} {} + {2024/02/23} {} {A simple and clear article style} \tl_const:Nn \l__minimclass_base_class_tl { article } diff --git a/macros/unicodetex/latex/simplivre/README.md b/macros/unicodetex/latex/simplivre/README.md index bee36bec07..573563659a 100644 --- a/macros/unicodetex/latex/simplivre/README.md +++ b/macros/unicodetex/latex/simplivre/README.md @@ -21,6 +21,21 @@ Compared with usual document classes, it has the following features: - Support both the standard and the AMS writing fashion. - ... and much more... +## To get started + +Prepration: + +- Make sure that your TeX distribution is up-to-dated. +- Check the required fonts indicated below, and make sure that they are installed. + +Once prepared: + +- You may get started by looking at one of the [demo documents](https://github.com/Jinwen-XU/minimalist/tree/main/simplivre/demo) that suits your need and edit the code there to get your own template. + +If you run into a problem, or if you would like some elements to be changed or improved: + +- Feel free to raise an issue or post a feature request via [the GitHub issue](https://github.com/Jinwen-XU/minimalist/issues). + ## Required fonts The current document class requires the following open-source fonts that are not included in the standard TeX collection: diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.pdf Binary files differnew file mode 100644 index 0000000000..497a84ac6b --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.tex new file mode 100644 index 0000000000..cd08d686d1 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classical.tex @@ -0,0 +1,124 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = classical, + % use indent = false, + % title in boldface, + % title in scshape, + % title in sffamily, + % theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage [ style = simple ] + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the style \textquote{classical}) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\part{Basic examples} +\parttext{Some introductory text.} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.pdf Binary files differnew file mode 100644 index 0000000000..4a5675645f --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.tex new file mode 100644 index 0000000000..78578c60d4 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-classicthesis.tex @@ -0,0 +1,126 @@ +\PassOptionsToPackage{ + % drafting=true, % print version information on the bottom of the pages + tocaligned=false, % the left column of the toc will be aligned (no indentation) + dottedtoc=false, % page numbers in ToC flushed right + eulerchapternumbers=true, % use AMS Euler for chapter font (otherwise Palatino) + floatperchapter=true, % numbering per chapter for all floats (i.e., Figure 1.1) + style=arsclassica % classicthesis, arsclassica, linedheaders, plain +}{classicthesis} +\documentclass[a4paper, 11pt, + use style = classicthesis, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage [ style = fancy, color = { main = Maroon, back = Goldenrod } ] + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the style \textquote{ClassicThesis}) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\ctparttext{Some introductory text. \blindtext} +\part{Basic examples} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.pdf Binary files differnew file mode 100644 index 0000000000..cfaab378bc --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.tex new file mode 100644 index 0000000000..89fde057fa --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-default.tex @@ -0,0 +1,123 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage [ style = academic ] + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the default style) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\part{Basic examples} +\parttext{Some introductory text.} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.pdf Binary files differnew file mode 100644 index 0000000000..dbba9df779 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.tex new file mode 100644 index 0000000000..0b7ed19adb --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-flow.tex @@ -0,0 +1,124 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = flow, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage [ style = academic ] + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the style \textquote{flow}) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\part{Basic examples} +\parttext{Some introductory text.} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.pdf Binary files differnew file mode 100644 index 0000000000..67725599d5 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.tex new file mode 100644 index 0000000000..8a94bf89ec --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-plain.tex @@ -0,0 +1,124 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + % use osf, + use style = plain, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the style \textquote{plain}) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\part{Basic examples} +\parttext{Some introductory text.} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.pdf b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.pdf Binary files differnew file mode 100644 index 0000000000..38b0933ac8 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.pdf diff --git a/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.tex b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.tex new file mode 100644 index 0000000000..dcb2204696 --- /dev/null +++ b/macros/unicodetex/latex/simplivre/demo/simplivre-demo-style-stream.tex @@ -0,0 +1,124 @@ +\documentclass[a4paper, 11pt, + % use font = times, % garamond, newcm, lmodern, ... + use osf, + use style = stream, + % use indent = false, + title in boldface, + % title in scshape, + % title in sffamily, + theorem in new line, + emphasize theorems, + theorem numbering = section, + % number theorems separately, + simple name, % for clever referencing + name in link, % for clever referencing +]{simplivre} +\usepackage{ProjLib} +\usepackage[ + % lang = {french}, + type = {CC}, + modifier = {by}, + version = {4.0}, + hyperxmp = false, +]{doclicense} + +\usepackage{blindtext} + +%% \UseLanguage{French} + +\numberwithin{equation}{section} +\SwitchTheoremNumbering{example,examples,claim} + +\begin{document} + +\frontmatter + +\TitlePage [ style = academic ] + { + % , logo = { } % the logo image + , title = { \fontspec{SourceSansPro}[WordSpace={1.25,1,1}] + \addfontfeature{LetterSpace=2.0} + Title of the book\\(demo of the style \textquote{stream}) + } + , author = { Author Name } + , date = { \today[only-year-month] } + % , date = { \TheDate{2024-01} } + , info = { + This text is... \blindtext + } + , license = { \addfontfeature{Numbers=Lining} \medskip\doclicenseThis } + , license page name = { Info } + } + +\tableofcontents + +\mainmatter + +\mainmatter + +\part{Basic examples} +\parttext{Some introductory text.} + +\chapter{Chapter title} + +\section{Section title} + +\subsection{Subsection title} + +Some introductory text. + +\begin{definition}[something] + Define something. +\end{definition} + +\begin{theorem}[some result]\label{thm:result}\index{Theorem on some result} + The statement. +\end{theorem} + +\begin{emphasis} + Clever reference: \cref{thm:result} (only name: \namecref{thm:result}, only number: \labelcref{thm:result}). +\end{emphasis} + +An equation:\index{Euler's equation} +\begin{equation}\label{eq:Euler} + \mathrm{e}^{\mathrm{i}\pi} + 1 = 0. +\end{equation} + +\begin{emphasis} + Reference of equation: \eqref{eq:Euler} or \cref{eq:Euler}. +\end{emphasis} + +\SetTheorem{corollary}{shared counter = subsubsection} +\begin{corollary}[of \cref{thm:result}]\label{cor:result} + Some corollary. +\end{corollary} +\SetTheorem{corollary}{shared counter = subsection} +\begin{proof} + Some lines of proof. +\end{proof} + +\begin{examples} + \begin{enumerate} + \item First example. + \item Second example. + \item Third example. + \end{enumerate} +\end{examples} + +\begin{example*}[Important example] + The numbering is switched in the preamble, thus \verb|example*| is the numbered version while \verb|example| is the unnumbered version. +\end{example*} + +\begin{proof*}[Proof of \cref{thm:result}] + Some lines of proof. +\end{proof*} + +\part{Demonstration} + +\blinddocument + +\backmatter + +\printindex + +\end{document} diff --git a/macros/unicodetex/latex/simplivre/simplivre.cls b/macros/unicodetex/latex/simplivre/simplivre.cls index 43ed3e3f30..cfb01a533d 100644 --- a/macros/unicodetex/latex/simplivre/simplivre.cls +++ b/macros/unicodetex/latex/simplivre/simplivre.cls @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {simplivre} - {2024/02/20} {} + {2024/02/23} {} {A simple and clear book style} \tl_const:Nn \l__minimclass_base_class_tl { book } |