diff options
author | Norbert Preining <norbert@preining.info> | 2022-03-21 03:02:04 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-03-21 03:02:04 +0000 |
commit | 418f27fe2e2b233c282c7388ed4f2bf3461a958f (patch) | |
tree | d52e162eeef9ce2f96597577dec046a9ecd9bd83 /macros/luatex/latex/letgut/source | |
parent | 932716f98734dec3d6502355f5618e5895729499 (diff) |
CTAN sync 202203210302
Diffstat (limited to 'macros/luatex/latex/letgut/source')
-rw-r--r-- | macros/luatex/latex/letgut/source/HOWTO.md | 33 | ||||
-rw-r--r-- | macros/luatex/latex/letgut/source/letgut-banner.org | 804 | ||||
-rw-r--r-- | macros/luatex/latex/letgut/source/letgut.org | 3405 |
3 files changed, 4242 insertions, 0 deletions
diff --git a/macros/luatex/latex/letgut/source/HOWTO.md b/macros/luatex/latex/letgut/source/HOWTO.md new file mode 100644 index 0000000000..678ece4f0c --- /dev/null +++ b/macros/luatex/latex/letgut/source/HOWTO.md @@ -0,0 +1,33 @@ +In order to: + +- tangle the `letgut.cls` and `letgut-banner.sty` files, +- build the documentations `letgut-code.pdf` and `letgut-banner-code.pdf` of the + codes, + +from the Org Mode source files `letgut.org` and `letgut-banner.org`: + +- it is necessary a reasonably recent version of Emacs, +- it is then sufficient to run (in a directory containing the `letgut.el` file + to be found in the current directory): + - for the `letgut` class: + + emacs -Q letgut.org --batch -l letgut.el -f org-babel-tangle --kill + emacs -Q letgut.org --batch -l letgut.el -f org-latex-export-to-pdf --kill + + - for the `letgut-banner` package: + + emacs -Q letgut-banner.org --batch -l letgut.el -f org-babel-tangle --kill + emacs -Q letgut-banner.org --batch -l letgut.el -f org-latex-export-to-pdf --kill + +This creates the files `letgut.cls`, `letgut-banner.sty`, `letgut-code.tex` and +`letgut-banner-code.tex`. + +One can then build the PDF files `letgut-code.pdf` and `letgut-banner-code.pdf` +by running `latexmk` on each of the corresponding `.tex` files in a directory +containing the following files to be found in the `.../doc/lualatex/letgut` +directory: `latexmkrc`, `letgut.bib`, `letgut-code.pdf`, `letgut-code.tex`, +`letgut.pdf`, `letgut.tex`, `listings-conf.tex`, `localconf.tex`, `README.md`, +`xindex-letgut.lua`. + +Likewise, the user documentation `letgut.pdf` is built by running `latexmk` on +the corresponding `.tex` file (which doesn't derive from an Org Mode file). diff --git a/macros/luatex/latex/letgut/source/letgut-banner.org b/macros/luatex/latex/letgut/source/letgut-banner.org new file mode 100644 index 0000000000..44fa5fdec9 --- /dev/null +++ b/macros/luatex/latex/letgut/source/letgut-banner.org @@ -0,0 +1,804 @@ +# Hey, Emacs! This is a -*- mode: org -*- file! + +#+TITLE: Support for the banner of the newsletter “La Lettre de GUTenberg” +#+AUTHOR: Association GUTenberg +#+EMAIL: secretariat@gutenberg.eu.org +#+DESCRIPTION: ... +#+KEYWORDS: ... +#+LANGUAGE: en +#+OPTIONS: num:t toc:nil title:nil + +#+LATEX_COMPILER: lualatex + +#+LaTeX_CLASS: letgut +#+LaTeX_HEADER: \setmainfont{KpRoman} +#+LaTeX_HEADER: \setsansfont{KpSans} +#+LaTeX_HEADER: \setmonofont[Scale = MatchLowercase]{RobotoMono} +#+LaTeX_HEADER: \letgutsetup{editorial=false} +#+LaTeX_HEADER: \input{listings-conf} +# #+LaTeX_HEADER: \input{codehigh-conf} +# #+LaTeX_HEADER: \letgutsetup{editorial=false,final} + +#+PROPERTY: header-args :padline no :tangle letgut-banner.sty :exports both :noweb yes :eval always +#+export_file_name: letgut-banner-code + +* Readme file :noexport: + +#+begin_src markdown :tangle README.md :exports none + letgut-banner - Support for the banner of the newsletter + “La Lettre de GUTenberg” + ============================================================= + + About + ------- + This package automatically draw the banner of the newsletter “La Lettre de + GUTenberg” with the current main font. + + Release + ------- + 2022-03-18 v0.9 + + Development + ----------- + Follow development, submit issues, and suggest improvements at + https://framagit.org/gutenberg/classe-lettre-gut. +#+end_src + +* Identification + +#+begin_src latex +% This is file `letgut.cls', +% generated with the Emacs Org-babel utility. +% +% The original source file is letgut-banner.org +% +% -------------:| --------------------------------------------------- +% letgut-banner:| Package for the banner of the newsletter +% | “La Lettre GUTenberg” +% Author:| Association GUTenberg +% E-mail:| secretariat@gutenberg.eu.org +% License:| Released under the LaTeX Project Public License +% | v1.3c or later +% See:| http://www.latex-project.org/lppl.txt +% +% Copyright (C) 1994-2022 by Association GUTenberg +% <secretariat@gutenberg.eu.org> +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License (LPPL), either +% version 1.3c of this license or (at your option) any later +% version. The latest version of this license is in the file: +% +% http://www.latex-project.org/lppl.txt +% +% This work is “maintained” (as per LPPL maintenance status) +% by Association GUTenberg. +#+end_src + +* Implementation + +These document classes can only be used with \LaTeXe, so we make +sure that an appropriate message is displayed when another \TeX{} +format is used. + +#+begin_src latex +\NeedsTeXFormat{LaTeX2e}[2020-10-01] +#+end_src + +Now, we can announce the package name and its version: + +#+begin_src latex +\ProvidesExplPackage{letgut-banner} +{2022-03-18} +{0.9} +{ + Package for the banner of the newsletter “La Lettre de GUTenberg” +} +#+end_src + +** Packages loaded + +In order to provide class options, we load the \package{l3keys2e} which provides +\LaTeXe{} option processing using \LaTeX3 keys: + + #+begin_src latex +\RequirePackage{l3keys2e} + #+end_src + +Till the Lua-based color will be added to the core \package{l3color} approach, +we have to rely on \package{xcolor} + +#+begin_src latex +\RequirePackage{xcolor} +#+end_src + +We want the material added to the first page to be not selectable in order to let the +reader who wants to copy the interesting text be able to select it (see below). + +#+begin_src latex +\RequirePackage{accsupp} +#+end_src + +What follows has to be done at this end of the preamble, otherwise the font set +with ~\setmainfont~ in the preamble isn't taken in account in the banner. + +We define an option for the color of the text in the “L” (that has to be the +same as the page color of the document). + +#+begin_src latex + \keys_define:nn { letgut-banner } + { + , pagecolor .clist_gset:N = \g__letgutbanner_pagecolor_clist + , pagecolor .initial:n = { 1,1,1 } + } + \ProcessKeysOptions { letgut-banner } +#+end_src + +#+begin_src latex +\AddToHook{begindocument}{ +#+end_src + +#+begin_src latex + \cs_generate_variant:Nn \color_fill:nn { nV } +#+end_src + +** Declarations + +*** Dimensions + + #+begin_src latex + \dim_new:N \g__letgutbanner_area_height_dim + \dim_new:N \g__letgutbanner_La_height_dim + \dim_new:N \g__letgutbanner_La_depth_dim + \dim_new:N \g__letgutbanner_La_yoffset_dim + \dim_new:N \g__letgutbanner_banner_vertical_contents_width_dim + \dim_new:N \g__letgutbanner_largest_LETR_box_height_dim + \dim_new:N \g__letgutbanner_between_letters_yoffset_dim + \dim_new:N \g__letgutbanner_between_letters_vertical_space_dim + \dim_new:N \g__letgutbanner_banner_padding_dim + \dim_if_exist:NF \g__letgutbanner_first_page_shrink_dim { + \dim_new:N \g__letgutbanner_first_page_shrink_dim + } + #+end_src + +- Dimensions of the page. If the present package is used with the + \class*{letgut}, they are borrowed from it. Otherwise, they are set to default + values. For this, we first generate a variant of ~\dim_const:Nn~ (see + https://github.com/latex3/latex3/issues/947#issuecomment-860950569). + #+begin_src latex + \cs_generate_variant:Nn \dim_const:Nn { NV } + \dim_if_exist:NTF \c__letgut_textheight_dim { + \dim_const:NV \c__letgutbanner_textheight_dim + \c__letgut_textheight_dim + }{ + \dim_const:Nn \c__letgutbanner_textheight_dim + { 25cm } + } + \dim_if_exist:NTF \c__letgut_textwidth_dim { + \dim_const:NV \c__letgutbanner_textwidth_dim + \c__letgut_textwidth_dim + }{ + \dim_const:Nn \c__letgutbanner_textwidth_dim + { 14cm } + } + \dim_if_exist:NTF \c__letgut_lmargin_dim { + \dim_const:NV \c__letgutbanner_lmargin_dim + \c__letgut_lmargin_dim + }{ + \dim_const:Nn \c__letgutbanner_lmargin_dim + { 5cm } + } + \dim_if_exist:NTF \c__letgut_tmargin_dim { + \dim_const:NV \c__letgutbanner_tmargin_dim + \c__letgut_tmargin_dim + }{ + \dim_const:Nn \c__letgutbanner_tmargin_dim + { 2.92cm } + % \dim_const:Nn \c__letgutbanner_tmargin_dim + % { 3cm } + } + \dim_if_exist:NTF \c__letgut_head_dim { + \dim_const:NV \c__letgutbanner_head_dim + \c__letgut_head_dim + }{ + \dim_const:Nn \c__letgutbanner_head_dim + { 0.6cm } + } + \dim_if_exist:NTF \c__letgut_headsep_dim { + \dim_const:NV \c__letgutbanner_headsep_dim + \c__letgut_headsep_dim + }{ + \dim_const:Nn \c__letgutbanner_headsep_dim + { 0.82cm } + % \dim_const:Nn \c__letgutbanner_headsep_dim + % { 0.9cm } + } + \dim_if_exist:NTF \c__letgut_marginparwidth_dim { + \dim_const:NV \c__letgutbanner_marginparwidth_dim + \c__letgut_marginparwidth_dim + }{ + \dim_const:Nn \c__letgutbanner_marginparwidth_dim + { 3.74cm } + } + #+end_src +- Dimensions of the banner. If the present package is used with the + \class*{letgut}, they are borrowed from it. Otherwise, they are set to + default values. + - Thickness of the “L”. + #+begin_src latex + \dim_if_exist:NTF \c__letgut_banner_thickness_dim { + \dim_const:NV \c__letgutbanner_banner_thickness_dim + \c__letgut_banner_thickness_dim + }{ + \dim_const:Nn \c__letgutbanner_banner_thickness_dim + { 4cm } + } + #+end_src + - Height of the “L” (that of the text area plus 3cm). + #+begin_src latex + \dim_if_exist:NTF \c__letgut_banner_height_dim { + \dim_const:NV \c__letgutbanner_banner_height_dim + \c__letgut_banner_height_dim + }{ + \dim_const:Nn \c__letgutbanner_banner_height_dim { + \c__letgutbanner_textheight_dim + + + 3cm + } + } + #+end_src + - Initial padding of the text embedded in the vertical bar of the “L”. + #+begin_src latex + \dim_const:Nn \c__letgutbanner_banner_padding_dim { .25cm } + #+end_src + - Width of the “L” (the width ($w$) of the text zone plus the width ($l$) of + the left margin minus half the difference between the width of the left + margin and the width ($d$) of the “L”: $=w+l-(l-d)/2=w+(l+d)/2$). + #+begin_src latex + \dim_const:Nn \c__letgutbanner_banner_width_dim { + \c__letgutbanner_textwidth_dim + + + ( + \c__letgutbanner_banner_thickness_dim + + + \c__letgutbanner_lmargin_dim + )/2 + } + #+end_src + - Initial width of the text embedded in the “L” vertical bar. + #+begin_src latex + \dim_const:Nn + \c__letgutbanner_banner_vertical_contents_width_dim { + \c__letgutbanner_banner_thickness_dim + - + 2\c__letgutbanner_banner_padding_dim + } + #+end_src + - Width of the text embedded in the horizontal bar of the “L” (of the text + area plus half the difference between that of the left margin and that of + the thickness of the “L”, minus the padding -- and not 2 times the + padding because this text will be stuck to its left “margin”). + #+begin_src latex + \dim_const:Nn + \c__letgutbanner_banner_horizontal_contents_width_dim { + \c__letgutbanner_textwidth_dim + - ( + \c__letgutbanner_banner_thickness_dim + - + \c__letgutbanner_lmargin_dim + )/2 + - + \c__letgutbanner_banner_padding_dim + } + #+end_src + +*** Boxes + +New boxes, for each of the letters in the word “LETTRE” (!), and then for the +rest of the content listed in the banner. +#+begin_src latex +\box_new:N \g__letgutbanner_L_box +\box_new:N \g__letgutbanner_E_box +\box_new:N \g__letgutbanner_T_box +\box_new:N \g__letgutbanner_R_box +\box_new:N \g__letgutbanner_La_box +\box_new:N \g__letgutbanner_GUTenberg_box +\box_new:N \g__letgutbanner_largest_LETR_box +\box_new:N \g__letgutbanner_g_box +#+end_src + +*** Floating point numbers + +- Minimum percentage of the common height of the letters of the word “LETTRE” + that their line spacing must represent. +#+begin_src latex +\fp_const:Nn \c__letgutbanner_leading_minimum_percent_fp { 0.15 } +#+end_src +- Factor applied to the line spacing between “La” and the 1st letter of + “LETTRE” compared to that between the letters of “LETTRE”. +#+begin_src latex +\fp_const:Nn \c__letgutbanner_leading_La_factor_fp { 1.5 } +#+end_src + +** Application des dimensions de la page + +#+begin_src latex + \geometry{ + asymmetric, + textheight = \c__letgutbanner_textheight_dim, + textwidth = \c__letgutbanner_textwidth_dim, + lmargin = \c__letgutbanner_lmargin_dim, + tmargin = \c__letgutbanner_tmargin_dim, + head = \c__letgutbanner_head_dim, + headsep = \c__letgutbanner_headsep_dim, + marginparwidth= \c__letgutbanner_marginparwidth_dim, + % showframe, + % verbose, + } +#+end_src + +** Filling of the boxes +#+begin_src latex + \hbox_gset:Nn \g__letgutbanner_L_box { \textbf{L} } + \hbox_gset:Nn \g__letgutbanner_E_box { \textbf{E} } + \hbox_gset:Nn \g__letgutbanner_T_box { \textbf{T} } + \hbox_gset:Nn \g__letgutbanner_R_box { \textbf{R} } + \hbox_gset:Nn \g__letgutbanner_La_box { \textbf{\textit{La}} } + \hbox_gset:Nn \g__letgutbanner_GUTenberg_box { + \textbf{\textit{GUTenberg}} + } + \hbox_gset:Nn \g__letgutbanner_g_box { \textbf{g} } +#+end_src + +** Computations + +Determination of the widths of each of the letter boxes of the word “LETTRE”. +#+begin_src latex + \dim_const:Nn \c__letgutbanner_L_width_dim { + \box_wd:N \g__letgutbanner_L_box + } + \dim_const:Nn \c__letgutbanner_E_width_dim { + \box_wd:N \g__letgutbanner_E_box + } + \dim_const:Nn \c__letgutbanner_T_width_dim { + \box_wd:N \g__letgutbanner_T_box + } + \dim_const:Nn \c__letgutbanner_R_width_dim { + \box_wd:N \g__letgutbanner_R_box + } +#+end_src +Determination of the largest of these widths, stored in the scratch dimension +~\g_tmpa_dim~. +#+begin_src latex +\dim_gset:Nn \g_tmpa_dim { + \fp_eval:n { + max ( + \c__letgutbanner_L_width_dim, + \c__letgutbanner_E_width_dim, + \c__letgutbanner_T_width_dim, + \c__letgutbanner_R_width_dim, + ) + }pt +} +#+end_src +Determination of the (1st) box whose width is the largest of all (~argmax~, as +it were). +#+begin_src latex +\box_gset_eq:NN \g__letgutbanner_largest_LETR_box \dim_case:nnF +{ \g_tmpa_dim } +{ + { \c__letgutbanner_L_width_dim } { \g__letgutbanner_L_box } + { \c__letgutbanner_E_width_dim } { \g__letgutbanner_E_box } + { \c__letgutbanner_T_width_dim } { \g__letgutbanner_T_box } + { \c__letgutbanner_R_width_dim } { \g__letgutbanner_R_box } +} +{ No~ idea! } +#+end_src +Resize the box containing “GUTenberg” to the width of the text embedded in the +horizontal bar of the “L”. +#+begin_src latex + \box_gresize_to_wd:Nn \g__letgutbanner_GUTenberg_box { + \c__letgutbanner_banner_horizontal_contents_width_dim + } +#+end_src +Determination of the height and depth of the box containing “GUTenberg” resized. +#+begin_src latex + \dim_const:Nn \c__letgutbanner_GUTenberg_height_dim { + \box_ht:N \g__letgutbanner_GUTenberg_box + } + \dim_const:Nn \c__letgutbanner_GUTenberg_depth_dim { + \box_dp:N \g__letgutbanner_GUTenberg_box + } +#+end_src +Determining the size of the vertical offset of the box containing the resized +“GUTenberg”, so that it is vertically centered in the horizontal bar of the “L”: +the box positioned in $0$ would be at the very bottom of the box containing the +banner so with base line at the bottom the horizontal bar of the “L” so we raise +it first by its depth ($d$) and then by half the difference between the heights +($H$) of the horizontal bar of the “L” and ($h+d$) total of the box containing +“GUTenberg” resized ($=d+H/2-(h+d)/2=(H-h+d)/2$). +#+begin_src latex + \dim_const:Nn \c__letgutbanner_GUTenberg_yoffset_dim { + ( + \c__letgutbanner_banner_thickness_dim + - + \c__letgutbanner_GUTenberg_height_dim + + + \c__letgutbanner_GUTenberg_depth_dim + )/2 + } +#+end_src +Once the height of the zone devoted to “La LETTRE” in the vertical bar of the +“L” has been fixed, the line spacing between the letters of the word “LETTRE” +depends in fact only on the width occupied by the widest of them, by definition +equal to the width allocated to the text embedded in the vertical bar of the +“L”. The latter, stored in ~\g__letgutbanner_banner_vertical_contents_width_dim~, is +initially fixed: +#+begin_src latex + \dim_gset:Nn + \g__letgutbanner_banner_vertical_contents_width_dim + \c__letgutbanner_banner_vertical_contents_width_dim +#+end_src +but, to avoid this line spacing being too small (or even negative), we test that +it is greater than a certain threshold, equal to a certain minimum percentage of +the height common to the letters of the word “LETTRE”, stored in: + +~\c__letgutbanner_leading_minimum_percent_fp~ + +and fixed at 0.15. If this is not the +case, we reduce (by 1pt): + +~\g__letgutbanner_banner_vertical_contents_width_dim~ + +and loop until it is the case. +#+begin_src latex + \dim_do_until:nNnn { + \g__letgutbanner_between_letters_vertical_space_dim + } + > + { + \fp_use:N\c__letgutbanner_leading_minimum_percent_fp + \g__letgutbanner_largest_LETR_box_height_dim + }{ +#+end_src +Resize the largest of these boxes to the width of the text embedded in the “L”. +#+begin_src latex + \box_gresize_to_wd:Nn \g__letgutbanner_largest_LETR_box { + \g__letgutbanner_banner_vertical_contents_width_dim + } +#+end_src +Height of this resized larger box. +#+begin_src latex + \dim_gset:Nn \g__letgutbanner_largest_LETR_box_height_dim { + \box_ht:N \g__letgutbanner_largest_LETR_box + } +#+end_src +Resize the boxes for each of the letters in the word “LETTRE” so that they are +all the same height as the widest of them. +#+begin_src latex + \box_gresize_to_ht:Nn \g__letgutbanner_L_box { + \g__letgutbanner_largest_LETR_box_height_dim + } + \box_gresize_to_ht:Nn \g__letgutbanner_E_box { + \g__letgutbanner_largest_LETR_box_height_dim + } + \box_gresize_to_ht:Nn \g__letgutbanner_T_box { + \g__letgutbanner_largest_LETR_box_height_dim + } + \box_gresize_to_ht:Nn \g__letgutbanner_R_box { + \g__letgutbanner_largest_LETR_box_height_dim + } +#+end_src +Resize the box containing “La” to the width of the text embedded in the “L” +vertical bar. +#+begin_src latex + \box_gresize_to_wd:Nn \g__letgutbanner_La_box { + \g__letgutbanner_banner_vertical_contents_width_dim + } +#+end_src +Determine the height ($h$) and depth ($d$) of the resized box containing “La”. +#+begin_src latex + \dim_gset:Nn \g__letgutbanner_La_height_dim { + \box_ht:N \g__letgutbanner_La_box + } + \dim_gset:Nn \g__letgutbanner_La_depth_dim { + \box_dp:N \g__letgutbanner_La_box + } +#+end_src +Determining the size of the vertical offset of the resized box containing “La” +so that its top is, relative to the top of the “L”, offset by the same amount as +the bottom of the box containing “GUTenberg” is offset from the bottom of the +“L” (i.e., the distance from the top of the page to the top of “La” and the +distance from the bottom of the page to the baseline of “GUTenberg” are +identical). +#+begin_src latex + \dim_gset:Nn \g__letgutbanner_La_yoffset_dim { + \c__letgutbanner_banner_height_dim + - + \c__letgutbanner_GUTenberg_yoffset_dim + - + \g__letgutbanner_La_height_dim + + + \g__letgutbanner_La_depth_dim + } +#+end_src +For the following, the area containing the letters of the word “LETTRE” aligned +vertically is fixed, defined as follows: + - its top is the baseline of “La”, + - its bottom is the baseline of “GUTenberg”. +Determination of the height of this area. +#+begin_src latex + \dim_gset:Nn \g__letgutbanner_area_height_dim { + \g__letgutbanner_La_yoffset_dim + - + \g__letgutbanner_La_depth_dim + - + \c__letgutbanner_GUTenberg_yoffset_dim + } +#+end_src +Determining the vertical jump ($s$) between the letters in the word “LETTRE” +with the constraints that: + - the top of the 1st letter (“L”) is $3e/2$ below the top of the area (where + $e$ is the common vertical space separating the letters of the word + “LETTRE”), + - the baseline of the last letter (“E”) is merged with the bottom of the area, + - this jump must not be less than 20 % of the common height $h$ to all these + letters i.e.: + + ~\g__letgutbanner_largest_LETR_box_height_dim~ + + otherwise the size of the largest of these boxes is reduced to less than the + width of the text embedded in the “L”. + +The sum of : + - the 5 vertical spaces ($5e$) between the letters in the word “LETTRE”, + - the 6 common heights ($6h$) to all these letters, + - $3e/2$, +must equal the height ($H$) of the zone. So we have $H=3e/2+5e+6h$, that is +$e=2(H-6h)/13$. Once initialized, the vertical jump between the letters is +$s=e+h$ that is $s=(2H+h)/13$. Therefore: + +1. Determine the vertical half-space between the letters. + #+begin_src latex + \dim_set:Nn \l_tmpa_dim { + ( + \g__letgutbanner_area_height_dim + - + 6\g__letgutbanner_largest_LETR_box_height_dim + )/13 + } + #+end_src +2. Vertical space between letters. + #+begin_src latex + \dim_gset:Nn \g__letgutbanner_between_letters_vertical_space_dim { + 2\l_tmpa_dim + } + #+end_src +3. If this space does not check the condition explained above, we reduce: + + ~\g__letgutbanner_banner_vertical_contents_width_dim~ + + and loop. + #+begin_src latex + \dim_gsub:Nn \g__letgutbanner_banner_vertical_contents_width_dim { + 1pt + } + } + #+end_src +The width allocated to the text embedded in the vertical bar of the “L” may have +been re-evaluated, so the padding (which must be symmetrical) may have changed +as well. + #+begin_src latex + \dim_gset:Nn \g__letgutbanner_banner_padding_dim { + ( + \c__letgutbanner_banner_thickness_dim + - + \g__letgutbanner_banner_vertical_contents_width_dim + )/2 + } + #+end_src +4. Determination of the vertical offset of the 1st letter (“L”). + #+begin_src latex + \dim_const:Nn \c__letgutbanner_first_letter_yoffset_dim { + \g__letgutbanner_La_yoffset_dim + - + \g__letgutbanner_largest_LETR_box_height_dim + - + \fp_use:N \c__letgutbanner_leading_La_factor_fp + \g__letgutbanner_between_letters_vertical_space_dim + } + #+end_src +5. Determination of the vertical jump between letters. + #+begin_src latex + \dim_gset:Nn \g__letgutbanner_between_letters_yoffset_dim { + \g__letgutbanner_between_letters_vertical_space_dim + + + \g__letgutbanner_largest_LETR_box_height_dim + } + #+end_src +Resize the box containing “g” to the width of the text. +#+begin_src latex + \box_gresize_to_wd:Nn \g__letgutbanner_g_box { + \c__letgutbanner_textwidth_dim + } +#+end_src +Calculates the size by which the height of the text box on the 1st page must be +reduced so that the banner does not encroach on the text. Relative to the top of +the page: + - the top of the horizontal bar of “L” is at a distance equal to the sum of : + - the distance between this top of page and the top of the vertical bar of + “L”, equal to the height ($p$) of the paper minus the height ($l$) of “L” +#+begin_src latex + \dim_gset:Nn \g__letgutbanner_first_page_shrink_dim { + \c__letgutbanner_tmargin_dim + + + \c__letgutbanner_textheight_dim + + + \c__letgutbanner_banner_thickness_dim + - + .5\paperheight + - + .5\c__letgutbanner_banner_height_dim + + + .5\baselineskip + } +#+end_src +Automatic addition on the 1st page (only) of the banner. +#+begin_src latex +\AddToHookNext{shipout/background}{ +#+end_src +We want the material added to this page to be not selectable in order to let the +reader who wants to copy the interesting text be able to select it. +#+begin_src latex + \BeginAccSupp{ActualText={}} +#+end_src +We put now the big “L” at the right place. +#+begin_src latex + \put( + .5\c__letgutbanner_lmargin_dim-.5\c__letgutbanner_banner_thickness_dim + , + -.5\paperheight-.5\c__letgutbanner_banner_height_dim + ){ + \put(0,0){ + \rule{ + \c__letgutbanner_banner_width_dim + }{ + \c__letgutbanner_banner_thickness_dim + } + } + \put(0,0){ + \rule{ + \c__letgutbanner_banner_thickness_dim + }{ + \c__letgutbanner_banner_height_dim + } + } + #+end_src +The color should not be systematically white, but should be identical to the one +chosen for the page background. +#+begin_src latex + % \color_fill:nV {rgb}{ \g__letgutbanner_pagecolor_clist } + \color[rgb]{ \g__letgutbanner_pagecolor_clist } + \put( + \g__letgutbanner_banner_padding_dim + , + \g__letgutbanner_La_yoffset_dim + ){ + \box_use:N \g__letgutbanner_La_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -0\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_L_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -1\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_E_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -2\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_T_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -3\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_T_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -4\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_R_box + } + \put( + \g__letgutbanner_banner_padding_dim + , + \c__letgutbanner_first_letter_yoffset_dim + -5\g__letgutbanner_between_letters_yoffset_dim + ){ + \box_use:N \g__letgutbanner_E_box + } + \put( + \c__letgutbanner_banner_thickness_dim + , + \c__letgutbanner_GUTenberg_yoffset_dim + ){ + \box_use:N \g__letgutbanner_GUTenberg_box + } + % \color_fill:n {black!10} + \color{ black!10 } + \put( + .5\c__letgutbanner_lmargin_dim+.5\c__letgutbanner_banner_thickness_dim + , + .5\paperheight + + + .5\c__letgutbanner_banner_height_dim + - + \c__letgutbanner_tmargin_dim + ){ + \box_move_down:nn {.5\c__letgutbanner_textheight_dim} + {\box_use:N \g__letgutbanner_g_box} + } +} + #+end_src + We end the part which isn't selectable. + #+begin_src latex + \EndAccSupp{} + } +#+end_src + +We close ~\AddToHook{begindocument}~. + +#+begin_src latex +} +#+end_src + +If the package is used with another class than \class{letgut}, we reduce the +textheight of the first page of the height of the horizontal bar of the “L”. + +#+begin_src latex +\@ifclassloaded{letgut}{ +}{ + \AddToHook{begindocument/end}{% + \enlargethispage{ + - \g__letgutbanner_first_page_shrink_dim + } + \thispagestyle{empty} + } +} +#+end_src + +* Example file (=letgut-banner-example.tex=) + +#+begin_src latex :tangle letgut-banner-example.tex :exports both + \documentclass[twoside]{article} + \usepackage{fontspec} + \usepackage[a4paper]{geometry} + \usepackage{fancyhdr} + \usepackage{letgut-banner} + \usepackage{lipsum} + \setmainfont{TeX Gyre Schola} + \fancyhf{} + \fancyhead[RO,LE]{\thepage} + \fancyhead[RE,LO]{Test~\textsf{letgut-banner}} + \pagestyle{fancy} + \begin{document} + \lipsum[1-20] + \end{document} +#+end_src diff --git a/macros/luatex/latex/letgut/source/letgut.org b/macros/luatex/latex/letgut/source/letgut.org new file mode 100644 index 0000000000..11bd545dec --- /dev/null +++ b/macros/luatex/latex/letgut/source/letgut.org @@ -0,0 +1,3405 @@ +# Hey, Emacs! This is a -*- mode: org -*- file! + +#+TITLE: Support for the newsletter “La Lettre GUTenberg” +#+AUTHOR: Association GUTenberg +#+EMAIL: secretariat@gutenberg.eu.org +#+DESCRIPTION: ... +#+KEYWORDS: ... +#+LANGUAGE: en +#+OPTIONS: num:t toc:nil title:nil + +#+LATEX_COMPILER: lualatex + +#+LaTeX_CLASS: letgut +#+LaTeX_HEADER: \setmainfont{KpRoman} +#+LaTeX_HEADER: \setsansfont{KpSans} +#+LaTeX_HEADER: \setmonofont[Scale = MatchLowercase]{RobotoMono} +#+LaTeX_HEADER: \letgutsetup{editorial=false} +#+LaTeX_HEADER: \input{listings-conf} +# #+LaTeX_HEADER: \input{codehigh-conf} +# #+LaTeX_HEADER: \letgutsetup{editorial=false,final} + +#+PROPERTY: header-args :padline no :tangle letgut.cls :exports both :noweb yes :eval always +#+export_file_name: letgut-code + +* Changelog file :noexport: + +#+begin_src markdown :tangle CHANGELOG.md +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic +Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.9] - 2022-03-18 + +### Added First public testing release +#+end_src + +* Readme file :noexport: + +#+begin_src markdown :tangle README.md +letgut - Support for the newsletter “La Lettre GUTenberg” +========================================================= + +About +------- +This bundle includes a LaTeX class, a `.sty` file and an acronym file dedicated +to the newsletter “La Lettre GUTenberg” of GUTenberg, the French TeX User Group. + +Release +------- +2022-03-18 v0.9 + +Development +----------- +Follow development, submit issues and suggest improvements at +https://framagit.org/gutenberg/classe-lettre-gut. +#+end_src + +* How to :noexport: + +We explain in a \file*{HOWTO.md} file how to: + +- tangle the \file*{letgut.cls} and \file*{letgut-banner.sty}, +- build the: + - documented codes \file*{letgut-code.pdf} and \file*{letgut-banner-code.pdf} + of the classe and the package, + - \file*{letgut.pdf} of the class + +from the \software[https://orgmode.org/]{Org Mode} source files +\file*{letgut.org} and \file*{letgut-banner.org}. + +#+begin_src markdown :tangle HOWTO.md :exports none +In order to: + +- tangle the `letgut.cls` and `letgut-banner.sty` files, +- build the documentations `letgut-code.pdf` and `letgut-banner-code.pdf` of the + codes, + +from the Org Mode source files `letgut.org` and `letgut-banner.org`: + +- it is necessary a reasonably recent version of Emacs, +- it is then sufficient to run (in a directory containing the `letgut.el` file + to be found in the current directory): + - for the `letgut` class: + + emacs -Q letgut.org --batch -l letgut.el -f org-babel-tangle --kill + emacs -Q letgut.org --batch -l letgut.el -f org-latex-export-to-pdf --kill + + - for the `letgut-banner` package: + + emacs -Q letgut-banner.org --batch -l letgut.el -f org-babel-tangle --kill + emacs -Q letgut-banner.org --batch -l letgut.el -f org-latex-export-to-pdf --kill + +This creates the files `letgut.cls`, `letgut-banner.sty`, `letgut-code.tex` and +`letgut-banner-code.tex`. + +One can then build the PDF files `letgut-code.pdf` and `letgut-banner-code.pdf` +by running `latexmk` on each of the corresponding `.tex` files in a directory +containing the following files to be found in the `.../doc/lualatex/letgut` +directory: `latexmkrc`, `letgut.bib`, `letgut-code.pdf`, `letgut-code.tex`, +`letgut.pdf`, `letgut.tex`, `listings-conf.tex`, `localconf.tex`, `README.md`, +`xindex-letgut.lua`. + +Likewise, the user documentation `letgut.pdf` is built by running `latexmk` on +the corresponding `.tex` file (which doesn't derive from an Org Mode file). +#+end_src + +* Identification + +#+begin_src latex +% This is file `letgut.cls', +% generated with the Emacs Org-babel utility. +% +% The original source file is letgut.org +% +% -------:| ---------------------------------------------------- +% letgut:| Class for the newsletter “La Lettre GUTenberg” +% Author:| Association GUTenberg +% E-mail:| secretariat@gutenberg.eu.org +% License:| Released under the LaTeX Project Public License +% | v1.3c or later +% See:| http://www.latex-project.org/lppl.txt +% +% Copyright (C) 1994-2022 by Association GUTenberg +% <secretariat@gutenberg.eu.org> +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License (LPPL), either +% version 1.3c of this license or (at your option) any later +% version. The latest version of this license is in the file: +% +% http://www.latex-project.org/lppl.txt +% +% This work is “maintained” (as per LPPL maintenance status) +% by Association GUTenberg. +% +#+end_src + +* Debugging + +#+begin_src latex +% \RequirePackage[ +% , check-declarations +% , enable-debug +% , backend=luatex +% ]{expl3} +#+end_src + +* Implementation + +These document classes can only be used with \LaTeXe, so we make +sure that an appropriate message is displayed when another \TeX{} +format is used. + +#+begin_src latex +\NeedsTeXFormat{LaTeX2e}[2020-10-01] +#+end_src + +We define some constant token lists immediately useful. + +#+begin_src latex + \ExplSyntaxOn + \tl_const:Nn \c__letgut_Lettre_tl { \emph{ Lettre } } + \tl_const:Nn \c__letgut_gutenberg_tl { GUTenberg } + \tl_const:Nn \c__letgut_Lettre_gutenberg_tl { + \c__letgut_Lettre_tl~\c_space_tl \c__letgut_gutenberg_tl + } + \tl_const:Nn \c__letgut_la_lettre_gutenberg_tl { + la~ \c__letgut_Lettre_gutenberg_tl + } + \tl_const:Nn \c__letgut_La_lettre_gutenberg_tl { + \text_titlecase_first:n \c__letgut_la_lettre_gutenberg_tl + } + \ExplSyntaxOff +#+end_src + +Now, we can announce the class name and its version: + +#+begin_src latex + \ProvidesExplClass{letgut} + {2022-03-18} + {0.9} + { + Class~ for~ the~ newsletter~ + “\c__letgut_La_lettre_gutenberg_tl” + } +#+end_src + +** Messages + +We specify the messages come from a class, which is letgut (see +\url{https://github.com/latex3/latex3/issues/887}). + +#+begin_src latex + \prop_gput:Nnn \g_msg_module_type_prop { letgut } { Class } +#+end_src + +Some messages are declared for future use. + +#+begin_src latex + \msg_new:nnn{letgut}{Wrong~engine}{ + The~ letgut~ class~ requires~ LuaTeX.\\\\ + You~ must~ change~ your~ typesetting~ engine~ to~ + “lualatex”~ instead~ of~ “latex”~ or~ “pdflatex” + or~ “xelatex”. + } + \msg_new:nnn{letgut}{Existing~command}{ + The~ command~ \c_backslash_str \text_lowercase:n{#1}~ + already~ exists~ and~ has~ not~ be~ overwritten~ by~ + \token_to_str:N \letgutacro{#1}{...}.~ + The~ corresponding~ acronym~ has~ to~ be~ used~ e.g.~ + like~ this:~ + \token_to_str:N \ac{ \text_lowercase:n{#1} }. + } + \msg_new:nnn{letgut}{Not~month~iso~date}{ + The~ supplied~ date~(“#1”)~ isn't~ at~ the~ month~ iso~ + date~ format~ (YYYY-MM):~ it~ will~ be~ printed~ as~ + it~ is. + } + \msg_new:nnn{letgut}{Banner~file~not~provided}{ + No~ `\c__letgut_banner_file_tl.pdf'~ file~ provided:~ + the~ banner~ will~ be~ automatically~ created. + } + \msg_new:nnn{letgut}{Editorial~file~missing}{ + File~`\c__letgut_editorial_file_tl.tex'~missing!~ + The~ editorial~ will~ be~ missing. + } + \msg_new:nnn{letgut}{Informations~file~missing}{ + File~ `\c__letgut_informations_gutenberg_file_tl.tex'~ + missing!~ The~ informations~ about~ + \c__letgut_gutenberg_tl\c_space_tl~ will~ be~ missing. + } + \msg_new:nnn{letgut}{pagecolor~inoperative~with~paper~option}{ + The~ `pagecolor=#1`~ option~ is~ inoperative~ with~ the~ `paper`~ + option:~ the~ color~ of~ the~ page~ will~ remain~ white. + } + \msg_new:nnn{letgut}{frontcover-missing}{ + You~ didn't~ use~ the~ `frontcover`~ option~ for~ the~ + bookreview~ “#1”,~ so~ the~ book~ cover~image~ will~ be~ missing:~ + are~ you~ sure? + } + \msg_new:nnn{letgut}{frontcover-file-not-found}{ + The~ book~ cover~ image~ `#2`~ you~ specified~ via~ the~ + `frontcover`~ option~ for~ the~ bookreview~ “#1”~ cannot~ be~ found. + } +#+end_src + +** Engine checking + +#+begin_src latex + \sys_if_engine_luatex:F { + \msg_fatal:nn{letgut}{Wrong~engine} + } +#+end_src + +** Declarations + +*** Booleans + +- For testing the emptyness of the title. + #+begin_src latex + \bool_new:N \g__letgut_title_empty_bool + #+end_src +- For the paper (or not) output. + #+begin_src latex + \bool_new:N \g__letgut_paper_bool + #+end_src +- For testing whether we currently are in a footnote or not. + #+begin_src latex + \bool_new:N \l__letgut_in_footnote_bool + #+end_src + +*** Dimensions + +- Geometry of the document + #+begin_src latex + \dim_const:Nn \c__letgut_textheight_dim { 25cm } + \dim_const:Nn \c__letgut_textwidth_dim { 14cm } + \dim_const:Nn \c__letgut_lmargin_dim { 5cm } + \dim_const:Nn \c__letgut_tmargin_dim { 2.92cm } + % \dim_const:Nn \c__letgut_tmargin_dim { 3cm } + \dim_const:Nn \c__letgut_head_dim { 0.6cm } + \dim_const:Nn \c__letgut_headsep_dim { 0.82cm } + % \dim_const:Nn \c__letgut_headsep_dim { 0.9cm } + \dim_const:Nn \c__letgut_marginparwidth_dim { 3.74cm } + #+end_src +- Horizontal offset of the headers and the sections titles: + #+begin_src latex + \dim_const:Nn \c__letgut_hoffset_dim { 3cm } + \dim_const:Nn \c__letgut_title_hoffset_dim { + -\c__letgut_hoffset_dim + } + \dim_const:Nn \c__letgut_subtitle_hoffset_dim { + \c__letgut_title_hoffset_dim + } + \dim_const:Nn \c__letgut_section_hoffset_dim { + \c__letgut_title_hoffset_dim + 1cm + } + \dim_const:Nn \c__letgut_subsection_hoffset_dim { + \c__letgut_title_hoffset_dim + 1.5cm + } + \dim_const:Nn \c__letgut_subsubsection_hoffset_dim { + \c__letgut_title_hoffset_dim + 2cm + } + \dim_const:Nn \c__letgut_paragraph_hoffset_dim { + \c__letgut_title_hoffset_dim + 2.5cm + } + \dim_const:Nn \c__letgut_subparagraph_hoffset_dim { + \c__letgut_title_hoffset_dim + 3cm + } + #+end_src +- Distance between the baseline of the header text and the decorative line: + #+begin_src latex + \dim_const:Nn \c__letgut_head_rule_skip_dim { 0.115cm } + #+end_src +- Head rule width: + #+begin_src latex + \dim_const:Nn \c__letgut_head_rule_width_dim { 0.03cm } + #+end_src +- Dimensions of the banner. + - Thickness of the “L”. + #+begin_src latex + \dim_const:Nn \c__letgut_banner_thickness_dim { 4cm } + #+end_src + - Height of the “L” (that of the text area plus 3cm). + #+begin_src latex + \dim_const:Nn \c__letgut_banner_height_dim { + \c__letgut_textheight_dim + + + 3cm + } + #+end_src +- Height of the membership reminder box. + #+begin_src latex + \dim_new:N \g__letgut_membership_reminder_box_height_dim + #+end_src +- Horizontal space for the frontcover in the margin in book reviews. + #+begin_src latex + \dim_const:Nn \c__letgut_bookreview_frontcover_margin_sep_dim { + 4mm + } + #+end_src +- Dimensions used by the listings and the examples. +#+begin_src latex + \dim_const:Nn \c__letgut_height_mentions_dim { 5mm } + \dim_const:Nn \c__letgut_from_left_boundingbox_to_text_dim { 5.5mm } + \dim_const:Nn \c__letgut_number_offset_dim { 1mm } + \dim_const:Nn \c__letgut_number_sep_dim { + \c__letgut_from_left_boundingbox_to_text_dim + + + \c__letgut_number_offset_dim + } +#+end_src + +*** Skips (lengths with rubber components) + + The following skips, borrowed from the standard classes, are specified in + ~ex~ unit, which depends on the font used and hence have to be specified + after the class has been loaded; in fact, we postpone this at the end of the + preamble, when the font is specified (thanks to ~\setmainfont~). + +#+begin_src latex + \AddToHook{begindocument/before}{% +#+end_src + +Before and after: + + - “titles titles”: + #+begin_src latex + \skip_const:Nn \c__letgut_before_title_title_skip + { + 3.5ex plus 1ex minus .2ex + } + \skip_const:Nn \c__letgut_after_title_title_skip + { + 2.3ex plus .2ex + } + #+end_src + - subtitles titles: + #+begin_src latex + \skip_const:Nn \c__letgut_before_subtitle_title_skip + { + \c__letgut_before_title_title_skip + } + \skip_const:Nn \c__letgut_after_subtitle_title_skip + { + \c__letgut_after_title_title_skip + } + #+end_src + - sections titles: + #+begin_src latex + \skip_const:Nn \c__letgut_before_section_title_skip + { + 3.25ex plus 1ex minus .2ex + } + \skip_const:Nn \c__letgut_after_section_title_skip + { + 1.5ex plus .2ex + } + #+end_src + - subsections titles (identical to the sections ones): + #+begin_src latex + \skip_const:Nn \c__letgut_before_subsection_title_skip + { + \c__letgut_before_section_title_skip + } + \skip_const:Nn \c__letgut_after_subsection_title_skip + { + \c__letgut_after_section_title_skip + } + #+end_src + - paragraphs titles: + #+begin_src latex + \skip_const:Nn \c__letgut_before_subsubsection_title_skip + { + 1.5ex plus .5ex minus .2ex + } + \skip_const:Nn \c__letgut_after_subsubsection_title_skip + { + 0.75ex plus 0.1ex + } + #+end_src + - paragraphs titles (identical to the subsubsection ones): + #+begin_src latex + \skip_const:Nn \c__letgut_before_paragraph_title_skip + { + \c__letgut_before_subsubsection_title_skip + } + \skip_const:Nn \c__letgut_after_paragraph_title_skip + { + \c__letgut_after_subsubsection_title_skip + } + #+end_src + - subparagraphs titles (identical to the paragraph ones): + #+begin_src latex + \skip_const:Nn \c__letgut_before_subparagraph_title_skip + { + \c__letgut_before_paragraph_title_skip + } + \skip_const:Nn \c__letgut_after_subparagraph_title_skip + { + \c__letgut_after_paragraph_title_skip + } + #+end_src + +We close the ~\AddToHook{begindocument/before}~ argument. + +#+begin_src latex +} +#+end_src + + +*** Integers + #+begin_src latex +\int_new:N \g__letgut_ltx_example_int + #+end_src + +*** Strings + + #+begin_src latex +\str_new:N \g__letgut_label_ltx_example_str +\str_new:N \g__letgut_callout_label_ltx_example_str +\str_const:Nn \c__letgut_label_ltx_example_str { + __letgut_label_ltx_example +} +\str_const:Nn \c__letgut_callout_label_ltx_example_str { + __letgut_callout_label_ltx_example +} + #+end_src + +*** Token lists + +**** Constant ones + + #+begin_src latex + \tl_const:Nn \c__letgut_cahier_tl { \emph{ Cahier } } + \tl_const:Nn \c__letgut_cahiers_tl { + \c__letgut_cahier_tl \emph{ s } + } + \tl_const:Nn \c__letgut_tugboat_tl { \emph{ TUGboat } } + \tl_const:Nn \c__letgut_banner_file_tl { bandeau } + \tl_const:Nn \c__letgut_editorial_file_tl { editorial } + \tl_const:Nn \c__letgut_informations_gutenberg_file_tl { + informations-gut + } + \tl_const:Nn \c__letgut_acronyms_file_tl { letgut-acronyms } + \tl_const:Nn \c__letgut_local_config_file_tl { localconf } + \tl_const:Nn \c__letgut_contents_name_tl { Sommaire } + \tl_const:Nn \c__letgut_draftwatermark_text_tl { + \textnormal{Brouillon} + } + \tl_const:Nn \c__letgut_membership_reminder_tl { + {\LARGE + \bfseries + Avez-vous~ pensé~ à~ régler~ votre~ cotisation~ ? + % \the\year~ ? + \par + \medskip + } + Si~ vous~ avez~ oublié,~ ce~ n'est~ ni~ trop~ tard~ + ni~ difficile~ : + \par + \url{http://gutenberg.eu.org/?Adherer-en-ligne} + \bool_if:NT \g__letgut_informations_bool { + \file_if_exist:nT + {./\c__letgut_informations_gutenberg_file_tl}{ + \par + Voir~ aussi~ page~ \pageref{letgut_label_adhesions}. + } + } + } + \tl_const:Nn \c__letgut_missing_editorial_tl { + Ne~ pas~ omettre~ l'éditorial~ !\\(à~ faire~ figurer~ + dans~ un~ \file*{\c__letgut_editorial_file_tl.tex}~ + dans~ le~ dossier~ courant) + } + \tl_const:Nn \c__letgut_missing_infomations_tl { + Ne~ pas~ omettre~ les~ informations~ sur~ + \c__letgut_gutenberg_tl{}~ !\\(dans~ un~ + \file*{\c__letgut_informations_gutenberg_file_tl.tex}~ + situé~ dans~ le~ dossier~ courant) + } + \tl_const:Nn \c__letgut_default_alert_box_color_tl { + gray9 + } + \tl_const:Nn \c__letgut_default_allcolors_links_color_tl + { + teal!60!black + } + #+end_src + +**** Variables ones + + #+begin_src latex + \tl_new:N \g__letgut_mark_tl + \tl_new:N \g__letgut_title_tl + \tl_new:N \l_letgut_last_name_tl + \tl_new:N \l_letgut_first_name_tl + \tl_new:N \l_letgut_title_tl + \tl_new:N \l__letgut_title_addon_tl + \tl_new:N \l__letgut_reference_text_tl + #+end_src + +*** Comma separated lists + +#+begin_src latex + \clist_new:N \g__letgut_pagecolor_clist + \clist_const:Nn \c__letgut_default_pagecolor_screen_clist + {1.0, 0.98, 0.94} + \clist_const:Nn \c__letgut_default_pagecolor_paper_clist + {1, 1, 1} +#+end_src + +*** Sequences + +#+begin_src latex + \seq_new:N \l__letgut_first_last_names_items_seq +#+end_src + +** Class options + +In order to provide class options, we load the \package{l3keys2e} which provides +\LaTeXe{} option processing using \LaTeX3 keys: + + #+begin_src latex + \RequirePackage{l3keys2e} + #+end_src + +We define the 2 load time options for the target audience: + +- ~for-readers~ (the default), for the “normal” “Lettre”, +- ~for-authors~, (only) the author(s) of an article of the “Lettre”. + +#+begin_src latex + \keys_define:nn { letgut } + { + , for-readers .bool_gset:N = \g__letgut_for_readers_bool + , for-readers .initial:n = { true } + , for-readers .default:n = { true } + , for-authors .bool_gset_inverse:N = \g__letgut_for_readers_bool + } + \ProcessKeysOptions { letgut } +#+end_src + +** Class and package loading + +The \letgutcls{} is based on the ~article~ class. It is by default two sided +because of the alternating headers, and will by typeset with ~11pt~ as global +font size. + +#+begin_src latex + \LoadClass[twoside,11pt]{article} +#+end_src + +We now load some packages. + +- The \letgutcls{} will have to be used with LuaLaTeX. Hence the font selection + package for XeLaTeX and LuaLaTeX. + #+begin_src latex + \RequirePackage{fontspec} + #+end_src +- For subliminal refinements towards typographical perfection. + #+begin_src latex + \RequirePackage[ + , stretch=30 + , shrink=25 + , letterspace=150 + ]{microtype} + #+end_src +- Help in implementing paragraph layouts where the paragraphs are separated by + a vertical space instead of (or in addition to) indenting them. + #+begin_src latex + \RequirePackage{parskip} + #+end_src +- Extensive control of page headers and footers in \LaTeXe. + #+begin_src latex + \RequirePackage{fancyhdr} + #+end_src +- Flexible and complete interface to document dimensions. + #+begin_src latex + \RequirePackage[a4paper]{geometry} + #+end_src +- Enhanced support for graphics. + #+begin_src latex +\RequirePackage{graphicx} + #+end_src +- Extending the array and tabular environments. + #+begin_src latex +\RequirePackage{array} + #+end_src +- Completely customisable TOCs. + #+begin_src latex +\RequirePackage{etoc} + #+end_src +- Control layout of itemize, enumerate, description, and design our own lists. + #+begin_src latex +\RequirePackage{enumitem} + #+end_src +- Select alternative section titles. + #+begin_src latex +\RequirePackage{titlesec} + #+end_src +- Several logos and ornaments. + #+begin_src latex +\RequirePackage{fourier-orns} + #+end_src +- Control float placement. + #+begin_src latex +\RequirePackage[section,above]{placeins} + #+end_src +- Sophisticated verbatim text. + #+begin_src latex +\RequirePackage{fancyvrb} + #+end_src +- Publication quality tables in LaTeX. + #+begin_src latex +\RequirePackage{booktabs} + #+end_src +- Context sensitive quotation facilities. + #+begin_src latex +\RequirePackage{csquotes} + #+end_src +- Mathematical tools to use with (and which loads) \package{amsmath}. + #+begin_src latex +\RequirePackage[fleqn]{mathtools} + #+end_src +- Better accessibility support for PDF files. This package is used because we + want the material added to the background (banner on the first page and draft + watermark) to be not selectable in order to let the reader who wants to copy + the interesting text be able to select it. +#+begin_src latex + \RequirePackage{accsupp} +#+end_src +- A comprehensive (SI) units package. + #+begin_src latex + \RequirePackage{siunitx} + #+end_src +- A collection of logos with bookmark support. + #+begin_src latex + \RequirePackage{hologo} + #+end_src +- Driver-independent color extensions. + #+begin_src latex + \RequirePackage[table]{xcolor} + #+end_src +- Coloured boxes, for LaTeX examples and theorems, etc. + #+begin_src latex +\RequirePackage{tcolorbox} + #+end_src +- Expandable macros to extract the data from references and allow counter + assignments or calculations. + #+begin_src latex +\RequirePackage{refcount} + #+end_src +- Select colors with proper WCAG color contrast. + #+begin_src latex + \RequirePackage{ninecolors} + #+end_src +- Typeset tabulars and arrays with LaTeX3 (for the alert boxes typeset as + simple tabulars). + #+begin_src latex +\RequirePackage{tabularray} + #+end_src +- Multilingual support for Plain TeX or LaTeX. + #+begin_src latex +\RequirePackage[english,french]{babel} + #+end_src +- Intelligent page references. + #+begin_src latex +\RequirePackage[nospace,french]{varioref} + #+end_src +- Macros for Euro sign. + #+begin_src latex +\RequirePackage[right]{eurosym} + #+end_src +- Typeset source code listings using LaTeX. + #+begin_src latex +\RequirePackage{listings} + #+end_src +- Modifying the layout of floats. + #+begin_src latex +\RequirePackage{floatrow} + #+end_src +- Sophisticated Bibliographies in LaTeX. + #+begin_src latex + \RequirePackage[ + sorting=none, + datamodel=letgut, + citestyle=letgut + ]{biblatex} + #+end_src +- Typeset acronyms. + #+begin_src latex +\RequirePackage{acro} + #+end_src + +The following packages have to be the last ones loaded. So we ensure this by +loading them just before the begining of the document: +#+begin_src latex +\AddToHook{begindocument/before}{ +#+end_src +- Extensive support for hypertext in LaTeX + #+begin_src latex + \RequirePackage{hyperref} + #+end_src +- Adjusting the anchors of captions + #+begin_src latex + \RequirePackage[all]{hypcap} + #+end_src +- Intelligent cross-referencing + #+begin_src latex + \RequirePackage[french]{cleveref} + #+end_src +We close the ~\AddToHook{begindocument/before}~ argument. +#+begin_src latex + } +#+end_src + +** Settings for the loaded packages + +- We switch to the French typographic conventions for \package{siunitx}. + #+begin_src latex + \sisetup{ + , locale=FR + , mode=text + } + #+end_src +- Concerning floats, we ask: + - the caption text will be justified, + - the figures and their captions to be boxed (in order to distiguish them from + the current text), + - the tables to have their captions above them. + #+begin_src latex + \DeclareMarginSet{hangleft}{ + \setfloatmargins{\hskip-\c__letgut_hoffset_dim}{\hfil} + } + \DeclareFloatVCode{__letgut_ruleabove}{ + \par\rule{\hsize}{.8pt}\vskip4pt\par + } + \DeclareFloatVCode{__letgut_rulebelow}{ + \par\vskip2pt\rule{\hsize}{.8pt}\par + } + \DeclareFloatStyle{__letgut_ruled}{ + precode=__letgut_ruleabove, + postcode=__letgut_rulebelow, + % heightadjust=all, + floatwidth=.8\linewidth + } + \floatsetup{objectset=justified} + \floatsetup[figure]{ + style=__letgut_ruled, + margins=hangleft, + capposition=beside, + capbesideposition={top,left}, + floatwidth=0.85\textwidth + } + \floatsetup[table]{capposition=top} + #+end_src + Moreover, the tables will be entitled \enquote{tableau} instead of + \enquote{table}. + #+begin_src latex + \renewcommand*\frenchtablename{Tableau} + #+end_src +- We fix some defaults for the listings : we define a style for all the listings + which resets all the \TeX{} control sequences/keywords and then load all the + basic (La)TeX dialects of TeX. But we start with a dialect which is missing in + the \package*{listings}. + #+begin_src latex + \lstdefinelanguage[classes]{TeX}[LaTeX]{TeX}{% + % Control sequences + moretexcs={% + abovecaptionskip,abstractname,appendix,appendixname, + arraycolsep,arrayrulewidth,author,backmatter,baselinestretch, + belowcaptionskip,bf,bibindent,bibname,bigskipamount, + bottomfraction,brokenpenalty,cal,chapter,chaptermark, + chaptername,clubpenalty,columnsep,columnseprule,contentsname, + date,dblfloatpagefraction,dblfloatsep,dbltextfloatsep, + dbltopfraction,descriptionlabel,displaywidowpenalty, + doublerulesep,evensidemargin,fboxrule,fboxsep,figurename, + floatpagefraction,floatsep,footins,footnoterule,footnotesep, + footnotesize,footskip,frontmatter,headheight,headsep,huge,Huge, + indexname,indexspace,interlinepenalty,intextsep,it,jot, + labelenumi,labelenumii,labelenumiii,labelenumiv,labelitemfont, + labelitemi,labelitemii,labelitemiii,labelitemiv,labelsep, + labelwidth,large,Large,LARGE,leftmargin,leftmargini, + leftmarginii,leftmarginiii,leftmarginiv,leftmarginv, + leftmarginvi,lineskip,listfigurename,listoffigures, + listoftables,listtablename,mainmatter,maketitle,marginparpush, + marginparsep,marginparwidth,maxdepth,medskipamount,mit, + newblock,normallineskip,normalsize,oddsidemargin,paragraph, + paragraphmark,parindent,parskip,part,partname,partopsep, + postdisplaypenalty,predisplaypenalty,refname,rm,sc,scriptsize, + section,sectionmark,sf,sl,small,smallskipamount,subitem, + subparagraph,subparagraphmark,subsection,subsectionmark, + subsubitem,subsubsection,subsubsectionmark,tabbingsep, + tabcolsep,tablename,tableofcontents,textfloatsep,textfraction, + textheight,textwidth,thechapter,theenumi,theenumii,theenumiii, + theenumiv,theequation,theparagraph,thepart,thesection, + thesubparagraph,thesubsection,thesubsubsection,tiny,title, + today,topfraction,topmargin,topskip,tt,widowpenalty, + },% + % Keywords of class 1 : keywords that contain other characters + % (since of the same class as the ones specified as + % 'otherkeywords') + morekeywords={% + % + },% + % Keywords of class 2 : environments names + morekeywords=[2]{% + abstract,description,figure,quotation,quote,table, + thebibliography,theindex,titlepage,verse% + },% + % Keywords of class 3 : mandatory arguments (not environments) + % & optional arguments which are keys (in key=value) + morekeywords=[3]{% + },% + % Keywords of class 4 : values of keys (in key=value) + morekeywords=[4]{% + },% + % Keywords of class 5 : arguments specifications (after “:” + % in expl3 syntax) + morekeywords=[5]{% + },% + % Keywords of class 6 : current package name (and possibly + % derived packages) + morekeywords=[6]{% + a0poster,aalok,aastex631,abntex2,achemso,acmart,acmconf, + active-conf,adfathesis,afparticle,afthesis,aguplus,aiaa-tc, + akklecture,akkscript,akktecdoc,akletter,myletter,ametsoc, + amsart,amsbook,amsdtx,amsldoc,amsproc,aomart,apa,apa6, + apa6e,apa7,arabart,arabbook,arabrep,arabrep1,articleingud, + asaetr,ascelike,asmeconf,asmejour,assignment,aucklandthesis, + bangorcsthesis,bangorexam,barticle,bbook,bletter, + bankstatement,article,book,letter,ltnews,ltxdoc,ltxguide, + minimal,proc,report,slides,source2edoc,basque-book,beamer, + beamerswitch,beaulivre,beilstein,argetabelle,bewerbung, + bgteubner,BHCexam,bitart,bitbook,bjfuthesis,BMSTU-IU8, + bookcover,bookest,bookshelf,br-lex,brandeis-dissertation, + brandeis-problemset,brandeis-thesis,buctcover,buctthesis, + bxjsarticle,bxjsbook,bxjsreport,bxjsslide,cascadilla,cd, + cd-cover,articoletteracdp,letteracdp,cesenaexam,cheatsheet, + chemmacros-manual,chletter,cje,cnbwp,cnltx-doc,codedoc, + colorart,colorbook,combine,cc,ConcProg,confproc,contracard, + courseoutline,coursepaper,cquthesis,csbulletin,csbulobalka, + csbulv1,ctexart,ctexbeamer,ctexbook,ctexrep,ctxdoc,curve, + cv4tw,cweb,idcc,ijdc-v14,ijdc-v9,dinbrief,disser,gost732, + dithesis,droit-fr,dtk,dvdcoll,easybook,ebsthesis,agecon, + ajae,apecon,ecca,erae,itaxpf,jrurstud,njf,oegatb,pocoec, + regstud,worlddev,ecv,einfart,ejpecp,elbioimp,elegantbook, + elegantnote,elegantpaper,elpres,cas-dc,cas-sc,elsarticle, + elteikthesis,emisa,emulateapj,erdc,eskd,eskdgraph,eskdtab, + eskdtext,estcpmm,europasscv,europecv,exam,exam-n,examdesign, + exesheet,extarticle,extbook,extletter,extproc,extreport, + facsimile,factura,fancyhandout,fancyslides,fbithesis,fcavtex, + fdudoc,fduthesis-en,fduthesis,fei,ffslides,fithesis, + fithesis2,fithesis3,fithesis4,flacards,flashcards,frletter, + g-brief,g-brief2,gaceta,gammas,gatech-thesis,gmdocc, + gradstudentresume,grant-afosr,grant-aro,grant-darpa,grant-doe, + grant-nih,grant-nrl,grant-nsf,grant-onr,grant,graphpaper, + gridslides,gsemthesis,guitartabs,gzt,gztarticle,h2020proposal, + hgbarticle,hgbreport,hgbthesis,harnon-cv,hausarbeit-jura, + hcart,hcletter,hcreport,hcslides,hecthese,hepthesis,hitec, + hithesis,hitreport,hitszthesis,hletter,hpsdiss,fsbispit, + huawei,hustthesis,icsv,IEEEconf,IEEEtran,ijmart,ijsra, + image-gallery,IMTEKda,inkpaper,invoice-class,iodhbwm,iscram, + isov2,isodoc,iwhdp,jacow,jlreq,jmlr,jmlrbook,jnuexam,jpsj2, + jura,jurabook,juraovw,juraurtl,kdgcoursetext,kdgmasterthesis, + kdpcover,kerntest,kluwer,knittingpattern,scrartcl,scrarticle, + scrbook,scrdoc,scrletter,scrlttr2,scrreport,scrreprt,komacv, + oblivoir-utf,oblivoir-xl,oblivoir,xoblivoir,ksp-thesis,l3doc, + labbook,leadsheet,leaflet,lebhart,lectures,letgut,lettre,limap, + limecv,lion-msc,lni,lps,lt3graph-packagedoc,ltxdockit, + ltxguidex,abstbook,beletter,flashcard,iagproc,cours,fiche, + matapli,matc3mem,mcmthesis,ltxmdf,medstarbeamer,meetingmins, + memoir,mensa-tex,mentis,metanorma,milog,minimart,minimbook, + mla,mluexercise,mnras,moderncv,modernposter,msu-thesis, + mucproc,mugsthesis,muling,musuos,muthesis,third-rep,mwart, + mwbk,mwrep,mycv,nature,ncc,nccproc,sibjnm,nddiss2e, + ndsu-thesis,newlfm,nih,nihbiosketch,njurepo,nlctdoc,nostarch, + nrc1,nrc2,artikel1,artikel2,artikel3,boek,boek3,brief, + rapport1,rapport3,nwejm,nwejmart,octavo,onrannual, + oup-authoring-template,journal,paper,papertex,pbsheet,pecha, + petiteannonce,philosophersimprint,pittetd,pkuthss,plari,play, + postcards,powerdot,FUpowerdot,ppr-prv,pracjourn,pressrelease, + proposal,reporting,dfgproposal,dfgreporting,euproposal, + eureporting,prosper,protocol,prtec,upmgr,wkmgr,pst-doc, + ptptex,qcm,quantumarticle,qyxf-book,ReadableCV,recipe, + RecipeBook,recipecard,refart,refrep,resphilosophica,revtex4-2, + revtex4,revtex4-1,rtklage,ryersonSGSThesis,ryethesis,sageep, + sapthesis,schuleab,schulein,schuleit,schulekl,schuleub, + schuleue,schullsg,schullzk,schulma-ab,schulma-gutachten, + schulma-klausur,schulma-komp,schulma-mdlprf,schulma-praes, + schwalbe,sciposter,screenplay,scrjrnl,sdapsclassic,sduthesis, + seminar,semproc,sesamanuel,seuthesix,sffms,cassete,etiketka, + shtthesis,caesar_book,sides,simplecv,simplivre,skbarticle, + skbbeamer,skbbook,skblncsbeamer,skblncsppt,skbmoderncv,skdoc, + skeyval-testclass,skrapport,smfart,smfbook,SPhdThesis,spie, + sr-vorl,sslides,stage,standalone,usthesis,hwexam,mikoslides, + omdoc,smglom,subfiles,suftesi,sugconf,tabriz-thesis,talk, + tcldoc,tclldoc,powersem,thesis-ekf,thesis-gwu,thuthesis, + tikz-kalender,tikzposter,tlc-article,TOPletter,toptesi, + tudabeamer,tudaexercise,tudaleaflet,tudaletter,tudaposter, + tudapub,tudasciposter,tudscrartcl,tudscrbook,tudscrdoc, + tudscrmanual,tudscrposter,tudscrreprt,tufte-book,tufte-handout, + ltugboat,ltugproc,tui,turabian,turabian-researchpaper, + turabian-thesis,my-thesis,ua-thesis,uafthesis, + uantwerpenbamathesis,uantwerpencoursetext,uantwerpenexam, + uantwerpenletter,uantwerpenphdthesis,uantwerpenreport, + ucalgmthesis,ucbthesis,ucdavisthesis,ucsmonograph,ucthesis, + udesoftec,uebungsblatt,uestcthesis,uhhassignment,uiucredborder, + uiucthesis,ulthese,legislation,umich-thesis,umthesis, + unam-thesis,unifith,unitn-bimrep,univie-ling-expose, + univie-ling-paper,univie-ling-thesis,univie-ling-wlg, + unizgklasa,uothesis,UoWthesis,upmethodology-document,URbeamer, + URletter,uspatent,ut-thesis,utexasthesis,uwmslide,uwthesis, + verifica,webquiz,willowtreebook,withargs-packagedoc, + wsemclassic,xduthesis,xebaposter,xmuthesis,xsim-manual, + yaletter,yathesis,ycbook,ydoc,york-thesis, + },% + otherkeywords={},% + alsoletter={0123456789-},% + alsodigit={},% + sensitive% + }[keywords,tex,comments]% + #+end_src + + #+begin_src latex + \lstdefinestyle{__letgut_all_reset}{ + basicstyle=\ttfamily, + language=TeX,% + texcs={},% + keywords={},% + keywords=[2]{},% + keywords=[3]{},% + keywords=[4]{},% + keywords=[5]{},% + otherkeywords={},% + alsoletter={},% + alsodigit={},% + alsolanguage=[AlLaTeX]TeX,% + alsolanguage=[LaTeX]TeX,% + alsolanguage=[plain]TeX,% + alsolanguage=[common]TeX,% + alsolanguage=[primitive]TeX,% + alsolanguage=[classes]TeX,% + #+end_src + Because of a current issue involving \package{parskip} and + \package{listings} + (\url{https://github.com/FrankMittelbach/fmitex-parskip/issues/3}), we have to + set the skip below the displayed listings to a zero length. + #+begin_src latex + belowskip=0pt, + } + \lstset{ + style=__letgut_all_reset + } + #+end_src + This style is applied automatically at the beginning of each ~\input~ + file. Hence, the keywords defined in a previous file (by loading some + peticular (La)TeX dialects, i.e. control sequences and keywords specific to + some class or packages) won't interfere with the ones of the current file. + #+begin_src latex + \AddToHook{cmd/input/before}{ + \lstset{% + style=__letgut_all_reset,% + } + } + #+end_src +- The ~\printbibliography~ command is redefined in order its ~heading~ is by + default set to ~subbibliography~. + #+begin_src latex + \NewCommandCopy{\__letgut_old_printbibliography}{ + \printbibliography + } + \RenewDocumentCommand {\printbibliography} { O{} } { + \phantomsection + \__letgut_old_printbibliography[#1] + } + #+end_src + For printing the bibliography, we define two new bibheadings for the + structure levels ~\title~ and ~\subtitle~. + #+begin_src latex + \defbibheading{title}[\refname]{% + \title{#1}} + \defbibheading{subtitle}[\refname]{% + \subtitle{#1}} + #+end_src +- The acronyms will be typset in footnote, with small caps shape. When they are + (English) foreign, it will be specified and the translation will be added. + #+begin_src latex + \acsetup{ + first-style=footnote, + format/short = {\scshape}, + format/foreign = {\em}, + foreign/display, + locale/format = {\upshape}, + locale/display, + } + #+end_src + Moreover, we redefine the private macro ~\acro_footnote:n~ of the + \package*{acro} in order to make the footnotes displaying the long forms of the + acronyms ended by a period (like ordinary footnotes). + #+begin_src latex + \cs_undefine:N \acro_footnote:n + \cs_new_protected:Npn \acro_footnote:n #1 + { + \tl_set:Ne \l__acro_tmpa_tl { + \l__acro_fnpct_check_tl + } + \exp_last_unbraced:Nno + \footnote {#1.} + \l__acro_tmpa_tl + } + #+end_src + + The following settings for packages that have to be the last ones loaded are + also done just before the begining of the document. + +#+begin_src latex + \AddToHook{begindocument/before}{ +#+end_src + +- We want the hyperlinks to be as unobtrusive as possible. + #+begin_src latex + \bool_if:NTF \g__letgut_paper_bool { + \hypersetup{draft} + }{ + \hypersetup{% + colorlinks,% + allcolors={letgut_allcolors_links},% + }% + } + #+end_src + + A preset of acronyms is input (if found). + #+begin_src latex + \file_if_exist:nT {\c__letgut_acronyms_file_tl}{ + \file_input:n {\c__letgut_acronyms_file_tl} + } + #+end_src + +- Depending on some chosen class options, some packages have to be loaded, + notably before \package*{hyperref} is loaded, and actions are taken + accordingly. + - If the `draft` mode (default) is on, we load the \package*{lua-typo} which + highlights typographical flaws with LuaLaTeX. For the moment, + # this option is disabled if the `paper` option is enabled since enabling + # both + the \package*{lua-typo} isn't loaded since the `luacolor` + package it loads + # + currently does not work well in ~shipout/background~ (see + https://github.com/ho-tex/luacolor/issues/4). + #+begin_src latex + % % \bool_if:NF \g__letgut_paper_bool { + \bool_if:NT \g__letgut_draft_bool { + % \RequirePackage[All]{lua-typo} + \AddToHook{shipout/background} + { + \__letgut_unselectable:n { + \put(0.5\paperwidth,-0.5\paperheight) + { + \Huge + #+end_src + Currently, we can't use \package{l3color}'s ~\color_fill:n~[fn:1] + and we have to rely on \package{xcolor}'s ~\color~. + #+begin_src latex + % \color_fill:n {black!10} + \color{black!10} + \hbox_set:Nn \l_tmpa_box { + \fontsize{0.25\paperwidth}{0.3\paperwidth} + \selectfont + \c__letgut_draftwatermark_text_tl + } + \hbox_set:Nn \l_tmpb_box { + \hbox_overlap_center:n { + \box_use:N \l_tmpa_box + } + } + #+end_src + The draft watermak is rotated in order to be parallely slanted to the first + diagonal of the page (angle $=\arctan(\text{paper height}/\text{paper + width})$). + #+begin_src latex + \box_rotate:Nn \l_tmpb_box { + \fp_eval:n { + atand ( + \dim_to_fp:n {\paperheight} + / + \dim_to_fp:n {\paperwidth} + ) + } + } + \box_use:N \l_tmpb_box + } + } + } + #+end_src + Moreover, we want all the overfull boxes to be shown (as with + ~draft~ option of the standard classes). + #+begin_src latex + \setlength\overfullrule{5pt} + } + % % } +#+end_src + +# - We proceed to some settings for the \package*{glossaries-extra}: +# - the acronyms will be displayed in small caps, in footnotes, +# - the acronym definitions in footnotes are terminated with a period, like +# other footnotes, +# - we load the file of the built-in glossaries and acronyms terms. +# +# Note that we don't make use of ~\makeglossaries~ since we don't need +# glossaries files, since we don't make use of ~\printglossary~ (and friends) +# since we don't need to display a glossary or a list of acronyms. +# #+begin_src latex +# \setabbreviationstyle[acronym]{short-sc-footnote} +# \glsdisablehyper +# \renewcommand*{\glsxtrabbrvfootnote}[2]{\footnote{#2.}} +# \loadglsentries{letgut-acronyms} +# #+end_src + +We close the ~\AddToHook{begindocument/before}~ argument. + +#+begin_src latex +} +#+end_src + +** Date handling + +#+begin_src latex + \int_new:N \g__letgut_date_month_int + \int_new:N \g__letgut_date_year_int + + \int_gset:Nn \g__letgut_date_month_int {\the\month} + \int_gset:Nn \g__letgut_date_year_int {\the\year} + + \tl_new:N \g__letgut_date_month_tl + \tl_new:N \g__letgut_date_tl + + \cs_new_protected:Npn \__letgut_date_parse:n #1 + { + \__letgut_if_is_iso_date:nTF {#1} + { + \__letgut_date_parse:www #1 \q_stop + }{ + \msg_term:nnn{letgut}{Not~month~iso~date}{#1} + \tl_gset:Nn \g__letgut_date_tl { #1 } + } + } + + \prg_new_protected_conditional:Npnn + \__letgut_if_is_iso_date:n #1 { T, F, TF } + { + \regex_match:nnTF { ^\d{4}-(\d{1,2}) } {#1} + { \prg_return_true: } + { \prg_return_false: } + } + + \prg_new_protected_conditional:Npnn + \__letgut_if_is_int:n #1 { T, F, TF } + { + \regex_match:nnTF { ^[\+\-]?[\d]+$ } {#1} + { \prg_return_true: } + { \prg_return_false: } + } + + \cs_new_protected:Npn \__letgut_month_name:n #1 + { + % \text_titlecase_first:n { + \int_case:nnF + { #1 } + { + { 1 }{ janvier } + { 2 }{ février } + { 3 }{ mars } + { 4 }{ avril } + { 5 }{ mai } + { 6 }{ juin } + { 7 }{ juillet } + { 8 }{ août } + { 9 }{ septembre } + { 10 }{ octobre } + { 11 }{ novembre } + { 12 }{ décembre } + } + { Month~ Error! } + % } + } + + \cs_new_protected:Npn \__letgut_date_parse:www #1-#2 + \q_stop + { + \int_compare:nTF + { + \the\year <= #1 <= \the\year+1 + #+end_src + +# >> (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + }{ + \int_gset:Nn \g__letgut_date_year_int {#1} + }{ + \int_gset:Nn \g__letgut_date_year_int {\the\year} + } + \__letgut_if_is_int:nTF {#2} + { + \int_compare:nTF + { + 1 <= #2 <= 12 + #+end_src + +# >> (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + } + {\int_gset:Nn \g__letgut_date_month_int {#2}} + {\int_gset:Nn \g__letgut_date_month_int {\the\month}} + }{ + \int_gset:Nn \g__letgut_date_month_int {\the\month} + } + \tl_gset:Nn \g__letgut_date_month_tl { + \__letgut_month_name:n { \g__letgut_date_month_int } + } + \tl_gset:Nn \g__letgut_date_tl { + \tl_use:N \g__letgut_date_month_tl + \c_space_tl + \int_use:N \g__letgut_date_year_int + } + } +#+end_src + +** Page color default settings + + By default, the page color will be the one linked to the ~screen~ option. + +#+begin_src latex + \pagecolor[rgb]{\c__letgut_default_pagecolor_screen_clist} + \clist_set_eq:NN \g__letgut_pagecolor_clist + \c__letgut_default_pagecolor_screen_clist +#+end_src + +** Options + +These options look to need to be specified rather at the end (throws an error if +defined before the ~\__letgut_date_parse:n~'s definition): + +- ~number~ for the number of the issue, +- ~date~ for the date of the issue, either empty (hence the current (month) + date) or at the format ~YYYY-MM~ or as free input, +- ~pagecolor~ (relevant only with the (default) ~screen~ load time option) for + a color of the page other than the default one, +- ~membership-reminder~ that typesets a membership reminder on the first page, + +#+begin_src latex + \keys_define:nn { letgut/setup } + { + , draft .bool_gset:N = \g__letgut_draft_bool + , draft .initial:n = { true } + , draft .default:n = { true } + , final .bool_gset_inverse:N = \g__letgut_draft_bool + , number .int_gset:N = \g__letgut_number_int + , date .code:n = { \__letgut_date_parse:n { #1 } } + , date .initial:x = {\the\year-\the\month} + , paper .code:n = { + \bool_gset_true:N \g__letgut_paper_bool + \pagecolor[rgb]{\c__letgut_default_pagecolor_paper_clist} + \clist_set_eq:NN \g__letgut_pagecolor_clist + \c__letgut_default_pagecolor_paper_clist + } + , screen .bool_gset_inverse:N = \g__letgut_paper_bool + , pagecolor .initial:V + = \c__letgut_default_pagecolor_screen_clist + , pagecolor .code:n = { + \definecolor{letgut_pagecolor}{rgb}{#1} + \AddToHook{begindocument/before} + { + \bool_if:NTF \g__letgut_paper_bool { + \msg_warning:nnn{letgut}{ + pagecolor~inoperative~with~paper~option + }{#1} + }{ + \clist_gset:Nn \g__letgut_pagecolor_clist { #1 } + \pagecolor[rgb]{#1} + } + } + } + , allcolorslinks .code:n = { + \colorlet{letgut_allcolors_links}{#1}} + , allcolorslinks .initial:V + = \c__letgut_default_allcolors_links_color_tl + , membership-reminder .bool_gset:N + = \g__letgut_membership_reminder_bool + , membership-reminder .initial:n = { true } + , editorial .bool_gset:N = \g__letgut_editorial_bool + , editorial .initial:n = { true } + , informations .bool_gset:N = \g__letgut_informations_bool + , informations .initial:n = { true } + } +#+end_src + +** Headers + +We now define the headers. + +- The distance between the baseline of the header text and the decorative line + in the header is made a little bit bigger. + #+begin_src latex + \renewcommand{\headruleskip}{ + \c__letgut_head_rule_skip_dim + } + #+end_src +- The decorative line width in the header is made a little bit bigger. + #+begin_src latex + \renewcommand{\headrulewidth}{ + \c__letgut_head_rule_width_dim + } + #+end_src +- The headers alternate between even and odd pages. + #+begin_src latex + \fancyhf{} + \fancyhead[RO,LE]{\thepage} + \fancyhead[RE,LO]{\g__letgut_mark_tl} + #+end_src +- The headers are left offset + #+begin_src latex + \fancyheadoffset[L]{\c__letgut_hoffset_dim} + #+end_src +- We load the default \package{fancyhdr}'s page style + #+begin_src latex + \pagestyle{fancy} +#+end_src + +** Marginal notes + We want the marginal notes to be in the left margin. + +#+begin_src latex + \reversemarginpar +#+end_src + +** Table of contents + + The table of contents is customized: + +- only the titles of the articles are shown (but the bookmarks have their natural depth): +#+begin_src latex + \etocsetnexttocdepth{0} + #+end_src +- layout: + #+begin_src latex + \etocsetstyle {section} + {} + {\leavevmode\leftskip 2cm\relax} + {\normalsize% + \etocname~\dotfill~\etocpage\par + } + {} +#+end_src +- its title is dropped: +#+begin_src latex + \renewcommand*\frenchcontentsname{} +#+end_src + +** COMMENT Alerts + + We create a box to display alerts. + +#+begin_src latex + \tcbuselibrary{xparse} + \DeclareTCBox{\alertbox}{}{ + nobeforeafter, + colback=red!5!white, + colframe=red!75!black, + title={Attention !}, + fonttitle=\bfseries, + before=\begin{center}, + after=\end{center} + } +#+end_src + +** Geometry of the document + +#+begin_src latex + \geometry{ + asymmetric, + textheight=\c__letgut_textheight_dim, + textwidth=\c__letgut_textwidth_dim, + lmargin=\c__letgut_lmargin_dim, + tmargin=\c__letgut_tmargin_dim, + head=\c__letgut_head_dim, + headsep=\c__letgut_headsep_dim, + marginparwidth=\c__letgut_marginparwidth_dim, + % verbose, + % showframe + } +#+end_src + +** Alert box + +#+begin_src latex + \cs_new_protected:Nn \__letgut_alert_box:nn + { + \noindent + \begin{tblr}{ + width=\linewidth, + rowspec={Q[c,m,#1]}, + colspec={| + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + >{\bfseries}X| + }, + vlines, + hlines, + rowsep=2.5mm, + colsep=2.5mm + } + #2 + \end{tblr} + \skip_vertical:N \c_zero_dim + } +#+end_src + +** “Title” and marks + + We redefine ~\@title~ in order to make it empty. Hence we can later test if + the ~\title~ has been populated by the user (thanks to ~\title~) and, if so, + we will (automatically) display on the first page and headers the provided + title instead of the number and the date (see below). +#+begin_src latex + \tl_gclear:N \@title +#+end_src + +At the end of preamble, we put the ~\@title~ (empty or populated by the +user) into ~\g__letgut_@title_str~ for later tests. +#+begin_src latex + \AddToHook{begindocument/before} + { + \str_set_eq:NN \g__letgut_@title_str \@title +#+end_src + +The number is added only if it is +# < (Just not to disturb the parentheses balancing +# detection of my editor.) +$>0$. + + #+begin_src latex + \tl_gset:Nn \g__letgut_title_tl { + \int_compare:nNnT + \g__letgut_number_int + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + > \c_zero_int + {numéro~ \int_use:N\g__letgut_number_int{}~ --~ } + \g__letgut_date_tl + } + \str_if_empty:NTF \g__letgut_@title_str { + \tl_gset:Nn \g__letgut_mark_tl { + \textit{\c__letgut_La_lettre_gutenberg_tl} + } + }{ + \tl_gset:Nn \g__letgut_mark_tl { + \g__letgut_@title_str + } + } + \tl_gput_right:Nn \g__letgut_mark_tl { + ,~\g__letgut_title_tl + } + } +#+end_src + +** First page handling + +The first page is special as it should automatically contain certain elements: +- the banner, +- either the number and the date of the issue, or a given title, +- the table of contents, +- the editorial, +- the membership reminder. + +The first page is inserted only is the target audience is the readers of the +Lettre. + +#+begin_src latex + \bool_if:NT \g__letgut_for_readers_bool { +#+end_src + +#+begin_src latex + \file_if_exist:nTF {\c__letgut_banner_file_tl.pdf}{ + \AddToHookNext{shipout/background} + { + \begin{picture}(0,0) + \put(-2cm,-25.275cm){ + \includegraphics[scale=0.96]{ + \c__letgut_banner_file_tl.pdf + } + } + \end{picture} + } + }{ + #+end_src + +The ~pagecolor~ option is possibly set (with ~\AddToHook{begindocument/before}~) +and the page color chosen has to be used for the letters of the banner so the +following code has to be postponed after the former (hence here +~\AddToHook{begindocument}~ and with ~\AddToHook{begindocument/before}~). + +#+begin_src latex + \msg_term:nn{letgut}{Banner~file~not~provided} + \RequirePackage[pagecolor={\g__letgut_pagecolor_clist}]{ + letgut-banner + } + } + #+end_src + +Here starts what is automatically added at the beginning of the document. + +#+begin_src latex + \AddToHook{begindocument/end} + { +#+end_src + +- If a membership reminder is asked, we create an (alert) box containing the + corresponding text and reduce the textheight of this page of the height of + this box. + #+begin_src latex + \bool_if:NT \g__letgut_membership_reminder_bool { + \box_new:N \g__letgut_membership_reminder_box + \vbox_gset:Nn \g__letgut_membership_reminder_box { + \alertbox []{ \c__letgut_membership_reminder_tl } + } + \dim_gset:Nn + \g__letgut_membership_reminder_box_height_dim { + \box_ht:N \g__letgut_membership_reminder_box + } + \enlargethispage{ + - \g__letgut_membership_reminder_box_height_dim + } + } + #+end_src +- We want the text on the first page to not encroach on the horizontal bar of + the banner. + #+begin_src latex + \dim_const:Nn \c__letgut_first_page_shrink_dim { + \c__letgut_banner_thickness_dim + + + \c__letgut_tmargin_dim + + + \c__letgut_textheight_dim + - + .5\paperheight + - + .5\c__letgut_banner_height_dim + } + \enlargethispage{ + - \c__letgut_first_page_shrink_dim + } + \enlargethispage{ + - \baselineskip + } + #+end_src +- If the user has specified a title, we make a (our own) title and use it and + the possibly provided author(s) for the metadata of the PDF; otherwise we + display the number and the date of the newsletter. + #+begin_src latex + \str_if_empty:NTF \g__letgut_@title_str { + \bool_gset_true:N \g__letgut_title_empty_bool + \begin{flushright} + \Huge + \text_titlecase_first:n { \g__letgut_title_tl } + \end{flushright} + \hypersetup{ + pdftitle={ + \c__letgut_Lettre_gutenberg_tl + \int_compare:nNnT + \g__letgut_number_int + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + > \c_zero_int + { + \c_space_tl~ \int_use:N \g__letgut_number_int + } + }, + pdfauthor={ + Association~ + \c__letgut_gutenberg_tl + \c_space_tl + (éditeur) + }, + } + \vspace*{1cm} + }{ + \hypersetup{ + pdftitle={\g__letgut_@title_str} + } + \tl_if_empty:NF \@author { + \hypersetup{ + pdfauthor={\@author} + } + } + #+end_src + Here, we insert the title, but don't rely on ~\maketitle~ because it + lets to ~\relax~ the command ~\title~ which is used later as new sectionning + levels for the titles of the articles of the Lettre. So we emulate the + intersting part of the ~\maketitle~ command (borrowed from \file{article.cls}). + #+begin_src latex + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks + {\LARGE \@title \par}% + \vskip 1.5em% + {\large + \lineskip .5em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1em% + {\large \@date}% + \end{center}% + \par + \vskip 1.5em + } + #+end_src +- No headers on the first page. This has to be inserted after the previous + (customized) ~\maketitle~ since this command inserts a ~\newpage~ which would + ruin the effort of ~\thispagestyle{empty}~ if inserted before. + #+begin_src latex + \thispagestyle{empty} + #+end_src +- The table of contents is automatically added and has a bookmark entry. + #+begin_src latex + \pdfbookmark[1]{ + \c__letgut_contents_name_tl + }{ + \c__letgut_contents_name_tl + } + \tableofcontents + #+end_src + Should a title be displayed, the table of contents would be added after it, + followed by a new page (otherwise, if ~\title~ used after ~\begin{document}~ + sees its title on the front page, it will overflow onto the banner). + #+begin_src latex + \bool_if:NTF \g__letgut_title_empty_bool { + \vspace*{1.5cm} + }{ + \newpage + } + #+end_src +- Conditionally to the fact the ~editorial~ option is not set to ~false~: if the + \file*{editorial.tex} of the editorial is found, its content is input and + has a bookmark entry; otherwise, a warning is displayed. + #+begin_src latex + \bool_if:NTF \g__letgut_editorial_bool { + \file_if_exist:nTF {./\c__letgut_editorial_file_tl}{ + \RenewDocumentCommand\author{ m } { + \__letgut_author:n { #1 } + } + \pdfbookmark[1]{Éditorial}{ + \c__letgut_editorial_file_tl + } + \file_input:n {./\c__letgut_editorial_file_tl} + % % \int_set:N \l_tmpa_int {\pagenumber} + % % \int_compare:nNnT \l_tmpa_int = 1 { \newpage } + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + % \if\count{\pagenumber}>1 + % \else + % \newpage + % \fi + }{ + \msg_warning:nn{letgut}{Editorial~file~missing} + \alertbox{ \c__letgut_missing_editorial_tl } + \newpage + } + }{ + % \newpage + } +#+end_src + +We close the ~\AddToHook{begindocument/end}~ argument. + +#+begin_src latex + } +#+end_src + +Membership reminder. + +#+begin_src latex + \AddToHook{begindocument}{ + \bool_if:NT \g__letgut_membership_reminder_bool { + \AddToHookNext{shipout/background} + { + \put(1in,-1in){ + \put( + \oddsidemargin, + - \topmargin + - \headheight + - \headsep + - \textheight + + \c__letgut_first_page_shrink_dim + + .5\baselineskip + ){ + \box_use:N \g__letgut_membership_reminder_box + } + } + } + } + } +#+end_src + +** Last page handling + +The last page is special: it should automatically contain some informations about +\gutenberg. + +#+begin_src latex + \AddToHook{enddocument} + { +#+end_src +Conditionally to the fact the ~informations~ option is not set to ~false~: if the +\file*{informations-gut.tex} which contains the informations about +\gutenberg. Otherwise, a warning is displayed. + #+begin_src latex + \bool_if:NT \g__letgut_informations_bool { + \clearpage + \phantomsection + \file_if_exist:nTF + {./\c__letgut_informations_gutenberg_file_tl}{ + \file_input:n {./\c__letgut_informations_gutenberg_file_tl} + }{ + \msg_warning:nn{letgut}{Informations~file~missing} + \alertbox{ \c__letgut_missing_infomations_tl } + } + } + #+end_src + +We close the ~\AddToHook{enddocument}~ argument. + +#+begin_src latex + } +#+end_src + +We close the boolean which tests whether the target audience is the readers or +the author(s) of the “Lettre”. + +#+begin_src latex + } +#+end_src + +** Sections, subsections, etc. + +*** Numbering + We want all the sections to be unnumbered. + + #+begin_src latex + \setcounter{secnumdepth}{-10} + #+end_src + +*** Format + +- We create the new level ~\title~ for the titles of the articles. They are + displayed uppercased. + #+begin_src latex + \AddToHook{begindocument/before}{% + \titleclass{\title}{straight}[\part] + \titleformat{\title}{ + \normalfont + \LARGE + \bfseries + \text_uppercase:n + }{}{1em}{ + \aldineleft\c_space_tl + }{} + \etocsetlevel{title}{0} + \def\toclevel@title{0}% + \etocsetstyle {title} + {} + { + \leavevmode\leftskip 2cm\relax + } + {\mdseries\normalsize + \etocname + \nobreak\leaders\hbox~ to~ 1ex{\hss.}\hfill + \etocpage + \par} + {} + #+end_src +- We also create the new level ~\subtitle~ for the subtitles of the + articles. They are dispayed uppercased (but in a smaller size than ~\title~). + #+begin_src latex + \titleclass{\subtitle}{straight}[\title] + \titleformat{\subtitle}{ + \normalfont + \Large + \bfseries + \text_uppercase:n + }{}{1em}{}{} + \etocsetlevel{subtitle}{1} + \def\toclevel@subtitle{1}% + \def\toclevel@subtitle{1} + #+end_src +- By default (that is when ~\subtitle~ is not used), the toc levels of the + sections, subsections, etc. are set to ~1~, ~2~, etc. But, when ~\subtitle~ is + used, since this level has toc level ~1~, the toc levels of the sections, + subsections, etc. have to be set to ~2~, ~3~, etc. And this has to be reset + each time ~\title~ and ~\subtitle~ are used. + #+begin_src latex + \AddToHook{cmd/title/before}{ + \etocsetlevel{section}{1} + \def\toclevel@section{1}% + \etocsetlevel{subsection}{2} + \def\toclevel@subsection{2}% + \etocsetlevel{subsubsection}{3} + \def\toclevel@subsubsection{3}% + \etocsetlevel{paragraph}{4} + \def\toclevel@paragraph{4}% + \etocsetlevel{subparagraph}{5} + \def\toclevel@subparagraph{5}% + } + \AddToHook{cmd/subtitle/before}{ + \etocsetlevel{section}{2} + \def\toclevel@section{2}% + \etocsetlevel{subsection}{3} + \def\toclevel@subsection{3}% + \etocsetlevel{subsubsection}{4} + \def\toclevel@subsubsection{4}% + \etocsetlevel{paragraph}{5} + \def\toclevel@paragraph{5}% + \etocsetlevel{subparagraph}{6} + \def\toclevel@subparagraph{6}% + } + #+end_src + # - The sections have the usual format, except that their titles are uppercase. + # #+begin_src latex + # \titleformat{\section}{ + # \normalfont + # \Large + # \bfseries + # \text_uppercase:n + # % }{\thesection}{1em}{}{} + # #+end_src + - The (sub)paragraphs have the usual format, except that they are not + “runin” (\package{titlesec}'s package's terminology). + #+begin_src latex + \titleformat{\paragraph}{ + \normalfont + \normalsize + \bfseries + }{\theparagraph}{1em}{} + \titleformat{\subparagraph}{ + \normalfont + \normalsize + \bfseries + }{\thesubparagraph}{1em}{} + } + #+end_src +- We modify the spacing, mainly by shifting the titles in the left margin (the + rest is borrowed from the standard classes). + #+begin_src latex + \titlespacing*{\title} + {\c__letgut_title_hoffset_dim} + {\c__letgut_before_title_title_skip} + {\c__letgut_after_title_title_skip} + \titlespacing*{\subtitle} + {\c__letgut_subtitle_hoffset_dim} + {\c__letgut_before_subtitle_title_skip} + {\c__letgut_after_subtitle_title_skip} + \titlespacing*{\section} + {\c__letgut_section_hoffset_dim} + {\c__letgut_before_section_title_skip} + {\c__letgut_after_section_title_skip} + \titlespacing*{\subsection} + {\c__letgut_subsection_hoffset_dim} + {\c__letgut_before_subsection_title_skip} + {\c__letgut_after_subsection_title_skip} + \titlespacing*{\subsubsection} + {\c__letgut_subsubsection_hoffset_dim} + {\c__letgut_before_subsubsection_title_skip} + {\c__letgut_after_subsubsection_title_skip} + \titlespacing*{\paragraph} + {\c__letgut_paragraph_hoffset_dim} + {\c__letgut_before_paragraph_title_skip} + {\c__letgut_after_paragraph_title_skip} + \titlespacing*{\subparagraph} + {\c__letgut_subparagraph_hoffset_dim} + {\c__letgut_before_subparagraph_title_skip} + {\c__letgut_after_subparagraph_title_skip} +#+end_src + +** Document commands + +*** Setup + +We define the command that lets us specify the newsletter setup. + +#+begin_src latex +\NewDocumentCommand \letgutsetup { m } { + \keys_set:nn { letgut/setup } { #1 } +} +#+end_src + +*** For the rubric dedicated to new stuffs appeared on \acs{ctan} + + - We create a new type of list, dedicated to the new stuffs (classes, packages, + etc.) on CTAN and similar to a description list (except the label provided in + the optional argument of ~\item~ is automatically an argument of the + ~\package~ command). + #+begin_src latex + \cs_new_protected:Nn \__letgut_ctan_news_item:n { + \package{#1}~: + } + \newlist{ctannews}{description}{1} + \setlist[ctannews]{format=\__letgut_ctan_news_item:n} + #+end_src + The stuffs created by French speaking people are highlighted in a special + way and, for this, a starred variant of the ~\item~ command is provided. We + insert a systematic ~\phantomsection~ in order the cross-references to such + items are correct. + #+begin_src latex + \cs_new_protected:Npn \__letgut_item:nn #1 #2 + { + \tl_if_empty:nTF {#2} + { + \__letgut_old_item + }{ + \__letgut_old_item[#2] + } + \phantomsection + \IfBooleanT {#1}{ + \mbox{}\marginpar[\mbox{}\hfill\francophony]{} + } + } + \NewCommandCopy{\__letgut_old_item}{\item} + \RenewDocumentCommand {\item} { s O{} } { + \__letgut_item:nn {#1}{#2} + } + #+end_src + +- Command that inserts the \enquote{francophony} logo. + #+begin_src latex + \NewDocumentCommand {\francophony} { } { + \raisebox{-1.5pt}{ + \includegraphics[width=\f@size pt]{ + Flag_of_La_Francophonie-crop + } + } + } + #+end_src + +*** Persons and authors + +For both persons and authors, the argument of: +- a single individual is given as: + - \meta{Last name}, \meta{First name} + - and possibly \meta{Last name}, \meta{First name}, \meta{Title} +- multiple individuals, the schemes for each of the individuals are the same of + a single one, separated by a semicolon. + +#+begin_src latex + \NewDocumentCommand {\person} { m } { + \__letgut_process_list:n {#1} + } + \cs_new_protected:Npn \__letgut_author:n #1 + { + \nopagebreak + \begin{flushright} + \__letgut_process_list:n {#1} + \end{flushright} + } + \AddToHook{begindocument/end}{% + \RenewDocumentCommand\author{ m } { + \__letgut_author:n { #1 } + } + } + #+end_src + + In the following ~\__letgut_titlecase_name~ control sequence, we parse last and + first names, splitting and unsplitting them at spaces and dashes (~-~) with + titlecasing in between. + + #+begin_src latex +\cs_new_protected:Npn \__letgut_titlecase_name:n #1 +{ + \seq_set_split:Nnn \l_tmpa_seq { - } {#1} + \seq_set_map_x:NNn \l_tmpb_seq \l_tmpa_seq { + \text_titlecase_first:n{ \text_lowercase:n {##1} } + } + \tl_set:Nx \l_tmpa_tl {\seq_use:Nn \l_tmpb_seq {-}} + \seq_clear:N \l_tmpa_seq + \seq_set_split:NnV \l_tmpa_seq { ~ } { \l_tmpa_tl } + \seq_set_map_x:NNn \l_tmpb_seq \l_tmpa_seq { + \text_titlecase_first:n{##1} + } + \seq_use:Nn \l_tmpb_seq {~} +} + #+end_src + + The following control sequence splits a semi-colon separated list and each item + is splitted as a comma separated list. + +#+begin_src latex + \cs_new_protected:Nn \__letgut_person_last_name:n + { + {\scshape \__letgut_titlecase_name:n {#1}} + } + \cs_new_protected:Nn \__letgut_person_first_name_last_name:nn + { + \__letgut_titlecase_name:n {#1} + \c_space_tl + \__letgut_person_last_name:n {#2} + } + \cs_new_protected:Nn + \__letgut_person_first_name_last_name_title:nnn + { + \__letgut_person_first_name_last_name:nn {#1} {#2} + \c_space_tl + (#3) + } + \seq_new:N \l__letgut_items_seq + \cs_new_protected:Npn \__letgut_process_list:n #1 + { + \seq_clear:N \l__letgut_items_seq + \seq_set_split:Nnn \l_tmpa_seq {and} {#1} + \seq_map_inline:Nn \l_tmpa_seq { + \seq_set_from_clist:Nn \l_tmpb_seq {##1} + \seq_pop_left:NN \l_tmpb_seq \l_letgut_last_name_tl + \seq_pop_left:NN \l_tmpb_seq \l_letgut_first_name_tl + \seq_pop_left:NN \l_tmpb_seq \l_letgut_title_tl + \seq_put_right:Nx \l__letgut_items_seq { + \quark_if_no_value:NTF \l_letgut_first_name_tl { + \__letgut_person_last_name:n { + \l_letgut_last_name_tl + } + }{ + \quark_if_no_value:NTF \l_letgut_title_tl { + \__letgut_person_first_name_last_name:nn + {\l_letgut_first_name_tl} + {\l_letgut_last_name_tl} + }{ + \__letgut_person_first_name_last_name_title:nnn + {\l_letgut_first_name_tl} + {\l_letgut_last_name_tl} + {\l_letgut_title_tl} + } + } + } + } + \seq_use:Nnnn \l__letgut_items_seq { + \c_space_tl \str_use:N \& \c_space_tl + } { ,~ } { \c_space_tl \str_use:N \& \c_space_tl } + } + #+end_src + +*** Horizontal rule + + #+begin_src latex + \NewDocumentCommand {\separator} { } { + \par + \skip_vertical:N 1em + \hrule + \skip_vertical:N 1em + } + #+end_src + +*** Alert boxes + + #+begin_src latex + \colorlet {letgut_default_alert_box_color} { + \c__letgut_default_alert_box_color_tl + } + \NewDocumentCommand \alertbox { + O{letgut_default_alert_box_color} +m + } { + \__letgut_alert_box:nn { #1 }{ #2 } + } + #+end_src + +*** Typesetting of packages, classes, files and softwares. + +The ~\c__letgut_httpsprefix_tl~ comes from: + +https://github.com/latex3/hyperref/issues/188#issuecomment-826302843. + + #+begin_src latex + \tl_const:Nx \c__letgut_httpsprefix_tl + {https\char_generate:nn{58}{12}//} + #+end_src + We define the font switches dediacted to each of packages and classes + (\TeX{} stuff), files and softwares. + #+begin_src latex + \tl_new:N \l__letgut__tex_stuff_font_switch_tl + \tl_new:N \l__letgut_files_font_switch_tl + \tl_new:N \l__letgut_softwares_font_switch_tl + \tl_set:Nn \l__letgut__tex_stuff_font_switch_tl {\sffamily} + \tl_set:Nn \l__letgut_files_font_switch_tl {\ttfamily} + \tl_set:Nn \l__letgut_softwares_font_switch_tl {\ttfamily} + #+end_src + + #+begin_src latex + \cs_new_protected:Nn \__letgut_tex_stuff:nn + { + \IfNoValueTF {#1} + { + \href{ + \c__letgut_httpsprefix_tl ctan.org/pkg/#2 + }{ + {\l__letgut__tex_stuff_font_switch_tl #2} + } + }{ + \tl_if_empty:nTF {#1} + { + {\l__letgut__tex_stuff_font_switch_tl #2} + }{ + \href{#1}{{\l__letgut__tex_stuff_font_switch_tl #2}} + } + } + } + \cs_new_protected:Nn \__letgut_software:nn + { + \tl_if_empty:nTF {#1} + { + {\l__letgut_softwares_font_switch_tl #2} + }{ + \href{#1}{{\l__letgut_softwares_font_switch_tl #2}} + } + } + \cs_new_protected:Nn \__letgut_file:n + { + {\l__letgut_files_font_switch_tl #1} + } + \NewDocumentCommand{\package}{ s o m O{package} } { + \IfBooleanT{#1}{ + #4 + \c_space_tl + } + \__letgut_tex_stuff:nn {#2}{#3} + } + \NewDocumentCommand{\class}{ s o m O{classe} } { + \IfBooleanT{#1}{ + #4 + \c_space_tl + } + \__letgut_tex_stuff:nn {#2}{#3} + } + \NewDocumentCommand{\file}{ s m O{fichier} } { + \IfBooleanT{#1}{ + #3 + \c_space_tl + } + \__letgut_file:n {#2} + } + \NewDocumentCommand {\software} { s O{} m O{logiciel} } { + \IfBooleanT{#1}{ + #4 + \c_space_tl + } + \__letgut_software:nn {#2}{#3} + } + #+end_src + +*** Names, etc. + +#+begin_src latex + \NewExpandableDocumentCommand { \gutenberg } { } { + \c__letgut_gutenberg_tl + } + \NewExpandableDocumentCommand { \gut } { } { + \c__letgut_gutenberg_tl + } + \NewExpandableDocumentCommand { \lettre } { } { + \c__letgut_Lettre_tl + } + \NewExpandableDocumentCommand { \lettregut } { } { + \lettre \c_space_tl \gutenberg + } + \NewExpandableDocumentCommand { \Cahier } { } { + \c__letgut_cahier_tl + } + \NewExpandableDocumentCommand { \Cahiers } { } { + \c__letgut_cahiers_tl + } + \NewExpandableDocumentCommand { \letgut } { } { + \class{letgut} + } + \NewExpandableDocumentCommand { \letgutcls } { } { + \class*{letgut} + } + \NewExpandableDocumentCommand { \tugboat } { } { + \c__letgut_tugboat_tl + } + \NewExpandableDocumentCommand { \knuth } { } { + \person{Knuth, Donald~ E.} + } + \NewExpandableDocumentCommand { \lamport } { } { + \person{Lamport, Leslie} + } +#+end_src + +*** Foreign locutions + +#+begin_src latex + \cs_new_protected:Npn \__letgut_emphasis:n #1 + { + \emph{#1} + } + \NewDocumentCommand { \foreignloc } { m } { + \__letgut_emphasis:n {#1} + } + \NewDocumentCommand { \latinloc } { m } { + \__letgut_emphasis:n {#1} + } +#+end_src + +*** Bookmarks handling + +We disabling some commands when their arguments have to go to bookmarks. + +#+begin_src latex + \AddToHook{begindocument/end}{ + \pdfstringdefDisableCommands{ + \def\person#1{#1} + \def\author#1{#1} + \def\package#1{#1} + % \def\package*#1{package~#1} + \def\class#1{#1} + % \def\class*#1{classe~#1} + \def\file#1{#1} + % \def\file*#1{fichier~#1} + \def\software#1{#1} + % \def\software*#1{logiciel~#1} + \def\foreignloc#1{#1} + \def\lettre{Lettre} + \def\gutenberg{GUTenberg} + \def\gut{\gutenberg} + \def\lettregut{\lettre\c_space_tl\gutenberg} + \def\Cahier{Cahier} + \def\Cahiers{\Cahier s} + \def\letgut{letgut} + \def\letgutcls{classe~ letgut} + \def\knuth{Donald~ E.~ Knuth} + \def\lamport{Leslie~ Lamport} + \def\latinloc#1{#1} + } + } +#+end_src + +*** Acronyms + +The following command let us define acronyms. The arguments are as follows: +- ~#1~: optional argument that let us override the default settings of this + command, +- ~#2~: the uppercase version of both the id and the short form of the acronym, +- ~#3~: the long form (in French if #4 has ~-NoValue-~, in English otherwise), +- ~#4~: the French translation of an English acronym. + +#+begin_src latex + \cs_new_protected:Nn \__letgut_acronym:nnnn + { + \AddToHook{begindocument/before}{ + \IfValueTF {#4}{ + \tl_if_empty:nTF {#4}{ + \exp_args:Nx \DeclareAcronym{\text_lowercase:n {#2}}{ + short = \text_lowercase:n {#2}, + sort= #2, + long = {\emph{#3}}, + extra-long = {anglais}, + pdfstring = #2, + short-acc = #2, + #1 + } + }{ + \exp_args:Nx \DeclareAcronym{\text_lowercase:n {#2}}{ + short = \text_lowercase:n {#2}, + sort= #2, + long = {#4}, + foreign = {#3}, + foreign-babel = english, + foreign-locale = anglais, + pdfstring = #2, + short-acc = #2, + #1 + } + } + }{ + \exp_args:Nx \DeclareAcronym{\text_lowercase:n {#2}}{ + short = \text_lowercase:n {#2}, + sort= #2, + long = {#3}, + pdfstring = #2, + short-acc = #2, + #1 + } + } +#+end_src +The ⟨id⟩ of the acronym will automatically be the name of a public command +(~\~⟨id⟩) acting as ~\ac{id}~. +#+begin_src latex + \exp_after:wN \cs_if_exist:cT { \text_lowercase:n {#2} } { + \msg_note:nnn{letgut}{Existing~command}{#2} + } + \exp_args:Nc \ProvideDocumentCommand + { \text_lowercase:n {#2} } { s } { + \IfBooleanTF {##1}{ + \exp_args:Nx \acs { \text_lowercase:n {#2} } + }{ + \exp_args:Nx \ac { \text_lowercase:n { #2 } } + } + } +#+end_src +We want the command ~\~⟨id⟩ to work also in bookmarks (the resulting string will +be the uppercased acronym). +#+begin_src latex + \pdfstringdefDisableCommands + { + \exp_after:wN + \def\cs:w \text_lowercase:n {#2} \cs_end: { #2 } + } + } + } +#+end_src + +The first occurrences of the acronyms will be displayed in their short forms, +with the long ones in footnotes. But what about acronyms whom first occurrences +arise within footnotes? We want the to be displayed as their short forms +followed by their the long form in parentheses. For this, we have to add +a boolean at the beginning (and reversed at the end) of the ~\footnote~ command +to know whether we currently are in a footnote or not and display the acronym +accordingly. + +#+begin_src latex + \NewCommandCopy{\__letgut_old_footnote}{\footnote} + \RenewDocumentCommand {\footnote} { m }{ + \bool_set_true:N \l__letgut_in_footnote_bool + \__letgut_old_footnote { #1 } + \bool_set_false:N \l__letgut_in_footnote_bool + } +#+end_src +We change a bit both the ~footnote~ acro template, the ~description~ list +template, and the macro which prints the locale. +#+begin_src latex + \DeclareAcroProperty{extra-foreign} + \DeclareAcroProperty{extra-long} + \RenewAcroTemplate {footnote} + { + \acrowrite {short} + \acroiffirstT + { + #+end_src + If we are in a footnote, first occurrences of the acronyms are displayed + as “short (long)”. Otherwise, they are displayed as “short\footnote{long}”. + #+begin_src latex + \bool_if:NTF \l__letgut_in_footnote_bool { + \space + ( + \acroifT {alt} { \acrotranslate {or} ~ \acrowrite {alt} ~ } + \acroifT {foreign} { \acrowrite {foreign} :~ } + \acrowrite {long} + \acrogroupcite + ) + }{ + \acfootnote + { + \acroifT {alt} { + \acrotranslate {or} ~ \acrowrite {alt} :~ + } + \acroifT {foreign} { \acrowrite {foreign} } + \acrowrite {long} + \acroifT {extra-long} { ~ [\acrowrite {extra-long}] } + \acroifT {extra-foreign} { + \c_space_tl [\acrowrite {extra-foreign}] + } + \acrogroupcite + } + } + } + } + \RenewAcroTemplate[list]{description}{% + \acroheading + \acropreamble + \begin{description} + \acronymsmapF{% + \item[\acrowrite{short}\acroifT{alt}{/\acrowrite{alt}}] + \acroifT{foreign}{ + \acrowrite{foreign}\acroifT{extra}{, } + }% + \acroifT{extra}{\acrowrite{extra}}% + \acroifanyT{foreign,extra}{\acspace (}% + \acrowrite{list}% + \acroifT {extra-foreign} { + , \c_space_tl \acrowrite {extra-foreign} + } + \acroifanyT{foreign,extra}{)}% + \acropagefill + \acropages + {\acrotranslate{page}\nobreakspace} + {\acrotranslate{pages}\nobreakspace}% + } + {\item\AcroRerun} + \end{description} + } + % #1: id + % #2: property + % #3: text + \cs_set_protected:Npn \acro_locale:nnn #1#2#3 + { + \acro_if_foreign:nTF {#2} + { + \acro_if_locale:nnTF {#1} {#2} + { + \__acro_foreign_language:en + { \str_lowercase:e { + \acro_property_get:nn {#1} {foreign-babel} + } + } + {#3} + \bool_if:NTF \l__acro_list_bool + { \bool_if:NT \l__acro_list_show_locale_bool } + { \bool_if:NT \l__acro_show_locale_bool } + { + { + \l__acro_locale_format_tl + { + \acro_property_if_set:nnTF {#1} { + foreign-locale + } + { + \acspace + [ + \acro_property_get:nn {#1} { + foreign-locale + } + ] + }{ + \baselanguage + { + \acro_property_get:nn {#1} { + foreign-babel + } + } + } + } + } + :~ + } + } + {#3} + } + {#3} + } +#+end_src +Now, the document command that let the user create acronyms. +#+begin_src latex + \NewDocumentCommand{\letgutacro}{ O{} m m o } + { + \__letgut_acronym:nnnn {#1} {#2} {#3} {#4} + } +#+end_src +For printing the acronyms, we define two new heading templates for the structure +levels ~\title~ and ~\subtitle~. +#+begin_src latex +\NewAcroTemplate[heading] {title} + { \title { \acrolistname } } +\NewAcroTemplate[heading] {subtitle} + { \subtitle { \acrolistname } } +#+end_src +We make ~\letgutacro~ available only in the preamble part of the document +(otherwise, no warning from \package{acro} but only the long form of the acronym +is printed when used for the first time with ~\ac~). +#+begin_src latex +\@onlypreamble\letgutacro +#+end_src + +** Bibliography + +We want the ~\citeauthor~ command to display, not only the last, but the +full name of the authors. + +#+begin_src latex + \NewCommandCopy{\__letgut_old_citeauthor}{ + \citeauthor + } + \RenewDocumentCommand {\citeauthor} { O{} O{} m } { + \AtNextCite{\DeclareNameAlias{labelname}{given-family}} + \__letgut_old_citeauthor[#1][#2]{#3} + } + #+end_src + +** Book reviews + +#+begin_src latex + \tl_new:N \g__letgut_bookreview_frontcover_tl + \tl_new:N \g__letgut_bookreview_bibkey_tl + #+end_src +The keys options are created. + #+begin_src latex + \keys_define:nn { gzt/bookreview } + { + title .tl_gset:N = \g__letgut_bookreview_title_tl, + frontcover .tl_gset:N = \g__letgut_bookreview_frontcover_tl, + bibkey .tl_gset:N = \g__letgut_bookreview_bibkey_tl, + reviewer .tl_gset:N = \g__letgut_bookreview_reviewer_tl, + price .tl_gset:N = \g__letgut_bookreview_price_tl, + #+end_src + +All these options, when used, must receive a value. + +#+begin_src latex + title .value_required:n = true, + frontcover .value_required:n = true, + bibkey .value_required:n = true, + reviewer .value_required:n = true, + } +#+end_src + +We create the new environment for the book reviews. + +#+begin_src latex + \cs_generate_variant:Nn \msg_warning:nnn { nnV } + \cs_generate_variant:Nn \msg_error:nnnn { nnVV } + \NewDocumentEnvironment{bookreview}{ m } + { + \keys_set:nn { gzt/bookreview } { #1 } + \section{\g__letgut_bookreview_title_tl} + \tl_if_empty:NTF \g__letgut_bookreview_frontcover_tl { + \msg_warning:nnV{letgut}{frontcover-missing}{ + \g__letgut_bookreview_title_tl + } + }{ +#+end_src + +We check if the front cover file is available against the list of accepted +extensions of the ~graphicx~ package. + +#+begin_src latex + \clist_map_inline:Nn \Gin@extensions { + \file_if_exist:nT{\g__letgut_bookreview_frontcover_tl##1}{ + \bool_set_true:N \l_tmpa_bool + \clist_map_break: + } + } + \bool_if:NTF \l_tmpa_bool { + \marginpar{ + \hspace*{\c__letgut_bookreview_frontcover_margin_sep_dim} + % \raggedleft + \raisebox{-\totalheight}{ + \fbox{ + \includegraphics[width=-\c__letgut_title_hoffset_dim]{ + \g__letgut_bookreview_frontcover_tl + } + } + } + } + }{ + \msg_error:nnVV + {letgut} + {frontcover-file-not-found} + {\g__letgut_bookreview_title_tl} + {\g__letgut_bookreview_frontcover_tl} + } + } + \noindent + \textsf{\fullcite{\g__letgut_bookreview_bibkey_tl}} + \tl_if_empty:NF \g__letgut_bookreview_price_tl{ + .\c_space_tl\EUR{\g__letgut_bookreview_price_tl} + } + \par + }{ + \exp_args:NV \author{\g__letgut_bookreview_reviewer_tl} + } +#+end_src + +** Miscellanous + +- We specify the possible hyphenations of \enquote{\gutenberg}. +#+begin_src latex + \hyphenation{GUT-enberg} +#+end_src + +*** Non selectable text + +We create a control sequence that makes its argument not selectable in the +PDF. This will be used notably for the line numbers of the listings and the +watermarks. +#+begin_src latex +\cs_new_protected:Npn \__letgut_unselectable:n #1 +{ + \BeginAccSupp{ActualText={}}#1\EndAccSupp{} +} +#+end_src + +*** Typesetting of code, etc. + + We provide a ~\meta~ macro that (poorly) mimics the one of the + \package*{doc}. It is added at the very end of the preamble since other + package that provide a better definition of this macro may have been loaded + (e.g. \package{tcolorbox}). + #+begin_src latex + \colorlet {__letgut_meta} { + brown + } + \cs_new_protected:Nn \__letgut_meta:nn + { + \bgroup + \normalfont + \ttfamily + \itshape + \textcolor{#1}{$\langle$#2$\rangle$} + \egroup + } + \AddToHook{begindocument/before}{ + \ProvideDocumentCommand{\meta}{ O{__letgut_meta} m } { + \__letgut_meta:nn {#1}{#2} + } + } + #+end_src + +** LaTeX listings and examples + +We first define some colors used in the listings and examples. + +#+begin_src latex + \definecolor{__letgut_backgroundCode}{cmyk}{0,0,0,0.04} + \definecolor{__letgut_borderCode}{cmyk}{0,0,0,0.2} + \definecolor{__letgut_foregroundLinenumber}{cmyk}{0,0,0,0.5} + \definecolor{__letgut_foregroundMention}{cmyk}{0,0,0,0} + \definecolor{__letgut_backgroundResult}{cmyk}{0,0,0,0} +#+end_src + +We now define the colors for the syntax highlighting and define the style of our +listings. + +#+begin_src latex + \colorlet{__letgut_texcs}{blue} + \colorlet{__letgut_comment}{gray} + \colorlet{__letgut_argument-specification-separator}{red} + \colorlet{__letgut_argument-specification}{cyan} + \colorlet{__letgut_mandatory-argument}{purple} + \colorlet{__letgut_environment}{teal} + \colorlet{__letgut_key}{__letgut_mandatory-argument} + \colorlet{__letgut_value}{violet} + \colorlet{__letgut_optional-argument}{__letgut_key} + \colorlet{__letgut_math}{green!50!black} + \lstset{% + texcsstyle=*\color{__letgut_texcs}, + commentstyle=\color{__letgut_comment}\itshape, + keywordstyle= \color{__letgut_argument-specification-separator}, + keywordstyle={[2]\color{__letgut_environment}}, + keywordstyle={[3]\color{__letgut_key}}, + keywordstyle={[4]\color{__letgut_value}}, + keywordstyle={[5]\color{__letgut_argument-specification}}, + keywordstyle={[6]\color{__letgut_key}}, + escapechar=£, + literate=*% + {\\\\}{{{\color{__letgut_texcs}\textbackslash\textbackslash}}}{2}% + {\\[}{{\textcolor{__letgut_math}{\textbackslash[}}}{2}% + {\\]}{{\textcolor{__letgut_math}{\textbackslash]}}}{2}% + {$}{{\textcolor{__letgut_math}{\$}}}{1}%$ + } +#+end_src + +For the listings and examples, we rely on \package*{tcolorbox}, and more +specifically on some of its libraries. + +#+begin_src latex + \tcbuselibrary{listings,xparse,breakable,skins} +#+end_src + +The functions: + +- ~\__letgut_code_result_mention_box:n~ draws the mentions “code” and “résultat” + in the codes boxes and the possible corresponding results boxes, +- ~\__letgut_title_code_result_box:n~ for the title of codes and the results + boxes: “Exemple” followed by the number of the example and, if a ~title addon~ + option is provided, the specified title addon. + +#+begin_src latex + \cs_new_protected:Npn \__letgut_code_result_mention_box:nn #1 #2 + { + \node[ + minimum~ width=1cm, + minimum~ height=\c__letgut_height_mentions_dim, + outer~ sep=auto, + anchor=north~ east, + fill=__letgut_borderCode + ]~ at~ (#1) + { + \itshape + \small + \color{__letgut_foregroundMention} + \__letgut_unselectable:n {#2} + }; + } + \cs_new_protected:Npn \__letgut_title_code_result_box:n #1 + { + Exemple~ \thetcbcounter + \tl_if_empty:NF {#1} { \hypersetup{hidelinks} \c_space_tl :~#1 } + } + \cs_new_protected:Nn \__letgut_on_callout_page:nn + { + \tl_set:Nn \l_tmpa_int {\getpagerefnumber{#1}} + \tl_set:Nn \l_tmpb_int {\thepage} + \int_compare:nNnF {\l_tmpa_int} = {\l_tmpb_int} + {#2} + } +#+end_src + +We define the style of the codes and the results boxes. + +#+begin_src latex + \tl_set:Nn \l__letgut_reference_text_tl { + Cf.~\vref{\g__letgut_label_ltx_example_str}. + } + \tcbset{ + __letgut_code/.style={ + listing~ options={ + % style=tcblatex, + numbers=left, + numbersep=\c__letgut_number_sep_dim, + #+end_src + We want the line numbers to not be selectable, hence the ~\__letgut_unselectable:n~:. + #+begin_src latex + numberstyle= + \scriptsize + \ttfamily + \color{__letgut_foregroundLinenumber} + \__letgut_unselectable:n, + }, + every~ float=\raggedleft, + colback=__letgut_backgroundCode, + breakable, + sharp~ corners, + boxrule=0.25mm, + colframe=__letgut_borderCode, + sidebyside~ align=top~ seam, + toprule~ at~ break=0mm, + bottomrule~ at~ break=0mm, + colbacktitle=__letgut_borderCode, + fonttitle=\sffamily\bfseries, + before~ title={ + \tl_set:Nn \l__letgut__tex_stuff_font_switch_tl {\rmfamily} + }, + #+end_src +We define a custom \package*{tcolorbox}'s ~title addon~ option that let us +specify an addon to the title which will added after the automatically +generated title “Exemple \meta{number}”. + #+begin_src latex + title~ addon/.store~ in=\l__letgut_title_addon_tl, + title=\__letgut_title_code_result_box:n {\l__letgut_title_addon_tl}, + #+end_src +We define a custom \package*{tcolorbox}'s ~reference text~ option that let us +override the text of the reference for the examples with code and result side by +side that are floating and not being of their call out pages. + #+begin_src latex + reference~ text/.code={ + \tl_set:Nn \l__letgut_reference_text_tl {##1} + }, + #+end_src +We define a custom \package*{tcolorbox}'s ~result width~ option that let us +specify the width of the result which is ~\linewidth~ by default. + #+begin_src latex + result~ width/.store~ in=\l__letgut_result_width_dim, + result~ width=\linewidth, + }, + __letgut_code_result/.style={ + __letgut_code={#1}, + bicolor, + colbacklower=__letgut_backgroundResult, + segmentation~ at~ break=false, + top=\c__letgut_height_mentions_dim, + middle=\c__letgut_height_mentions_dim, + #+end_src + We want the side by side code/result examples to automatically be floating. + #+begin_src latex + sidebyside@true/.code={% + \tcb@sidebysidetrue% + \tcb@isbreakablefalse% + \pgfkeysalso{floatplacement=ht}% + \pgfkeysalso{float}% + \pgfkeysalso{label={\g__letgut_label_ltx_example_str}}% + \tl_set:Nx \l_tmpa_tl { + \getpagerefnumber { + \g__letgut_callout_label_ltx_example_str + } + } + \tl_set:Nx \l_tmpb_tl { + \getpagerefnumber { + \g__letgut_label_ltx_example_str + } + } + \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl + { + \l__letgut_reference_text_tl + \tl_set:Nn \l__letgut_reference_text_tl { + Cf.~\vref{\g__letgut_label_ltx_example_str}. + } + \pgfkeysalso{ + drop~ shadow=black, + grow~ to~ left~ by=4cm, + boxed~ title~ style={sharp~ corners}, + } + \pgfkeysalso{after~ title~ app=\c_space_tl (cf.~page~\thepage)} + } + },% + overlay={ + \iftcb@sidebyside + \__letgut_code_result_mention_box:nn {segmentation.north} {code} + \__letgut_code_result_mention_box:nn {interior.north~ east} {résultat} + \else + \ifcase\tcbsegmentstate + % 0 = Box contains only an upper part + \__letgut_code_result_mention_box:nn {interior.north~ east} {code} + \or% + % 1 = Box contains an upper and a lower part + \__letgut_code_result_mention_box:nn {interior.north~ east} {code + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + \int_compare:nNnT {\thetcbbreakpart} > {1} {~(suite)} + } + \__letgut_code_result_mention_box:nn { + [yshift=.1mm]segmentation.east + } {résultat} + \else% + % 2 = Box contains only a lower part + \__letgut_code_result_mention_box:nn {interior.north~ east} {résultat + #+end_src + +# < (Just not to disturb the parentheses balancing +# detection of my editor.) + + #+begin_src latex + \int_compare:nNnT {\thetcbbreakpart} > {1} {~(suite)} + } + \fi + \fi + }, + }, + } +#+end_src + +The \package*{tcolorbox} listings defined below make use of +\package*{cleveref}'s features. But, since the latter package is loaded +~\AddToHook{begindocument/before}~, the same is needed for these listings. + +#+begin_src latex +\AddToHook{begindocument/before}{ +#+end_src + +We now define the environments that let us display: + +1. only LaTeX code: +#+begin_src latex + \DeclareTCBListing[ + auto~ counter, + crefname={exemple}{exemples} + ]{ltx-code}{ !O{} }{% + __letgut_code, + listing~ only, + #1% + } +#+end_src +1. both LaTeX code and its result: + 1. ordinary: +#+begin_src latex + \DeclareTCBListing[ + use~ counter~ from=ltx-code, + crefname={exemple}{exemples} + ]{ltx-code-result}{ !O{} }{% + __letgut_code_result, + #1% + } +#+end_src + 2. with the result obtained externally: +#+begin_src latex + \DeclareTCBListing[ + use~ counter~ from=ltx-code, + crefname={exemple}{exemples} + ]{ltx-code-external-result}{ O{} m }{% + __letgut_code_result, + listing~ and~ comment, + image~ comment={width=\l__letgut_result_width_dim}{#2}, + center~ lower, + #1% + } +#+end_src + +#+begin_src latex +} +#+end_src + +The examples with code and result side by side will be floating but we want the +ones being of their call out pages to have before and after them a reduced +vertical glue (~\g__letgut_reduced_intextsep_dim~). Hence we store the original +glue (~\intextsep~) in a custom one (~\g__letgut_orig_intextsep_dim~) in order +to retrieve the original skip for floats other than these ones. + +#+begin_src latex + \skip_const:Nn \c__letgut_orig_intextsep_skip {\intextsep} + \skip_const:Nn \c__letgut_reduced_intextsep_skip { + 4\p@ \@plus .667\p@ \@minus .667\p@ + } + #+end_src + +We now use hooks in order to... + + #+begin_src latex + \AddToHook{env/ltx-code-result/before}{ + \int_gincr:N \g__letgut_ltx_example_int + \str_set:Nx \g__letgut_label_ltx_example_str { + \c__letgut_label_ltx_example_str- + \int_use:N \g__letgut_ltx_example_int + } + \str_set:Nx \g__letgut_callout_label_ltx_example_str { + \c__letgut_callout_label_ltx_example_str- + \int_use:N \g__letgut_ltx_example_int + } + \label{\g__letgut_callout_label_ltx_example_str} + \tl_set:Nx \l_tmpa_tl { + \getpagerefnumber { + \g__letgut_callout_label_ltx_example_str + } + } + \tl_set:Nx \l_tmpb_tl { + \getpagerefnumber { + \g__letgut_label_ltx_example_str + } + } + \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl + { + \skip_set_eq:NN \intextsep \c__letgut_reduced_intextsep_skip + } + } +#+end_src + +** Local config file + +Each issue of the Lettre requires certain local configurations: configuration +dedicated to the issue in question, particular packages used in the articles, +specific configurations of the \package*{listings}, etc. In order to not clutter +the main \file*{.tex} of the Lettre, a local configuration file named +\file{localconf.tex}, if present in the current directory, is automatically +included at the end of the end of the preamble. And since this file is input in +the current category régime (~\ExplSyntaxOn~), a ~\ExplSyntaxOff~ is +automatically inserted at its beginning. + +#+begin_src latex + \file_if_exist:nT {./\c__letgut_local_config_file_tl}{ + \AddToHook { file/before/./\c__letgut_local_config_file_tl } { + \ExplSyntaxOff + } + \file_input:n {./\c__letgut_local_config_file_tl} + } +#+end_src + +We don't want the book review entry types to be listed in the bibliography +(they appears only thanks to the ~bookreview~ environment). + +#+begin_src latex + \ExecuteBibliographyOptions[bookreview]{skipbib,skiplab} +#+end_src + +#+begin_src latex + \endinput +#+end_src + +* (biblatex) Data model + +We give the (\package{biblatex}) data model that enriches the default one for +several purposes: +- the books reviews, +- the books advertisements. + +#+begin_src latex :tangle letgut.lbx :exports both + \ProvidesFile{letgut.lbx}[2022-03-18 v0.9 letgut localization] + \InheritBibliographyExtras{french} + \DeclareBibliographyStrings{ + inherit = {french}, + number = {{\no}{\no}}, + volume = {{volume}{vol\adddot}}, + volumes = {{volumes}{vol\adddot}}, + } + #+end_src + + We create the new bibliography driver ~bookreview~ (that seems to + create the corresponding new entry). + + #+begin_src latex :tangle letgut.dbx :exports both + \ProvidesFile{letgut.dbx}[2022-03-18 v0.9 letgut data model macros] + \DeclareBibliographyDriver{bookreview}{% + \usebibmacro{bibindex}% + \usebibmacro{begentry}% + \usebibmacro{author/editor+others/translator+others}% + \setunit{\printdelim{nametitledelim}} + \newblock + \usebibmacro{maintitle+title}% + \newunit + \printlist{language}% + \newunit\newblock + \usebibmacro{byauthor}% + \newunit\newblock + \usebibmacro{byeditor+others}% + \newunit\newblock + \printfield{edition}% + \newunit + \iffieldundef{maintitle} + {\printfield{volume}% + \printfield{part}} + {}% + \newunit + \printfield{volumes}% + \newunit\newblock + \usebibmacro{series+number}% + \newunit\newblock + \printfield{note}% + \newunit\newblock + \usebibmacro{publisher+location+date}% + \newunit\newblock + \usebibmacro{chapter+pages}% + \newunit + \printfield{pagetotal}% + \newunit\newblock + \iftoggle{bbx:isbn} + {\printfield{isbn}} + {}% + \newunit\newblock + \usebibmacro{doi+eprint+url}% + \newunit\newblock + \usebibmacro{addendum+pubstate}% + \setunit{\bibpagerefpunct}\newblock + \usebibmacro{pageref}% + \newunit\newblock + \iftoggle{bbx:related} + {\usebibmacro{related:init}% + \usebibmacro{related}} + {}% + \finentrypunct + \usebibmacro{finentry}} +#+end_src + +We provide a specific ~biblatex~ citation style . + +#+begin_src latex :tangle letgut.cbx :exports both + \ProvidesFile{letgut.cbx}[2022-03-18 v0.9 letgut base citation style] + \RequireCitationStyle{numeric} +#+end_src + +The books reviewed have their titles not only emphasized, but in bold face as +well... + +#+begin_src latex :tangle letgut.cbx :exports both + \DeclareFieldFormat[bookreview]{title}{\textbf{\emph{#1}}} +#+end_src + +... but not their subtitles. + +#+begin_src latex :tangle letgut.cbx :exports both + \renewbibmacro*{title}{% + \ifboolexpr{ + test {\iffieldundef{title}} + and + test {\iffieldundef{subtitle}} + } + {} + {\printtext[title]{% + \printfield[titlecase]{title}% + \setunit{\subtitlepunct}}% + \printfield[emph]{subtitle}% + \newunit}% + \printfield{titleaddon}} +#+end_src + +* Provided files + +** Example file of an issue of the newsletter + + #+begin_src latex :tangle lettre-example.tex :exports both + \documentclass{letgut} + + \letgutsetup{ + % % Option booléenne pour la version finale de la Lettre. + % % L'option contraire`draft` (par défaut) affiche + % % « Brouillon » en filigrane et actionne le package + % % `lua-typo`. + % + % , final + % + % % Option coloriant le fond de la page d'une couleur + % % par défaut (`1.0, 0.98, 0.94` en « rgb ») mais + % % modifiable au moyen de l'option `pagecolor` ci-dessous. + % + % , paper + % + % % Numéro de la Lettre + % + , number=44 + % + % % Date de la Lettre. Celle-ci est déduite de la + % % date du jour, mais peut être spécifiée sous la forme + % % AAAA-MM (avec garde-fous) ou librement + % % (p. ex. `date=Printemps 2021`). + % + % , date=2025-16 + % + % % Couleur de la page, à spécifier selon le modèle « rgb ». + % + % , pagecolor={1.0, 0.1, 0.94} + % + % % Couleur des hyperliens, à spécifier selon le modèle + % % « named ». + % + % , allcolorslinks=cyan + % + % % Un (r)appel à cotisation est automatiquement ajouté + % % en 1re page. Si on ne le souhaite pas, il suffit de + % % passer l'option `membership-reminder=false`. + % + % , membership-reminder=false + % + % % Si un fichier `editorial.tex`, on s'en doute censé + % % contenir l'éditorial, est présent dans le répertoire + % % courant, son contenu est automatiquement ajouté en + % % 1re page. Si un tel fichier est absent du répertoire + % % courant, une alerte est affichée à la place, sauf si, + % % parce qu'on ne souhaite pas d'éditorial, on passe + % % l'option `editorial=false`. + % + % , editorial=false + % + % % Les informations concernant GUTenberg, si elles + % % figurent dans un fichier `informations-gut.tex` + % % présent dans le répertoire courant, sont + % % automatiquement ajoutées en dernière page. + % % Si on ne souhaite pas que figurent ces + % % informations, il suffit de passer l'option + % % `informations=false`. + % + % , informations=false + } + + \setmainfont{TeX Gyre Schola} % Par exemple + + \usepackage[maths=both]{duckuments} + \usepackage{mwe} + + % \addbibresource{biblio.bib} + + \begin{document} + \duckument + \end{document} + + %%% Local Variables: + %%% mode: latex + %%% TeX-engine: luatex + %%% TeX-master: t + %%% End: + #+end_src + +** Example of an editorial + + #+begin_src latex :tangle editorial.tex :exports both + Ceci est un intéressant éditorial de la \lettregut{} + dans lequel on peut causer de l'\ag{} et du \ca{} + de l'association. Il peut aussi y être question du \ctan. + + \lipsum[1-5] + + \begin{figure}[ht] + \centering + \includegraphics[width=.7\linewidth]{example-image} + \caption{Ducks ?} + \label{fig:ducks} + \end{figure} + + \lipsum[6-10] + #+end_src + +** Informations about \gutenberg + + #+begin_src latex :tangle informations-gut.tex :exports both + \enlargethispage{1.5cm} + \small + \vspace*{-1cm} + \hspace*{-1.5cm}% + \raisebox{-\height+0.7\baselineskip}{% + \begin{minipage}[t]{.6\textwidth}%\vspace{0pt}% + \includegraphics[width=\linewidth]{logo-gut.pdf} + \end{minipage}% + }% + \hfill% + \begin{minipage}[t]{.4\textwidth}%\vspace{0pt}% + \footnotesize\raggedleft% + Association \gut{}\\ + 15 rue des Halles -- \textsc{bp} 74\\ + 75001 Paris\\ + France\\ + \nolinkurl{secretariat@gutenberg.eu.org} + \end{minipage}% + + \begin{description} + \item[Site internet :] \url{https://www.gutenberg.eu.org/} + \item[\Cahiers{} :] \url{http://cahiers.gutenberg.eu.org/} + \item[Problèmes techniques :] + \leavevmode + \begin{description} + \item[la liste \texttt{gut} :] + \url{https://www.gutenberg.eu.org/-Listes-de-diffusion-} + \item[le site \TeX nique de questions et réponses :] + \url{https://texnique.fr/} + \item[la foire aux questions :] + \url{https://faq.gutenberg.eu.org} + \end{description} + \end{description} + % + \alertbox{% + Cette association est la vôtre: faites-nous part de + vos idées, de vos envies, de vos préoccupations + à l'adresse \nolinkurl{secretariat@gutenberg.eu.org}.% + } + + % \section[Association GUTenberg (tout sur l')] + % {Adhésion à l'association} + \title{Adhésion à l'association} + \label{letgut_label_adhesions} + + \begin{itemize} + \item % Adhésions et abonnements + Les adhésions sont à renouveler en début d'année + pour l'année civile. + % \item Il n'y a pas de lettre de rappel, chaque membre + % doit faire son renouvellement annuel; %\hspace*{1em} + % merci de renvoyer spontanément le bulletin ci-dessous + % en début d'année. + \item Les administrations peuvent joindre un bon de commande + revêtu de la signature de la personne responsable ; + les étudiants doivent joindre un justificatif. + % \item Si vous souhaitez que vos coordonnées restent + % confidentielles, merci de le signaler. + \end{itemize} + + \section{Tarifs \the\year} + + Les membres de \gut\ peuvent adhérer à l'association + internationale, le \acf{tug}, et recevoir son bulletin + \emph{\acs{tug}boat} à un tarif préférentiel : + \begin{description} + \item[tarif normal :] \EUR{65} (au lieu de 85~\$) + \item[tarif étudiant :] \EUR{40} (au lieu de 55~\$) + \end{description} + % (\EUR{49,50}, étudiants et demandeurs d'emploi : + % \EUR{29}, au lieu de 85\$ et % 65\$). Voir + % \url{% + % https://www.gutenberg.eu.org/?Adherer-a-l-association% + % }. + + \footnotesize + \begin{center} + \begin{tabular}{lr} + \toprule + \textbf{Type d'adhésion} & \textbf{Prix} \\ + \midrule + Membre individuel & \EUR{30} \\ + Membre individuel + adhésion \acs{tug} & \EUR{95} \\ + Membre individuel étudiant/demandeur d'emploi & \EUR{15} \\ + Membre individuel étudiant + adhésion \acs{tug} & \EUR{55} \\ + Association d'étudiants & \EUR{65} \\ + Organisme à but non lucratif & \EUR{130} \\ + Organisme à but lucratif & \EUR{229} \\ + \bottomrule + \end{tabular} + \end{center} + + \section{Règlements} + + Les règlements peuvent s'effectuer par : + \begin{itemize} + \item \textbf{virement bancaire}% + \footnote{Nous vous remercions de \textbf{privilégier} + le \textbf{virement bancaire}.\label{fn:1}} (IBAN : + FR76 1870 7000 3003 0191 3568 475)% + \leavevmode + + \alertbox{% + Veillez à bien \emph{indiquer vos nom et prénom} + dans les références du virement !% + } + \item Paypal\footnotemark[\value{footnote}] : + \url{https://www.gutenberg.eu.org/?Adherer-en-ligne} + \item bulletin et chèque\footnotemark[\value{footnote}] : + \url{https://www.gutenberg.eu.org/?Adherer-a-l-association} + \end{itemize} + + \vfill + + \begin{center} + \begin{tblr}{ + width=.75\linewidth, + colspec={ + % < (Just not to disturb the parentheses + % balancing detection of my editor.) + >{\bfseries}r@{ }X + }, + vline{1,3}={solid}, + hline{1,7}={solid}, + rowsep=0mm, + row{1} = {abovesep+=.25cm}, + row{2} = {belowsep+=.125cm}, + row{6} = {belowsep+=.25cm}, + % colsep=2.5mm, + } + \SetCell[c=2]{c} \emph{La \lettregut}\\ + \SetCell[c=2]{c} \mdseries Bulletin irrégulomestriel + de l'association \gut\\ + Directeur de la publication : + & \person{Bideault, Patrick} \\ + Comité de rédaction : + & {Patrick \bsc{Bideault}, Denis \bsc{Bitouzé}, \\ + Céline \bsc{Chevalier} \& Maxime \bsc{Chupin}} \\ + Adresse de la rédaction : & + { + Association \gut\\ + 15 rue des Halles -- \textsc{bp} 74\\ + 75001 Paris + } + \\ + \acs{issn} : & 2742-6149 (version numérique) + \end{tblr} + \end{center} + \vfill + \mbox{} + \clearpage + + %%% Local Variables: + %%% mode: latex + %%% End: + #+end_src + +* Footnotes + +[fn:1]See \url{https://github.com/ho-tex/luacolor/issues/4\#issuecomment-848774260}. |