summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
Diffstat (limited to 'support')
-rw-r--r--support/TeX4ht/source/ChangeLog90
-rw-r--r--support/TeX4ht/source/mktex4ht-cnf.tex5
-rw-r--r--support/TeX4ht/source/tex4ht-4ht.tex273
-rw-r--r--support/TeX4ht/source/tex4ht-html4.tex111
-rw-r--r--support/TeX4ht/source/tex4ht-ooffice.tex122
-rwxr-xr-xsupport/epstopdf/epstopdf.pl10
-rw-r--r--support/latex-git-log/README.md22
-rw-r--r--support/latex-git-log/example-output.tex217
-rw-r--r--support/latex-git-log/example.pdfbin77887 -> 51051 bytes
-rw-r--r--support/latex-git-log/example.tex40
-rwxr-xr-xsupport/latex-git-log/latex-git-log81
-rw-r--r--support/latex-git-log/po/de.po8
-rw-r--r--support/latexindent/LatexIndent/GetYamlSettings.pm32
-rw-r--r--support/latexindent/LatexIndent/Logger.pm2
-rw-r--r--support/latexindent/LatexIndent/Sentence.pm4
-rw-r--r--support/latexindent/LatexIndent/Special.pm4
-rw-r--r--support/latexindent/LatexIndent/TrailingComments.pm32
-rw-r--r--support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm40
-rw-r--r--support/latexindent/LatexIndent/Version.pm4
-rw-r--r--support/latexindent/README2
-rw-r--r--support/latexindent/bin/linux/latexindentbin7847663 -> 7875395 bytes
-rw-r--r--support/latexindent/bin/macos/latexindentbin7564675 -> 7569205 bytes
-rw-r--r--support/latexindent/defaultSettings.yaml4
-rw-r--r--support/latexindent/documentation/contributors.bib11
-rw-r--r--support/latexindent/documentation/latexindent-yaml-schema.json9
-rw-r--r--support/latexindent/documentation/latexindent.pdfbin1297746 -> 1297627 bytes
-rw-r--r--support/latexindent/documentation/latexindent.tex72
-rwxr-xr-xsupport/latexindent/latexindent.pl2
-rw-r--r--support/pdfjam/VERSION2
-rwxr-xr-xsupport/pdfjam/bin/pdfjam4
-rw-r--r--support/pdfxup/README4
-rw-r--r--support/pdfxup/RELEASES4
-rw-r--r--support/pdfxup/doc/Makefile3
-rw-r--r--support/pdfxup/doc/pdfxup-doc.pdf (renamed from support/pdfxup/pdfxup.pdf)bin90128 -> 94798 bytes
-rw-r--r--support/pdfxup/doc/pdfxup-doc.tex163
-rw-r--r--support/pdfxup/doc/pdfxup.pdfbin0 -> 96697 bytes
-rwxr-xr-xsupport/pdfxup/pdfxup134
-rw-r--r--support/pdfxup/pdfxup.12
-rw-r--r--support/pkgcheck/CHANGES.md17
-rw-r--r--support/pkgcheck/Cargo.toml63
-rwxr-xr-xsupport/pkgcheck/bin/pkgcheckbin7266008 -> 8028168 bytes
-rw-r--r--support/pkgcheck/docs/errorsd.tex154
-rw-r--r--support/pkgcheck/docs/pkgcheck.pdfbin89893 -> 90348 bytes
-rw-r--r--support/pkgcheck/docs/title.tex2
-rw-r--r--support/pkgcheck/docs/warningsd.tex53
-rw-r--r--support/pkgcheck/src/gparser.rs1
-rw-r--r--support/pkgcheck/src/linkcheck.rs4
-rw-r--r--support/pkgcheck/src/main.rs338
-rw-r--r--support/pkgcheck/src/messages/errorsd.rs26
-rw-r--r--support/pkgcheck/src/messages/fatald.rs1
-rw-r--r--support/pkgcheck/src/messages/informationd.rs1
-rw-r--r--support/pkgcheck/src/messages/mod.rs76
-rw-r--r--support/pkgcheck/src/messages/warningsd.rs19
-rw-r--r--support/pkgcheck/src/recode.rs4
-rw-r--r--support/pkgcheck/src/utils.rs46
-rw-r--r--support/texlab/CHANGELOG.md17
-rw-r--r--support/texlab/Cargo.lock48
-rw-r--r--support/texlab/crates/base-db/src/config.rs54
-rw-r--r--support/texlab/crates/base-db/src/deps/graph.rs6
-rw-r--r--support/texlab/crates/base-db/src/deps/root.rs4
-rw-r--r--support/texlab/crates/base-db/src/document.rs5
-rw-r--r--support/texlab/crates/base-db/src/semantics/auxiliary.rs2
-rw-r--r--support/texlab/crates/base-db/src/semantics/tex.rs123
-rw-r--r--support/texlab/crates/base-db/src/workspace.rs2
-rw-r--r--support/texlab/crates/bibfmt/src/lib.rs6
-rw-r--r--support/texlab/crates/bibtex-utils/Cargo.toml2
-rw-r--r--support/texlab/crates/commands/Cargo.toml6
-rw-r--r--support/texlab/crates/commands/src/find_envs.rs2
-rw-r--r--support/texlab/crates/commands/src/fwd_search.rs2
-rw-r--r--support/texlab/crates/commands/src/placeholders.rs2
-rw-r--r--support/texlab/crates/completion-data/Cargo.toml6
-rw-r--r--support/texlab/crates/completion/Cargo.toml1
-rw-r--r--support/texlab/crates/completion/src/lib.rs8
-rw-r--r--support/texlab/crates/completion/src/providers/argument.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/color.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/color_model.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/command.rs4
-rw-r--r--support/texlab/crates/completion/src/providers/environment.rs6
-rw-r--r--support/texlab/crates/completion/src/providers/glossary.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/import.rs8
-rw-r--r--support/texlab/crates/completion/src/providers/include.rs6
-rw-r--r--support/texlab/crates/completion/src/providers/label_ref.rs46
-rw-r--r--support/texlab/crates/completion/src/providers/tikz_library.rs2
-rw-r--r--support/texlab/crates/completion/src/tests.rs213
-rw-r--r--support/texlab/crates/definition/src/command.rs12
-rw-r--r--support/texlab/crates/definition/src/tests.rs2
-rw-r--r--support/texlab/crates/diagnostics/src/chktex.rs2
-rw-r--r--support/texlab/crates/diagnostics/src/citations.rs6
-rw-r--r--support/texlab/crates/diagnostics/src/manager.rs10
-rw-r--r--support/texlab/crates/diagnostics/src/tests.rs4
-rw-r--r--support/texlab/crates/distro/Cargo.toml2
-rw-r--r--support/texlab/crates/highlights/src/lib.rs2
-rw-r--r--support/texlab/crates/hover/src/lib.rs12
-rw-r--r--support/texlab/crates/inlay-hints/src/label.rs1
-rw-r--r--support/texlab/crates/ipc/Cargo.toml4
-rw-r--r--support/texlab/crates/parser/src/build_log.rs2
-rw-r--r--support/texlab/crates/parser/src/config.rs24
-rw-r--r--support/texlab/crates/parser/src/latexmkrc.rs8
-rw-r--r--support/texlab/crates/references/src/command.rs2
-rw-r--r--support/texlab/crates/references/src/entry.rs4
-rw-r--r--support/texlab/crates/references/src/label.rs2
-rw-r--r--support/texlab/crates/rename/Cargo.toml1
-rw-r--r--support/texlab/crates/rename/src/command.rs7
-rw-r--r--support/texlab/crates/rename/src/entry.rs4
-rw-r--r--support/texlab/crates/rename/src/label.rs47
-rw-r--r--support/texlab/crates/rename/src/lib.rs30
-rw-r--r--support/texlab/crates/rename/src/tests.rs111
-rw-r--r--support/texlab/crates/texlab/Cargo.toml12
-rw-r--r--support/texlab/crates/texlab/src/features/folding.rs2
-rw-r--r--support/texlab/crates/texlab/src/features/rename.rs2
-rw-r--r--support/texlab/crates/texlab/src/main.rs1
-rw-r--r--support/texlab/crates/texlab/src/server.rs20
-rw-r--r--support/texlab/crates/texlab/src/server/extensions.rs28
-rw-r--r--support/texlab/crates/texlab/src/server/options.rs6
-rw-r--r--support/texlab/crates/texlab/src/util.rs2
-rw-r--r--support/texlab/crates/texlab/src/util/client_flags.rs6
-rw-r--r--support/texlab/crates/texlab/src/util/from_proto.rs80
-rw-r--r--support/texlab/crates/texlab/src/util/to_proto.rs11
-rw-r--r--support/texlab/texlab.14
-rw-r--r--support/texlab/texlab.pdfbin26307 -> 26397 bytes
-rw-r--r--support/texlogfilter/README7
-rwxr-xr-xsupport/texlogfilter/texlogfilter17
-rw-r--r--support/texlogfilter/texlogfilter.html7
-rw-r--r--support/texshop/README.txt2
-rw-r--r--support/texshop/texshop533.html29
-rw-r--r--support/texshop/texshop536.html64
126 files changed, 2586 insertions, 920 deletions
diff --git a/support/TeX4ht/source/ChangeLog b/support/TeX4ht/source/ChangeLog
index ccd09bba95..958b14b479 100644
--- a/support/TeX4ht/source/ChangeLog
+++ b/support/TeX4ht/source/ChangeLog
@@ -1,3 +1,93 @@
+2024-06-21 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (arydshln.4ht): fixed clash between Colortbl and
+ Arydshln packages.
+ https://tex.stackexchange.com/a/721185/2891
+
+2024-06-23 Karl Berry <karl@freefriends.org>
+
+ * tex4ht-cpright.tex: https for urls.
+
+2024-06-21 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-html4.tex (html4.4ht): don't use picture name as alt in
+ \epsfbox, it can lead to spurious characters in the resulting HTML.
+ Thanks to Rolf Brigola
+
+2024-06-20 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (footmisc.4ht): fixed handling of footnote counter
+ reset.
+ https://tex.stackexchange.com/a/720989/2891
+
+
+2024-06-17 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (tabularray.4ht): updated names of token lists that
+ holds rowspan and colspan.
+ https://tex.stackexchange.com/a/720800/2891
+
+2024-06-15 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (nameref.4ht): use \@currentlabelname if \NR:Title
+ is not set.
+ https://tex.stackexchange.com/a/720647/2891
+
+2024-06-10 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (babel-sty-hooks.4ht): use \ProvideDocumentCommand
+ to define \:babelfont, in order to prevent errors if Babel is used
+ multiple times.
+ https://puszcza.gnu.org.ua/bugs/?626
+
+2024-06-06 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (listings.4ht): fixed error with otherkeywords
+ style.
+ https://tex.stackexchange.com/a/719878/2891
+
+2024-05-28 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-html4.tex (html4.4ht): renamed jurabib cofigurations to
+ jurabook.
+
+ * tex4ht-4ht.tex (jurabook.4ht): fixed footnotes handling in
+ Jurabook.
+ https://github.com/michal-h21/make4ht/issues/148
+
+2024-05-27 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-ooffice.tex (ooffice.4ht): added support for jurabook
+ sections and toc in the ODT format.
+ https://github.com/michal-h21/make4ht/issues/148
+
+ * tex4ht-4ht.tex (jurabook.4ht, juraovw.4ht, juraurtl.4ht),
+ * tex4ht-html4.tex (html4.4ht): added support for custom sectioning
+ commands provided by Jurabook.
+ https://github.com/michal-h21/make4ht/issues/148
+
+2024-05-22 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (imakeidx.4ht): added support for the
+ \indexprologue command.
+ https://tex.stackexchange.com/a/714548/2891
+
+2024-05-20 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (
+ index.4ht, imakeidx.4ht, memoir.4ht, indextools.4ht
+ ): added support for optional argument of \index used inside of
+ \caption.
+ https://tex.stackexchange.com/a/718360/2891
+
+2024-05-10 Michal Hoftich <michal.h21@gmail.com>
+
+ * tex4ht-4ht.tex (lettrine.4ht): defined more keys supported by the
+ \lettrine command.
+ https://tex.stackexchange.com/a/717883/2891
+ * tex4ht-html4.tex (html4.4ht): moved HTML declarations for the
+ Lettrine package from lettrine.4ht.
+
2024-05-10 Michal Hoftich <michal.h21@gmail.com>
* tex4ht-fonts-noncjk.tex (
diff --git a/support/TeX4ht/source/mktex4ht-cnf.tex b/support/TeX4ht/source/mktex4ht-cnf.tex
index 9fdfe40b68..7bc692fff6 100644
--- a/support/TeX4ht/source/mktex4ht-cnf.tex
+++ b/support/TeX4ht/source/mktex4ht-cnf.tex
@@ -1,4 +1,4 @@
-% $Id: mktex4ht-cnf.tex 1502 2024-04-18 12:55:56Z michal_h21 $
+% $Id: mktex4ht-cnf.tex 1523 2024-05-27 14:16:04Z michal_h21 $
% Manually-maintained file, listing *.4ht files created by tex4ht-4ht.tex.
% Read by tex4ht-cond4ht.
%
@@ -111,6 +111,9 @@
\AddFile{9}{scrbook}
\AddFile{9}{scrartcl}
\AddFile{9}{scrreprt}
+\AddFile{9}{jurabook}
+\AddFile{9}{juraurtl}
+\AddFile{9}{juraovw}
\AddFile{6}{letter}
\AddFile{9}{elsart}
\AddFile{9}{apa}
diff --git a/support/TeX4ht/source/tex4ht-4ht.tex b/support/TeX4ht/source/tex4ht-4ht.tex
index 8d96fba96d..16387851fd 100644
--- a/support/TeX4ht/source/tex4ht-4ht.tex
+++ b/support/TeX4ht/source/tex4ht-4ht.tex
@@ -1,4 +1,4 @@
-% $Id: tex4ht-4ht.tex 1516 2024-05-09 13:28:51Z michal_h21 $
+% $Id: tex4ht-4ht.tex 1535 2024-06-23 20:28:31Z michal_h21 $
% tex tex4ht-4ht or ht tex tex4ht-4ht
%
% Copyright 2009-2024 TeX Users Group
@@ -3487,11 +3487,20 @@ configuration until now. It seems to be useful when we need to inject something
into the environment without messing the existing \`|\ConfigureEnv|
definitions.
+% Michal 2024-06-15
+% I've added use of \a:newlabel{\@currentlabelname} if \NR:Type is empty.
+% It seems to add support for name ref labels that are not supported yet
+% We need to empty \NR:Type after \label. I hope this doesn't break anything.
+% https://tex.stackexchange.com/a/720647/2891
+
\<nameref v.2 configurations\><<<
\let\NR:Type\relax
\let\ltx@label\label
-\def\prf:label{{\ifx \NR:Title\:UnDef \else \NR:Title\fi}%
+\def\prf:label{{\ifx \NR:Title\:UnDef \a:newlabel{\@currentlabelname}\else \NR:Title\fi}%
{\ifx \NR:Type\relax \else \NR:Type .1\fi}{}}%
+
+\append:defI\label{\let\NR:Title\undefined}
+
\let\NR:StartSec\:StartSec
\let\NR:no@sect\no@sect
\def\no@sect#1#2#3#4#5#6[#7]#8{\gdef\NR:Title{\a:newlabel{#7}}%
@@ -11216,12 +11225,13 @@ compilation errors
\<arydshln.4ht\><<<
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% arydshln.4ht (|version), generated from |jobname.tex
-% Copyright 2022 TeX Users Group
+% Copyright 2022-2024 TeX Users Group
|<TeX4ht license text|>
% this is a copy of code that arydshln inserts to \@array
\def\:new:array{\adl@everyvbox\everyvbox
\everyvbox{\adl@arrayinit \the\adl@everyvbox \everyvbox\adl@everyvbox}%
- \ifadl@inactive \adl@inactivate \else \adl@activate \fi
+ % this line may lead to errors if the document uses Colortbl:
+ % \ifadl@inactive \adl@inactivate \else \adl@activate \fi
\let\adl@noalign\noalign}
\ifcsname n:@array:\endcsname% if \@array was already patched by TeX4ht
\let\orig:n@array\n:@array:
@@ -11335,7 +11345,7 @@ We need to load the tabularx package, because we use it instead of Tabu for actu
\<tabularray.4ht\><<<
% tabularray.4ht (|version), generated from |jobname.tex
-% Copyright 2022-2023 TeX Users Group
+% Copyright 2022-2024 TeX Users Group
|<TeX4ht license text|>
|<tabularray definitions|>
|<tabularray table and rows|>
@@ -11441,13 +11451,13 @@ for horizontal and vertical alignment, background color and rules.
% find columns that are covered by rowspan and colspan
\xdef\HCol{\@arabic\c@colnum}
\xdef\HRow{\@arabic\c@rownum}
- \xdef\HMultispan{\l__tblr_cell_colspan_tl}
- \xdef\HRowspan{\l__tblr_cell_rowspan_tl}
+ \xdef\HMultispan{\lTblrCellColSpanTl}
+ \xdef\HRowspan{\lTblrCellRowSpanTl}
\let\CellAttributes\@empty
\let\CellStyle\@empty
% calculate ignored cells, if the current cell uses colspan or rowspan
- \int_step_inline:nnn{\c@rownum }{\c@rownum - 1 + \l__tblr_cell_rowspan_tl}{
- \int_step_inline:nnn{\c@colnum }{\c@colnum - 1 + \l__tblr_cell_colspan_tl}{
+ \int_step_inline:nnn{\c@rownum }{\c@rownum - 1 + \lTblrCellRowSpanTl}{
+ \int_step_inline:nnn{\c@colnum }{\c@colnum - 1 + \lTblrCellColSpanTl}{
% the loop always matches the current cell, we must ignore it
\str_if_eq:eeF{\HCol.\HRow}{####1.##1}{%
\cs_gset:cpn{ignoredcell-####1-##1}{}
@@ -12261,6 +12271,13 @@ and print them when it is safe.
\ExplSyntaxOff
>>>
+\<latex caption index optional\><<<
+\ExplSyntaxOn
+\renewcommand\:saveindex[2][]{\seq_gput_right:Nn\:savedindex{[#1]{#2}}}
+\def\:printsavedindex{\seq_map_inline:Nn\:savedindex{\index##1}}
+\ExplSyntaxOff
+>>>
+
\<latex caption index save\><<<
\:initsaveindex%
\let\index\:saveindex%
@@ -16518,6 +16535,7 @@ DIV.right
\<memoir.4ht\><<<
% memoir.4ht (|version), generated from |jobname.tex
% Copyright |CopyYear.2003. Eitan M. Gurari
+% Copyright 2003-2024 TeX Users Group
|<TeX4ht copywrite|>
\input book.4ht
\input verse.4ht
@@ -16530,6 +16548,7 @@ DIV.right
|<memoir 2008|>
|<mempatch cfg|>
\fi
+|<latex caption index optional|>
\Hinput{memoir}
\endinput
>>> \AddFile{8}{memoir}
@@ -19214,6 +19233,119 @@ UnDFexyz}%
\HtmlEnv \Toc:Title{#1}\:addchap{#2}}
>>>
+%%%%%%%%%%%%%%%%%%
+\Chapter{juramisc}
+%%%%%%%%%%%%%%%%%%
+
+Classes in the Juramisc bundle
+
+\<jurabook.4ht\><<<
+% jurabook.4ht (|version), generated from |jobname.tex
+% Copyright 2024 TeX Users Group
+|<TeX4ht copywrite|>
+|<jurabook subsections|>
+|<jurabook toc|>
+|<jurabook footnotes|>
+\Hinput{jurabook}
+>>> \AddFile{9}{jurabook}
+
+\<juraurtl.4ht\><<<
+% juraurtl.4ht (|version), generated from |jobname.tex
+% Copyright 2024 TeX Users Group
+|<TeX4ht copywrite|>
+\Hinput{juraurtl}
+>>> \AddFile{9}{juraurtl}
+
+\<juraovw.4ht\><<<
+% juraovw.4ht (|version), generated from |jobname.tex
+% Copyright 2024 TeX Users Group
+|<TeX4ht copywrite|>
+\Hinput{juraovw}
+>>> \AddFile{9}{juraovw}
+
+\Section{Jurabook sections}
+
+Jurabook defines lot of extra sectioning commands, so we need to
+define them. Other than that, it reuses classic LaTeX classes, so
+other sectioning commands should work out of the box.
+
+\<jurabook subsections\><<<
+\let\no@subthreesection\subthreesection
+\Def:Section\subthreesection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubthreesection \fi}{#1}
+\let\no:subthreesection\subthreesection
+\def\subthreesection{\rdef:sec{subthreesection}}
+
+\let\no@subfoursection\subfoursection
+\Def:Section\subfoursection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubfoursection \fi}{#1}
+\let\no:subfoursection\subfoursection
+\def\subfoursection{\rdef:sec{subfoursection}}
+
+\let\no@subfivesection\subfivesection
+\Def:Section\subfivesection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubfivesection \fi}{#1}
+\let\no:subfivesection\subfivesection
+\def\subfivesection{\rdef:sec{subfivesection}}
+
+\let\no@subsixsection\subsixsection
+\Def:Section\subsixsection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubsixsection \fi}{#1}
+\let\no:subsixsection\subsixsection
+\def\subsixsection{\rdef:sec{subsixsection}}
+
+
+\let\no@subsevensection\subsevensection
+\Def:Section\subsevensection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubsevensection \fi}{#1}
+\let\no:subsevensection\subsevensection
+\def\subsevensection{\rdef:sec{subsevensection}}
+
+
+\let\no@subeightsection\subeightsection
+\Def:Section\subeightsection{\ifnum \c:secnumdepth>\c@secnumdepth \else
+ \thesubeightsection \fi}{#1}
+\let\no:subeightsection\subeightsection
+\def\subeightsection{\rdef:sec{subeightsection}}
+>>>
+
+We need to include these sectionins in the TOC
+
+\<jurabook toc\><<<
+\NewConfigure{tableofcontents*}[1]{%
+ \def\:tempa{#1}\ifx\empty\:tempa
+ \ifx \au:StartSec\:UnDef \else \gdef\:StartSec{\au:StartSec}\fi
+ \else
+ \edef\auto:toc{#1}%
+ \ifx \au:StartSec\:UnDef
+ \let\au:StartSec\:StartSec
+ \def\:StartSec{\:tableofcontents
+ \global\let\auto:toc\:UnDef \global\let\:StartSec\au:StartSec\:StartSec}%
+ \append:def\tableofcontents{\gdef\:StartSec{\au:StartSec}}%
+ \fi \fi
+}
+
+\Configure{tableofcontents*}{part,chapter,section,subsection,subsubsection,subthreesection,subfoursection,subfivesection,subsixsection,subsevensection,subeightsection}
+>>>
+
+This code is a copy from jurabook.cls. It rewrites the default version used by
+Jurabook, which starts a list environment. This leads to HTML tag mismatches
+and is unnecessary in general.
+
+The \`'\@makefntext' command will be redefined again in book.4ht, so we don't need to
+insert TeX4ht hooks in this version.
+
+\<jurabook footnotes\><<<
+ \renewcommand{\@makefntext}[1]{%
+ \stepcounter{totalfootnotes}%
+ \renewcommand{\baselinestretch}{\@ne}% (nur) dieses hinzugefuegt fuer einzeilige Ausgabe
+ \parindent 1em%
+ \noindent%
+ \@infootnotetrue%
+ \hb@xt@1.8em{\hss\@makefnmark}#1%
+ \@infootnotefalse}
+>>>
+
%%%%%%%%%%%%%%%%%%%
\Chapter{letter}
%%%%%%%%%%%%%%%%%
@@ -24820,7 +24952,7 @@ Handle circumflex catcodes when the \Verb|early^| option is used.
\<babel-sty-hooks.4ht\><<<
% babel-sty-hooks.4ht, generated from |jobname.tex
-% Copyright 2022 TeX Users Group
+% Copyright 2022-2024 TeX Users Group
|<TeX4ht license text|>
|<disable early sup|>
|<babelfont|>
@@ -24832,7 +24964,7 @@ It can cause fatal errors, because it changes font encodings
and can cause loating of OTF fonts
\<babelfont\><<<
-\NewDocumentCommand\:babelfont{o m o m}{}
+\ProvideDocumentCommand\:babelfont{o m o m}{}
\:AtEndOfPackage{%
% disable \babelfont
@@ -32413,6 +32545,7 @@ not necessary in MathML anyway.
\<index.4ht\><<<
% index.4ht (|version), generated from |jobname.tex
% Copyright |CopyYear.1999. Eitan M. Gurari
+% Copyright 2024 TeX Users Group
|<TeX4ht copywrite|>
|<index shared|>
\expandafter\ifx \csname @vwritefile\endcsname\relax
@@ -32420,6 +32553,7 @@ not necessary in MathML anyway.
\else
|<index 3.02|>
\fi
+|<latex caption index optional|>
\Hinput{index}
\endinput
>>> \AddFile{7}{index}
@@ -32519,11 +32653,11 @@ multind.sty\EndLink
\<imakeidx.4ht\><<<
% imakeidx.4ht (|version), generated from |jobname.tex
-% Copyright 2019-2022 TeX Users Group
+% Copyright 2019-2024 TeX Users Group
|<TeX4ht license text|>
|<imakeidx.sty|>
-
+|<latex caption index optional|>
\Hinput{imakeidx}
\endinput
@@ -32558,10 +32692,10 @@ destination to the idx file
\fi
>>>
-Support for the intoc option of Imakeidx:
+Support for the intoc option of Imakeidx and the \`'\indexprologue' command.
\<imakeidx.sty\><<<
-\Configure{@begin}{theindex}{\ind:defs\imki@maybeaddtotoc}
+\Configure{@begin}{theindex}{\ind:defs\imki@maybeaddtotoc\imki@idxprologue\global\let\imki@idxprologue\relax}
>>>
Prevent the automatic index compilation, the index produced by tex4ht
@@ -32588,11 +32722,12 @@ d|<haddr prefix|>\last:haddr
\<indextools.4ht\><<<
% indextools.4ht (|version), generated from |jobname.tex
-% Copyright 2022 TeX Users Group
+% Copyright 2022-2024 TeX Users Group
|<TeX4ht license text|>
|<indextools index|>
|<indextools defs|>
|<indextools disable options|>
+|<latex caption index optional|>
\Hinput{indextools}
\endinput
@@ -33218,10 +33353,17 @@ content.
\NewConfigure{listings-init}{2}
>>>
+Use the TextStyle hook to insert markup for inline listings. This hook can
+be used also in other contexts, so we need to execute it conditionally,
+based on the \Verb|\lst@ifmode| condition.
+See \Link[https://tex.stackexchange.com/q/719828/2891]{}{}for example\EndLink.
+
\<listings sty\><<<
\lst@AddToHook{TextStyle}{%
\Configure{listings}{}{}{}{}%
- \a:lstinline \bgroup \aftergroup\b:lstinline\aftergroup\egroup
+ \lst@ifmode\else%
+ \a:lstinline \bgroup \aftergroup\b:lstinline\aftergroup\egroup%
+ \fi%
}
\NewConfigure{lstinline}{2}
>>>
@@ -34954,7 +35096,7 @@ but fatal error is a worse possibility.
% Lettrine
\<lettrine.4ht\><<<
% lettrine.4ht (|version), generated from |jobname.tex
-% Copyright 2012-2018 TeX Users Group
+% Copyright 2012-2024 TeX Users Group
|<TeX4ht license text|>
|<config lettrine|>
\Hinput{lettrine}
@@ -34963,10 +35105,24 @@ but fatal error is a worse possibility.
\<config lettrine\><<<
\NewConfigure{lettrine}{7}
+\NewConfigure{lettrinechar}{2}
\define@key{L}{ante}{\def\LH:ante{#1}}%
\define@key{L}{findent}{\def\LH:findent{#1}}%
\define@key{L}{lhang}{\def\LH:lhang{#1}}%
\define@key{L}{lines}{\def\LH:lines{#1}}%
+\define@key{L}{slope}{}
+\define@key{L}{depth}{}
+\define@key{L}{loversize}{}
+\define@key{L}{lraise}{}
+\define@key{L}{nindent}{}
+\define@key{L}{novskip}{}
+\define@key{L}{image}{}
+\define@key{L}{grid}{}
+\define@key{L}{realheight}{}
+\define@key{L}{refstring}{}
+\define@key{L}{refstring}{}
+\define@key{L}{optionsfile}{}
+
\def\reset:LH:keys{\let\LH:ante\@empty
\def\LH:lines{2}%
\def\LH:lhang{0}%
@@ -34979,48 +35135,9 @@ but fatal error is a worse possibility.
\a:lettrine
\ifx\LH:ante\@empty\else\f:lettrine\LH:ante\g:lettrine\fi
\c:lettrine
- \HCode{<span class="lettrine-}#2\HCode{">}#2\HCode{</span>}
+ \a:lettrinechar#2\b:lettrinechar
\b:lettrine\d:lettrine#3\e:lettrine
\reset:LH:keys}
-%
-% a: before lettrine
-% b: after lettrine
-% c: before letter
-% d: between letter and string
-% e: after string
-% f: before ante
-% g: after ante
-%
-\Configure{lettrine}
- {\HCode{<span class="lettrine">}}
- {\HCode{</span>}}
-%
- {\HCode{<span class="lettrine-letter">}}
- {\HCode{</span><span class="lettrine-line">}}
- {\HCode{</span>}}
-%
- {\HCode{<span class="lettrine-ante">}}
- {\HCode{</span>}}
-%
-% Define default Css
-%
-\Css{.lettrine{float: left;
- line-height: 0.7; margin-left: -0.1em;
- margin-bottom: -.5em; margin-right: 0.2em;
- }}
-\Css{.lettrine-ante{vertical-align: top;}}
-\Css{.lettrine-letter{font-style: normal;
- font-size: 4em; color: gray;}}
-%
-\Css{.lettrine-A{margin-right: 0.3em;}}
-\Css{.lettrine-A + .lettrine-line{margin-left: -0.4em;}}
-\Css{.lettrine-J{line-height: 1; margin-right: 0;}}
-\Css{.lettrine-H, .lettrine-I, .lettrine-N, .lettrine-U{margin-right: 0;}}
-\Css{.lettrine-V{margin-right: -0.3em;}}
-\Css{.lettrine-V + .lettrine-line{margin-left: 0.3em;}}
-\Css{.lettrine-Q{padding-bottom: 1em;margin-top: -0.6em;}}
-\Css{.lettrine-line{font-variant: small-caps;}}
-\Css{p.indent{text-indent: 0em;}}
>>>
\Section{osudeG.sty}
@@ -37784,9 +37901,39 @@ Use
\<footmisc.4ht\><<<
% footmisc.4ht (|version), generated from |jobname.tex
-% Copyright 2019 TeX Users Group
+% Copyright 2019-2024 TeX Users Group
|<TeX4ht license text|>
+|<footmisc footnote counter|>
+|<footmisc footnotetext|>
+|<footmisc symbols|>
+
+
+\Hinput{footmisc}
+\endinput
+>>> \AddFile{9}{footmisc}
+Footmisc can reset the normal footnote counter on every page. Footnote links are
+then wrong, as they point to an earlier footnote. My solution is to use a global
+counter that gives each footnote unique number and which doesn't rely on the footnote
+symbol.
+
+\<footmisc footnote counter\><<<
+\newcounter{:footnotes}
+
+\def\FNnum{\the\:footnotes}
+
+\HRestore\footnote
+
+\def\:tempc{%
+ \HAssign\FNnum = \csname c@:footnotes\endcsname%
+ \stepcounter{:footnotes}%
+ \HAdvance\FNnum by 1%
+ \o:footnote:%
+}
+\HLet\footnote=\:tempc
+>>>
+
+\<footmisc footnotetext\><<<
\long\def\@footnotetext#1{\leavevmode
\vbox{%\IgnorePar
\leftskip0pt {\ht:everypar{}\parindent0pt\leavevmode}%
@@ -37805,6 +37952,9 @@ Use
\color@endgroup
\ht:special{t4ht@[}}\ht:special{t4ht@]}}
+>>>
+
+\<footmisc symbols\><<<
% detect if the symbol or symbol* option were used
% we can detect that by testing of \thefootnote macro
@@ -37821,10 +37971,7 @@ Use
\newcommand\p@footmisc@footnote[1]{\p@footnote{#1}}
\fi
\fi
-
-\Hinput{footmisc}
-\endinput
->>> \AddFile{9}{footmisc}
+>>>
%%%%%%%%%%%%%%%
\Section{tablefootnote}
diff --git a/support/TeX4ht/source/tex4ht-html4.tex b/support/TeX4ht/source/tex4ht-html4.tex
index 4c591c9b37..eb45f6f2ac 100644
--- a/support/TeX4ht/source/tex4ht-html4.tex
+++ b/support/TeX4ht/source/tex4ht-html4.tex
@@ -1,4 +1,4 @@
-% $Id: tex4ht-html4.tex 1516 2024-05-09 13:28:51Z michal_h21 $
+% $Id: tex4ht-html4.tex 1533 2024-06-21 13:38:57Z michal_h21 $
% Compile 4 times: latex tex4ht-html4
% Copy html4.4ht into the work directory before all but the last compilation.
%
@@ -9041,8 +9041,70 @@ The hbox is for avoiding the start of a new paragraph, if in vmode.
+%%%%%%%%%%%%%%%%%%
+\section{juramisc}
+%%%%%%%%%%%%%%%%%%
+
+\<configure html4 jurabook\><<<
+|<jurabook sections|>
+|<jurabook toc|>
+>>>
+
+\<configure html4 juraurtl\><<<
+>>>
+
+\<configure html4 juraovw\><<<
+>>>
+
+\<jurabook sections\><<<
+\Configure{subthreesection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subthreesection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subthreesection}{\HCode{<span class="titlemark">}\thesubthreesection\HCode{</span>}}
+
+\Configure{subfoursection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subfoursection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subfoursection}{\HCode{<span class="titlemark">}\thesubfoursection\HCode{</span>}}
+
+\Configure{subfivesection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subfivesection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subfivesection}{\HCode{<span class="titlemark">}\thesubfivesection\HCode{</span>}}
+
+\Configure{subsixsection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subsixsection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subsixsection}{\HCode{<span class="titlemark">}\thesubsixsection\HCode{</span>}}
+
+
+\Configure{subsevensection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subsevensection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subsevensection}{\HCode{<span class="titlemark">}\thesubsevensection\HCode{</span>}}
+
+\Configure{subeightsection}
+ {}{}
+ {\ifvmode\IgnorePar\fi\EndP\HCode{<h5 class="subeightsection">}\TitleMark\space} {\HCode{</h5>}\par\ShowPar}
+
+\ConfigureMark{subeightsection}{\HCode{<span class="titlemark">}\thesubeightsection\HCode{</span>}}
+>>>
+\<jurabook toc\><<<
+\def\tocsubthreesection#1#2#3{\par\toc:num{subthreesection}{#1}{#2}\par}
+\def\tocsubfoursection#1#2#3{\par\toc:num{subfoursection}{#1}{#2}\par}
+\def\tocsubfivesection#1#2#3{\par\toc:num{subfivesection}{#1}{#2}\par}
+\def\tocsubsixsection#1#2#3{\par\toc:num{subsixsection}{#1}{#2}\par}
+\def\tocsubsevensection#1#2#3{\par\toc:num{subsevensection}{#1}{#2}\par}
+\def\tocsubeightsection#1#2#3{\par\toc:num{subeightsection}{#1}{#2}\par}
+
+>>>
%%%%%%%%%%%%%%%%%%
\section{letter}
@@ -13762,7 +13824,7 @@ for margin pars.
\<configure html4 epsf\><<<
\Configure{epsfsetgraph}
- {\Picture+[\PicName]{}}
+ {\Picture+[]{}}
{\EndPicture}
>>>
@@ -15872,6 +15934,51 @@ IE doesn't distinguish between upper and lower case characters in css
>>>
+\section{lettrine.sty}
+
+\<configure html4 lettrine\><<<
+%
+% a: before lettrine
+% b: after lettrine
+% c: before letter
+% d: between letter and string
+% e: after string
+% f: before ante
+% g: after ante
+%
+\Configure{lettrine}
+ {\HCode{<span class="lettrine">}}
+ {\HCode{</span>}}
+%
+ {\HCode{<span class="lettrine-letter">}}
+ {\HCode{</span><span class="lettrine-line">}}
+ {\HCode{</span>}}
+%
+ {\HCode{<span class="lettrine-ante">}}
+ {\HCode{</span>}}
+
+\Configure{lettrinechar}{\HCode{<span class="lettrine-\HlettrineChar">}}{\HCode{</span>}}
+%
+% Define default Css
+%
+\Css{.lettrine{float: left;
+ line-height: 0.7; margin-left: -0.1em;
+ margin-bottom: -.5em; margin-right: 0.2em;
+ }}
+\Css{.lettrine-ante{vertical-align: top;}}
+\Css{.lettrine-letter{font-style: normal;
+ font-size: 4em; color: gray;}}
+%
+\Css{.lettrine-A{margin-right: 0em;}}
+\Css{.lettrine-A + .lettrine-line{margin-left: -0.4em;}}
+\Css{.lettrine-J{line-height: 0.9; margin-right: 0;}}
+\Css{.lettrine-H, .lettrine-I, .lettrine-N, .lettrine-U{margin-right: 0;}}
+\Css{.lettrine-V{margin-right: -0.0em;}}
+\Css{.lettrine-V + .lettrine-line{margin-left: 0.3em;}}
+\Css{.lettrine-Q{line-height: 0.9;padding-bottom: 1em;margin-top: -0.6em;}}
+\Css{.lettrine-line{font-variant: small-caps;}}
+>>>
+
%%%%%%%%%%%%%%%%%%
\section{gmatrix.sty}
diff --git a/support/TeX4ht/source/tex4ht-ooffice.tex b/support/TeX4ht/source/tex4ht-ooffice.tex
index 65a79d3dcc..ed0a77f4ff 100644
--- a/support/TeX4ht/source/tex4ht-ooffice.tex
+++ b/support/TeX4ht/source/tex4ht-ooffice.tex
@@ -1,4 +1,4 @@
-% $Id: tex4ht-ooffice.tex 1455 2024-01-29 13:45:00Z michal_h21 $
+% $Id: tex4ht-ooffice.tex 1524 2024-05-27 19:41:45Z michal_h21 $
% compile 3 times: latex tex4ht-ooffice
% htlatex tex4ht-ooffice "xhtml,4,sections+"
%
@@ -4620,6 +4620,81 @@ a more desirable for translations into MS Word.
{\HCode{</text:h>\Hnewline}\par\ShowPar}
>>>
+\<jurabook sections\><<<
+\ConfigureMark{subthreesection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subthreesection}\fi }
+\Configure{subthreesection}
+ {\IgnorePar\EndP \HCode{<!--start of subthreesection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subthreesection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subthreesection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+\ConfigureMark{subfoursection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subfoursection}\fi }
+\Configure{subfoursection}
+ {\IgnorePar\EndP \HCode{<!--start of subfoursection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subfoursection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subfoursection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+\ConfigureMark{subfivesection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subfivesection}\fi }
+\Configure{subfivesection}
+ {\IgnorePar\EndP \HCode{<!--start of subfivesection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subfivesection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subfivesection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+\ConfigureMark{subsixsection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subsixsection}\fi }
+\Configure{subsixsection}
+ {\IgnorePar\EndP \HCode{<!--start of subsixsection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subsixsection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subsixsection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+\ConfigureMark{subsevensection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subsevensection}\fi }
+\Configure{subsevensection}
+ {\IgnorePar\EndP \HCode{<!--start of subsevensection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subsevensection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subsevensection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+\ConfigureMark{subeightsection}
+ {\ifnum \c:secnumdepth>\c@secnumdepth \expandafter\:gobble
+ \else \@seccntformat{subeightsection}\fi }
+\Configure{subeightsection}
+ {\IgnorePar\EndP \HCode{<!--start of subeightsection-->}}
+ {\IgnorePar\EndP \HCode{<!--end of subeightsection-->}}
+ {\HCode{<text:h
+ text:style-name="\csname a:Heading-4|<cond rtl class|>\endcsname"
+ \text:outlinelevel="4" ><text:span
+ text:style-name="subeightsection" >}\TitleMark\space
+ \HCode{</text:span>}\IgnoreIndent}
+ {\HCode{</text:h>\Hnewline}\par\ShowPar}
+>>>
+
@@ -5346,6 +5421,46 @@ Why we need the following in content.xml instead of styles.xml
|<content style 8|>%
>>>
+\<jurabook tocs\><<<
+\ConfigureToc{subthreesection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+
+\ConfigureToc{subfoursection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+\ConfigureToc{subfivesection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+\ConfigureToc{subsixsection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+\ConfigureToc{subsevensection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+\ConfigureToc{subeightsection}
+ {\HCode{<text:p text:style-name="P3" ><text:span
+ text:style-name="toc-mark" >}}
+ { \HCode{</text:span>}}
+ {}
+ {\HCode{</text:p>}}
+>>>
+
%%%%%%%%%%%%%
\subsection{Tables of Figures}
@@ -9427,6 +9542,11 @@ fn\the\c@footnote x\minipageNum
|<mwcls sections|>
>>>
+\<configure ooffice jurabook\><<<
+|<jurabook sections|>
+|<jurabook tocs|>
+>>>
+
\<configure ooffice slides\><<<
\Configure{maketitle}
{\HCode{<!--begin maketitle-->}}
diff --git a/support/epstopdf/epstopdf.pl b/support/epstopdf/epstopdf.pl
index df768ef815..1a59965017 100755
--- a/support/epstopdf/epstopdf.pl
+++ b/support/epstopdf/epstopdf.pl
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
use warnings;
-# $Id: epstopdf.pl 71121 2024-04-29 17:27:25Z karl $
+# $Id: epstopdf.pl 71584 2024-06-21 22:40:28Z karl $
# (Copyright lines below.)
#
# Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,9 @@ use warnings;
#
# emacs-page
#
-my $ver = "2.34";
+my $ver = "2.35";
+# 2024/06/21 2.35 (Karl Berry)
+# * path_sep for OS/2 is also ";".
# 2024/04/29 2.34 (Karl Berry)
# * if --debug is first argument, give more output.
# * do not check for kpsewhich in PATH unless restricted.
@@ -226,7 +228,7 @@ my $ver = "2.34";
### emacs-page
### program identification
my $program = "epstopdf";
-my $ident = '($Id: epstopdf.pl 71121 2024-04-29 17:27:25Z karl $)' . " $ver";
+my $ident = '($Id: epstopdf.pl 71584 2024-06-21 22:40:28Z karl $)' . " $ver";
my $copyright = <<END_COPYRIGHT ;
Copyright 2009-2024 Karl Berry et al.
Copyright 2002-2009 Gerben Wierda et al.
@@ -258,7 +260,7 @@ debug " on_cygwin=$on_cygwin, on_msys=$on_msys";
# Split PATH and use / as directory separator.
#
-my $path_sep = ( ($^O =~ /^MSWin/) ? ';' : ':' ); # not msys
+my $path_sep = ($^O =~ /^(OS2|MSWin)i/) ? ';' : ':'; # not msys
my @pdirs = split($path_sep, $ENV{"PATH"});
# Normalize directory separators to /. Always valid on Windows.
if ($on_windows_or_cygwin) {
diff --git a/support/latex-git-log/README.md b/support/latex-git-log/README.md
index f3d5f15f2c..c186186418 100644
--- a/support/latex-git-log/README.md
+++ b/support/latex-git-log/README.md
@@ -1,7 +1,15 @@
+<!--
+SPDX-FileCopyrightText: 2013,2020,2024 Robin Schneider <ypid@riseup.net>
+
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
# latex-git-log
This program will output the entire version history as table written in LaTeX
if it is executed within a git repository.
+When file argument(s) are given, only the history that changed these file(s)
+will be output.
It is intended that you redirect the standard output of this script to a file which can then be included from your main LaTeX document.
@@ -12,7 +20,7 @@ landscape page.
### Of this script
-This module requires these other modules and libraries:
+This script requires the following Perl modules:
IPC::System::Simple
Locale::Maketext::Simple
@@ -25,27 +33,25 @@ The table is using the *longtable* package and the links to a web resource for
each commit use the `\href` macro from *hyperref*. So these two packages have
to be loaded.
-Furthermore you need to defined the macro `\longtableendfoot` which will be
+Furthermore you need to define the macro `\longtableendfoot` which will be
expanded on the bottom of every page if the table will be continued on the next
page. You can defined it to a localized message to inform the reader that this
table is not complete and will be continued.
## License and development
-Copyright (C) 2012-2013,2017,2019-2020 Robin Schneider <ypid@riseup.net> <br/>
-SPDX-License-Identifier: GPL-3.0-or-later <br/>
+License: GPL-3.0-or-later <br/>
CTAN: https://ctan.org/pkg/latex-git-log <br/>
Source code repository: https://github.com/ypid/typesetting/tree/master/scripts/latex-git-log <br/>
Please report bugs and feature requests at https://github.com/ypid/typesetting/issues
## Usage
- latex-git-log [options]
+ latex-git-log [options] [file] ...
Options:
--author set this if you want the author included
- --startcommit set the start value of count commit
--width set the width in cm of the commit message field in the LaTeX table
--git-c-add set an base URL to link to a commit
--user set a github user to derive the base URL
@@ -80,3 +86,7 @@ Please report bugs and feature requests at https://github.com/ypid/typesetting/i
need a translation to another language then you can either
create a .po file or I can register this project on one of those
websites for online translation.
+
+## Bugs and limitations
+
+* The translation features does not seem to work. So this script is unable to output German. English works.
diff --git a/support/latex-git-log/example-output.tex b/support/latex-git-log/example-output.tex
index da2c199b5c..f8a396e651 100644
--- a/support/latex-git-log/example-output.tex
+++ b/support/latex-git-log/example-output.tex
@@ -1,9 +1,13 @@
-%% This file was generated by the script latex-git-log
-%% Base git commit URL: https://github.com/ypid/typesetting/commit
+% SPDX-FileCopyrightText: 2024 Robin Schneider <ypid@riseup.net>
+%
+% SPDX-License-Identifier: CC0-1.0 OR MIT
+
+% This file was generated by the script latex-git-log.
+% Base git commit URL: https://github.com/ypid/typesetting/commit
\begin{tabular}{lp{12cm}}
\label{tabular:legend:git-log}
\textbf{acronym} & \textbf{meaning} \\
- V & \texttt{version} \\
+ H & \texttt{commit hash} \\
tag & \texttt{git tag} \\
MF & Number of \texttt{modified files}. \\
AL & Number of \texttt{added lines}. \\
@@ -12,9 +16,8 @@
\bigskip
-\iflanguage{ngerman}{\shorthandoff{"}}{}
-\begin{longtable}{|rllp{13cm}rrr|}
-\hline \multicolumn{1}{|c}{\textbf{V}} & \multicolumn{1}{c}{\textbf{tag}}
+\begin{longtable}{|rllp{12cm}rrr|}
+\hline \multicolumn{1}{|c}{\textbf{H}} & \multicolumn{1}{c}{\textbf{tag}}
& \multicolumn{1}{c}{\textbf{date}}
& \multicolumn{1}{c}{\textbf{commit message}} & \multicolumn{1}{c}{\textbf{MF}}
& \multicolumn{1}{c}{\textbf{AL}} & \multicolumn{1}{c|}{\textbf{DL}} \\ \hline
@@ -26,45 +29,165 @@
\hline% \hline
\endlastfoot
-\hline 1 & & 2012-08-18 & \href{https://github.com/ypid/typesetting/commit/3ff663fcfbc56662426740cf6bab2a840e320db6}{added template.dtx from http://texhacks.blogspot.de/2011/01/simpler-dtx-template.html} & 2 & 127 & 0 \\
-\hline 2 & & 2012-08-19 & \href{https://github.com/ypid/typesetting/commit/e9fc9a2847fe14067bb3ec8d4e4298ff8806f11f}{made my first changes on the docstrip template} & 2 & 40 & 48 \\
-\hline 3 & & 2012-08-19 & \href{https://github.com/ypid/typesetting/commit/cbc7bbcdda54f7b43f2039531d2a4f58c35f8964}{optimized} & 1 & 5 & 4 \\
-\hline 4 & & 2012-08-22 & \href{https://github.com/ypid/typesetting/commit/55d994c391c509897dd56a6a755c51a1e62bd4d4}{optimized} & 2 & 119 & 115 \\
-\hline 5 & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/933466b223d70adeda6a865b4b13b4cdfa245070}{added my primary template} & 6 & 252 & 6 \\
-\hline 6 & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/5995d70f82b680d3a529aa592558dcdde6f407b7}{added PDFs} & 2 & 0 & 0 \\
-\hline 7 & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/7e1efb265b43fb9aad3fa94b22408951076016f3}{added README (Credits)} & 1 & 1 & 0 \\
-\hline 8 & & 2012-08-26 & \href{https://github.com/ypid/typesetting/commit/619a7f6db915bc1e05d0c9ee374aaff53195b257}{converted template.dtx and template.ins to a template for sty2dtx} & 7 & 49 & 62 \\
-\hline 9 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/06f948149a3b0bd2c81062078add19af6bb1ac5d}{optimized} & 6 & 48 & 22 \\
-\hline 10 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/09316b528dc90f45fa4ef6cf9cf5886c4e25c5bb}{added scripts} & 6 & 222 & 0 \\
-\hline 11 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/4c434dcd45aa4a73112b1393d096776eaa938b83}{added README for scripts} & 1 & 10 & 0 \\
-\hline 12 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/794a3db5bd4f0165a347f0628c78f32350731b2a}{optimized scripts} & 4 & 9 & 6 \\
-\hline 13 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/7c80a541828c3e7896c7f55c8b56d745b84a5414}{added MyPackages} & 22 & 1162 & 2 \\
-\hline 14 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/b408bc9fa5f91ff5a7687fc4903d520ab09a288d}{added my Makefile} & 5 & 106 & 0 \\
-\hline 15 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/d86bd28e3f0d0e14d7eb239eb6ad9afab2da47c0}{added more scripts} & 4 & 1465 & 0 \\
-\hline 16 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/ab0554ce8d44852a76b7ad0246e04268b8347acb}{optimized} & 5 & 4 & 1459 \\
-\hline 17 & & 2012-08-31 & \href{https://github.com/ypid/typesetting/commit/75a5b9d653b2798a9cb8f10535f50abf98e94cd2}{optimized} & 7 & 52 & 31 \\
-\hline 18 & & 2012-09-09 & \href{https://github.com/ypid/typesetting/commit/2a99a061ae89f5bd6bd6ace4aac66ad9a768b0fc}{optimized} & 4 & 23 & 10 \\
-\hline 19 & & 2012-09-16 & \href{https://github.com/ypid/typesetting/commit/c2463e8229fbc506a70b4efb157679ecf3aae795}{optimized} & 6 & 10 & 7 \\
-\hline 20 & & 2012-09-23 & \href{https://github.com/ypid/typesetting/commit/1b6cb46337c516e3042d94956e7bf4f097822a47}{added more packages} & 9 & 491 & 12 \\
-\hline 21 & & 2012-09-23 & \href{https://github.com/ypid/typesetting/commit/92a41f208a275b6fcdfe9c442be8c135ec0d1c92}{added school templates} & 25 & 502 & 25 \\
-\hline 22 & & 2012-09-30 & \href{https://github.com/ypid/typesetting/commit/32e21641dff2ffd9fecfe33b93def53d6a305963}{added more templates} & 20 & 537 & 4 \\
-\hline 23 & & 2012-11-03 & \href{https://github.com/ypid/typesetting/commit/2309fa9dd41d0acaf74d6de66976f7ae6f1e7c6b}{rewrote LaTeX-git-log as perl script} & 2 & 63 & 61 \\
-\hline 24 & & 2012-11-03 & \href{https://github.com/ypid/typesetting/commit/773e5b801cfd2ad9a2af8c9d379dd0e2f9afd3cf}{optimized} & 2 & 5 & 4 \\
-\hline 25 & & 2012-11-28 & \href{https://github.com/ypid/typesetting/commit/4ffc0488959ada2a97ba50d5a7db1390afce4a26}{added more templates and optimized} & 12 & 141 & 3 \\
-\hline 26 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/dc3b091e5e8d68daa1c4b73ab96e7bc201a6ed08}{Updated templates.} & 17 & 92 & 55 \\
-\hline 27 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/457664094f33618c62348fe5a9798cc98117bcad}{Added macro for showing the github URL and optimized.} & 8 & 26 & 38 \\
-\hline 28 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/71547c919a2b36548e65320be8ce0d318b473523}{Optimized} & 3 & 36 & 0 \\
-\hline 29 & & 2013-04-20 & \href{https://github.com/ypid/typesetting/commit/3681cf7bc6d18878ca03af4009bdfc9e8835dbcd}{Optimized.} & 5 & 40 & 12 \\
-\hline 30 & & 2013-04-20 & \href{https://github.com/ypid/typesetting/commit/c0ef81a414620007d6f39fa95e59888045fa5cf0}{Optimized.} & 12 & 67 & 22 \\
-\hline 31 & & 2013-04-21 & \href{https://github.com/ypid/typesetting/commit/782b0e0e51773b02cf909600444da892c890b926}{Optimized.} & 4 & 30 & 13 \\
-\hline 32 & & 2013-05-22 & \href{https://github.com/ypid/typesetting/commit/f3048459117aa782b32324bd08ce77bfde325a62}{Optimized (mainly LaTeX-git-wdiff).} & 9 & 229 & 78 \\
-\hline 33 & & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/c5c45122518ad0e6cf9712dc248b26fd3eea4cf0}{Optimized.} & 3 & 15 & 12 \\
-\hline 34 & v1.0 & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/af3d63d88a8e37c45c4dc7c8b54ee55091f7ea80}{Made latex-git-log ready for CTAN.} & 6 & 482 & 199 \\
-\hline 35 & & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/489927feca92be10ddb5bde1b8fb11dae6b37bbb}{Optimized latex-git-log.} & 6 & 12 & 15 \\
-\hline 36 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/6d0ff0a6ae2baba715704f7dea23ebb0ac9ddc02}{Optimized.} & 3 & 106 & 79 \\
-\hline 37 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/ff9d61b343971ca964ca5e2708253abe3dad4dab}{Fixed layout.} & 1 & 9 & 5 \\
-\hline 38 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/2c128bf3eb4d734a11f3e7ebfdc93c01eafbd6f4}{Taking care about special charters in the commit message.} & 2 & 48 & 10 \\
-\hline 39 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/7b1683a671fe687ca58f895564341ee4c82a7f7d}{Fixed problem with escaped $\backslash$href.} & 1 & 10 & 3 \\
-\hline 40 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/6b25666f78ff276bbe161a0a7b659ad0c836aa22}{Made the script prettier with perltidy.} & 1 & 33 & 25 \\
-\hline 41 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/38698ff91b2253abddacd135e332d9ace5127122}{Also escape the author field.} & 3 & 10 & 10 \\
+\hline 3ff663f & & 2012-08-18 & \href{https://github.com/ypid/typesetting/commit/3ff663fcfbc56662426740cf6bab2a840e320db6}{added template.dtx from http://texhacks.blogspot.de/2011/01/simpler-dtx-template.html} & 2 & 127 & 0 \\
+\hline e9fc9a2 & & 2012-08-19 & \href{https://github.com/ypid/typesetting/commit/e9fc9a2847fe14067bb3ec8d4e4298ff8806f11f}{made my first changes on the docstrip template} & 2 & 40 & 48 \\
+\hline cbc7bbc & & 2012-08-19 & \href{https://github.com/ypid/typesetting/commit/cbc7bbcdda54f7b43f2039531d2a4f58c35f8964}{optimized} & 1 & 5 & 4 \\
+\hline 55d994c & & 2012-08-22 & \href{https://github.com/ypid/typesetting/commit/55d994c391c509897dd56a6a755c51a1e62bd4d4}{optimized} & 1 & 17 & 13 \\
+\hline 933466b & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/933466b223d70adeda6a865b4b13b4cdfa245070}{added my primary template} & 6 & 252 & 6 \\
+\hline 5995d70 & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/5995d70f82b680d3a529aa592558dcdde6f407b7}{added PDFs} & 2 & 0 & 0 \\
+\hline 7e1efb2 & & 2012-08-23 & \href{https://github.com/ypid/typesetting/commit/7e1efb265b43fb9aad3fa94b22408951076016f3}{added README (Credits)} & 1 & 1 & 0 \\
+\hline 619a7f6 & & 2012-08-26 & \href{https://github.com/ypid/typesetting/commit/619a7f6db915bc1e05d0c9ee374aaff53195b257}{converted template.dtx and template.ins to a template for sty2dtx} & 7 & 49 & 62 \\
+\hline 06f9481 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/06f948149a3b0bd2c81062078add19af6bb1ac5d}{optimized} & 6 & 48 & 22 \\
+\hline 09316b5 & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/09316b528dc90f45fa4ef6cf9cf5886c4e25c5bb}{added scripts} & 6 & 222 & 0 \\
+\hline 4c434dc & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/4c434dcd45aa4a73112b1393d096776eaa938b83}{added README for scripts} & 1 & 10 & 0 \\
+\hline 794a3db & & 2012-08-27 & \href{https://github.com/ypid/typesetting/commit/794a3db5bd4f0165a347f0628c78f32350731b2a}{optimized scripts} & 4 & 9 & 6 \\
+\hline 7c80a54 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/7c80a541828c3e7896c7f55c8b56d745b84a5414}{added MyPackages} & 22 & 1162 & 2 \\
+\hline b408bc9 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/b408bc9fa5f91ff5a7687fc4903d520ab09a288d}{added my Makefile} & 5 & 106 & 0 \\
+\hline d86bd28 & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/d86bd28e3f0d0e14d7eb239eb6ad9afab2da47c0}{added more scripts} & 4 & 1465 & 0 \\
+\hline ab0554c & & 2012-08-28 & \href{https://github.com/ypid/typesetting/commit/ab0554ce8d44852a76b7ad0246e04268b8347acb}{optimized} & 5 & 4 & 1459 \\
+\hline 75a5b9d & & 2012-08-31 & \href{https://github.com/ypid/typesetting/commit/75a5b9d653b2798a9cb8f10535f50abf98e94cd2}{optimized} & 7 & 52 & 31 \\
+\hline 2a99a06 & & 2012-09-09 & \href{https://github.com/ypid/typesetting/commit/2a99a061ae89f5bd6bd6ace4aac66ad9a768b0fc}{optimized} & 4 & 23 & 10 \\
+\hline c2463e8 & & 2012-09-16 & \href{https://github.com/ypid/typesetting/commit/c2463e8229fbc506a70b4efb157679ecf3aae795}{optimized} & 6 & 10 & 7 \\
+\hline 1b6cb46 & & 2012-09-23 & \href{https://github.com/ypid/typesetting/commit/1b6cb46337c516e3042d94956e7bf4f097822a47}{added more packages} & 9 & 491 & 12 \\
+\hline 92a41f2 & & 2012-09-23 & \href{https://github.com/ypid/typesetting/commit/92a41f208a275b6fcdfe9c442be8c135ec0d1c92}{added school templates} & 25 & 502 & 25 \\
+\hline 32e2164 & & 2012-09-30 & \href{https://github.com/ypid/typesetting/commit/32e21641dff2ffd9fecfe33b93def53d6a305963}{added more templates} & 20 & 537 & 4 \\
+\hline 2309fa9 & & 2012-11-03 & \href{https://github.com/ypid/typesetting/commit/2309fa9dd41d0acaf74d6de66976f7ae6f1e7c6b}{rewrote LaTeX-git-log as perl script} & 2 & 63 & 61 \\
+\hline 773e5b8 & & 2012-11-03 & \href{https://github.com/ypid/typesetting/commit/773e5b801cfd2ad9a2af8c9d379dd0e2f9afd3cf}{optimized} & 2 & 5 & 4 \\
+\hline 4ffc048 & & 2012-11-28 & \href{https://github.com/ypid/typesetting/commit/4ffc0488959ada2a97ba50d5a7db1390afce4a26}{added more templates and optimized} & 12 & 141 & 3 \\
+\hline dc3b091 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/dc3b091e5e8d68daa1c4b73ab96e7bc201a6ed08}{Updated templates.} & 17 & 92 & 55 \\
+\hline 4576640 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/457664094f33618c62348fe5a9798cc98117bcad}{Added macro for showing the github URL and optimized.} & 8 & 26 & 38 \\
+\hline 71547c9 & & 2013-04-04 & \href{https://github.com/ypid/typesetting/commit/71547c919a2b36548e65320be8ce0d318b473523}{Optimized} & 3 & 36 & 0 \\
+\hline 3681cf7 & & 2013-04-20 & \href{https://github.com/ypid/typesetting/commit/3681cf7bc6d18878ca03af4009bdfc9e8835dbcd}{Optimized.} & 5 & 40 & 12 \\
+\hline c0ef81a & & 2013-04-20 & \href{https://github.com/ypid/typesetting/commit/c0ef81a414620007d6f39fa95e59888045fa5cf0}{Optimized.} & 12 & 67 & 22 \\
+\hline 782b0e0 & & 2013-04-21 & \href{https://github.com/ypid/typesetting/commit/782b0e0e51773b02cf909600444da892c890b926}{Optimized.} & 4 & 30 & 13 \\
+\hline f304845 & & 2013-05-22 & \href{https://github.com/ypid/typesetting/commit/f3048459117aa782b32324bd08ce77bfde325a62}{Optimized (mainly LaTeX-git-wdiff).} & 8 & 205 & 54 \\
+\hline c5c4512 & & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/c5c45122518ad0e6cf9712dc248b26fd3eea4cf0}{Optimized.} & 3 & 15 & 12 \\
+\hline af3d63d & v1.0 & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/af3d63d88a8e37c45c4dc7c8b54ee55091f7ea80}{Made latex-git-log ready for CTAN.} & 6 & 482 & 199 \\
+\hline 489927f & & 2013-06-15 & \href{https://github.com/ypid/typesetting/commit/489927feca92be10ddb5bde1b8fb11dae6b37bbb}{Optimized latex-git-log.} & 6 & 12 & 15 \\
+\hline 6d0ff0a & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/6d0ff0a6ae2baba715704f7dea23ebb0ac9ddc02}{Optimized.} & 2 & 53 & 26 \\
+\hline ff9d61b & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/ff9d61b343971ca964ca5e2708253abe3dad4dab}{Fixed layout.} & 1 & 9 & 5 \\
+\hline 2c128bf & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/2c128bf3eb4d734a11f3e7ebfdc93c01eafbd6f4}{Taking care about special charters in the commit message.} & 2 & 48 & 10 \\
+\hline 7b1683a & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/7b1683a671fe687ca58f895564341ee4c82a7f7d}{Fixed problem with escaped $\backslash$href.} & 1 & 10 & 3 \\
+\hline 6b25666 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/6b25666f78ff276bbe161a0a7b659ad0c836aa22}{Made the script prettier with perltidy.} & 1 & 33 & 25 \\
+\hline 38698ff & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/38698ff91b2253abddacd135e332d9ace5127122}{Also escape the author field.} & 3 & 10 & 10 \\
+\hline 92a1348 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/92a13483f1d72b15b80a80a0353edaac344d09a2}{Fixed translation and problem with --author.} & 4 & 33 & 17 \\
+\hline 971d92b & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/971d92bd25176270a817fe106010ef7f2db6a4f5}{Fixed spelling.} & 3 & 16 & 15 \\
+\hline 997c10c & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/997c10ca34da6d579ecbc3f6cbeeec2898cb8b17}{Updated README.} & 1 & 3 & 6 \\
+\hline dae8299 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/dae82997bac80dc9a205e901159cc4ed38678bc1}{Updated README.} & 2 & 8 & 2 \\
+\hline 2c6c975 & & 2013-06-16 & \href{https://github.com/ypid/typesetting/commit/2c6c975b9b4e570155127fffad9d09d819e286b2}{Updated README.} & 1 & 1 & 1 \\
+\hline b452ef3 & & 2013-06-18 & \href{https://github.com/ypid/typesetting/commit/b452ef377e4254584ebd70cf0575a86de75ddd15}{Fixed typo.} & 2 & 2 & 2 \\
+\hline 812516f & & 2013-06-23 & \href{https://github.com/ypid/typesetting/commit/812516f2d3679c80df731968d0ad048e70ecd287}{Optimized MyPackages.} & 5 & 157 & 123 \\
+\hline 28d6d14 & & 2013-06-23 & \href{https://github.com/ypid/typesetting/commit/28d6d149c978a37614a1c3a85e6bb185d9831366}{Enhanced.} & 27 & 176 & 252 \\
+\hline 86c9ef8 & & 2013-06-24 & \href{https://github.com/ypid/typesetting/commit/86c9ef8898b858504417b0ce600eddad4ddcf07a}{Optimized. Now using minted for listings ;)} & 2 & 91 & 9 \\
+\hline 07dd7bc & & 2013-06-29 & \href{https://github.com/ypid/typesetting/commit/07dd7bc664fcf781261f3acb8227e9f65ab07ff4}{Optimized.} & 18 & 49 & 45 \\
+\hline 78e5eb9 & & 2013-07-01 & \href{https://github.com/ypid/typesetting/commit/78e5eb9e5e65efac6f37c887c668a7af5cca1789}{Enhanced.} & 10 & 97 & 78 \\
+\hline d434467 & & 2014-03-04 & \href{https://github.com/ypid/typesetting/commit/d43446790b1f599b4b9603ea6a35ef38c6d89a46}{Committed changes.} & 10 & 50 & 42 \\
+\hline 2c282ba & & 2014-03-24 & \href{https://github.com/ypid/typesetting/commit/2c282badd9181e22bf87d5d7bd1c62b9f340e988}{Optimized.} & 6 & 18 & 9 \\
+\hline 23bcb81 & & 2014-05-14 & \href{https://github.com/ypid/typesetting/commit/23bcb81711a102774651e7a29d19e57a7eeee7b9}{Optimized.} & 4 & 20 & 19 \\
+\hline 0a23f56 & & 2014-05-14 & \href{https://github.com/ypid/typesetting/commit/0a23f5635d4abba9b2aaa85813b25cda3dd2fd09}{Use $\backslash$listoflistings … ($\backslash$lstlistoflistings locks wired in my setting)} & 5 & 21 & 21 \\
+\hline 3c24da4 & & 2014-05-22 & \href{https://github.com/ypid/typesetting/commit/3c24da481eddd7217f5a4a54ac182a32cd37bcd4}{Added testing code for macros …} & 8 & 60 & 40 \\
+\hline eaff441 & & 2014-06-03 & \href{https://github.com/ypid/typesetting/commit/eaff44162c1027cb579a4bf3c894ebb0cc949e81}{Optimized. Fixes git hooks.} & 2 & 3 & 1 \\
+\hline e4d004f & & 2015-02-05 & \href{https://github.com/ypid/typesetting/commit/e4d004f8e12657918d8078299f68e77d71476803}{Enhanced my LaTeX bundles and added support for LuaLaTeX.} & 14 & 214 & 188 \\
+\hline 48bf054 & & 2015-02-06 & \href{https://github.com/ypid/typesetting/commit/48bf054fb8aa82ae9acae2b104e1343e544254a9}{Set new email address.} & 30 & 108 & 109 \\
+\hline f7f1f3c & & 2015-02-06 & \href{https://github.com/ypid/typesetting/commit/f7f1f3cfd3ddee1c55167e7265a70a923a4ab64b}{Enhanced LuaLaTeX compatibility.} & 7 & 35 & 11 \\
+\hline 5017aa0 & & 2015-02-06 & \href{https://github.com/ypid/typesetting/commit/5017aa052d3e93b58b4da31cbcee32f73ea3ea2e}{Fixed up my packages and the Epochenheft template.} & 19 & 173 & 250 \\
+\hline 9b0a20b & & 2015-02-06 & \href{https://github.com/ypid/typesetting/commit/9b0a20b9e00535e507da3acfca7efd75fd508a7f}{Fixed hook.} & 1 & 1 & 1 \\
+\hline 1d1cc01 & & 2015-02-07 & \href{https://github.com/ypid/typesetting/commit/1d1cc0109eb2f1eed704ac6bdaa5c4dfa15e2c8a}{Fixed up template and packages. Added the package authorRS.} & 15 & 77 & 21 \\
+\hline 8525167 & & 2015-02-07 & \href{https://github.com/ypid/typesetting/commit/85251679b1f39bf874649307db1e2f8dcd671747}{Fixed up packages. Use native $\backslash$subject command.} & 4 & 25 & 8 \\
+\hline df826ed & & 2015-02-07 & \href{https://github.com/ypid/typesetting/commit/df826ed8d0c0341dbcc02c17876fc225811bdd6c}{Fixed up acro for LuaLaTeX.} & 4 & 32 & 1 \\
+\hline 4699c6f & & 2015-02-07 & \href{https://github.com/ypid/typesetting/commit/4699c6f84612f410119e64e67b56960ed0dac977}{Fixed up packages.} & 12 & 68 & 33 \\
+\hline cb4e89e & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/cb4e89e28145dff637a9af13e726c0bb8b11440a}{Optimized for final document.} & 8 & 58 & 5 \\
+\hline 5d61a8f & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/5d61a8fc1bf1a3193dc03b442293299ef9f50ced}{Optimized.} & 3 & 18 & 2 \\
+\hline 8fb9e99 & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/8fb9e9912fdb76c11651516d2d17cfec6be68cb7}{Merge branch 'luaLaTeX'.} & - & - & - \\
+\hline f352a8f & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/f352a8fe35c4a93a3d239b5dd755d3335957e9c4}{Optimized.} & 9 & 112 & 85 \\
+\hline a6429ca & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/a6429ca856fcdfa010861001b80528333de16cba}{Enabled hooks for this repo.} & 1 & 1 & 0 \\
+\hline 1d398ca & & 2015-02-11 & \href{https://github.com/ypid/typesetting/commit/1d398cac05aa7c0be07139b30e8549c0bfb75544}{Added README.md.} & 3 & 4 & 1 \\
+\hline fcecad4 & & 2015-02-13 & \href{https://github.com/ypid/typesetting/commit/fcecad42d65fad16e7d86a6f1b94ff94d58d0ee5}{Optimized.} & 10 & 73 & 31 \\
+\hline 60ed275 & & 2015-02-28 & \href{https://github.com/ypid/typesetting/commit/60ed275b248d08ba1f5158552db2b31b4ccaf68b}{Optimized typography based on LaTeX für Studierende und Wissenschaftler.} & 12 & 121 & 32 \\
+\hline 848c689 & & 2015-02-28 & \href{https://github.com/ypid/typesetting/commit/848c689cdb6d1a19933e3d5c348cfd3090bae747}{Fixed encoding of Unicode in PDF bookmarks.} & 4 & 2 & 7 \\
+\hline 0fdd501 & & 2015-02-28 & \href{https://github.com/ypid/typesetting/commit/0fdd50162acc66341e9e89291b247f0e37516cec}{Optimized.} & 16 & 151 & 72 \\
+\hline 343d887 & & 2015-02-28 & \href{https://github.com/ypid/typesetting/commit/343d8873e5ebe25449548f69aee587e07aed151d}{Fixed up letter template.} & 8 & 43 & 15 \\
+\hline 889175a & & 2015-03-05 & \href{https://github.com/ypid/typesetting/commit/889175a7db49b5d43a20c212a90e5aadec5f953b}{Optimized packages.} & 4 & 19 & 13 \\
+\hline 087ec11 & & 2015-03-25 & \href{https://github.com/ypid/typesetting/commit/087ec11ee218690b9a73face011878e811263377}{Optimized for moderncv.} & 12 & 131 & 116 \\
+\hline e9eaaa5 & & 2015-04-05 & \href{https://github.com/ypid/typesetting/commit/e9eaaa5736d2e4020d670d3b860cb9968a0f2fba}{Fixed English language code.} & 2 & 6 & 2 \\
+\hline 753afd6 & & 2015-04-08 & \href{https://github.com/ypid/typesetting/commit/753afd6bb0f28c70b5f12c017814371ccb728272}{Use ((( ))) as fold marker.} & 1 & 8 & 8 \\
+\hline c0247ea & & 2015-04-08 & \href{https://github.com/ypid/typesetting/commit/c0247ea085a45a9ae2ed56ecaadc81355632db5e}{Hyperref should be loaded after most packages. But hyperxmp should be loaded after.} & 1 & 3 & 1 \\
+\hline d6f3e50 & & 2015-05-16 & \href{https://github.com/ypid/typesetting/commit/d6f3e50f0c134e42fa994d5544f6580d33c7c1c8}{Optimized.} & 3 & 7 & 2 \\
+\hline 535c7de & & 2015-05-20 & \href{https://github.com/ypid/typesetting/commit/535c7dec92682c4eadcaee1340b0fdec28d39a28}{Added acronymRS removed ctr files and optimized literature and others.} & 27 & 455 & 123 \\
+\hline 4c92122 & & 2015-05-24 & \href{https://github.com/ypid/typesetting/commit/4c92122decb454e876e1791b3ae1e67f4a5c75f7}{Optimized packages. Added acronyms, fixed literatureRS. Coped TeXinfoRS.} & 13 & 273 & 42 \\
+\hline 5bc68b0 & & 2015-05-24 & \href{https://github.com/ypid/typesetting/commit/5bc68b0ab50912c9070f74b533585b07cc3ed078}{Optimized references in the document.} & 4 & 26 & 8 \\
+\hline 66dfa73 & & 2015-05-25 & \href{https://github.com/ypid/typesetting/commit/66dfa73c3a531fdf2b97f4d9975d0646a49ab161}{Optimized references in the text further.} & 3 & 26 & 12 \\
+\hline 396332c & & 2015-05-25 & \href{https://github.com/ypid/typesetting/commit/396332c368786b99d0c377c9584ecab333fe45e0}{Added default license to the project.} & 1 & 4 & 0 \\
+\hline 0cb789b & & 2015-05-25 & \href{https://github.com/ypid/typesetting/commit/0cb789b5de0f57dd4770cc0b33c1064a6ccba94d}{Optimized. Fixed a few warnings.} & 11 & 73 & 19 \\
+\hline ff07dad & & 2015-05-25 & \href{https://github.com/ypid/typesetting/commit/ff07dade58ca31b6add898fc584d73d3fddd0776}{Fixed spacing after refer to macros.} & 1 & 4 & 4 \\
+\hline be2ca4d & & 2015-05-26 & \href{https://github.com/ypid/typesetting/commit/be2ca4d5d361ff5e536d6964a131d13c3d4f5b55}{Fixed up my packages for twoside print. It messed up my draft print :(} & 3 & 9 & 4 \\
+\hline faa3eea & & 2015-05-26 & \href{https://github.com/ypid/typesetting/commit/faa3eeaf213ebf6747c5a68c7e8b64c638db0009}{Fixed typo.} & 1 & 1 & 1 \\
+\hline c2d15ea & & 2015-05-27 & \href{https://github.com/ypid/typesetting/commit/c2d15ea2b7a84867deebfe6786277a61bdc139f7}{Optimized.} & 4 & 13 & 3 \\
+\hline eecd0ea & & 2015-05-27 & \href{https://github.com/ypid/typesetting/commit/eecd0ea5a2647ba47ab2c2fc71fe5e999573032d}{Made tables look nicer in print.} & 1 & 3 & 1 \\
+\hline 95126ec & & 2015-05-28 & \href{https://github.com/ypid/typesetting/commit/95126ecaa1d48056fc925abc1a1e239b44edd4ca}{Added acronyms and forced isodate to use german as default language.} & 4 & 45 & 9 \\
+\hline 22adff8 & & 2015-05-28 & \href{https://github.com/ypid/typesetting/commit/22adff897223ea40efba41208af032cbb02f8c62}{Fixed release critical bugs :)} & 4 & 26 & 7 \\
+\hline c655ba2 & v2.0 & 2015-05-28 & \href{https://github.com/ypid/typesetting/commit/c655ba2046a65613d267a0e3734b5f98f49d5f45}{Added new Makefile for LaTeX projects.} & 4 & 53 & 82 \\
+\hline beea9b8 & & 2015-06-07 & \href{https://github.com/ypid/typesetting/commit/beea9b8a0d6f38a4a9e93b788618a24045732d4d}{Removed LPPL license.} & 1 & 0 & 15 \\
+\hline 69c0326 & & 2015-06-07 & \href{https://github.com/ypid/typesetting/commit/69c03266945f16253e5b3fefe09c6eeb08f0898f}{Optimized my packages for working with letters.} & 5 & 78 & 65 \\
+\hline 82e04e2 & & 2015-06-21 & \href{https://github.com/ypid/typesetting/commit/82e04e29efeeda55760c0531f0f79b77116fded6}{Fixed up beamer template.} & 11 & 387 & 213 \\
+\hline 4848209 & & 2015-06-21 & \href{https://github.com/ypid/typesetting/commit/4848209c7a69582944332e14f0419e44de5ddf19}{Created my own beamer style.} & 8 & 107 & 62 \\
+\hline c5681ea & & 2015-06-22 & \href{https://github.com/ypid/typesetting/commit/c5681ea9ebccbde05a7f1f3dd4e25d5aee2a247d}{Fixed layout bug in my slides.} & 2 & 122 & 5 \\
+\hline fdc127a & & 2015-07-20 & \href{https://github.com/ypid/typesetting/commit/fdc127a83c75e189e526c3caed2ff9ad753eb286}{Updated. Making old chemistry documents work again.} & 6 & 184 & 41 \\
+\hline 3b9114b & & 2015-09-01 & \href{https://github.com/ypid/typesetting/commit/3b9114b22434f0b24a8b4a1c2daaef74268c9228}{Optimized.} & 3 & 11 & 6 \\
+\hline c68e656 & & 2015-12-10 & \href{https://github.com/ypid/typesetting/commit/c68e65600b3cdf0d7e99f25d0e4181dd40ef197c}{Improved latex-optimize-text a bit and tried URL regex stuff.} & 4 & 17 & 5 \\
+\hline 6258007 & & 2017-02-16 & \href{https://github.com/ypid/typesetting/commit/625800737b800725c9ac4efb8b875e4032f4078e}{Evolve} & 8 & 75 & 51 \\
+\hline 92fe6b5 & & 2017-04-26 & \href{https://github.com/ypid/typesetting/commit/92fe6b5dabbfe7ba28ff77bc7e73c21214c70c6d}{Optimize MyPackages} & 7 & 26 & 25 \\
+\hline 6b37fcc & & 2017-10-08 & \href{https://github.com/ypid/typesetting/commit/6b37fcc7dbe70aec3de054f95a4bce25932985e9}{No more legacy date formats. ISO 8601 is an international standard.} & 1 & 5 & 5 \\
+\hline a1cfa47 & & 2017-11-13 & \href{https://github.com/ypid/typesetting/commit/a1cfa47484f2232b589e8a3f3805a539ee20d1b7}{specify git revision range} & 2 & 6 & 0 \\
+\hline f95c860 & & 2017-11-13 & \href{https://github.com/ypid/typesetting/commit/f95c860585111290ac5dc3685c9d72226e8d69d0}{Align command line option variables} & 1 & 7 & 7 \\
+\hline 565872f & & 2017-11-13 & \href{https://github.com/ypid/typesetting/commit/565872fdc58731167cbf73975325435bf8c5145d}{Merge branch '\#1'} & - & - & - \\
+\hline 3af2ecd & & 2018-05-28 & \href{https://github.com/ypid/typesetting/commit/3af2ecdc13baa29772324d40e1ba4582a192dfac}{TOC: Link from both: The section label and the page number.} & 1 & 1 & 0 \\
+\hline 27e1441 & & 2019-02-13 & \href{https://github.com/ypid/typesetting/commit/27e14417b30e91e48777567d2fcdcb3ac51b7f78}{change latex-git-log to cover merge commits} & 1 & 14 & 4 \\
+\hline 258a37d & & 2019-02-13 & \href{https://github.com/ypid/typesetting/commit/258a37d98c192f82012bb5a3425218d472b677af}{restore confusion with tags} & 1 & 2 & 2 \\
+\hline 21e32d5 & & 2019-02-13 & \href{https://github.com/ypid/typesetting/commit/21e32d57d373bf9a831ff2a6c7d31091227d9050}{repair getting tags} & 1 & 4 & 3 \\
+\hline 239d959 & & 2019-04-07 & \href{https://github.com/ypid/typesetting/commit/239d95916f60e7fea6fbf32363b4757a28aa5e91}{Make git tag parsing more robust} & 1 & 4 & 2 \\
+\hline f98f16a & & 2019-04-07 & \href{https://github.com/ypid/typesetting/commit/f98f16a34f006a07803350ea1b73a64584fa6e97}{Remove space introduced in \#2} & 1 & 1 & 1 \\
+\hline d345341 & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/d345341bd4937e6cbc904c2782c61be31e8a9678}{Move latex-rm-tmpfiles from my scripts repo to this one} & 1 & 5 & 0 \\
+\hline 93b1ec2 & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/93b1ec27a9776c7226cbbc1857bc456f33153edd}{Use updated license SPDX identifier} & 2 & 2 & 2 \\
+\hline abb549e & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/abb549e71d92f13fa835e8a0d5ad63ddb1ff4b2e}{Don’t require calctime which is not public} & 1 & 1 & 1 \\
+\hline 22efbf1 & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/22efbf199a379cd0cb09970f7bfc56274ef85b37}{Don’t load private package authorRobinRS by default} & 2 & 1 & 1 \\
+\hline bbebfbb & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/bbebfbb96859f767e26d9f543532c960819cb375}{Don’t load slashbox which is not in TexLive 2016} & 1 & 1 & 1 \\
+\hline b40d5cb & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/b40d5cbb7ecdf573f4a20a1f761fd2d4e08cd6ff}{Make acronymRS compatible with acro v2.7} & 1 & 27 & 34 \\
+\hline 11e3514 & & 2019-05-27 & \href{https://github.com/ypid/typesetting/commit/11e3514b0153cf01f7522fb502f63434037ad33c}{hyphsubst is not needed for LuaLaTeX} & 1 & 8 & 4 \\
+\hline 4bae2cb & & 2019-09-04 & \href{https://github.com/ypid/typesetting/commit/4bae2cbb59aec4a6399970d11a22221eaccb0ab1}{Support to use $\backslash$Anschrift directly in letters} & 1 & 2 & 2 \\
+\hline ec4ad7d & & 2019-09-04 & \href{https://github.com/ypid/typesetting/commit/ec4ad7de54dd3497c7ef20f5d7dfa6ed084a47f1}{RFC 3339/ISO 8201 overwrites DIN norm when it comes to dates} & 1 & 3 & 2 \\
+\hline e9a422c & & 2019-04-07 & \href{https://github.com/ypid/typesetting/commit/e9a422c028b4819ec539bd8fecafeccf64904fd1}{Remove git repo url auto detect and href disable. href is now opt-in.} & 1 & 3 & 17 \\
+\hline 653096c & & 2020-01-26 & \href{https://github.com/ypid/typesetting/commit/653096ccc55a4380de64a64355ba180ad76bc6a0}{Merge branch '\#2'. Closes \#4.} & - & - & - \\
+\hline 087b27b & & 2020-02-26 & \href{https://github.com/ypid/typesetting/commit/087b27b6c43b1771ecb015e47f2436b480f95e0d}{Fix latex-git-log documentation} & 2 & 13 & 7 \\
+\hline 35437de & & 2020-02-26 & \href{https://github.com/ypid/typesetting/commit/35437def862b666d4c21b7df61b6e21e98150374}{Calling --help should also output Synopsis} & 1 & 4 & 3 \\
+\hline 95549c6 & latex-git-log/v1.0.0 & 2020-02-26 & \href{https://github.com/ypid/typesetting/commit/95549c6bf98962170d3caee8552d6fa58715e5da}{Release version 1.0.0 of latex-git-log} & 1 & 1 & 1 \\
+\hline 23bef58 & & 2024-03-20 & \href{https://github.com/ypid/typesetting/commit/23bef58ed102850dcfad56464e739ccb33227714}{latex-git-log: Add file arguments} & 2 & 12 & 2 \\
+\hline 51be3d0 & & 2024-04-17 & \href{https://github.com/ypid/typesetting/commit/51be3d03735a1bb6f4d2e1cbe63ac6ccf8fef72a}{Merge branch '\#5'} & - & - & - \\
+\hline 72f0882 & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/72f08826873fd1263b3d2f9c2c48466d3300934c}{fix: lower case LaTeX-git-log to remove pain for macOS and Windows users} & 9 & 2 & 2 \\
+\hline 852d74c & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/852d74c620d608bc2a59737ecd0b0225f40970a9}{chore(latex-git-log): start to follow https://reuse.software/} & 4 & 245 & 2 \\
+\hline 6058f64 & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/6058f64889abd60b9c001054bde50813236d8b1d}{chore: drop outdated git hook templates} & 5 & 0 & 24 \\
+\hline 724ea64 & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/724ea647f0aea74925f721f3a8215f4aa66c5b05}{build(latex-git-log): use commitizen for release management} & 2 & 14 & 5 \\
+\hline 98fb3b1 & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/98fb3b1cf71101d0012b85cfb6211f75dd1b8db9}{chore: extend .gitignore file for bazel.build} & 1 & 16 & 0 \\
+\hline 84d9df5 & & 2024-05-20 & \href{https://github.com/ypid/typesetting/commit/84d9df575a7918619051ffd8a6c0c8851a829594}{fix(latex-git-log): --user and --repo flags where not included in URL} & 1 & 1 & 1 \\
+\hline 366fc89 & & 2024-05-19 & \href{https://github.com/ypid/typesetting/commit/366fc89342d611b5ac11a5a3a036586451318113}{build(latex-git-log): start using Bazel build system} & 19 & 3933 & 18 \\
+\hline 9286ca6 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/9286ca6535ad3c02fa26ee241abb6d4accbd77ed}{build: get aspect-correctness.bazelrc file} & 1 & 75 & 0 \\
+\hline 0120766 & & 2024-05-26 & \href{https://github.com/ypid/typesetting/commit/01207665460cf9108bfa17594a196867216da55e}{build(latex-git-log): finish setting up Bazel build system} & 11 & 231 & 1418 \\
+\hline 3cd73f8 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/3cd73f8d353cbe36ed96b6dbbfb0de2d7a6c30ef}{build(latex-git-log): remove genrule\_stamped.bzl experiment} & 1 & 0 & 27 \\
+\hline a2fe127 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/a2fe12786b6485a4a7288f1aab26afe4c2494d63}{build(latex-git-log): drop Taskfile.yml, it is too limited} & 1 & 0 & 30 \\
+\hline aa05c17 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/aa05c177cd3baf0a6a12f5ac9d2aecb3b23271f8}{build: use commitizen to check commit messages} & 1 & 9 & 0 \\
+\hline 8dd67eb & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/8dd67eb9671cd239c3981479f9b4fd60a0ab74a1}{chore: make new files reuse.software compliant} & 2 & 12 & 0 \\
+\hline 8ad9824 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/8ad9824e30d54ad7a0d907614d28a7e6cb9aac07}{chore(latex-git-log): make reuse.software compliant} & 4 & 21 & 1 \\
+\hline b920b12 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/b920b12c04122cbadc052ccc4317ab197940f4a4}{style(latex-git-log): TeX code comments are introduced by one \%, not two} & 1 & 2 & 2 \\
+\hline 8ab96f4 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/8ab96f41efe17743b5bb0d1967df232c291addd8}{feat(latex-git-log): make generated file reuse.software compliant} & 1 & 6 & 1 \\
+\hline a7eb636 & & 2024-05-29 & \href{https://github.com/ypid/typesetting/commit/a7eb6364ab40b79c6e1a49a02243b516439a68d7}{chore: ensure text of all used licenses are included} & 3 & 203 & 0 \\
+\hline db1869f & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/db1869f27961af46d7a73cdd0bde3cc1b03c8e20}{docs(latex-git-log): mention that script is in Perl} & 2 & 2 & 2 \\
+\hline c029c99 & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/c029c99427424d53d728db46c785f39bd3cca5c6}{docs(latex-git-log): drop German version of GPL from manpage} & 1 & 0 & 13 \\
+\hline faeaae7 & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/faeaae7b2b7d3dcb844fb3e376824313b03aef15}{chore(latex-git-log): copyright years in script need to be in sync} & 1 & 1 & 1 \\
+\hline 474e980 & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/474e980e1f8e5fa36b7782095d383101827abb13}{docs(latex-git-log): note that only English works to known bugs} & 2 & 14 & 0 \\
+\hline 4e8a7ed & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/4e8a7edb69e6a02178dd6d81948a7120b8caaa20}{docs(latex-git-log): fix typo} & 2 & 2 & 2 \\
+\hline 07d3a7e & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/07d3a7e838beeb5737d1506fedfa28288b03956d}{fix(latex-git-log): print commit hash instead of artificial version} & 3 & 14 & 17 \\
+\hline 422272d & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/422272dcdf41b36c51d856b0005b70551102f059}{build(latex-git-log): SOURCE\_DATE\_EPOCH from env has precedence} & 1 & 4 & 2 \\
+\hline 3cdf233 & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/3cdf2337c930b9446bacf51ccef880434c1596ad}{chore(latex-git-log): regenerate example.tex} & 1 & 167 & 47 \\
+\hline e7dda12 & & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/e7dda1265766365bf5e13668734a8f9768d9c14f}{Merge branch 'bump/latex-git-log/v1.1.0'} & - & - & - \\
+\hline 84d7a6c & HEAD -> master, latex-git-log/v1.1.0 & 2024-05-31 & \href{https://github.com/ypid/typesetting/commit/84d7a6c64cd4c962fff02a04638b793ce50d19f2}{bump(latex-git-log): version 1.0.0 → 1.1.0} & 2 & 2 & 2 \\
\end{longtable}
diff --git a/support/latex-git-log/example.pdf b/support/latex-git-log/example.pdf
index 54c9c6093e..ecccf4777e 100644
--- a/support/latex-git-log/example.pdf
+++ b/support/latex-git-log/example.pdf
Binary files differ
diff --git a/support/latex-git-log/example.tex b/support/latex-git-log/example.tex
index fec2a0e31f..7527e47673 100644
--- a/support/latex-git-log/example.tex
+++ b/support/latex-git-log/example.tex
@@ -1,8 +1,38 @@
-\documentclass[12pt,a4paper,english,landscape]{scrartcl}
+% SPDX-FileCopyrightText: 2013,2020,2024 Robin Schneider <ypid@riseup.net>
+%
+% SPDX-License-Identifier: GPL-3.0-or-later
+
+\documentclass[
+ a4paper,
+ ngerman,
+ landscape,
+ DIV=15,
+]{scrartcl}
+
+\usepackage{
+ iftex,
+}
+
+\ifPDFTeX%
+ \usepackage[utf8]{inputenc}
+ \usepackage[T1]{fontenc}
+ \usepackage{babel}
+\fi
+\ifLuaTeX%
+ \usepackage{
+ fontspec,
+ polyglossia,
+ }
+\fi
+
+\ifLuaTeX%
+ \usepackage{selnolig}
+\fi
+
+\usepackage[
+ tracking=true,
+]{microtype}
-\usepackage[utf8]{inputenc}
-\usepackage[T1]{fontenc}
-\usepackage{babel}
\usepackage{longtable,hyperref}
\newcommand{\longtableendfoot}{Please continue at the next page}
@@ -11,7 +41,7 @@
The example-output.tex was generated with this command:
\begin{verbatim}
- latex-git-log --width=13 --lang=en > example-output.tex
+ latex-git-log --user ypid --repo typesetting --width=12 --lang=en > example-output.tex
\end{verbatim}
\end{document}
diff --git a/support/latex-git-log/latex-git-log b/support/latex-git-log/latex-git-log
index 35d831b6eb..3cce9ef9b8 100755
--- a/support/latex-git-log/latex-git-log
+++ b/support/latex-git-log/latex-git-log
@@ -1,4 +1,6 @@
#!/usr/bin/env perl
+# SPDX-FileCopyrightText: 2012-2013,2017,2019-2020,2024 Robin Schneider <ypid@riseup.net>
+#
# SPDX-License-Identifier: GPL-3.0-or-later
# Modules and pragmas {{{
@@ -8,6 +10,7 @@ use autodie;
use feature qw(say);
use utf8;
use open qw(:std :utf8);
+use English;
binmode STDOUT, ':encoding(UTF-8)';
use IPC::System::Simple qw(capturex);
use Getopt::Long;
@@ -31,7 +34,6 @@ use Locale::Maketext::Simple (
# Optional parameters {{{
my $print_author = 0;
-my $commit_count = 1;
my $width = 0;
my $lang = undef;
my $version = 0;
@@ -41,7 +43,6 @@ my $revision_range = 0;
my ( $git_user, $git_repo, $git_commit_address );
GetOptions(
'author' => \$print_author,
- 'startcommit=s' => \$commit_count,
'width=s' => \$width,
'git-c-add=s' => \$git_commit_address,
'user=s' => \$git_user,
@@ -58,14 +59,19 @@ pod2usage( -verbose => 99, -sections => 'Version' ) if $version;
my $git_remote = ( split /\n/xms, capturex(qw(git remote -v)) )[0];
loc_lang($lang) if ( defined $lang );
-say '%% This file was generated by the script latex-git-log';
+my $committer_year_of_last_commit = ( split /\n/xms, capturex('git', '--no-pager', 'log', '-1', '--pretty=%cd', '--date=format:%Y') )[0];
+say "% SPDX-FileCopyrightText: $committer_year_of_last_commit Robin Schneider <ypid\@riseup.net>
+%
+% SPDX-License-Identifier: CC0-1.0 OR MIT
+
+% This file was generated by the script latex-git-log.";
my $git_command_commit_msg = '%s';
if ( (defined $git_user and defined $git_repo) or $git_commit_address ) {
unless ( defined $git_commit_address ) {
- $git_commit_address = "https://github.com/$+{user}/$+{repo}/commit";
+ $git_commit_address = "https://github.com/$git_user/$git_repo/commit";
}
$git_command_commit_msg = '%H & %s';
- say '%% Base git commit URL: ' . $git_commit_address;
+ say '% Base git commit URL: ' . $git_commit_address;
}
if ($width) {
$width = "p{${width}cm}";
@@ -79,7 +85,7 @@ else {
say '\begin{tabular}{lp{12cm}}
\label{tabular:legend:git-log}
\textbf{' . loc('acronym') . '} & \textbf{' . loc('meaning') . '} \\\\
- V & \texttt{' . loc('version') . '} \\\\
+ H & \texttt{' . loc('commit hash') . '} \\\\
' . loc('tag') . ' & ' . loc('\texttt{git tag}') . ' \\\\
' . loc('MF') . ' & ' . loc('Number of \texttt{modified files}.') . ' \\\\
' . loc('AL') . ' & ' . loc('Number of \texttt{added lines}.') . ' \\\\
@@ -87,8 +93,11 @@ say '\begin{tabular}{lp{12cm}}
\end{tabular}
\bigskip
+';
-\iflanguage{ngerman}{\shorthandoff{"}}{}';
+# Users should set this themselves if they need it because it can cause build errors like:
+# Undefined control sequence.
+# \iflanguage{ngerman}{\shorthandoff{"}}{}';
if ($print_author) {
say "\\begin{longtable}{|rllllrrr|}";
@@ -96,7 +105,7 @@ if ($print_author) {
else {
say "\\begin{longtable}{|rll${width}rrr|}";
}
-say '\hline \multicolumn{1}{|c}{\textbf{' . loc('V') . '}} & \multicolumn{1}{c}{\textbf{' . loc('tag') . '}}';
+say '\hline \multicolumn{1}{|c}{\textbf{' . loc('H') . '}} & \multicolumn{1}{c}{\textbf{' . loc('tag') . '}}';
say '& \multicolumn{1}{c}{\textbf{' . loc('author') . '}}' if $print_author;
say '& \multicolumn{1}{c}{\textbf{' . loc('date') . '}}
& \multicolumn{1}{c}{\textbf{' . loc('commit message') . '}} & \multicolumn{1}{c}{\textbf{' . loc('MF') . '}}
@@ -122,19 +131,25 @@ say '\endfoot
my @lines;
my @git_command = qw(git log --date=short --shortstat);
if ($print_author) {
- push( @git_command, qq(--pretty=format:%H & %an NoTinAuthorFiled& %ad & $git_command_commit_msg) );
+ push( @git_command, qq(--pretty=format:%h & %an NoTinAuthorFiled& %ad & $git_command_commit_msg) );
}
else {
- push( @git_command, qq(--pretty=format:%H %ad & $git_command_commit_msg) );
+ push( @git_command, qq(--pretty=format:%h %ad & $git_command_commit_msg) );
}
if ($revision_range) {
push( @git_command, qq($revision_range) );
}
+
+# check for command-line file arguments
+if ($#ARGV >= 0) {
+ push( @git_command, ("--", @ARGV) );
+}
+
@lines = reverse capturex(@git_command);
# }}}
# Get tags {{{
-my @tags_commits = capturex( 'git', 'log', '--tags', '--no-walk', '--pretty=\'%H %d\'' );
+my @tags_commits = capturex( 'git', 'log', '--tags', '--no-walk', '--pretty=\'%h %d\'' );
my %commit_tags; # The key will be a SHA1 commit hash and the value a comma separated list of all tags.
for (@tags_commits) {
chomp;
@@ -185,12 +200,13 @@ my @changes;
for (@lines) {
next if /\A\Z/xms;
chomp;
- if ( m/^([0-9a-f]{40})\s/g and !$which_line) {
+ if ( m/^([0-9a-f]{7,})\s/g and !$which_line) {
$which_line ^= 1; ## additional toggle for merge commits
@changes = ( "-", "-", "-" );
}
if ($which_line) {
- s/\A([0-9a-f]{40})\s//xms or die "Did not match the commit hash\n";
+ s/\A(?<short_commit_hash>[0-9a-f]{7,})\s//xms or die "Did not match the commit hash\n";
+ my $short_commit_hash = $LAST_PAREN_MATCH{short_commit_hash};
my $tags = exists $commit_tags{$1} ? $commit_tags{$1} : q();
my $date_author = '';
my $c_msg = '';
@@ -211,8 +227,7 @@ for (@lines) {
else {
$c_msg = latex_escape($c_msg);
}
- say "\\hline $commit_count & $tags & $date_author $c_msg & " . join( ' & ', @changes ) . ' \\\\';
- $commit_count++;
+ say "\\hline $short_commit_hash & $tags & $date_author $c_msg & " . join( ' & ', @changes ) . ' \\\\';
} ## end if ($which_line)
else {
@changes = ( 0, 0, 0 );
@@ -235,12 +250,11 @@ latex-git-log - Generates the version history of a git project as LaTeX source c
=head1 Synopsis
-latex-git-log [options]
+latex-git-log [options] [file] ...
Options:
--author set this if you want the author included
- --startcommit set the start value of count commit
--width set the width in cm of the commit message field in the LaTeX table
--git-c-add set an base URL to link to a commit
--user set a github user to derive the base URL
@@ -291,7 +305,7 @@ You can use it like this:
=head2 Of this script
-This module requires these other modules and libraries:
+This script requires the following Perl modules:
IPC::System::Simple
Locale::Maketext::Simple
@@ -306,13 +320,15 @@ be loaded.
Furthermore you need to defined the macro B<\longtableendfoot> which will be
expanded on the bottom of every page if the table will be continued on the next
-page. You can defined it to a localized message to inform the reader that this
+page. You can define it to a localized message to inform the reader that this
table is not complete and will be continued.
=head1 Description
B<This program> will output the entire version history as table written in
LaTeX if it is executed within a git repository.
+When I<file> argument(s) are given, only the history that changed these file(s)
+will be output.
It is intended that you redirect the standard output of this script to a file
which can then be included from your main LaTeX document.
@@ -322,7 +338,7 @@ landscape page.
=head1 Version
-1.0.0
+1.1.0
=head1 Author
@@ -336,9 +352,19 @@ Source code repository: https://github.com/ypid/typesetting/tree/master/scripts/
Please report bugs and feature requests at https://github.com/ypid/typesetting/issues
+=head1 Bugs and limitations
+
+=over 4
+
+=item
+
+The translation features does not seem to work. So this script is unable to output German. English works.
+
+=back
+
=head1 License and Copyright
-Copyright (C) 2012-2013,2017,2019 Robin Schneider <ypid@riseup.net>
+Copyright (C) 2012-2013,2017,2019-2020,2024 Robin Schneider <ypid@riseup.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -353,18 +379,5 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-Dieses Programm ist Freie Software: Sie können es unter den Bedingungen
-der GNU General Public License, wie von der Free Software Foundation,
-Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren
-veröffentlichten Version, weiterverbreiten und/oder modifizieren.
-
-Dieses Programm wird in der Hoffnung, dass es nützlich sein wird, aber
-OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
-Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
-Siehe die GNU General Public License für weitere Details.
-
-Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
-Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.
-
=cut
# }}}
diff --git a/support/latex-git-log/po/de.po b/support/latex-git-log/po/de.po
index 401e7fe172..c9dcdab438 100644
--- a/support/latex-git-log/po/de.po
+++ b/support/latex-git-log/po/de.po
@@ -17,11 +17,11 @@ msgstr "Abkürzung"
msgid "meaning"
msgstr "Bedeutung"
-msgid "version"
-msgstr "Version"
+msgid "commit hash"
+msgstr "Commit Prüfsumme"
-msgid "V"
-msgid "V"
+msgid "H"
+msgid "H"
msgid "tag"
msgstr "Tag"
diff --git a/support/latexindent/LatexIndent/GetYamlSettings.pm b/support/latexindent/LatexIndent/GetYamlSettings.pm
index 4d4940371d..6365e0fd93 100644
--- a/support/latexindent/LatexIndent/GetYamlSettings.pm
+++ b/support/latexindent/LatexIndent/GetYamlSettings.pm
@@ -389,36 +389,8 @@ sub yaml_read_settings {
# output the contents of indentconfig to the log file
$logger->info( Dump \%{ $userSettings->[0] } );
- # change the encoding of the paths according to the field `encoding`
- if ( $userSettings and ( ref( $userSettings->[0] ) eq 'HASH' ) and $userSettings->[0]->{encoding} ) {
- use Encode;
- my $encoding = $userSettings->[0]->{encoding};
- my $encodingObject = find_encoding($encoding);
-
- # Check if the encoding is valid.
- if ( ref($encodingObject) ) {
- $logger->info("*Encoding of the paths is $encoding");
- foreach ( @{ $userSettings->[0]->{paths} } ) {
- my $temp = $encodingObject->encode("$_");
- $logger->info("Transform file encoding: $_ -> $temp");
- push( @absPaths, $temp );
- }
- }
- else {
- $logger->warn("*encoding \"$encoding\" not found");
- $logger->warn("Ignore this setting and will take the default encoding.");
- @absPaths = @{ $userSettings->[0]->{paths} };
- foreach ( @{ $userSettings->[0]->{paths} } ) {
- push( @absPaths, $_ );
- }
- }
- }
- else # No such setting, and will take the default
- {
- # $logger->info("*Encoding of the paths takes the default.");
- foreach ( @{ $userSettings->[0]->{paths} } ) {
- push( @absPaths, $_ );
- }
+ foreach ( @{ $userSettings->[0]->{paths} } ) {
+ push( @absPaths, $_ );
}
}
diff --git a/support/latexindent/LatexIndent/Logger.pm b/support/latexindent/LatexIndent/Logger.pm
index 425c8eae07..7c4352a95f 100644
--- a/support/latexindent/LatexIndent/Logger.pm
+++ b/support/latexindent/LatexIndent/Logger.pm
@@ -18,7 +18,7 @@ package LatexIndent::Logger;
use strict;
use warnings;
-use Exporter;
+use Exporter qw/import/;
use LatexIndent::Switches qw/%switches/;
our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321
our @EXPORT_OK = qw/@logFileLines/;
diff --git a/support/latexindent/LatexIndent/Sentence.pm b/support/latexindent/LatexIndent/Sentence.pm
index 9a7f32e7db..465f2310b3 100644
--- a/support/latexindent/LatexIndent/Sentence.pm
+++ b/support/latexindent/LatexIndent/Sentence.pm
@@ -49,7 +49,7 @@ sub one_sentence_per_line {
{
if ($yesNo) {
if ( $sentencesFollowEachPart eq "par" ) {
- $sentencesFollowEachPart = qr/\R?\\par/s;
+ $sentencesFollowEachPart = qr/\R?\\par(?![a-zA-Z])/s;
}
elsif ( $sentencesFollowEachPart eq "blankLine" ) {
$sentencesFollowEachPart = qr/
@@ -207,7 +207,7 @@ sub one_sentence_per_line {
# similarly for \par
if ( ${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} }{par} ) {
- $notWithinSentence .= "|" . qr/(?:\R?\\par)/s;
+ $notWithinSentence .= "|" . qr/(?:\R?\\par(?![a-zA-Z]))/s;
}
my $sentenceRegEx = qr/
diff --git a/support/latexindent/LatexIndent/Special.pm b/support/latexindent/LatexIndent/Special.pm
index 096d2935c9..8dac47bfc0 100644
--- a/support/latexindent/LatexIndent/Special.pm
+++ b/support/latexindent/LatexIndent/Special.pm
@@ -17,14 +17,14 @@ package LatexIndent::Special;
# For all communication, please visit: https://github.com/cmhughes/latexindent.pl
use strict;
use warnings;
+use Exporter qw/import/;
use LatexIndent::Tokens qw/%tokens/;
use LatexIndent::TrailingComments qw/$trailingCommentRegExp/;
use LatexIndent::GetYamlSettings qw/%mainSettings/;
use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/;
use LatexIndent::LogFile qw/$logger/;
-use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/;
+use LatexIndent::IfElseFi;
use Data::Dumper;
-use Exporter qw/import/;
our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321
our @EXPORT_OK
= qw/find_special construct_special_begin $specialBeginAndBracesBracketsBasicRegExp $specialBeginBasicRegExp/;
diff --git a/support/latexindent/LatexIndent/TrailingComments.pm b/support/latexindent/LatexIndent/TrailingComments.pm
index 9d6532500a..5e47ae3f3f 100644
--- a/support/latexindent/LatexIndent/TrailingComments.pm
+++ b/support/latexindent/LatexIndent/TrailingComments.pm
@@ -27,12 +27,20 @@ our @EXPORT_OK
= qw/remove_trailing_comments put_trailing_comments_back_in $trailingCommentRegExp add_comment_symbol construct_trailing_comment_regexp @trailingComments/;
our @trailingComments;
our $commentCounter = 0;
+our $notPrecededByRegExp;
our $trailingCommentRegExp;
sub construct_trailing_comment_regexp {
- my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/;
+ $notPrecededByRegExp = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPrecededBy}/;
+ my $notPreceededBy = ${${mainSettings{fineTuning}}{trailingComments}}{notPreceededBy};
- $trailingCommentRegExp = qr/$notPreceededBy%$tokens{trailingComment}\d+$tokens{endOfToken}/;
+ if ( $notPreceededBy ) {
+ $logger->warn(
+ "*fineTuning:trailingComments:notPreceededBy is ok for now, but in future versions, fineTuning:trailingComments:notPrecededBy will be used" );
+ $notPrecededByRegExp = qr/$notPreceededBy/;
+ }
+
+ $trailingCommentRegExp = qr/$notPrecededByRegExp%$tokens{trailingComment}\d+$tokens{endOfToken}/;
}
sub add_comment_symbol {
@@ -66,17 +74,16 @@ sub remove_trailing_comments {
$logger->trace("*Storing trailing comments") if $is_t_switch_active;
- my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/;
- my $afterComment = qr/${${$mainSettings{fineTuning}}{trailingComments}}{afterComment}/;
+ my $afterComment = qr/${${$mainSettings{fineTuning}}{trailingComments}}{afterComment}/;
# perform the substitution
${$self}{body} =~ s/
- $notPreceededBy # not preceded by a \
- % # %
+ $notPrecededByRegExp # not preceded by a \
+ % # %
(
- $afterComment # anything else
+ $afterComment # anything else
)
- $ # up to the end of a line
+ $ # up to the end of a line
/
# increment comment counter and store comment
$commentCounter++;
@@ -134,14 +141,13 @@ sub put_trailing_comments_back_in {
# replace the line-broken trailing comment ID with a non-broken trailing comment ID
${$self}{body} =~ s/%\R?$trailingcommentIDwithLineBreaksRegExp/%$trailingcommentID/s;
}
- my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/;
if (${$self}{body} =~ m/%$trailingcommentID
(
- (?! # not immediately preceded by
- $notPreceededBy # \
- % # %
+ (?! # not immediately preceded by
+ $notPrecededByRegExp # \
+ % # %
).*?
- ) # captured into $1
+ ) # captured into $1
(\h*)?$
/mx and $1 ne ''
)
diff --git a/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm b/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm
index 45a2b6f538..d6d8b595c0 100644
--- a/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm
+++ b/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm
@@ -5,22 +5,39 @@ use warnings;
use feature qw( say state );
use utf8;
use Config qw( %Config );
-use Encode qw( decode encode );
+use Encode qw(find_encoding decode encode );
use Exporter qw/import/;
our @EXPORT_OK
= qw/commandlineargs_with_encode @new_args copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode isdir_with_encode mkdir_with_encode/;
+our $encodingObject;
+
+if ($^O eq 'MSWin32') {
+ my $encoding_sys = 'cp' . Win32::GetACP();
+ $encodingObject = find_encoding( $encoding_sys );
+
+ # Check if the encoding is valid.
+ unless ( ref($encodingObject) ) {
+ $encodingObject = find_encoding( 'utf-8' );
+ }
+}
+else {
+ $encodingObject = find_encoding( 'utf-8' );
+}
+
sub copy_with_encode {
use File::Copy;
my ( $source, $destination ) = @_;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::File;
Win32::Unicode::File->import(qw(copyW));
copyW( $source, $destination, 1 );
}
else {
+ $source = $encodingObject->encode($source);
+ $destination = $encodingObject->encode($destination);
copy( $source, $destination );
}
}
@@ -28,12 +45,13 @@ sub copy_with_encode {
sub exist_with_encode {
my ($filename) = @_;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::File;
Win32::Unicode::File->import(qw(statW));
return statW($filename);
}
else {
+ $filename = $encodingObject->encode($filename);
return -e $filename;
}
}
@@ -41,7 +59,7 @@ sub exist_with_encode {
sub zero_with_encode {
my ($filename) = @_;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::File;
Win32::Unicode::File->import(qw(file_size));
my $size = file_size($filename);
@@ -53,6 +71,7 @@ sub zero_with_encode {
}
}
else {
+ $filename = $encodingObject->encode($filename);
return -z $filename;
}
}
@@ -62,7 +81,7 @@ sub open_with_encode {
my $filename = shift;
my $fh;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::File;
Win32::Unicode::File->import;
$fh = Win32::Unicode::File->new;
@@ -74,6 +93,7 @@ sub open_with_encode {
}
}
else {
+ $filename = $encodingObject->encode($filename);
if ( open( $fh, $mode, $filename ) ) {
return $fh;
}
@@ -95,13 +115,14 @@ sub read_yaml_with_encode {
sub isdir_with_encode {
my $path = shift;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::File;
Win32::Unicode::File->import(qw(file_type));
return file_type( 'd', $path );
}
else {
+ $path = $encodingObject->encode($path);
return -d $path;
}
}
@@ -109,7 +130,7 @@ sub isdir_with_encode {
sub mkdir_with_encode {
my $path = shift;
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::Unicode::Dir;
Win32::Unicode::Dir->import(qw(mkdirW));
@@ -118,7 +139,7 @@ sub mkdir_with_encode {
else {
require File::Path;
File::Path->import(qw(make_path));
-
+ $path = $encodingObject->encode($path);
make_path($path);
}
}
@@ -126,7 +147,7 @@ sub mkdir_with_encode {
#https://stackoverflow.com/a/63868721
#https://stackoverflow.com/a/44489228
sub commandlineargs_with_encode {
- if ( $FindBin::Script eq 'latexindent.exe' ) {
+ if ( $FindBin::Script =~ /\.exe$/ ) {
require Win32::API;
import Win32::API qw( ReadMemory );
@@ -207,7 +228,6 @@ sub commandlineargs_with_encode {
@ARGV = @{$args};
}
else {
- my $encodingObject = "utf-8";
@ARGV = map { decode( $encodingObject, $_ ) } @ARGV;
our @new_args = @ARGV;
}
diff --git a/support/latexindent/LatexIndent/Version.pm b/support/latexindent/LatexIndent/Version.pm
index b42ea7bdaf..5232967fb9 100644
--- a/support/latexindent/LatexIndent/Version.pm
+++ b/support/latexindent/LatexIndent/Version.pm
@@ -20,6 +20,6 @@ use warnings;
use Exporter qw/import/;
our @EXPORT_OK = qw/$versionNumber $versionDate/;
-our $versionNumber = '3.24';
-our $versionDate = '2024-04-28';
+our $versionNumber = '3.24.2';
+our $versionDate = '2024-06-15';
1
diff --git a/support/latexindent/README b/support/latexindent/README
index 6b589faadf..0b58c4ee72 100644
--- a/support/latexindent/README
+++ b/support/latexindent/README
@@ -1,5 +1,5 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- latexindent.pl, version 3.24, 2024-04-28
+ latexindent.pl, version 3.24.2, 2024-06-15
PERL script to indent code within environments, and align delimited
environments in .tex files.
diff --git a/support/latexindent/bin/linux/latexindent b/support/latexindent/bin/linux/latexindent
index 60df957ca2..00a6b1c1ae 100644
--- a/support/latexindent/bin/linux/latexindent
+++ b/support/latexindent/bin/linux/latexindent
Binary files differ
diff --git a/support/latexindent/bin/macos/latexindent b/support/latexindent/bin/macos/latexindent
index 3be492c85a..649392d07e 100644
--- a/support/latexindent/bin/macos/latexindent
+++ b/support/latexindent/bin/macos/latexindent
Binary files differ
diff --git a/support/latexindent/defaultSettings.yaml b/support/latexindent/defaultSettings.yaml
index 1d281dd7fa..15073c2f98 100644
--- a/support/latexindent/defaultSettings.yaml
+++ b/support/latexindent/defaultSettings.yaml
@@ -1,5 +1,5 @@
#
-# latexindent.pl, version 3.24, 2024-04-28
+# latexindent.pl, version 3.24.2, 2024-06-15
#
# defaultSettings.yaml, the default settings for latexindent.pl
#
@@ -649,7 +649,7 @@ fineTuning:
before: (?:#\d\h*;?,?\/?)+|\<.*?\>
between: _|\^|\*
trailingComments:
- notPreceededBy: (?<!\\)
+ notPrecededBy: (?<!\\)
afterComment: .*?
modifyLineBreaks:
doubleBackSlash: \\\\(?:\h*\[\h*\d+\h*[a-zA-Z]+\h*\])?
diff --git a/support/latexindent/documentation/contributors.bib b/support/latexindent/documentation/contributors.bib
index 2da6ea818d..49fc2debe7 100644
--- a/support/latexindent/documentation/contributors.bib
+++ b/support/latexindent/documentation/contributors.bib
@@ -224,3 +224,14 @@
author = "Jesse Stricker",
urldate = {2023-07-12},
keywords = {contributor},}
+
+%
+% 2024
+%
+@online{fengzyf,
+ title = "Encoding work",
+ url = "https://github.com/cmhughes/latexindent.pl/pull/548",
+ date = {2024-06-15},
+ author = "fengzyf",
+ urldate = {2024-06-15},
+ keywords = {contributor},}
diff --git a/support/latexindent/documentation/latexindent-yaml-schema.json b/support/latexindent/documentation/latexindent-yaml-schema.json
index 397d577e92..8f457e916f 100644
--- a/support/latexindent/documentation/latexindent-yaml-schema.json
+++ b/support/latexindent/documentation/latexindent-yaml-schema.json
@@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/schema",
"$id": "latexindent-yaml-schema.json",
"title": "latexindent.pl YAML schema",
- "description": "latexindent.pl YAML schema helper, V3.24 2024-04-28",
+ "description": "latexindent.pl YAML schema helper, V3.24.2 2024-06-15",
"type": "object",
"properties": {
"fileExtensionPreference": {
@@ -1496,10 +1496,15 @@
"description": "fine tuning, for trailing comments",
"type": "object",
"properties": {
- "notPreceededBy": {
+ "notPrecededBy": {
"description": "regular expression for what can NOT come before %, for example \\%",
"type": "string"
},
+ "notPreceededBy": {
+ "description": "please use notPrecededBy instead",
+ "type": "string",
+ "deprecated": true
+ },
"afterComment": {
"description": "regular expression for what can come after %",
"type": "string"
diff --git a/support/latexindent/documentation/latexindent.pdf b/support/latexindent/documentation/latexindent.pdf
index 9555a30a14..60f57e8d37 100644
--- a/support/latexindent/documentation/latexindent.pdf
+++ b/support/latexindent/documentation/latexindent.pdf
Binary files differ
diff --git a/support/latexindent/documentation/latexindent.tex b/support/latexindent/documentation/latexindent.tex
index fc96a1db9a..e5a2ae3b16 100644
--- a/support/latexindent/documentation/latexindent.tex
+++ b/support/latexindent/documentation/latexindent.tex
@@ -859,6 +859,9 @@
throughout this document for details}.
\subsection{Quick start}\label{sec:quickstart}
+ When \texttt{latexindent.pl} reads and writes files, the files are read and written in UTF-8 format by default.
+ That is to say, the encoding format for tex and yaml files needs to be in UTF-8 format.
+
If you'd like to get started with \texttt{latexindent.pl} then simply type
\begin{commandshell}
@@ -1224,6 +1227,10 @@ perl latexindent-module-installer.pl
written to \texttt{indent.log}, but other additional information will be written
depending on which of the following options are used.
+ When using \texttt{latexindent.pl} in different ways on different systems, the range of
+ characters supported by its switches/flags/options may vary. We discuss these in Section
+ \cref{app:encoding}.
+
\flagbox{-v, --version}
\index{switches!-v, --version definition and details}
\announce{2017-06-25}{version}
@@ -1865,17 +1872,6 @@ latexindent.pl myfile.tex
\texttt{latexindent.yaml} and friends settings files. This can lead to creative nesting
of configuration files; a demonstration is given in \vref{sec:appendix:paths}.
- If you find that \announce{2021-06-19}{encoding option for indentconfig.yaml}
- \texttt{latexindent.pl} does not read your YAML file, then it might be as a result of
- the default commandline encoding not being UTF-8; normally this will only occur for
- Windows users. In this case, you might like to explore the \texttt{encoding} option for
- \texttt{indentconfig.yaml} as demonstrated in \cref{lst:indentconfig-encoding}.%
-
- \cmhlistingsfromfile[style=yaml-LST]{demonstrations/encoding.yaml}[yaml-TCB]{The \texttt{encoding} option for \texttt{indentconfig.yaml}}{lst:indentconfig-encoding}
-
- Thank you to \cite{qiancy98} for this contribution; please see \vref{app:encoding} and
- details within \cite{encoding} for further information.
-
\subsection{localSettings.yaml and friends}\label{sec:localsettings}
The \texttt{-l} switch tells \texttt{latexindent.pl} to look for
\texttt{localSettings.yaml} and/or friends in the \emph{same directory} as
@@ -8567,8 +8563,8 @@ perl latexindent-module-installer.pl
\begin{commandshell}
sudo apt-get install perlbrew
perlbrew init
-perlbrew install perl-5.34.0
-perlbrew switch perl-5.34.0
+perlbrew install perl-5.39.1
+perlbrew switch perl-5.39.1
sudo apt-get install curl
curl -L http://cpanmin.us | perl - App::cpanminus
cpanm YAML::Tiny
@@ -8614,21 +8610,19 @@ sudo apt install texlive-extra-utils
\index{latexindent-linux} \index{linux} \index{TeXLive}
\paragraph{Arch-based distributions}
- First install the dependencies
+ \texttt{latexindent} is included in Arch-packaged TeX Live, and can be installed by:
\begin{commandshell}
-sudo pacman -S perl cpanminus
+sudo pacman -S texlive-binextra perl-yaml-tiny perl-file-homedir
\end{commandshell}
- In addition, install \texttt{perl-file-homedir} from AUR, using your AUR helper of
- choice,
+ To enable optional \texttt{--GCString} switch, install
+ \texttt{perl-unicode-linebreak}:
\begin{commandshell}
-sudo paru -S perl-file-homedir
+sudo pacman -S perl-unicode-linebreak
\end{commandshell}
- then run the latexindent-module-installer.pl file located at helper-scripts/
-
\paragraph{Alpine}
If you are using Alpine, some \texttt{Perl} modules are not build-compatible with
Alpine, but replacements are available through \texttt{apk}. For example, you might
@@ -9427,21 +9421,33 @@ TRACE: Searching myenv for optional and mandatory arguments
and \lstinline!-----! respectively.
\end{example}
- \section{Encoding indentconfig.yaml}\label{app:encoding}
- In relation to \vref{sec:indentconfig}, Windows users that encounter encoding issues
- with \texttt{indentconfig.yaml}, may wish to run the following command in either
- \texttt{cmd.exe} or \texttt{powershell.exe}:
+ \section{Encoding}\label{app:encoding}
+
+ When using latexindent in different ways on different systems, the range of characters
+ supported by its switches/flags/options (see \vref{sec:commandline}) may vary.
+
+ For the Windows executable file \texttt{latexindent.exe}, its options support UTF-8
+ characters.
+
+ For the Windows Perl script \texttt{latexindent.pl}, its option switch supports the
+ characters supported by the encoding corresponding to the system code page. You can
+ check the system code page by running the following command in either \texttt{cmd.exe}
+ or \texttt{powershell.exe}:
\begin{dosprompt}
-chcp
- \end{dosprompt}
- They may receive the following result
+ chcp
+ \end{dosprompt}
+ which may receive the following result
\begin{dosprompt}
-Active code page: 936
- \end{dosprompt}
- and can then use the settings given in \cref{lst:indentconfig-encoding1} within their
- \texttt{indentconfig.yaml}, where 936 is the result of the \texttt{chcp} command.
-
- \cmhlistingsfromfile[style=yaml-LST]{demonstrations/encoding1.yaml}[yaml-TCB]{\texttt{encoding} demonstration for \texttt{indentconfig.yaml}}{lst:indentconfig-encoding1}
+ Active code page: 936
+ \end{dosprompt}
+ and then the characters supported by the code page can be found in \href{Microsoft's
+ code page identifier
+ table}{https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers}. For
+ example, the characters supported by the encoding corresponding to code page 936 are:
+ ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312).
+
+ For Ubuntu Linux and macOS users, whether using the Perl script or the executable file,
+ the options support UTF-8 characters.
\section{dos2unix linebreak adjustment}
diff --git a/support/latexindent/latexindent.pl b/support/latexindent/latexindent.pl
index 2c2232a046..c85bdf2047 100755
--- a/support/latexindent/latexindent.pl
+++ b/support/latexindent/latexindent.pl
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
#
-# latexindent.pl, version 3.24, 2024-04-28
+# latexindent.pl, version 3.24.2, 2024-06-15
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/support/pdfjam/VERSION b/support/pdfjam/VERSION
index ab9bd6936f..cd7061f818 100644
--- a/support/pdfjam/VERSION
+++ b/support/pdfjam/VERSION
@@ -1 +1 @@
-This is pdfjam 3.11
+This is pdfjam 3.12
diff --git a/support/pdfjam/bin/pdfjam b/support/pdfjam/bin/pdfjam
index 814da49599..ff9a0123cd 100755
--- a/support/pdfjam/bin/pdfjam
+++ b/support/pdfjam/bin/pdfjam
@@ -1,5 +1,5 @@
#!/bin/sh
-version=3.11
+version=3.12
#########################################################################
## ##
## pdfjam: A shell-script interface to the "pdfpages" LaTeX package ##
@@ -1144,7 +1144,7 @@ do
then
if tty -s ; then
error_exit \
- "tty is connected to connected to stdin, no PDF/JPG/PNG file found" \
+ "tty is connected to stdin, no PDF/JPG/PNG file found" \
$E_NOINPUT
fi
cat > "$uniqueName"
diff --git a/support/pdfxup/README b/support/pdfxup/README
index 335ae71dd8..7bbb705d4c 100644
--- a/support/pdfxup/README
+++ b/support/pdfxup/README
@@ -1,4 +1,4 @@
-PDFXUP -- v2.11 (2024/03/15)
+PDFXUP -- v2.12 (2024/06/11)
N. Markey <pdfxup@markey.fr>
@@ -18,7 +18,7 @@ graphicx package) in order to produce the new document.
-%% (c) 2024/03/15 Nicolas Markey <pdfxup at markey dot fr>
+%% (c) 2024/06/11 Nicolas Markey <pdfxup at markey dot fr>
%%
%% This work may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License, either version 1.3 of this license
diff --git a/support/pdfxup/RELEASES b/support/pdfxup/RELEASES
index b6272603a3..f0e9b93643 100644
--- a/support/pdfxup/RELEASES
+++ b/support/pdfxup/RELEASES
@@ -65,3 +65,7 @@ v2.10 (2021/04/25)
v2.11 (2024/03/15)
- fixed a bug in testdim, which did not support fractional values
(bug reported by Walt Tuvell)
+
+v2.12 (2024/06/11)
+ - fixed several bugs related with page ranges (bugs reported by
+ Sanjoy Mahajan)
diff --git a/support/pdfxup/doc/Makefile b/support/pdfxup/doc/Makefile
new file mode 100644
index 0000000000..ea9fe01b2f
--- /dev/null
+++ b/support/pdfxup/doc/Makefile
@@ -0,0 +1,3 @@
+all:
+ pdflatex pdfxup-doc.tex
+ pdfxup -o pdfxup.pdf pdfxup-doc.pdf
diff --git a/support/pdfxup/pdfxup.pdf b/support/pdfxup/doc/pdfxup-doc.pdf
index 2c629a8b2e..cf3f9af936 100644
--- a/support/pdfxup/pdfxup.pdf
+++ b/support/pdfxup/doc/pdfxup-doc.pdf
Binary files differ
diff --git a/support/pdfxup/doc/pdfxup-doc.tex b/support/pdfxup/doc/pdfxup-doc.tex
new file mode 100644
index 0000000000..c051d0483f
--- /dev/null
+++ b/support/pdfxup/doc/pdfxup-doc.tex
@@ -0,0 +1,163 @@
+\documentclass{article}
+\usepackage[margin=6cm]{geometry}
+\usepackage{tikz}
+\usepackage{xspace}
+\def\pdfxup{\texttt{pdfxup}\xspace}
+
+\begin{document}
+\title{\pdfxup \\[2mm]
+ \normalsize
+ version 2.12 -- 2024/06/11}
+\author{Nicolas Markey}
+\date{}
+
+\maketitle
+
+\def\abstractname{}
+\begin{abstract}
+\pdfxup is a shell script that creates $n$-up PDF documents, while at
+the same time removing as much white stripes as possible. This
+document reviews the main features of \pdfxup. See the \verb+man+ page
+for more details.
+\end{abstract}
+
+\section{Basic usage}
+Running \pdfxup with no options creates a 2-up document from the
+original PDF file:
+\begin{center}
+\begin{tikzpicture}[scale=1.5]
+ \begin{scope}
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \end{scope}
+ \begin{scope}[xshift=1.2cm]
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,1.2}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ %\draw [line width=.5mm,black!50!white] (.3,1.2) -- +(.4,0);
+ \end{scope}
+ %
+ \draw[->] (2.6,.7) -- +(1,0);% node[midway,above] {scale=97\%};
+ %
+ \begin{scope}[yshift=2mm,xshift=4cm]
+ \draw (0,0) |- (1.5,1.1) |- cycle;
+ \begin{scope}[yshift=-1.8mm,xshift=-1.5mm,scale=.97]
+ \draw[line width=.02pt] (.178,.25) |- (.922,1.25) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \begin{scope}[xshift=7.5mm]
+ \draw[line width=.02pt] (.178,.25) |- (.922,1.25) |- cycle;
+ \foreach \x in {.3,.4,...,1.2}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \end{scope}
+ \end{scope}
+ \end{scope}
+\end{tikzpicture}
+\end{center}
+
+It removes white strips around text, so that it does not need to scale
+down the original document too much. All margins in the resulting PDF
+can be adapted using various options. The number of rows and columns
+of pages can be modified using options \verb+-x+ and \verb+-y+. By
+default, the output file is in landscape mode, but this can be changed
+using option \verb+-l=no+.
+
+Computing the boundig box is performed automatically using
+GhostScript. This may take time for long documents, but it is often
+sufficient to compute the bounding box on the first few pages, using
+option \verb+-bb+. Bounding-box computation can be turned off (so that
+original margins are kept) using \verb+-kbb+.
+
+It is possible to only include a subset of pages using option
+\verb+-p+ (notice that if a page is listed twice, it will be included
+twice).
+
+\section{Creating a booklet}
+\pdfxup can create booklets: this is similar to the operation above,
+but the pages are ordered and oriented in the adequate way. Booklet
+mode is triggered with the \verb+-b+ option.
+\begin{center}
+\begin{tikzpicture}[scale=1.5]
+ \begin{scope}
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \end{scope}
+ \begin{scope}[xshift=1.2cm]
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,1.2}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ %\draw [line width=.5mm,black!50!white] (.3,1.2) -- +(.4,0);
+ \end{scope}
+ %
+ \draw[->] (2.6,.7) -- +(1,0);% node[midway,above] {scale=97\%};
+ %
+ \begin{scope}[yshift=2mm,xshift=4cm]
+ \draw (0,0) |- (1.5,1.1) |- cycle;
+ \begin{scope}[yshift=-1.8mm,xshift=6mm,scale=.97]
+% \draw[line width=.02pt] (.178,.25) |- (.922,1.25) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \end{scope}
+ \fill[white] (1.2,-.01) -| (1.51,.3) -- cycle;
+ \draw[fill=white] (1.2,0) .. controls +(40:2mm) and +(-60:2mm) .. (1.2,.35) -- (1.5,.3) -- cycle;
+ \begin{scope}
+ \draw[clip] (1.2,0) .. controls +(40:2mm) and +(-60:2mm) .. (1.2,.35) -- (1.5,.3) -- cycle;
+ \draw[line width=.5mm,black!50!white] (1.3,.3) .. controls +(-60:1mm) and +(90:2mm) .. ++(-80:3mm);
+ \draw[line width=.5mm,black!50!white] (1.38,.28) .. controls +(-69:1mm) and +(90:2mm) .. ++(-80:3mm);
+ \end{scope}
+ \end{scope}
+\end{tikzpicture}
+\end{center}
+
+\section{Watermarking}
+Using option \verb+-w+, you can add watermarking to the original file:
+\begin{center}
+\begin{tikzpicture}[scale=1.5]
+ \begin{scope}
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \end{scope}
+ \begin{scope}[xshift=1.2cm]
+ \draw (0,0) |- (1.1,1.5) |- cycle;
+ \foreach \x in {.3,.4,...,1.2}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ %\draw [line width=.5mm,black!50!white] (.3,1.2) -- +(.4,0);
+ \end{scope}
+ %
+ \draw[->] (2.6,.7) -- +(1,0);% node[midway,above] {scale=97\%};
+ %
+ \begin{scope}[yshift=2mm,xshift=4cm]
+ \draw (0,0) |- (1.5,1.1) |- cycle;
+ \begin{scope}[yshift=-1.8mm,xshift=-1.5mm,scale=.97]
+ \path (.178,.5) -- (.922,1) node[midway,sloped,opacity=.5]
+ {\bfseries\large draft};
+ \draw[line width=.02pt] (.178,.25) |- (.922,1.25) |- cycle;
+ \foreach \x in {.3,.4,...,.9}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \draw [line width=.5mm,black!50!white] (.3,1.1) -- +(.5,0);
+ \begin{scope}[xshift=7.5mm]
+ \path (.178,.5) -- (.922,1) node[midway,sloped,opacity=.5]
+ {\bfseries\large draft};
+ \draw[line width=.02pt] (.178,.25) |- (.922,1.25) |- cycle;
+ \foreach \x in {.3,.4,...,1.2}
+ {\draw [line width=.5mm,black!50!white] (.2,\x) -- +(.7,0);}
+ \end{scope}
+ \end{scope}
+ \end{scope}
+\end{tikzpicture}
+\end{center}
+
+
+\pdfxup has many other options, setting up margins, frames, order of pages,~...
+Please look at the \texttt{man} page for more details.
+
+
+\end{document}
diff --git a/support/pdfxup/doc/pdfxup.pdf b/support/pdfxup/doc/pdfxup.pdf
new file mode 100644
index 0000000000..7fda750bff
--- /dev/null
+++ b/support/pdfxup/doc/pdfxup.pdf
Binary files differ
diff --git a/support/pdfxup/pdfxup b/support/pdfxup/pdfxup
index d31db88f9e..b7197de00c 100755
--- a/support/pdfxup/pdfxup
+++ b/support/pdfxup/pdfxup
@@ -2,12 +2,12 @@
shopt -s extglob
shopt -s lastpipe
-VERSION="2.11"
-VDATE="2024/03/15"
+VERSION="2.12"
+VDATE="2024/06/11"
## see release notes at the end of this file.
-## (c) 2024/03/15 Nicolas Markey <pdfxup at markey dot fr>
+## (c) 2024/06/11 Nicolas Markey <pdfxup at markey dot fr>
##
## This work may be distributed and/or modified under the conditions of
## the LaTeX Project Public License, either version 1.3 of this license
@@ -392,17 +392,17 @@ function cleancslor()
fi
;;
-+([0-9]))
- if [[ $i -le $nbp ]]; then
+ if [[ ${i%-} -le $nbp ]]; then
result+="1$i,";
nbpages+=${i#-};
else
- myecho 1+ " $file has $nbp page(s); changed 1$i to 1-$nbp."
+ myecho 1+ " $file has $nbp page(s); changed range 1$i to 1-$nbp."
result+="1$nbp,";
nbpages+=${nbp#-};
fi
;;
+([0-9])-)
- if [[ $i -le $nbp ]]; then
+ if [[ ${i%-} -le $nbp ]]; then
result+="$i$nbp,";
nbpages+=$(expr $nbp + 1 - ${i%-});
else
@@ -427,6 +427,20 @@ function cleancslor()
-)
result+="1-$nbp,";
nbpages+=$nbp;;
+ %+([0-9]))
+ ## explicitly list all values...
+ ## (simpler, but admitedly less efficient,
+ ## than handling real modulos)
+ declare -i cptr;
+ cptr=1;
+ step=`echo $i|cut -d% -f2`;
+ while [[ $cptr -le $nbp ]]; do
+ if [[ $cptr -gt 0 ]]; then
+ result+="$cptr,";
+ nbpages+=1;
+ fi
+ cptr+=$step;
+ done;;
+([0-9])%+([0-9]))
## explicitly list all values...
## (simpler, but admitedly less efficient,
@@ -435,8 +449,25 @@ function cleancslor()
cptr=`echo $i|cut -d% -f1`;
step=`echo $i|cut -d% -f2`;
while [[ $cptr -le $nbp ]]; do
- result+="$cptr,";
- nbpages+=1;
+ if [[ $cptr -gt 0 && $cptr -le $nbp ]]; then
+ result+="$cptr,";
+ nbpages+=1;
+ fi
+ cptr+=$step;
+ done;;
+ +([0-9])%+([0-9]-+([0-9])))
+ ## explicitly list all values...
+ ## (simpler, but admitedly less efficient,
+ ## than handling real modulos)
+ declare -i cptr;
+ cptr=`echo $i|cut -d% -f1`;
+ step=`echo $i|cut -d% -f2|cut -d- -f1`;
+ last=`echo $i|cut -d% -f2|cut -d- -f2`;
+ while [[ $cptr -le $last ]]; do
+ if [[ $cptr -gt 0 && $cptr -le $nbp ]]; then
+ result+="$cptr,";
+ nbpages+=1;
+ fi
cptr+=$step;
done;;
*)
@@ -690,22 +721,28 @@ while [ $# != 0 ]; do
shift;;
-p|--pages|--page)
case $2 in
- -)
+ +([0-9,\-%]))
PAGES+="$2,";
;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$2'.";
echo "Aborting.";
exit 0;
;;
- *)
- PAGES+="$2,";
- ;;
esac
shift 2;;
- -p*|--page*)
+ -p=*|--pages?=*)
ANS=`echo $1|sed -re "s/--?p(ages?)?=?//"`;
- PAGES+="$ANS,";
+ case $ANS in
+ +([0-9,\-%]))
+ PAGES+="$ANS,";
+ ;;
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$ANS'.";
+ echo "Aborting.";
+ exit 0;
+ ;;
+ esac
shift;;
-o|--out|--output-file|--outfile)
OUTPUTFILE=$2;
@@ -837,41 +874,53 @@ while [ $# != 0 ]; do
shift;;
-nobb|--nobb|-no-bb|--no-bb)
case $2 in
- -)
+ +([0-9,\-%]))
EXCLUDE_FOR_BBOX+="$2,";
;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$2'.";
echo "Aborting.";
exit 0;
;;
- *)
- EXCLUDE_FOR_BBOX+="$2,";
- ;;
esac
shift 2;;
-nobb*|--no-bb*)
ANS=`echo $1|sed -re "s/--?no-?bb=?//"`;
- EXCLUDE_FOR_BBOX+="$ANS,";
+ case $ANS in
+ +([0-9,\-%]))
+ EXCLUDE_FOR_BBOX+="$ANS,";
+ ;;
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$ANS'.";
+ echo "Aborting.";
+ exit 0;
+ ;;
+ esac
shift;;
-bb|--bb|--bounding-box)
case $2 in
- -)
+ +([0-9,\-%]))
INCLUDE_FOR_BBOX+="$2,";
;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$2'.";
echo "Aborting.";
exit 0;
;;
- *)
- INCLUDE_FOR_BBOX+="$2,";
- ;;
esac
shift 2;;
-bb*|--bb*|--bounding-box)
ANS=`echo $1|sed -re "s/--?b(ounding-?)?b(ox)?=?//"`;
- INCLUDE_FOR_BBOX+="$ANS,";
+ case $ANS in
+ +([0-9,\-%]))
+ INCLUDE_FOR_BBOX+="$ANS,";
+ ;;
+ *)
+ echo "Error: option '$1' expects a set of pages, not '$ANS'.";
+ echo "Aborting.";
+ exit 0;
+ ;;
+ esac
shift;;
-kbb|--keepbb|--keep-bb|--original-bb)
case $2 in
@@ -1008,17 +1057,23 @@ while [ $# != 0 ]; do
shift;;
-*)
usage;;
- *:+([0-9\-,\%]))
+ *:+([0-9\-,%]))
ARG=$1;
file=${ARG%:*};
PAGES+="${ARG#*:},";
## only one file is allowed, and no options
## should appear after the file name...
+ if [[ $2 ]]; then
+ echo "All options after PDF file ($1) will be dropped.";
+ fi
break;;
*)
file=$1;
## only one file is allowed, and no options
## should appear after the file name...
+ if [[ $2 ]]; then
+ echo "All options after PDF file ($1) will be dropped.";
+ fi
break;;
esac;
done
@@ -1223,6 +1278,7 @@ nbwp=1; ## set even if no watemark
if [[ $WATERMARK_FILE != "" ]]; then
if [[ ! -e $WATERMARK_FILE ]]; then
myecho 1+ " pdfxup: watermarking file not found. Omiting watermarking."
+ WATERMARK_FILE=""
else
myecho 2+ " * using file $WATERMARK_FILE for watermarking";
fi
@@ -1259,7 +1315,11 @@ if [[ $KEEP_ORIG_BBOX == 0 ]]; then
if [[ $SBB == 0 ]]; then
myecho 1+ -n "-> computing bounding box";
myecho 2+ "";
-
+
+ ## This does not correctly handles EXCLUDE_FOR_BBOX; actually, option -nobb is ignored
+ ## when page range or -bb is used. Best way of handling this would be to range over all pages
+ ## and test if page should be included. -nobb should then have priority over -bb (for pages
+ ## that would be listed in both of them)
for r in ${INCLUDE_FOR_BBOX//,/$IFS};
do
case $r in
@@ -1561,10 +1621,14 @@ pdfxup has numerous options:
name the resulting file booklet.pdf.
# pdfxup -kbb -x1 -y2 -l0 beamer-frames.pdf
-> arranges 2 beamer frames per page (not reducing margins)
+ Version 2.00 introduces config files; using beamer2.xup
+ config file, you can equivalently do
+ pdfxup -cf beamer2.xup beamer-frames.pdf
# pdfxup -kbb -x2 -y2 -l1 beamer-frames.pdf
+ pdfxup -cf beamer4.xup beamer-frames.pdf
-> arranges 4 beamer frames per page (not reducing margins)
# pdfxup -fw0 -w draft.png file.pdf
- -> remove frame border; add 'draft' watermarking on all pages
+ -> no frame border; add 'draft' watermarking on all pages
##################################################################
##
@@ -1633,3 +1697,7 @@ v2.10 (2021/04/25)
v2.11 (2024/03/15)
- fixed a bug in testdim, which did not support fractional values
(bug reported by Walt Tuvell)
+
+v2.12 (2024/06/11)
+ - fixed several bugs related with page ranges (bugs reported by
+ Sanjoy Mahajan)
diff --git a/support/pdfxup/pdfxup.1 b/support/pdfxup/pdfxup.1
index 8ca0c2b394..49851a17f0 100644
--- a/support/pdfxup/pdfxup.1
+++ b/support/pdfxup/pdfxup.1
@@ -1,6 +1,6 @@
.\" Manpage for pdfxup.
.\" Contact pdfxup@markey.fr to correct errors or typos.
-.TH man 1 "24 april 2021" "2.10" "pdfxup man page"
+.TH man 1 "11 june 2024" "2.12" "pdfxup man page"
.SH NAME
pdfxup \- n-up tool with reduced margins
.SH SYNOPSIS
diff --git a/support/pkgcheck/CHANGES.md b/support/pkgcheck/CHANGES.md
index 3f1414d6bf..c6985a7d06 100644
--- a/support/pkgcheck/CHANGES.md
+++ b/support/pkgcheck/CHANGES.md
@@ -6,6 +6,23 @@
# Changes
+
+## 2024-06-11 (3.2.0)
+### Added
+ - add generation of completion support for nushell
+ - add a new warning message W0011 if a file in the package tree
+ has a future modification time
+ - add Thumbs.db as temporary file
+ - (Experimental) for l3backend-dev and l3kernel-dev use the real directory name
+ latex-dev/l3backend resp. latex-dev/l3kernel when checking path names in the
+ TDS archive
+ - new E0042 error when there are filenames with different letter cases in a TDS archive
+ - new E0043 error when a symlink is found in the TDS archive
+### Changed
+ - small improvement in src/recode.rs due to clippy suggestions
+ - small code reorganization in check_tds_archive()
+ - crates update
+
## 2022-12-26 (3.1.0)
### Added
- now checking for hard links which generate a warning message
diff --git a/support/pkgcheck/Cargo.toml b/support/pkgcheck/Cargo.toml
index c765d91590..b35bb8a7e4 100644
--- a/support/pkgcheck/Cargo.toml
+++ b/support/pkgcheck/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pkgcheck"
-version = "3.1.0"
+version = "3.2.0"
authors = ["Manfred Lotz <manfred@ctan.org>"]
description = "Command-line tool to check packages uploaded to CTAN."
license = "MIT/Apache-2.0"
@@ -17,52 +17,74 @@ panic = "abort"
lto = true
[dependencies]
-blake3 = "1.3"
+blake3 = "1.5"
clap = { version = "4", features = ["derive"] }
clap_complete = "4"
+clap_complete_nushell = "4.5"
colored = "2"
-config = "0.13"
+config = "0.14"
escargot = "0.5"
fern = "0.6"
glob = "0.3"
-home = "0.5.3"
-once_cell = "1.13"
+home = "0.5.9"
+once_cell = "1.19"
#lazy_static = "1"
-linkify = "0.9"
+linkify = "0.10"
log = "0.4"
num_cpus = "1"
-openssl-probe = "0.1.4"
-pest = "2.3"
-pest_derive = "2.3"
+openssl-probe = "0.1.5"
+pest = "2.7"
+pest_derive = "2.7"
regex = "1"
-reqwest = { version = "0.11", features = ["blocking", "gzip"] }
+reqwest = { version = "0.12", features = ["blocking", "gzip"] }
rustc-hash = "1.1"
scoped_threadpool = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
-tempfile = "3.1"
+tempfile = "3.8"
threadpool = "1.8"
tokio = { version = "1", features = ["full"] }
unbytify = "0.2"
-unicode-bom = "1"
-url = "2.1"
+unicode-bom = "2"
+url = "2.4"
walkdir = "2.3"
-zip = { version = "^0.6", default-features = false, features = ["deflate"] }
+##zip = { version = "^0.6", default-features = false, features = ["deflate"] }
+zip = { version = "^2.1", default-features = false, features = ["deflate"] }
[dev-dependencies]
assert_cmd = "2"
-predicates = "2"
+predicates = "3"
[package.metadata.deb]
section = "utility"
depends = ""
priority = "optional"
assets = [
- ["target/x86_64-unknown-linux-musl/release/pkgcheck", "usr/bin/", "755"],
- ["LICENSE-MIT", "usr/share/doc/pkgcheck/", "644"],
- ["LICENSE-APACHE", "usr/share/doc/pkgcheck/", "644"],
- ["README.md", "usr/share/doc/pkgcheck/README", "644"],
- ["docs/pkgcheck.pdf", "usr/share/doc/pkgcheck/pkgcheck.pdf", "644"],
+ [
+ "target/x86_64-unknown-linux-musl/release/pkgcheck",
+ "usr/bin/",
+ "755",
+ ],
+ [
+ "LICENSE-MIT",
+ "usr/share/doc/pkgcheck/",
+ "644",
+ ],
+ [
+ "LICENSE-APACHE",
+ "usr/share/doc/pkgcheck/",
+ "644",
+ ],
+ [
+ "README.md",
+ "usr/share/doc/pkgcheck/README",
+ "644",
+ ],
+ [
+ "docs/pkgcheck.pdf",
+ "usr/share/doc/pkgcheck/pkgcheck.pdf",
+ "644",
+ ],
]
extended-description = """\
A checker for uploaded packages to CTAN
@@ -71,7 +93,6 @@ A checker for uploaded packages to CTAN
changelog = "CHANGES.md"
-
[package.metadata.rpm]
package = "pkgcheck"
diff --git a/support/pkgcheck/bin/pkgcheck b/support/pkgcheck/bin/pkgcheck
index abaea81efc..293c66dd08 100755
--- a/support/pkgcheck/bin/pkgcheck
+++ b/support/pkgcheck/bin/pkgcheck
Binary files differ
diff --git a/support/pkgcheck/docs/errorsd.tex b/support/pkgcheck/docs/errorsd.tex
index 7fb3509791..c37a082641 100644
--- a/support/pkgcheck/docs/errorsd.tex
+++ b/support/pkgcheck/docs/errorsd.tex
@@ -1,6 +1,5 @@
-\hypertarget{e0001----bad-characters-in-file-name}{%
\subsection{E0001 -\/- Bad characters in file
-name}\label{e0001----bad-characters-in-file-name}}
+name}\label{e0001----bad-characters-in-file-name}
File name should not contain non-ascii characters. Additionally, file
names should not contain control characters or other characters which
@@ -9,9 +8,8 @@ may have a special meaning for UNIX shells.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#nounixspecialcharacters}
-\hypertarget{e0002----file-permissions}{%
\subsection{E0002 -\/- File
-Permissions}\label{e0002----file-permissions}}
+Permissions}\label{e0002----file-permissions}
Files submitted to CTAN should be world readable.
@@ -21,16 +19,14 @@ be marked as such.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#filepermissions}
-\hypertarget{e0003----readme-is-not-a-text-file}{%
\subsection{E0003 -\/- README is not a text
-file}\label{e0003----readme-is-not-a-text-file}}
+file}\label{e0003----readme-is-not-a-text-file}
The \texttt{README} file specified in the error message must be a text
-file but it isn't.
+file but it isn\textquotesingle t.
-\hypertarget{e0004----empty-directory-not-allowed}{%
\subsection{E0004 -\/- Empty directory not
-allowed}\label{e0004----empty-directory-not-allowed}}
+allowed}\label{e0004----empty-directory-not-allowed}
Empty directories are considered as rubbish, and are usually not
accepted as part of a package, neither in the package tree nor in the
@@ -39,9 +35,8 @@ TDS zip archive.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#noemptyfiles}
-\hypertarget{e0005----empty-files-not-allowed}{%
\subsection{E0005 -\/- Empty files not
-allowed}\label{e0005----empty-files-not-allowed}}
+allowed}\label{e0005----empty-files-not-allowed}
Empty files are considered as rubbish, and are usually not accepted as
part of a package.
@@ -49,9 +44,8 @@ part of a package.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#noemptyfiles}
-\hypertarget{e0006----hidden-directories-not-allowed}{%
\subsection{E0006 -\/- Hidden directories not
-allowed}\label{e0006----hidden-directories-not-allowed}}
+allowed}\label{e0006----hidden-directories-not-allowed}
A package should not contain hidden directories, neither in the package
tree nor in the TDS zip archive.
@@ -59,9 +53,8 @@ tree nor in the TDS zip archive.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#noauxfiles}
-\hypertarget{e0007----hidden-files-not-allowed}{%
\subsection{E0007 -\/- Hidden files not
-allowed}\label{e0007----hidden-files-not-allowed}}
+allowed}\label{e0007----hidden-files-not-allowed}
A package should not contain hidden files, neither in the package tree
nor in the TDS zip archive.
@@ -69,9 +62,8 @@ nor in the TDS zip archive.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#noauxfiles}
-\hypertarget{e0008----temporary-file-detected}{%
\subsection{E0008 -\/- Temporary file
-detected}\label{e0008----temporary-file-detected}}
+detected}\label{e0008----temporary-file-detected}
A temporary file was detected. These are typically files created by TeX
\& friends and should not be part of a package.
@@ -81,9 +73,8 @@ Temporary files will also be detected in a TDS zip archive.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#noauxfiles}
-\hypertarget{e0009----package-doesnt-contain-a-readme-file}{%
-\subsection{E0009 -\/- Package doesn't contain a README
-file}\label{e0009----package-doesnt-contain-a-readme-file}}
+\subsection{E0009 -\/- Package doesn\textquotesingle t contain a README
+file}\label{e0009----package-doesnt-contain-a-readme-file}
A package must contain at least one of \texttt{README},
\texttt{README.md} or \texttt{README.txt} file.
@@ -91,15 +82,13 @@ A package must contain at least one of \texttt{README},
For more details refer to:
\url{http://mirrors.ibiblio.org/CTAN/help/ctan/CTAN-upload-addendum.html\#readme}
-\hypertarget{e0010----broken-symlink-detected}{%
\subsection{E0010 -\/- Broken symlink
-detected}\label{e0010----broken-symlink-detected}}
+detected}\label{e0010----broken-symlink-detected}
A broken symlink was detected.
-\hypertarget{e0011----wrong-permission-for-directory}{%
\subsection{E0011 -\/- Wrong permission for
-directory}\label{e0011----wrong-permission-for-directory}}
+directory}\label{e0011----wrong-permission-for-directory}
Directories should have rwx for the owner and at least \texttt{r-x} for
others (i.e. world readable).
@@ -107,9 +96,8 @@ others (i.e. world readable).
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#filepermissions}
-\hypertarget{e0012----crlf-line-endings-detected}{%
\subsection{E0012 -\/- CRLF line endings
-detected}\label{e0012----crlf-line-endings-detected}}
+detected}\label{e0012----crlf-line-endings-detected}
The file specified in the error message contains CRLF line endings. Text
files should have UNIX style line endings.
@@ -117,37 +105,32 @@ files should have UNIX style line endings.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf}
-\hypertarget{e0013----socket-special-fie-detected}{%
\subsection{E0013 -\/- Socket special fie
-detected}\label{e0013----socket-special-fie-detected}}
+detected}\label{e0013----socket-special-fie-detected}
The file specified in the error message is a socket special file which
is not allowed.
-\hypertarget{e0014----fifo-special-file-detected}{%
\subsection{E0014 -\/- Fifo special file
-detected}\label{e0014----fifo-special-file-detected}}
+detected}\label{e0014----fifo-special-file-detected}
The file specified in the error message is a fifo special file which is
not allowed.
-\hypertarget{e0015----bloch-device-file-detected}{%
\subsection{E0015 -\/- Bloch device file
-detected}\label{e0015----bloch-device-file-detected}}
+detected}\label{e0015----bloch-device-file-detected}
The file specified in the error message is a block device file which is
not allowed.
-\hypertarget{e0016----character-device-file-detected}{%
\subsection{E0016 -\/- Character device file
-detected}\label{e0016----character-device-file-detected}}
+detected}\label{e0016----character-device-file-detected}
The file specified in the error message is a character device file which
is not allowed.
-\hypertarget{e0017----pdf-document-is-in-error}{%
\subsection{E0017 -\/- PDF document is in
-error}\label{e0017----pdf-document-is-in-error}}
+error}\label{e0017----pdf-document-is-in-error}
The PDF document mentioned in the message is in error.
@@ -167,20 +150,18 @@ Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
\end{verbatim}
-\hypertarget{e0018----unwanted-directory-detected}{%
\subsection{E0018 -\/- Unwanted directory
-detected}\label{e0018----unwanted-directory-detected}}
+detected}\label{e0018----unwanted-directory-detected}
A directory was detected which should not be part of a package. Example:
\texttt{\_\_MACOSX}
-\hypertarget{e0019----generated-file-detected}{%
\subsection{E0019 -\/- Generated file
-detected}\label{e0019----generated-file-detected}}
+detected}\label{e0019----generated-file-detected}
-In order to avoid redundancy we don't want to have included files in a
-package which easily can be generated from other files in the
-submission.
+In order to avoid redundancy we don\textquotesingle t want to have
+included files in a package which easily can be generated from other
+files in the submission.
Exceptions are the \texttt{README} files of the package, i.e.
\texttt{README}, \texttt{README.md} or \texttt{README.txt},
@@ -192,10 +173,9 @@ directory tree.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#nogeneratedfiles}
-\hypertarget{e0020----unwanted-directory-detected-in-the-top-level-directory-in-tds-zip-archive}{%
\subsection{E0020 -\/- Unwanted directory detected in the top level
directory in TDS zip
-archive}\label{e0020----unwanted-directory-detected-in-the-top-level-directory-in-tds-zip-archive}}
+archive}\label{e0020----unwanted-directory-detected-in-the-top-level-directory-in-tds-zip-archive}
The name of a top level directory of a TDS archive must be one of those
listed here: \texttt{asymptote}, \texttt{bibtex}, \texttt{chktex},
@@ -208,30 +188,26 @@ listed here: \texttt{asymptote}, \texttt{bibtex}, \texttt{chktex},
Any other other directory at the top level is an error.
-\hypertarget{e0021----error-when-reading-a-file}{%
\subsection{E0021 -\/- Error when reading a
-file}\label{e0021----error-when-reading-a-file}}
+file}\label{e0021----error-when-reading-a-file}
An error was encountered when reading the file specified in the message.
-\hypertarget{e0022----check-of-an-url-in-a-readme-file-failed}{%
\subsection{E0022 -\/- Check of an URL in a README file
-failed}\label{e0022----check-of-an-url-in-a-readme-file-failed}}
+failed}\label{e0022----check-of-an-url-in-a-readme-file-failed}
URL checking is in effect. An error occcurred when trying to retrieve an
URL which was found in the specified \texttt{README} file.
-\hypertarget{e0023----follow-up-error-when-trying-to-read-a-directory-with-insufficient-permissions}{%
\subsection{E0023 -\/- Follow up error when trying to read a directory
with insufficient
-permissions}\label{e0023----follow-up-error-when-trying-to-read-a-directory-with-insufficient-permissions}}
+permissions}\label{e0023----follow-up-error-when-trying-to-read-a-directory-with-insufficient-permissions}
Error which is a follow-up error. For instance, when a directory could
not be read.
-\hypertarget{e0024----tds-zip-archive-has-wrong-permissions}{%
\subsection{E0024 -\/- TDS zip archive has wrong
-permissions}\label{e0024----tds-zip-archive-has-wrong-permissions}}
+permissions}\label{e0024----tds-zip-archive-has-wrong-permissions}
The TDS zip archive should have at least \texttt{r-\/-} for the owner
and at least \texttt{r-\/-} for others (i.e. world readable).
@@ -239,37 +215,34 @@ and at least \texttt{r-\/-} for others (i.e. world readable).
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#filepermissions}
-\hypertarget{e0025----duplicate-names-when-ignoring-letter-case-for-files-or-directories}{%
\subsection{E0025 -\/- Duplicate names when ignoring letter case for
files or
-directories}\label{e0025----duplicate-names-when-ignoring-letter-case-for-files-or-directories}}
+directories}\label{e0025----duplicate-names-when-ignoring-letter-case-for-files-or-directories}
As there are operating systems which do not distinguish between
-\texttt{myfile} and \texttt{MYFILE} we don't want to have file names in
-a directory which are the same after converting to lower case.
+\texttt{myfile} and \texttt{MYFILE} we don\textquotesingle t want to
+have file names in a directory which are the same after converting to
+lower case.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#filenames}
-\hypertarget{e0026----files-not-in-tds-or-different-in-tds-and-non-install-tree}{%
\subsection{E0026 -\/- Files not in TDS or different in TDS and
non-install
-tree}\label{e0026----files-not-in-tds-or-different-in-tds-and-non-install-tree}}
+tree}\label{e0026----files-not-in-tds-or-different-in-tds-and-non-install-tree}
The file mentioned in the error message is either not existing in the
TDS zip archive, or it is different to the one in the non-install tree
-\hypertarget{e0027----an-io-error-occurred}{%
\subsection{E0027 -\/- An I/O error
-occurred}\label{e0027----an-io-error-occurred}}
+occurred}\label{e0027----an-io-error-occurred}
Some kind of I/O error occurred. If you believe there is an error in
\texttt{pkgcheck} please contact the author.
-\hypertarget{e0028----a-path-name-in-a-tds-zip-archive-must-contain-the-package-name}{%
\subsection{E0028 -\/- A path name in a TDS zip archive must contain the
package
-name}\label{e0028----a-path-name-in-a-tds-zip-archive-must-contain-the-package-name}}
+name}\label{e0028----a-path-name-in-a-tds-zip-archive-must-contain-the-package-name}
The path names in a TDS zip archive must contain the package name.
@@ -283,9 +256,8 @@ source/latex/somepkg/somepkg.dtx
...
\end{verbatim}
-\hypertarget{e0029----readme-file--encoding-with-bom-detected}{%
\subsection{\texorpdfstring{E0029 -\/- README file: encoding with BOM
-detected}{E0029 -\/- README file: encoding with BOM detected}}\label{e0029----readme-file--encoding-with-bom-detected}}
+detected}{E0029 -\/- README file: encoding with BOM detected}}\label{e0029----readme-file--encoding-with-bom-detected}
A README file should be either ASCII or UTF-8 without BOM(byte order
mark)
@@ -293,55 +265,48 @@ mark)
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#readme}
-\hypertarget{e0030----a-symlink-was-found-which-points-outside-of-the-package-directory-tree}{%
\subsection{E0030 -\/- A symlink was found which points outside of the
package directory
-tree}\label{e0030----a-symlink-was-found-which-points-outside-of-the-package-directory-tree}}
+tree}\label{e0030----a-symlink-was-found-which-points-outside-of-the-package-directory-tree}
A symlink must not point to a file or directory outside of the package
directory tree.
-\hypertarget{e0031----file-name-contains-invalid-utf-8-characters}{%
\subsection{E0031 -\/- File name contains invalid UTF-8
-character(s)}\label{e0031----file-name-contains-invalid-utf-8-characters}}
+character(s)}\label{e0031----file-name-contains-invalid-utf-8-characters}
A file name contains invalid UTF-8 character(s).
-\hypertarget{e0033----error-when-unpacking-tds-archive}{%
\subsection{E0033 -\/- Error when unpacking tds
-archive}\label{e0033----error-when-unpacking-tds-archive}}
+archive}\label{e0033----error-when-unpacking-tds-archive}
In order to investigate the contents of the TDS zip archive
\texttt{pkgcheck} unpacks the TDS zip archive to a temporary location
which failed for the reason given in the error message.
-\hypertarget{e0034----unwanted-file-detected-in-the-top-level-directory-in-tds-zip-archive}{%
\subsection{E0034 -\/- Unwanted file detected in the top level directory
in TDS zip
-archive}\label{e0034----unwanted-file-detected-in-the-top-level-directory-in-tds-zip-archive}}
+archive}\label{e0034----unwanted-file-detected-in-the-top-level-directory-in-tds-zip-archive}
A top level directory of a TDS archive should only contain certain
directories but no files.
-\hypertarget{e0035----unwanted-tds-archive-detected-in-package-directory-tree}{%
\subsection{E0035 -\/- Unwanted TDS archive detected in package
directory
-tree}\label{e0035----unwanted-tds-archive-detected-in-package-directory-tree}}
+tree}\label{e0035----unwanted-tds-archive-detected-in-package-directory-tree}
A package directory should not contain a TDS zip archive.
-\hypertarget{e0036----dtxins-files-found-in-wrong-directory-in-tds-zip-archive}{%
\subsection{E0036 -\/- .dtx/.ins files found in wrong directory in TDS
zip
-archive}\label{e0036----dtxins-files-found-in-wrong-directory-in-tds-zip-archive}}
+archive}\label{e0036----dtxins-files-found-in-wrong-directory-in-tds-zip-archive}
In a TDS zip archive a \texttt{.dtx} resp. \texttt{.ins} file must be in
a subdirectory of either of \texttt{source/} or \texttt{doc/} top level
directories.
-\hypertarget{e0037----cr-line-endings-detected}{%
\subsection{E0037 -\/- CR line endings
-detected}\label{e0037----cr-line-endings-detected}}
+detected}\label{e0037----cr-line-endings-detected}
The file specified in the error message contains CR line endings. Text
files should have UNIX style line endings.
@@ -349,10 +314,9 @@ files should have UNIX style line endings.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf}
-\hypertarget{e0038----file-has-inconsistent-line-endings-cr-x-lf-y-crlf-z}{%
\subsection{E0038 -\/- File has inconsistent line endings: CR: x, LF: y,
CRLF:
-z}\label{e0038----file-has-inconsistent-line-endings-cr-x-lf-y-crlf-z}}
+z}\label{e0038----file-has-inconsistent-line-endings-cr-x-lf-y-crlf-z}
The file specified in the error message contains CR line endings. Text
files should have UNIX style line endings.
@@ -360,16 +324,14 @@ files should have UNIX style line endings.
For more details refer to:
\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf}
-\hypertarget{e0039----no-doc-directory-found-in-the-top-level-directory-of-the-tds-zip-archive}{%
\subsection{E0039 -\/- No doc/ directory found in the top level
directory of the TDS zip
-archive}\label{e0039----no-doc-directory-found-in-the-top-level-directory-of-the-tds-zip-archive}}
+archive}\label{e0039----no-doc-directory-found-in-the-top-level-directory-of-the-tds-zip-archive}
A TDS zip archive is required to contain a top level directory doc/.
-\hypertarget{e0040----too-few-top-level-directories-in-the-tds-zip-archive}{%
\subsection{E0040 -\/- Too few top level directories in the TDS zip
-archive}\label{e0040----too-few-top-level-directories-in-the-tds-zip-archive}}
+archive}\label{e0040----too-few-top-level-directories-in-the-tds-zip-archive}
The top level directory of a TDS zip archive must contain at least a
\texttt{doc} directory and one or more of the following directories:
@@ -383,16 +345,26 @@ The top level directory of a TDS zip archive must contain at least a
Any other other directory at the top level is an error.
-\hypertarget{e0041----one-or-more-map-file-found-for-the-package-but-none-of-them-is-in-a-path-starting-with-fontsmapdvips}{%
\subsection{E0041 -\/- One or more map file found for the package but
none of them is in a path starting with
-fonts/map/dvips}\label{e0041----one-or-more-map-file-found-for-the-package-but-none-of-them-is-in-a-path-starting-with-fontsmapdvips}}
+fonts/map/dvips}\label{e0041----one-or-more-map-file-found-for-the-package-but-none-of-them-is-in-a-path-starting-with-fontsmapdvips}
At least one map file was found which was not in a path starting with
\texttt{fonts/map/dvips}.
-\hypertarget{e0042----config-file--doesnt-exist}{%
-\subsection{\texorpdfstring{E0042 -\/- Config file doesn't
-exist}{E0042 -\/- Config file doesn't exist}}\label{e0042----config-file--doesnt-exist}}
+\subsection{E0042 -\/- TDS zip archive: duplicate names when ignoring
+letter case for files or
+directories}\label{e0042----tds-zip-archive-duplicate-names-when-ignoring-letter-case-for-files-or-directories}
-The config file specified at the command line doesn't exist.
+As there are operating systems which do not distinguish between
+\texttt{myfile} and \texttt{MYFILE} we don\textquotesingle t want to
+have file names in a directory which are the same after converting to
+lower case.
+
+For more details refer to:
+\url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#filenames}
+
+\subsection{\texorpdfstring{E0043 -\/- Symlink found in TDS zip
+archive}{E0043 -\/- Symlink found in TDS zip archive}}\label{e0043----symlink--found-in-tds-zip-archive}
+
+The TDS zip archive contained a symlink which is not allowed.
diff --git a/support/pkgcheck/docs/pkgcheck.pdf b/support/pkgcheck/docs/pkgcheck.pdf
index 5d5259bab4..149531d21a 100644
--- a/support/pkgcheck/docs/pkgcheck.pdf
+++ b/support/pkgcheck/docs/pkgcheck.pdf
Binary files differ
diff --git a/support/pkgcheck/docs/title.tex b/support/pkgcheck/docs/title.tex
index 8dcca045d1..9745306ef3 100644
--- a/support/pkgcheck/docs/title.tex
+++ b/support/pkgcheck/docs/title.tex
@@ -1 +1 @@
-\title{pkgcheck Utility, v3.1.0}
+\title{pkgcheck Utility, v3.2.0}
diff --git a/support/pkgcheck/docs/warningsd.tex b/support/pkgcheck/docs/warningsd.tex
index 24667fc2f8..5e1565ef48 100644
--- a/support/pkgcheck/docs/warningsd.tex
+++ b/support/pkgcheck/docs/warningsd.tex
@@ -1,23 +1,20 @@
-\hypertarget{w0001----archive-as-package-file-detected}{%
\subsection{W0001 -\/- Archive as package file
-detected}\label{w0001----archive-as-package-file-detected}}
+detected}\label{w0001----archive-as-package-file-detected}
Usually a CTAN package should not contain archives. An exception are
situations where, for example, the source code of a package is kept in a
separate zip archive.
-\hypertarget{w0002----duplicate-files-detected}{%
\subsection{W0002 -\/- Duplicate files
-detected}\label{w0002----duplicate-files-detected}}
+detected}\label{w0002----duplicate-files-detected}
Duplicate files were detected which are listed right after this message.
The message is a warning message as something like this could not be
seen as an error in general.
-\hypertarget{w0003----same-named-files-detected-in-the-package-tree}{%
\subsection{W0003 -\/- Same named files detected in the package
-tree}\label{w0003----same-named-files-detected-in-the-package-tree}}
+tree}\label{w0003----same-named-files-detected-in-the-package-tree}
We like to have unique file names over the whole package directory tree.
When we discover same named files we report it as a warning. Common
@@ -28,9 +25,8 @@ names like \texttt{README}, \texttt{README.txt}, \texttt{README.md},
For more details refer to:
\url{http://mirror.utexas.edu/ctan/help/ctan/CTAN-upload-addendum.html\#uniquefilenames}
-\hypertarget{w0004-----encoding-with-bom-detected}{%
\subsection{\texorpdfstring{W0004 -\/- encoding with BOM
-detected}{W0004 -\/- encoding with BOM detected}}\label{w0004-----encoding-with-bom-detected}}
+detected}{W0004 -\/- encoding with BOM detected}}\label{w0004-----encoding-with-bom-detected}
A UTF encoded package file contains a BOM (byte order mark). Currently,
we issues a warning.
@@ -38,33 +34,29 @@ we issues a warning.
Nevertheless, the CTAN team discourages uses of BOM. Please be aware,
that in some future time this could be reagarded as an error.
-\hypertarget{w0005----very-large-file--with-size-size-detected-in-package}{%
\subsection{\texorpdfstring{W0005 -\/- Very large file with size
\texttt{\textless{}size\textgreater{}} detected in
-package}{W0005 -\/- Very large file with size \textless size\textgreater{} detected in package}}\label{w0005----very-large-file--with-size-size-detected-in-package}}
+package}{W0005 -\/- Very large file with size \textless size\textgreater{} detected in package}}\label{w0005----very-large-file--with-size-size-detected-in-package}
(Experimental) We issue the message if there is a file is larger than
40MiB in the package directory tree.
-\hypertarget{w0006----very-large-file-with-size-size-detected-in-tds-zip-archive}{%
\subsection{\texorpdfstring{W0006 -\/- Very large file with size
\texttt{\textless{}size\textgreater{}} detected in TDS zip
-archive}{W0006 -\/- Very large file with size \textless size\textgreater{} detected in TDS zip archive}}\label{w0006----very-large-file-with-size-size-detected-in-tds-zip-archive}}
+archive}{W0006 -\/- Very large file with size \textless size\textgreater{} detected in TDS zip archive}}\label{w0006----very-large-file-with-size-size-detected-in-tds-zip-archive}
(Experimental) We issue the message if there is a file larger than 40MiB
in the TDS zip archive.
-\hypertarget{w0007----empty-directory-detected-in-the-tds-zip-archive}{%
\subsection{W0007 -\/- Empty directory detected in the TDS zip
-archive}\label{w0007----empty-directory-detected-in-the-tds-zip-archive}}
+archive}\label{w0007----empty-directory-detected-in-the-tds-zip-archive}
Empty directories in a TDS zip archive are discouraged. As they usually
don\textquotesingle t create errors in the distribution we issue a
warning only.
-\hypertarget{w0008----windows-file-has-unix-line-endings}{%
\subsection{W0008 -\/- Windows file has Unix line
-endings}\label{w0008----windows-file-has-unix-line-endings}}
+endings}\label{w0008----windows-file-has-unix-line-endings}
A Windows file with Unix line endings was detected.
@@ -82,19 +74,36 @@ We regard a file as a Windows file if its name ends with:
\texttt{.reg}
\end{itemize}
-\hypertarget{w0009----replacing-----with-the-same-from-config-file}{%
-\subsection{\texorpdfstring{W0009 -\/- Replacing -\textgreater{} ` with
-the same from config
-file",}{W0009 -\/- Replacing -\textgreater{} ` with the same from config file",}}\label{w0009----replacing-----with-the-same-from-config-file}}
+\subsection{\texorpdfstring{W0009 -\/- Replacing
+\texttt{\textless{}pkgname\textgreater{}\ -\textgreater{}\ \textless{}tpkg\textgreater{}}
+with the same from config
+file",}{W0009 -\/- Replacing \textless pkgname\textgreater{} -\textgreater{} \textless tpkg\textgreater{} with the same from config file",}}\label{w0009----replacing-pkgname---tpkg-with-the-same-from-config-file}
This message can only show up if \texttt{pkgcheck} got called with
\texttt{-\/-config}. Indicates that an entry in the \texttt{pkgcheck}
config file does the same as the hard-coded entry. This helps to keep a
clean config file.
-\hypertarget{w0010----hardlinks-detected-with-inode-}{%
\subsection{\texorpdfstring{W0010 -\/- Hardlinks detected with inode
-}{W0010 -\/- Hardlinks detected with inode }}\label{w0010----hardlinks-detected-with-inode-}}
+}{W0010 -\/- Hardlinks detected with inode }}\label{w0010----hardlinks-detected-with-inode-}
Hardlinks found in the package directory tree. The inode number will be
displayed
+
+\subsection{\texorpdfstring{W0011 -\/- has an mtime in the future by
+seconds, or \textless hours, minutes,
+seconds\textgreater{}}{W0011 -\/- has an mtime in the future by seconds, or \textless hours, minutes, seconds\textgreater{}}}\label{w0011-----has-an-mtime-in-the-future-by--seconds-or-hours-minutes-seconds}
+
+The file has a future modification time. This is most probably caused by
+the archiver tool which doesn\textquotesingle t pay attention to the
+timezone when adding the file to the archive
+
+The future time will be displayed in
+
+\begin{itemize}
+\tightlist
+\item
+ seconds
+\item
+ and hours, minutes and seconds
+\end{itemize}
diff --git a/support/pkgcheck/src/gparser.rs b/support/pkgcheck/src/gparser.rs
index 4c10ba9f7a..136f6f41b1 100644
--- a/support/pkgcheck/src/gparser.rs
+++ b/support/pkgcheck/src/gparser.rs
@@ -1,4 +1,3 @@
-
use log::*;
use pest::Parser;
diff --git a/support/pkgcheck/src/linkcheck.rs b/support/pkgcheck/src/linkcheck.rs
index ba0cd73cea..bd61239ef2 100644
--- a/support/pkgcheck/src/linkcheck.rs
+++ b/support/pkgcheck/src/linkcheck.rs
@@ -121,7 +121,7 @@ fn check_link(url: &str, fname: &str, urlhash: &Arc<Mutex<UrlHash>>, print_all:
match check_link_inner(&url, true) {
UrlStatus::UrlOk => {
let mut urlhash = urlhash.lock().unwrap();
- if let Some(mut hs) = urlhash.get_mut(&url) {
+ if let Some(hs) = urlhash.get_mut(&url) {
if print_all {
for p in hs.paths.iter() {
print_ok(super::ARGS.no_colors, &url, p);
@@ -132,7 +132,7 @@ fn check_link(url: &str, fname: &str, urlhash: &Arc<Mutex<UrlHash>>, print_all:
}
UrlStatus::UrlError(e) => {
let mut urlhash = urlhash.lock().unwrap();
- if let Some(mut hs) = urlhash.get_mut(&url) {
+ if let Some(hs) = urlhash.get_mut(&url) {
for p in hs.paths.iter() {
e0022!(p, e);
}
diff --git a/support/pkgcheck/src/main.rs b/support/pkgcheck/src/main.rs
index 9ff8390f9c..6ad786dcd9 100644
--- a/support/pkgcheck/src/main.rs
+++ b/support/pkgcheck/src/main.rs
@@ -26,10 +26,10 @@ use std::fmt::Display;
use std::str;
use utils::*;
+use scoped_threadpool::Pool;
use serde::{Deserialize, Serialize};
-use std::os::unix::fs::MetadataExt;
use std::borrow::Cow;
-use scoped_threadpool::Pool;
+use std::os::unix::fs::MetadataExt;
use tempfile::Builder;
@@ -54,16 +54,92 @@ use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use rustc_hash::{FxHashMap, FxHashSet};
+use std::time::SystemTime;
use std::fmt::Arguments;
use std::sync::mpsc::{channel, Sender};
-use clap::{Command, CommandFactory, Parser, ValueHint};
-use clap_complete::{generate, Generator, Shell};
+use clap::builder::PossibleValue;
+use clap::{Command, CommandFactory, Parser, ValueEnum, ValueHint};
+//use clap_complete::{generate, Generator, Shell};
+use clap_complete::{shells, Generator};
+use clap_complete_nushell::Nushell;
#[cfg(unix)]
use walkdir::{DirEntry, WalkDir};
+/// Shell with auto-generated completion script available.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+#[non_exhaustive]
+pub enum Shell {
+ /// Bourne Again SHell (bash)
+ Bash,
+ /// Elvish shell
+ Elvish,
+ /// Friendly Interactive SHell (fish)
+ Fish,
+ /// PowerShell
+ PowerShell,
+ /// Z SHell (zsh)
+ Zsh,
+ /// Nu shell (nu)
+ Nu,
+}
+
+impl Generator for Shell {
+ fn file_name(&self, name: &str) -> String {
+ match self {
+ Shell::Bash => shells::Bash.file_name(name),
+ Shell::Elvish => shells::Elvish.file_name(name),
+ Shell::Fish => shells::Fish.file_name(name),
+ Shell::PowerShell => shells::PowerShell.file_name(name),
+ Shell::Zsh => shells::Zsh.file_name(name),
+ Shell::Nu => Nushell.file_name(name),
+ }
+ }
+
+ fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::Write) {
+ match self {
+ Shell::Bash => shells::Bash.generate(cmd, buf),
+ Shell::Elvish => shells::Elvish.generate(cmd, buf),
+ Shell::Fish => shells::Fish.generate(cmd, buf),
+ Shell::PowerShell => shells::PowerShell.generate(cmd, buf),
+ Shell::Zsh => shells::Zsh.generate(cmd, buf),
+ Shell::Nu => Nushell.generate(cmd, buf),
+ }
+ }
+}
+
+// Hand-rolled so it can work even when `derive` feature is disabled
+impl ValueEnum for Shell {
+ fn value_variants<'a>() -> &'a [Self] {
+ &[
+ Shell::Bash,
+ Shell::Elvish,
+ Shell::Fish,
+ Shell::PowerShell,
+ Shell::Zsh,
+ Shell::Nu,
+ ]
+ }
+
+ fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
+ Some(match self {
+ Shell::Bash => PossibleValue::new("bash"),
+ Shell::Elvish => PossibleValue::new("elvish"),
+ Shell::Fish => PossibleValue::new("fish"),
+ Shell::PowerShell => PossibleValue::new("powershell"),
+ Shell::Zsh => PossibleValue::new("zsh"),
+ Shell::Nu => PossibleValue::new("nu"),
+ })
+ }
+}
+
+fn is_future_mtime(now: SystemTime, mtime: SystemTime) -> bool {
+ mtime > now
+ //mtime > now + Duration::new(1800, 0)
+}
+
fn format_message(message: &Arguments, no_color: bool) -> Cow<'static, str> {
let msg_str = format!("{}", message);
if msg_str.starts_with(' ') {
@@ -99,7 +175,7 @@ pub struct PathExceptions {
fn get_config_file_name() -> Option<String> {
if let Some(config_file) = &ARGS.config_file {
if Path::new(&config_file).exists() {
- return Some(config_file.to_string())
+ return Some(config_file.to_string());
} else {
f0008!(config_file);
std::process::exit(1);
@@ -124,6 +200,8 @@ fn read_yaml_config() -> FxHashMap<String, String> {
for (p, q) in [
("armtex", "armenian"),
("babel-base", "babel"),
+ ("l3backend-dev", "latex-dev/l3backend"),
+ ("l3kernel-dev", "latex-dev/l3kernel"),
("latex-amsmath", "latex"),
("latex-amsmath-dev", "latex-dev"),
("latex-base", "latex"),
@@ -148,7 +226,10 @@ fn read_yaml_config() -> FxHashMap<String, String> {
let data = match fs::read_to_string(&config_filename) {
Ok(str) => str,
- Err(e) => { f0009!(&config_filename, e); std::process::exit(1); }
+ Err(e) => {
+ f0009!(&config_filename, e);
+ std::process::exit(1);
+ }
};
let path_exceptions = serde_yaml::from_str::<PathExceptions>(&data);
@@ -171,7 +252,10 @@ fn read_yaml_config() -> FxHashMap<String, String> {
}
pb
}
- Err(e) => { f0010!(e); std::process::exit(1);},
+ Err(e) => {
+ f0010!(e);
+ std::process::exit(1);
+ }
};
pkg_replacements
}
@@ -277,7 +361,11 @@ fn check_readme(dir_entry: &str, is_readme: &ReadmeKind, ft: &filemagic::Mimetyp
return false;
}
filemagic::Mimetype::Bom(b) => {
- e0029!(msg_name, b.as_ref());
+ // wegmit e0029!(msg_name, b.as_ref());
+ e0029!(
+ msg_name,
+ <unicode_bom::Bom as std::convert::AsRef<str>>::as_ref(b)
+ );
return false;
}
filemagic::Mimetype::Text(_le) => match File::open(dir_entry) {
@@ -329,55 +417,58 @@ fn _get_devno(entry: &DirEntry) -> u64 {
#[derive(Parser, Debug, PartialEq)]
#[clap(author, version, about, long_about = None)]
+#[command(arg_required_else_help(true))]
struct Args {
- #[clap(short = 'I', long = "ignore-dupes", help = "Ignore dupes")]
+ #[arg(short = 'I', long = "ignore-dupes", help = "Ignore dupes")]
ignore_dupes: bool,
- #[clap(long = "ignore-same-named", help = "Ignore same-named files")]
+ #[arg(long = "ignore-same-named", help = "Ignore same-named files")]
ignore_same_named: bool,
- #[clap(short = 'v', long = "verbose", help = "Verbose operation?")]
+ #[arg(short = 'v', long = "verbose", help = "Verbose operation?")]
verbose: bool,
- #[clap(short = 'L', long = "correct-le", help = "Correct line endings")]
+ #[arg(short = 'L', long = "correct-le", help = "Correct line endings")]
correct_le: bool,
- #[clap(short = 'C', long = "correct-perms", help = "Correct permissions")]
+ #[arg(short = 'C', long = "correct-perms", help = "Correct permissions")]
correct_perms: bool,
- #[clap(long = "no-colors", help = "Don't display messages in color")]
+ #[arg(long = "no-colors", help = "Don't display messages in color")]
no_colors: bool,
- #[clap(long = "urlcheck", help = "Check URLs found in README files")]
+ #[arg(long = "urlcheck", help = "Check URLs found in README files")]
urlcheck: bool,
- #[clap(short = 'T', long = "tds-zip", help = "tds zip archive", group = "tds", value_hint = ValueHint::FilePath)]
+ #[arg(short = 'T', long = "tds-zip", help = "tds zip archive", group = "tds", value_hint = ValueHint::FilePath)]
tds_zip: Option<String>,
- #[clap(
+ #[arg(
short = 'e',
long = "explain",
help = "Explain error or warning message",
group = "only_one"
)]
explain: Option<String>,
- #[clap(
+ #[arg(
long = "explain-all",
help = "Explains all error or warning messages",
group = "only_one"
)]
explain_all: bool,
- #[clap(long = "generate-completion", group = "only_one", value_enum)]
+ #[arg(long = "generate-completion", group = "only_one", value_enum)]
generator: Option<Shell>,
- #[clap(
+ #[arg(
long = "show-temp-endings",
help = "Show file endings for temporary files",
group = "only_one"
)]
show_tmp_endings: bool,
- #[clap(short = 'd', long = "package-dir", help = "Package directory", value_hint = ValueHint::DirPath)]
+ #[arg(short = 'd', long = "package-dir", help = "Package directory", value_hint = ValueHint::DirPath)]
pkg_dir: Option<String>,
- #[clap(long = "config-file", help = "Specify config file to use", value_hint = ValueHint::FilePath)]
+ #[arg(long = "config-file", help = "Specify config file to use", value_hint = ValueHint::FilePath)]
config_file: Option<String>,
}
// In the pas we took care to avoid visiting a single inode twice, which takes care of (false positive) hardlinks.
// Now we want to know if there is a hardlink in the package directory
#[cfg(unix)]
-fn check_inode(set: &mut FxHashMap<(u64, u64), Vec<String>>, filename: &str, meta: &Metadata) {
- set.entry((get_devno(meta), meta.ino())).or_insert_with(Vec::new).push(filename.to_string());
+fn check_inode(set: &mut FxHashMap<(u64, u64), Vec<String>>, filename: &str, meta: &Metadata) {
+ set.entry((get_devno(meta), meta.ino()))
+ .or_default()
+ .push(filename.to_string());
}
#[cfg(not(unix))]
@@ -387,6 +478,8 @@ fn check_inode(_: &mut FxHashSet<u64>, _: &Metadata) -> bool {
static ARGS: Lazy<Args> = Lazy::new(Args::parse);
static ERROR_OCCURRED: AtomicBool = AtomicBool::new(false);
+//Get the current time
+static NOW: Lazy<SystemTime> = Lazy::new(SystemTime::now);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DPath {
@@ -434,14 +527,15 @@ impl DupPath {
type DupHashes = FxHashMap<(u64, Vec<u8>), DupPath>;
fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
- generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
+ //generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
+ clap_complete::generate(gen, cmd, "pkgcheck", &mut std::io::stdout());
}
fn main() {
let _ = setup_logger(ARGS.no_colors);
// read yaml config file if one is given explicitly or implicitly
- let pkg_replace : FxHashMap<String, String> = read_yaml_config();
+ let pkg_replace: FxHashMap<String, String> = read_yaml_config();
match &ARGS.explain {
None => (),
@@ -716,9 +810,16 @@ fn check_tds_archive_name(tds_zip: &Option<String>) -> Option<String> {
// }
// }
-fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_replace: &FxHashMap<String, String>) {
+fn check_tds_archive(
+ pkg_name: &str,
+ tds_zip: &str,
+ hashes: &DupHashes,
+ pkg_replace: &FxHashMap<String, String>,
+) {
i0003!(tds_zip);
+ let mut lcnames: FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>> = FxHashMap::default();
+
let dir_entry = Path::new(tds_zip);
let p = get_perms(dir_entry);
if !owner_has(p, 4) || !others_have(p, 4) || x_bit_set(p) {
@@ -731,12 +832,6 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
let ut = Utils::new(utils::CheckType::Tds);
- let real_pkg_name = if let Some(real_name) = pkg_replace.get(pkg_name) {
- real_name
- } else {
- pkg_name
- };
-
let tmp_dir = match Builder::new().prefix("pkgcheck").tempdir() {
Ok(tdir) => tdir,
Err(e) => {
@@ -777,7 +872,7 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
let path = dir_entry.path().to_path_buf();
let sizeref = &mut sizes;
- sizeref.entry(fsize).or_insert_with(Vec::new).push(path);
+ sizeref.entry(fsize).or_default().push(path);
};
let mut map_files_found = false;
@@ -846,6 +941,15 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
}
};
+ // let mtime = meta.modified().unwrap();
+ // if is_future_mtime(*NOW, mtime) {
+ // let diff = mtime.duration_since(*NOW).unwrap();
+ // println!(
+ // "{} has an mtime in the future by {} seconds",
+ // &file_name,
+ // diff.as_secs()
+ // );
+ // }
let ft = get_filetype(&dir_entry);
if let FType::Error(e) = ft {
@@ -853,12 +957,27 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
continue;
}
+ // this is the path name without the temporary part
+ // from unpacking the TDS zip archive
let dir_entry_display = if dir_entry.depth() == 0 {
&dir_entry_str[tmp_dir_offset - 1..]
} else {
&dir_entry_str[tmp_dir_offset..]
};
+ let filetype = match ft {
+ FType::Directory => FileKind::Directory,
+ FType::Regular => FileKind::File,
+ FType::Symlink => {
+ e0043!(dir_entry_display);
+ continue;
+ }
+ _ => panic!(
+ "Unexpected file type for {} in zip archive",
+ dir_entry_display
+ ),
+ };
+ register_duplicate_filename(&mut lcnames, dir_entry_display, filetype);
ut.check_for_temporary_file(dir_entry_display);
// In the top level directory of a TDS zip archive
@@ -912,11 +1031,14 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
}
// if the path doesn't contain a man page...
- if !dir_entry_str.contains("/man/") {
- let pkg_name_s = format!("/{}/", real_pkg_name);
- // ...then we want to have the package name in the path
- if !dir_entry_str.contains(&pkg_name_s) {
- e0028!(real_pkg_name, dir_entry_display);
+ if !dir_entry_str.contains("/man/") && !dir_entry_str.contains(pkg_name) {
+ if let Some(real_name) = pkg_replace.get(pkg_name) {
+ let pkg_name_s = format!("/{}/", real_name);
+ if !dir_entry_str.contains(&pkg_name_s) {
+ e0028!(pkg_name_s, dir_entry_display);
+ }
+ } else {
+ e0028!(pkg_name, dir_entry_display);
}
}
@@ -952,10 +1074,7 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
let hashref = &mut tds_hashes;
scope.execute(move || {
for (size, path, hash) in rx.iter() {
- hashref
- .entry((size, hash))
- .or_insert_with(Vec::new)
- .push(path);
+ hashref.entry((size, hash)).or_default().push(path);
}
});
@@ -974,6 +1093,7 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_repl
e0026!(p);
}
}
+ print_casefolding_tds(&lcnames);
}
fn get_extension_from_filename(filename: &str) -> Option<&str> {
@@ -1073,6 +1193,21 @@ enum ReadmeKind {
Symlink(String),
}
+fn register_duplicate_filename(
+ lcnames: &mut FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>>,
+ dir_entry: &str,
+ fk: FileKind,
+) {
+ let lc_dir_entry_str = dir_entry.to_lowercase();
+ if let Some(_dir_name) = filename(dir_entry) {
+ // let lcnref = &mut lcnames;
+ lcnames
+ .entry(PathBuf::from(lc_dir_entry_str))
+ .or_default()
+ .push((PathBuf::from(&dir_entry), fk));
+ }
+}
+
fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
let mut lcnames: FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>> = FxHashMap::default();
@@ -1125,6 +1260,12 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
// above in the definition of dir_entry_str
let file_name = dir_entry.file_name().to_str().unwrap().to_string();
+ let mtime = meta.modified().unwrap();
+ if is_future_mtime(*NOW, mtime) {
+ let diff = mtime.duration_since(*NOW).unwrap();
+ w0011!(&file_name, diff.as_secs(), &utils::format_duration(&diff));
+ }
+
// we check for weird stuff like socket files aso.
let ft = get_filetype(&dir_entry);
if found_unwanted_filetype(dir_entry_str, &ft) {
@@ -1136,6 +1277,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
// 1. dealing with symlinks
if ft == FType::Symlink {
match get_symlink(&dir_entry) {
+ // broken symlink
Ok(None) => {
e0010!(&dir_entry_str);
continue;
@@ -1147,22 +1289,18 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
Ok(Some(p)) => {
let pd: String =
p.canonicalize().unwrap().to_string_lossy().to_string();
+ // symlink pointing to outside of the package directory tree
if !pd.starts_with(&root_absolute) {
e0030!(&dir_entry_str, p.display());
continue;
}
- let lc_dir_entry_str = dir_entry_str.to_lowercase();
if let Some(_dir_name) = filename(dir_entry_str) {
- let lcnref = &mut lcnames;
- lcnref
- .entry(PathBuf::from(lc_dir_entry_str))
- .or_insert_with(Vec::new)
- .push((
- PathBuf::from(&dir_entry_str),
- //FileKind::Symlink(&dir_entry_str.into()),
- FileKind::Symlink(pd.clone()),
- ));
+ register_duplicate_filename(
+ &mut lcnames,
+ dir_entry_str,
+ FileKind::Symlink(pd.clone()),
+ );
}
if is_readme(&file_name) {
readme_found = true;
@@ -1184,14 +1322,13 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
// 2. dealing with directories
if ft == FType::Directory {
- let lc_dir_entry_str = dir_entry_str.to_lowercase();
+ //let lc_dir_entry_str = dir_entry_str.to_lowercase();
if let Some(_dir_name) = filename(dir_entry_str) {
- let lcnref = &mut lcnames;
-
- lcnref
- .entry(PathBuf::from(lc_dir_entry_str))
- .or_insert_with(Vec::new)
- .push((PathBuf::from(dir_entry_str), FileKind::Directory));
+ register_duplicate_filename(
+ &mut lcnames,
+ dir_entry_str,
+ FileKind::Directory,
+ );
}
if !owner_has(p, 5) || !others_have(p, 5) {
@@ -1222,7 +1359,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
doubleref
.entry(PathBuf::from(file_name))
- .or_insert_with(Vec::new)
+ .or_default()
.push(PathBuf::from(&dir_entry_str));
}
@@ -1258,14 +1395,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
));
}
- let lc_dir_entry_str = dir_entry_str.to_lowercase();
-
- let lcnref = &mut lcnames;
-
- lcnref
- .entry(PathBuf::from(lc_dir_entry_str))
- .or_insert_with(Vec::new)
- .push((PathBuf::from(&dir_entry_str), FileKind::File));
+ register_duplicate_filename(&mut lcnames, dir_entry_str, FileKind::File);
}
Err(e) => {
@@ -1293,7 +1423,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
let sizeref = &mut sizes;
let path = path.clone();
- sizeref.entry(fsize).or_insert_with(Vec::new).push(path);
+ sizeref.entry(fsize).or_default().push(path);
};
for (path, (meta, _file_name, is_readme)) in file_names.iter() {
let dir_entry_str = match path.to_str() {
@@ -1362,38 +1492,37 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
}
fmm => error!("Should not occur: {} has {:?}", dir_entry_str, fmm),
},
- Some(_) | None => {
- match ft {
- filemagic::Mimetype::Text(LineEnding::Crlf) => {
- e0012!(&dir_entry_str);
- if ARGS.correct_le {
- fix_inconsistent_le(dir_entry_str);
- }
+ Some(_) | None => match ft {
+ filemagic::Mimetype::Text(LineEnding::Crlf) => {
+ e0012!(&dir_entry_str);
+ if ARGS.correct_le {
+ fix_inconsistent_le(dir_entry_str);
}
- filemagic::Mimetype::Text(LineEnding::Cr) => {
- e0037!(&dir_entry_str);
- if ARGS.correct_le {
- fix_inconsistent_le(dir_entry_str);
- }
+ }
+ filemagic::Mimetype::Text(LineEnding::Cr) => {
+ e0037!(&dir_entry_str);
+ if ARGS.correct_le {
+ fix_inconsistent_le(dir_entry_str);
}
- filemagic::Mimetype::Text(LineEnding::Mixed(0, 0, 0)) => (),
- filemagic::Mimetype::Text(LineEnding::Mixed(cr, lf, crlf)) => {
- //println!(">>>{}: {:?} {},{},{}", &dir_entry_str, ft, x, y, z);
- e0038!(&dir_entry_str, cr, lf, crlf);
- if ARGS.correct_le {
- fix_inconsistent_le(dir_entry_str);
- }
+ }
+ filemagic::Mimetype::Text(LineEnding::Mixed(0, 0, 0)) => (),
+ filemagic::Mimetype::Text(LineEnding::Mixed(cr, lf, crlf)) => {
+ e0038!(&dir_entry_str, cr, lf, crlf);
+ if ARGS.correct_le {
+ fix_inconsistent_le(dir_entry_str);
}
- filemagic::Mimetype::Text(LineEnding::Lf) => (),
- fmm => error!("Should not occur: {} has {:?}", dir_entry_str, fmm),
}
- }
+ filemagic::Mimetype::Text(LineEnding::Lf) => (),
+ fmm => error!("Should not occur: {} has {:?}", dir_entry_str, fmm),
+ },
}
}
filemagic::Mimetype::Bom(b) => {
- //println!("{}: {} with BOM detected", dir_entry_str, b.as_ref());
- w0004!(&dir_entry_str, b.as_ref());
+ w0004!(
+ &dir_entry_str,
+ <unicode_bom::Bom as std::convert::AsRef<str>>::as_ref(&b)
+ );
check_and_correct_perms(dir_entry_str, p);
}
filemagic::Mimetype::Binary | filemagic::Mimetype::Script(_) => {
@@ -1462,10 +1591,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
let hashref = &mut hashes;
scope.execute(move || {
for (size, path, hash) in rx.iter() {
- hashref
- .entry((size, hash))
- .or_insert_with(DupPath::new)
- .push(path);
+ hashref.entry((size, hash)).or_default().push(path);
}
});
@@ -1489,18 +1615,30 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> {
}
fn print_hardlinks(hashes: &FxHashMap<(u64, u64), Vec<String>>) {
- for ((_devid,inode), eles) in hashes.iter() {
+ for ((_devid, inode), eles) in hashes.iter() {
if eles.len() > 1 {
w0010!(inode);
for hfile in eles.iter() {
info!(" >>> {}", &hfile);
}
+ }
+ }
+}
+fn print_casefolding_tds(hashes: &FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>>) {
+ for (k, eles) in hashes.iter() {
+ // println!("pcf_tds: {:?}, {:?}", k, &eles);
+ if eles.len() == 1 {
+ continue;
}
+ e0042!(k.display());
+
+ for (p, ty) in eles {
+ info!(" >>> {} ({})", p.display(), ty);
+ }
}
}
-
fn print_casefolding(hashes: &FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>>) {
for (k, eles) in hashes.iter() {
//println!("pcf: {:?}, {:?}", k, &eles);
diff --git a/support/pkgcheck/src/messages/errorsd.rs b/support/pkgcheck/src/messages/errorsd.rs
index 39a8ccb357..532f0df371 100644
--- a/support/pkgcheck/src/messages/errorsd.rs
+++ b/support/pkgcheck/src/messages/errorsd.rs
@@ -528,3 +528,29 @@ fonts/map/dvips.
"#
)
}
+
+pub fn e0042d() {
+ error!(
+ r#"
+E0042 -- TDS zip archive: duplicate names when ignoring letter case for files or directories
+
+As there are operating systems which do not distinguish between myfile
+and MYFILE we don't want to have file names in a directory which are the
+same after converting to lower case.
+
+For more details refer to:
+http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filenames
+"#
+ )
+}
+
+pub fn e0043d() {
+ error!(
+ r#"
+E0043 -- Symlink found in TDS zip archive
+
+The TDS zip archive contained a symlink which is not allowed.
+"#
+ )
+}
+
diff --git a/support/pkgcheck/src/messages/fatald.rs b/support/pkgcheck/src/messages/fatald.rs
index 0558612c72..24ece06bad 100644
--- a/support/pkgcheck/src/messages/fatald.rs
+++ b/support/pkgcheck/src/messages/fatald.rs
@@ -107,4 +107,3 @@ rerun.
"#
)
}
-
diff --git a/support/pkgcheck/src/messages/informationd.rs b/support/pkgcheck/src/messages/informationd.rs
index 0eca9849a0..7a87378ad0 100644
--- a/support/pkgcheck/src/messages/informationd.rs
+++ b/support/pkgcheck/src/messages/informationd.rs
@@ -127,4 +127,3 @@ pkgcheck.yml config file like in the following example
"#
)
}
-
diff --git a/support/pkgcheck/src/messages/mod.rs b/support/pkgcheck/src/messages/mod.rs
index 721f27ff7b..265babc961 100644
--- a/support/pkgcheck/src/messages/mod.rs
+++ b/support/pkgcheck/src/messages/mod.rs
@@ -2,11 +2,11 @@ mod errorsd;
mod fatald;
mod informationd;
mod warningsd;
-use colored::Colorize;
use self::errorsd::*;
use self::fatald::*;
use self::informationd::*;
use self::warningsd::*;
+use colored::Colorize;
macro_rules! error_occurred {
() => {
@@ -14,7 +14,6 @@ macro_rules! error_occurred {
};
}
-
macro_rules! no_colors {
() => {
$crate::ARGS.no_colors
@@ -33,7 +32,10 @@ macro_rules! fatal {
macro_rules! f0001 {
() => {{
error_occurred!();
- eprintln!("{} Specify a directory to check (use option -d)", fatal!("F0001"),);
+ eprintln!(
+ "{} Specify a directory to check (use option -d)",
+ fatal!("F0001"),
+ );
}};
}
@@ -42,7 +44,8 @@ macro_rules! f0002 {
error_occurred!();
eprintln!(
"{} Specified directory {} does not exist. Exiting...",
- fatal!("F0002"), $fmt1
+ fatal!("F0002"),
+ $fmt1
);
}};
}
@@ -52,7 +55,8 @@ macro_rules! f0003 {
error_occurred!();
eprintln!(
"{} Specified TDS archive {} does not exist or is no file. Exiting...",
- fatal!("F0003"), $fmt1
+ fatal!("F0003"),
+ $fmt1
);
}};
}
@@ -62,7 +66,8 @@ macro_rules! f0004 {
error_occurred!();
eprintln!(
"{} File {} specified as TDS archive is no zip archive. Exiting...",
- fatal!("F0004"), $fmt1
+ fatal!("F0004"),
+ $fmt1
);
}};
}
@@ -72,7 +77,8 @@ macro_rules! f0005 {
error_occurred!();
eprintln!(
"{} Bad filename {} for the tds.zip archive. Exiting...",
- fatal!("F0005"), $fmt1
+ fatal!("F0005"),
+ $fmt1
);
}};
}
@@ -104,7 +110,8 @@ macro_rules! f0008 {
error_occurred!();
eprintln!(
"{} Config file {} doesn't exist. Exiting...",
- fatal!("F0007"), $fmt
+ fatal!("F0007"),
+ $fmt
);
}};
}
@@ -114,7 +121,9 @@ macro_rules! f0009 {
error_occurred!();
eprintln!(
"{} Error reading config file {}: {} Exiting...",
- fatal!("F0009"), $fmt1, $fmt2
+ fatal!("F0009"),
+ $fmt1,
+ $fmt2
);
}};
}
@@ -124,7 +133,8 @@ macro_rules! f0010 {
error_occurred!();
eprintln!(
"{} Config file's content could not be read properly: {} Exiting...",
- fatal!("F0010"), $fmt
+ fatal!("F0010"),
+ $fmt
);
}};
}
@@ -369,7 +379,10 @@ macro_rules! e0026 {
macro_rules! e0027 {
($fmt1:expr, $fmt2:expr) => {{
error_occurred!();
- error!("{} {}: An I/O error occurred -> {}", "E0027", $fmt1, $fmt2);
+ error!(
+ "{} {}: An I/O error occurred -> {}",
+ "E0027", $fmt1, $fmt2
+ );
}};
}
@@ -494,6 +507,22 @@ macro_rules! e0041 {
}};
}
+macro_rules! e0042 {
+ ($fmt:expr) => {{
+ error_occurred!();
+ error!(
+ "{} TDS zip archive: duplicate names when ignoring letter case for: {}",
+ "E0042", $fmt
+ );
+ }};
+}
+
+macro_rules! e0043 {
+ ($fmt:expr) => {{
+ error_occurred!();
+ error!("{} Symlink {} found in TDS zip archive", "E0043", $fmt);
+ }};
+}
macro_rules! w0001 {
($fmt:expr) => {{
@@ -569,9 +598,7 @@ macro_rules! w0009 {
error_occurred!();
warn!(
"{} Replacing `{} -> {}` with the same from config file",
- "W0009",
- $fmt1,
- $fmt2
+ "W0009", $fmt1, $fmt2
)
}};
}
@@ -582,6 +609,15 @@ macro_rules! w0010 {
}};
}
+macro_rules! w0011 {
+ ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
+ warn!(
+ "{} {} has an mtime in the future by {} seconds, or {}",
+ "W0011", $fmt1, $fmt2, $fmt3
+ )
+ }};
+}
+
macro_rules! i0002 {
($fmt:expr) => {{
info!(
@@ -638,11 +674,7 @@ macro_rules! i0009 {
error_occurred!();
warn!(
"{} Updating entry `{} -> {}` with `{} -> {}` from config file",
- "I0009",
- $fmt1,
- $fmt2,
- $fmt1,
- $fmt3
+ "I0009", $fmt1, $fmt2, $fmt1, $fmt3
)
}};
}
@@ -701,6 +733,8 @@ pub fn explains(err: &str) {
"E0039" => e0039d(),
"E0040" => e0040d(),
"E0041" => e0041d(),
+ "E0042" => e0042d(),
+ "E0043" => e0043d(),
// "I0001" => i0001d!(),
"I0001" => i0001d(),
@@ -723,6 +757,7 @@ pub fn explains(err: &str) {
"W0008" => w0008d(),
"W0009" => w0009d(),
"W0010" => w0010d(),
+ "W0011" => w0011d(),
e => eprintln!(
"{} Unknown error code `{}` specified with option -e resp. --explain. Exiting...",
@@ -785,6 +820,8 @@ pub fn explains_all() {
explains("E0039");
explains("E0040");
explains("E0041");
+ explains("E0042");
+ explains("E0043");
explains("I0001");
explains("I0002");
@@ -806,4 +843,5 @@ pub fn explains_all() {
explains("W0008");
explains("W0009");
explains("W0010");
+ explains("W0011");
}
diff --git a/support/pkgcheck/src/messages/warningsd.rs b/support/pkgcheck/src/messages/warningsd.rs
index 6fe37835cf..176fc1d2de 100644
--- a/support/pkgcheck/src/messages/warningsd.rs
+++ b/support/pkgcheck/src/messages/warningsd.rs
@@ -111,7 +111,7 @@ We regard a file as a Windows file if its name ends with:
pub fn w0009d() {
warn!(
r#"
-W0009 -- Replacing -> ` with the same from config file",
+W0009 -- Replacing <pkgname> -> <tpkg> with the same from config file",
This message can only show up if pkgcheck got called with --config.
Indicates that an entry in the pkgcheck config file does the same as the
@@ -131,3 +131,20 @@ displayed
)
}
+pub fn w0011d() {
+ warn!(
+ r#"
+W0011 -- has an mtime in the future by seconds, or <hours, minutes, seconds>
+
+The file has a future modification time. This is most probably caused by
+the archiver tool which doesn't pay attention to the timezone when
+adding the file to the archive
+
+The future time will be displayed in
+
+- seconds
+- and hours, minutes and seconds
+"#
+ )
+}
+
diff --git a/support/pkgcheck/src/recode.rs b/support/pkgcheck/src/recode.rs
index 827da9587b..4d71ac5467 100644
--- a/support/pkgcheck/src/recode.rs
+++ b/support/pkgcheck/src/recode.rs
@@ -74,7 +74,7 @@ pub fn wrong_line_endings2crlf(fname: &str) -> Result<(), io::Error> {
};
// write back
- match hdl_out.write(&another_vec) {
+ match hdl_out.write_all(&another_vec) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
@@ -102,7 +102,7 @@ pub fn wrong_line_endings2lf(fname: &str) -> Result<(), io::Error> {
};
// write back
- match hdl_out.write(&another_vec) {
+ match hdl_out.write_all(&another_vec) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
diff --git a/support/pkgcheck/src/utils.rs b/support/pkgcheck/src/utils.rs
index b311453b66..e934c6d9d9 100644
--- a/support/pkgcheck/src/utils.rs
+++ b/support/pkgcheck/src/utils.rs
@@ -5,16 +5,17 @@ use std::fs::read_link;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::path::PathBuf;
+use std::time::Duration;
use walkdir::DirEntry;
use once_cell::sync::Lazy; // 1.3.1
use regex::Regex;
use std::borrow::Cow;
-use std::io;
use std::fs::File;
+use std::io;
use std::process::Command;
-use zip::result::ZipResult;
use std::sync::atomic::Ordering;
+use zip::result::ZipResult;
use std::fs;
@@ -121,7 +122,6 @@ impl Utils {
}
pub fn check_for_temporary_file(&self, dir_entry_str: &str) {
-
static RE: Lazy<Regex> = Lazy::new(regex_temporary_file_endings);
if RE.is_match(dir_entry_str) {
@@ -269,7 +269,7 @@ pub fn temp_file_endings() -> Vec<(String, String)> {
(".xref", "htlatex related"),
(".xray", "dump of \\show output"),
("~", "a file name ending with ~ (tilde) is temporary anyway"),
- // ( ".lyx~", "LyX related backup file" ),
+ ("Thumbs.db", "thumbnails file in Windows"),
];
v.into_iter()
@@ -474,6 +474,16 @@ pub fn dirname(entry: &str) -> Option<&str> {
}
#[test]
+fn test_format_duration() {
+ assert!(format_duration(&Duration::new(5, 0)) == String::from("5sec"));
+ assert!(format_duration(&Duration::new(105, 0)) == String::from("1min 45sec"));
+ assert!(format_duration(&Duration::new(3801, 0)) == String::from("1h 3min 21sec"));
+ assert!(format_duration(&Duration::new(25449, 0)) == String::from("7h 4min 9sec"));
+ assert!(format_duration(&Duration::new(108245, 0)) == String::from("1d 6h 4min 5sec"));
+ assert!(format_duration(&Duration::new(0, 0)) == String::from("0sec"));
+}
+
+#[test]
fn test_filename() {
assert!(filename("/etc/fstab") == Some("fstab"));
assert!(filename("fstab") == Some("fstab"));
@@ -482,6 +492,7 @@ fn test_filename() {
assert!(filename("/") == None);
}
+// We return the right part of a path name if it does not end with a `/`
pub fn filename(entry: &str) -> Option<&str> {
if entry.ends_with('/') {
return None;
@@ -502,3 +513,30 @@ pub fn basename(path: &str) -> Cow<str> {
None => path.into(),
}
}
+
+pub fn format_duration(duration: &Duration) -> String {
+ let seconds = duration.as_secs();
+ let days = seconds / 86400;
+ let hours = (seconds % 86400) / 3600;
+ let minutes = (seconds % 3600) / 60;
+ let seconds = seconds % 60;
+
+ let mut result = String::new();
+ if days > 0 {
+ result.push_str(&format!("{}d ", days));
+ }
+
+ if hours > 0 {
+ result.push_str(&format!("{}h ", hours));
+ }
+
+ if minutes > 0 {
+ result.push_str(&format!("{}min ", minutes));
+ }
+
+ if seconds > 0 || result.is_empty() {
+ result.push_str(&format!("{}sec", seconds));
+ }
+
+ return result.trim().to_string();
+}
diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md
index 0a3b5ed683..007f344876 100644
--- a/support/texlab/CHANGELOG.md
+++ b/support/texlab/CHANGELOG.md
@@ -5,6 +5,23 @@ 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](https://semver.org/spec/v2.0.0.html).
+## [5.17.0] - 2024-06-23
+
+### Added
+
+- Add label commands from `zref` and `zref-clever` to the list of default label commands
+ ([#1140](https://github.com/latex-lsp/texlab/pull/1140))
+- Add `texlab.experimental.labelDefinitionPrefixes` and
+ `texlab.experimental.labelReferencePrefixes` options ([#1139](https://github.com/latex-lsp/texlab/pull/1139))
+
+## [5.16.1] - 2024-05-25
+
+### Fixed
+
+- Don't treat `\label{}` and `\ref{}` with macro parameter as label commands ([#1119](https://github.com/latex-lsp/texlab/issues/1119))
+- Fix parsing `latexmkrc` for `latexmk` versions older than `v4.8.4` ([#1128](https://github.com/latex-lsp/texlab/issues/1128))
+- Remove unused `texlab.rootDirectory` setting from documentation
+
## [5.16.0] - 2024-05-01
### Added
diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock
index 80599217fd..09847a2a79 100644
--- a/support/texlab/Cargo.lock
+++ b/support/texlab/Cargo.lock
@@ -73,9 +73,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.82"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "autocfg"
@@ -190,9 +190,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
-version = "0.4.31"
+version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"num-traits",
]
@@ -334,6 +334,7 @@ dependencies = [
"expect-test",
"fuzzy-matcher",
"line-index",
+ "parser",
"rayon",
"rowan",
"rustc-hash",
@@ -594,9 +595,9 @@ dependencies = [
[[package]]
name = "flate2"
-version = "1.0.29"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4556222738635b7a3417ae6130d8f52201e45a0c4d1a907f0826383adb5f85e7"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -860,9 +861,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.153"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "line-index"
@@ -1094,9 +1095,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "parking_lot"
-version = "0.12.1"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -1337,6 +1338,7 @@ name = "rename"
version = "0.0.0"
dependencies = [
"base-db",
+ "parser",
"rowan",
"rustc-hash",
"syntax",
@@ -1404,18 +1406,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
-version = "1.0.199"
+version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a"
+checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.199"
+version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc"
+checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
dependencies = [
"proc-macro2",
"quote",
@@ -1424,9 +1426,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
+checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa",
"ryu",
@@ -1445,9 +1447,9 @@ dependencies = [
[[package]]
name = "serde_repr"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
+checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
@@ -1548,7 +1550,7 @@ dependencies = [
[[package]]
name = "texlab"
-version = "5.16.0"
+version = "5.17.0"
dependencies = [
"anyhow",
"base-db",
@@ -1601,18 +1603,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "thiserror"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
diff --git a/support/texlab/crates/base-db/src/config.rs b/support/texlab/crates/base-db/src/config.rs
index 9814e3e674..e4c827e61c 100644
--- a/support/texlab/crates/base-db/src/config.rs
+++ b/support/texlab/crates/base-db/src/config.rs
@@ -3,9 +3,8 @@ use std::time::Duration;
use parser::SyntaxConfig;
use regex::Regex;
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct Config {
- pub root_dir: Option<String>,
pub build: BuildConfig,
pub diagnostics: DiagnosticsConfig,
pub formatting: FormattingConfig,
@@ -36,7 +35,7 @@ pub struct DiagnosticsConfig {
pub delay: Duration,
}
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct ChktexConfig {
pub on_open: bool,
pub on_save: bool,
@@ -65,13 +64,13 @@ pub enum Formatter {
LatexIndent,
}
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct LatexIndentConfig {
pub local: Option<String>,
pub modify_line_breaks: bool,
}
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct SymbolConfig {
pub allowed_patterns: Vec<Regex>,
pub ignored_patterns: Vec<Regex>,
@@ -96,22 +95,6 @@ pub enum MatchingAlgo {
PrefixIgnoreCase,
}
-impl Default for Config {
- fn default() -> Self {
- Self {
- root_dir: None,
- build: BuildConfig::default(),
- diagnostics: DiagnosticsConfig::default(),
- formatting: FormattingConfig::default(),
- synctex: None,
- symbols: SymbolConfig::default(),
- syntax: SyntaxConfig::default(),
- completion: CompletionConfig::default(),
- inlay_hints: InlayHintConfig::default(),
- }
- }
-}
-
impl Default for BuildConfig {
fn default() -> Self {
Self {
@@ -141,17 +124,6 @@ impl Default for DiagnosticsConfig {
}
}
-impl Default for ChktexConfig {
- fn default() -> Self {
- Self {
- on_open: false,
- on_save: false,
- on_edit: false,
- additional_args: Vec::new(),
- }
- }
-}
-
impl Default for FormattingConfig {
fn default() -> Self {
Self {
@@ -163,24 +135,6 @@ impl Default for FormattingConfig {
}
}
-impl Default for LatexIndentConfig {
- fn default() -> Self {
- Self {
- local: None,
- modify_line_breaks: false,
- }
- }
-}
-
-impl Default for SymbolConfig {
- fn default() -> Self {
- Self {
- allowed_patterns: Vec::new(),
- ignored_patterns: Vec::new(),
- }
- }
-}
-
impl Default for InlayHintConfig {
fn default() -> Self {
Self {
diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs
index e07368d078..4b2399b7f8 100644
--- a/support/texlab/crates/base-db/src/deps/graph.rs
+++ b/support/texlab/crates/base-db/src/deps/graph.rs
@@ -22,7 +22,7 @@ pub struct Edge {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum EdgeData {
- DirectLink(DirectLinkData),
+ DirectLink(Box<DirectLinkData>),
AdditionalFiles,
Artifact,
}
@@ -159,7 +159,7 @@ impl Graph {
for target_uri in file_names
.iter()
.flat_map(|file_name| {
- util::expand_relative_path(&file_name, &start.root.src_dir, workspace.folders())
+ util::expand_relative_path(file_name, &start.root.src_dir, workspace.folders())
})
.chain(distro_files)
{
@@ -179,7 +179,7 @@ impl Graph {
self.edges.push(Edge {
source: start.source.uri.clone(),
target: target.uri.clone(),
- data: EdgeData::DirectLink(link_data),
+ data: EdgeData::DirectLink(Box::new(link_data)),
});
break;
diff --git a/support/texlab/crates/base-db/src/deps/root.rs b/support/texlab/crates/base-db/src/deps/root.rs
index a8cec6604a..03fd41a9a0 100644
--- a/support/texlab/crates/base-db/src/deps/root.rs
+++ b/support/texlab/crates/base-db/src/deps/root.rs
@@ -31,11 +31,11 @@ impl ProjectRoot {
}
let Ok(parent) = current.join("..") else {
- break Self::from_config(workspace, &dir);
+ break Self::from_config(workspace, dir);
};
if current == parent || Some(&parent) == home_dir.as_ref() {
- break Self::from_config(workspace, &dir);
+ break Self::from_config(workspace, dir);
}
current = parent;
diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs
index 7a388129fd..afb5869d69 100644
--- a/support/texlab/crates/base-db/src/document.rs
+++ b/support/texlab/crates/base-db/src/document.rs
@@ -56,7 +56,10 @@ impl Document {
Language::Tex => {
let green = parser::parse_latex(&text, &params.config.syntax);
let mut semantics = semantics::tex::Semantics::default();
- semantics.process_root(&latex::SyntaxNode::new_root(green.clone()));
+ semantics.process_root(
+ &params.config.syntax,
+ &latex::SyntaxNode::new_root(green.clone()),
+ );
DocumentData::Tex(TexDocumentData { green, semantics })
}
Language::Bib => {
diff --git a/support/texlab/crates/base-db/src/semantics/auxiliary.rs b/support/texlab/crates/base-db/src/semantics/auxiliary.rs
index 489a7d1ac6..8c9fe012e6 100644
--- a/support/texlab/crates/base-db/src/semantics/auxiliary.rs
+++ b/support/texlab/crates/base-db/src/semantics/auxiliary.rs
@@ -36,7 +36,7 @@ impl Semantics {
Some(group)
})?;
- let text = group.content_text()?.replace('{', "").replace('}', "");
+ let text = group.content_text()?.replace(['{', '}'], "");
self.label_numbers.insert(name, text);
Some(())
}
diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs
index 1ad8969a80..a1301091d4 100644
--- a/support/texlab/crates/base-db/src/semantics/tex.rs
+++ b/support/texlab/crates/base-db/src/semantics/tex.rs
@@ -3,7 +3,28 @@ use rustc_hash::FxHashSet;
use syntax::latex::{self, HasBrack, HasCurly};
use titlecase::titlecase;
+use parser::SyntaxConfig;
+
use super::Span;
+use crate::semantics::tex::latex::SyntaxToken;
+
+fn maybe_prepend_prefix(
+ map: &Vec<(String, String)>,
+ command: &Option<SyntaxToken>,
+ name: &Span,
+) -> Span {
+ match command {
+ Some(x) => Span::new(
+ map.iter()
+ .find_map(|(k, v)| if k == &x.text()[1..] { Some(v) } else { None })
+ .unwrap_or(&String::new())
+ .to_owned()
+ + &name.text,
+ name.range,
+ ),
+ None => name.clone(),
+ }
+}
#[derive(Debug, Clone, Default)]
pub struct Semantics {
@@ -19,11 +40,11 @@ pub struct Semantics {
}
impl Semantics {
- pub fn process_root(&mut self, root: &latex::SyntaxNode) {
+ pub fn process_root(&mut self, conf: &SyntaxConfig, root: &latex::SyntaxNode) {
for node in root.descendants_with_tokens() {
match node {
latex::SyntaxElement::Node(node) => {
- self.process_node(&node);
+ self.process_node(conf, &node);
}
latex::SyntaxElement::Token(token) => {
if token.kind() == latex::COMMAND_NAME {
@@ -40,17 +61,17 @@ impl Semantics {
.any(|link| link.kind == LinkKind::Cls && link.path.text == "subfiles");
}
- fn process_node(&mut self, node: &latex::SyntaxNode) {
+ fn process_node(&mut self, conf: &SyntaxConfig, node: &latex::SyntaxNode) {
if let Some(include) = latex::Include::cast(node.clone()) {
self.process_include(include);
} else if let Some(import) = latex::Import::cast(node.clone()) {
self.process_import(import);
} else if let Some(label) = latex::LabelDefinition::cast(node.clone()) {
- self.process_label_definition(label);
+ self.process_label_definition(conf, label);
} else if let Some(label) = latex::LabelReference::cast(node.clone()) {
- self.process_label_reference(label);
+ self.process_label_reference(conf, label);
} else if let Some(label) = latex::LabelReferenceRange::cast(node.clone()) {
- self.process_label_reference_range(label);
+ self.process_label_reference_range(conf, label);
} else if let Some(citation) = latex::Citation::cast(node.clone()) {
self.process_citation(citation);
} else if let Some(environment) = latex::Environment::cast(node.clone()) {
@@ -111,11 +132,16 @@ impl Semantics {
});
}
- fn process_label_definition(&mut self, label: latex::LabelDefinition) {
+ fn process_label_definition(&mut self, conf: &SyntaxConfig, label: latex::LabelDefinition) {
let Some(name) = label.name().and_then(|group| group.key()) else {
return;
};
+ let name = Span::from(&name);
+ if name.text.contains('#') {
+ return;
+ }
+
let full_range = latex::small_range(&label);
let mut objects = Vec::new();
for node in label.syntax().ancestors() {
@@ -185,46 +211,75 @@ impl Semantics {
self.labels.push(Label {
kind: LabelKind::Definition,
- name: Span::from(&name),
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(&conf.label_definition_prefixes, &label.command(), &name),
targets: objects,
full_range,
});
}
- fn process_label_reference(&mut self, label: latex::LabelReference) {
+ fn process_label_reference(&mut self, conf: &SyntaxConfig, label: latex::LabelReference) {
let Some(name_list) = label.name_list() else {
return;
};
let full_range = latex::small_range(&label);
for name in name_list.keys() {
- self.labels.push(Label {
- kind: LabelKind::Reference,
- name: Span::from(&name),
- targets: Vec::new(),
- full_range,
- });
+ let name = Span::from(&name);
+ if !name.text.contains('#') {
+ self.labels.push(Label {
+ kind: LabelKind::Reference,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
+ targets: Vec::new(),
+ full_range,
+ });
+ }
}
}
- fn process_label_reference_range(&mut self, label: latex::LabelReferenceRange) {
+ fn process_label_reference_range(
+ &mut self,
+ conf: &SyntaxConfig,
+ label: latex::LabelReferenceRange,
+ ) {
let full_range = latex::small_range(&label);
if let Some(from) = label.from().and_then(|group| group.key()) {
- self.labels.push(Label {
- kind: LabelKind::ReferenceRange,
- name: Span::from(&from),
- targets: Vec::new(),
- full_range,
- });
+ let name = Span::from(&from);
+ if !name.text.contains('#') {
+ self.labels.push(Label {
+ kind: LabelKind::ReferenceRange,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
+ targets: Vec::new(),
+ full_range,
+ });
+ }
}
if let Some(to) = label.to().and_then(|group| group.key()) {
- self.labels.push(Label {
- kind: LabelKind::ReferenceRange,
- name: Span::from(&to),
- targets: Vec::new(),
- full_range,
- });
+ let name = Span::from(&to);
+ if !name.text.contains('#') {
+ self.labels.push(Label {
+ kind: LabelKind::ReferenceRange,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
+ targets: Vec::new(),
+ full_range,
+ });
+ }
}
}
@@ -232,10 +287,13 @@ impl Semantics {
let full_range = latex::small_range(&citation);
if let Some(list) = citation.key_list() {
for key in list.keys() {
- self.citations.push(Citation {
- name: Span::from(&key),
- full_range,
- });
+ let name = Span::from(&key);
+ if !name.text.contains('#') {
+ self.citations.push(Citation {
+ name: Span::from(&key),
+ full_range,
+ });
+ }
}
}
}
@@ -319,6 +377,7 @@ pub enum LabelKind {
#[derive(Debug, Clone)]
pub struct Label {
pub kind: LabelKind,
+ pub cmd: Option<String>,
pub name: Span,
pub targets: Vec<LabelTarget>,
pub full_range: TextRange,
diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs
index 75674dcf8d..f2564ed415 100644
--- a/support/texlab/crates/base-db/src/workspace.rs
+++ b/support/texlab/crates/base-db/src/workspace.rs
@@ -99,7 +99,7 @@ impl Workspace {
Cow::Owned(text) => text,
};
- let owner = if self.distro.file_name_db.contains(&path) {
+ let owner = if self.distro.file_name_db.contains(path) {
Owner::Distro
} else {
Owner::Server
diff --git a/support/texlab/crates/bibfmt/src/lib.rs b/support/texlab/crates/bibfmt/src/lib.rs
index cfce131f2c..8840daa1c4 100644
--- a/support/texlab/crates/bibfmt/src/lib.rs
+++ b/support/texlab/crates/bibfmt/src/lib.rs
@@ -11,7 +11,7 @@ pub struct Options {
impl Options {
fn indent(&self) -> String {
if self.insert_spaces {
- std::iter::repeat(' ').take(self.tab_size).collect()
+ " ".repeat(self.tab_size)
} else {
String::from("\t")
}
@@ -126,7 +126,7 @@ impl<'a> Formatter<'a> {
}
bibtex::FIELD => {
let field = bibtex::Field::cast(parent).unwrap();
- self.output.push_str(&self.indent);
+ self.output.push_str(self.indent);
let name = field.name_token().unwrap();
self.output.push_str(name.text());
self.output.push_str(" = ");
@@ -160,7 +160,7 @@ impl<'a> Formatter<'a> {
if length + current_length + space_length > self.options.line_length {
self.output.push('\n');
self.output.push_str(self.indent.as_ref());
- for _ in 0..=align - self.options.tab_size as usize {
+ for _ in 0..=align - self.options.tab_size {
self.output.push(' ');
}
length = align;
diff --git a/support/texlab/crates/bibtex-utils/Cargo.toml b/support/texlab/crates/bibtex-utils/Cargo.toml
index 97e13517f5..c20508107c 100644
--- a/support/texlab/crates/bibtex-utils/Cargo.toml
+++ b/support/texlab/crates/bibtex-utils/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-chrono = { version = "0.4.26", default-features = false, features = ["std"] }
+chrono = { version = "0.4.38", default-features = false, features = ["std"] }
human_name = "2.0.3"
itertools = "0.12.1"
rowan = "0.15.15"
diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml
index c726e5f0d5..6e415f20d6 100644
--- a/support/texlab/crates/commands/Cargo.toml
+++ b/support/texlab/crates/commands/Cargo.toml
@@ -7,17 +7,17 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.82"
+anyhow = "1.0.86"
base-db = { path = "../base-db" }
bstr = "1.9.1"
crossbeam-channel = "0.5.12"
itertools = "0.12.1"
-libc = "0.2.153"
+libc = "0.2.155"
log = "0.4.21"
rowan = "0.15.15"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
-thiserror = "1.0.59"
+thiserror = "1.0.61"
url = "2.5.0"
[dev-dependencies]
diff --git a/support/texlab/crates/commands/src/find_envs.rs b/support/texlab/crates/commands/src/find_envs.rs
index 7a17345d80..1ea88657ab 100644
--- a/support/texlab/crates/commands/src/find_envs.rs
+++ b/support/texlab/crates/commands/src/find_envs.rs
@@ -53,7 +53,7 @@ mod tests {
let workspace = fixture.workspace;
let document = workspace.iter().next().unwrap();
let offset = fixture.documents[0].cursor.unwrap();
- let results = find_environments(&document, offset);
+ let results = find_environments(document, offset);
expect.assert_debug_eq(&results);
}
diff --git a/support/texlab/crates/commands/src/fwd_search.rs b/support/texlab/crates/commands/src/fwd_search.rs
index f1991cd48e..f3480ef3e2 100644
--- a/support/texlab/crates/commands/src/fwd_search.rs
+++ b/support/texlab/crates/commands/src/fwd_search.rs
@@ -103,7 +103,7 @@ impl ForwardSearch {
})
.ok_or_else(|| ForwardSearchError::InvalidPath(document.uri.clone()))?;
- let pdf_path = pdf_dir.join(&pdf_name);
+ let pdf_path = pdf_dir.join(pdf_name);
let pdf_exists = pdf_path.exists();
log::debug!("[FwdSearch] pdf_path={pdf_path:?}, pdf_exists={pdf_exists}");
diff --git a/support/texlab/crates/commands/src/placeholders.rs b/support/texlab/crates/commands/src/placeholders.rs
index 9994420f5d..328a95773a 100644
--- a/support/texlab/crates/commands/src/placeholders.rs
+++ b/support/texlab/crates/commands/src/placeholders.rs
@@ -45,6 +45,6 @@ mod tests {
&[('f', "foo")],
);
- assert_eq!(output, vec!["foo".into(), "%f", "%f".into(), "foobar"]);
+ assert_eq!(output, vec!["foo", "%f", "%f", "foobar"]);
}
}
diff --git a/support/texlab/crates/completion-data/Cargo.toml b/support/texlab/crates/completion-data/Cargo.toml
index 59b707e474..970cd6a578 100644
--- a/support/texlab/crates/completion-data/Cargo.toml
+++ b/support/texlab/crates/completion-data/Cargo.toml
@@ -7,12 +7,12 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-flate2 = "1.0.29"
+flate2 = "1.0.30"
itertools = "0.12.1"
once_cell = "1.19.0"
rustc-hash = "1.1.0"
-serde = { version = "1.0.195", features = ["derive"] }
-serde_json = "1.0.115"
+serde = { version = "1.0.202", features = ["derive"] }
+serde_json = "1.0.117"
[lib]
doctest = false
diff --git a/support/texlab/crates/completion/Cargo.toml b/support/texlab/crates/completion/Cargo.toml
index e28e04dfc7..6469b5f004 100644
--- a/support/texlab/crates/completion/Cargo.toml
+++ b/support/texlab/crates/completion/Cargo.toml
@@ -22,6 +22,7 @@ criterion = "0.5.1"
distro = { path = "../distro" }
expect-test = "1.5.0"
test-utils = { path = "../test-utils" }
+parser = { path = "../parser" }
[lib]
doctest = false
diff --git a/support/texlab/crates/completion/src/lib.rs b/support/texlab/crates/completion/src/lib.rs
index 7fc5bba174..5bfd94d944 100644
--- a/support/texlab/crates/completion/src/lib.rs
+++ b/support/texlab/crates/completion/src/lib.rs
@@ -72,12 +72,12 @@ impl<'a> CompletionItemData<'a> {
Self::Citation(data) => &data.entry.name.text,
Self::Environment(data) => data.name,
Self::GlossaryEntry(data) => &data.name,
- Self::Label(data) => data.name,
+ Self::Label(data) => &data.name,
Self::Color(name) => name,
Self::ColorModel(name) => name,
- Self::File(name) => &name,
- Self::Directory(name) => &name,
- Self::Argument(data) => &data.0.name,
+ Self::File(name) => name,
+ Self::Directory(name) => name,
+ Self::Argument(data) => data.0.name,
Self::Package(name) => name,
Self::DocumentClass(name) => name,
Self::EntryType(data) => data.0.name,
diff --git a/support/texlab/crates/completion/src/providers/argument.rs b/support/texlab/crates/completion/src/providers/argument.rs
index 6637cecdd6..a9c8f4304b 100644
--- a/support/texlab/crates/completion/src/providers/argument.rs
+++ b/support/texlab/crates/completion/src/providers/argument.rs
@@ -37,7 +37,7 @@ pub fn complete_arguments<'a>(
.filter(|(i, _)| *i == index)
{
for arg in &param.0 {
- if let Some(score) = builder.matcher.score(&arg.name, &cursor.text) {
+ if let Some(score) = builder.matcher.score(arg.name, &cursor.text) {
let data = CompletionItemData::Argument(ArgumentData(arg));
builder
.items
diff --git a/support/texlab/crates/completion/src/providers/color.rs b/support/texlab/crates/completion/src/providers/color.rs
index cbdd38dc32..8be1b50555 100644
--- a/support/texlab/crates/completion/src/providers/color.rs
+++ b/support/texlab/crates/completion/src/providers/color.rs
@@ -14,7 +14,7 @@ pub fn complete_colors<'a>(
latex::ColorReference::cast(group.syntax().parent()?)?;
for name in COLORS {
- if let Some(score) = builder.matcher.score(&name, &cursor.text) {
+ if let Some(score) = builder.matcher.score(name, &cursor.text) {
let data = CompletionItemData::Color(name);
builder
.items
diff --git a/support/texlab/crates/completion/src/providers/color_model.rs b/support/texlab/crates/completion/src/providers/color_model.rs
index 4b991c4807..80970b1913 100644
--- a/support/texlab/crates/completion/src/providers/color_model.rs
+++ b/support/texlab/crates/completion/src/providers/color_model.rs
@@ -14,7 +14,7 @@ pub fn complete_color_models<'a>(
let cursor = check_color_definition(params).or_else(|| check_color_definition_set(params))?;
for name in MODEL_NAMES {
- if let Some(score) = builder.matcher.score(&name, &cursor.text) {
+ if let Some(score) = builder.matcher.score(name, &cursor.text) {
let data = CompletionItemData::ColorModel(name);
builder
.items
diff --git a/support/texlab/crates/completion/src/providers/command.rs b/support/texlab/crates/completion/src/providers/command.rs
index f404d42ab3..34f8876e1f 100644
--- a/support/texlab/crates/completion/src/providers/command.rs
+++ b/support/texlab/crates/completion/src/providers/command.rs
@@ -44,7 +44,7 @@ impl<'a, 'b> Processor<'a, 'b> {
pub fn add_delimiters(&mut self) {
for (left, right) in DELIMITERS {
- let Some(score) = self.0.builder.matcher.score(&left, &self.0.cursor.text) else {
+ let Some(score) = self.0.builder.matcher.score(left, &self.0.cursor.text) else {
continue;
};
@@ -68,7 +68,7 @@ impl<'a, 'b> Processor<'a, 'b> {
let data = CompletionItemData::Command(CommandData {
name: &command.name,
glyph: command.glyph.as_deref(),
- image: command.image.as_deref(),
+ image: command.image,
package: Some(package),
});
diff --git a/support/texlab/crates/completion/src/providers/environment.rs b/support/texlab/crates/completion/src/providers/environment.rs
index 393dd100ba..b56377550e 100644
--- a/support/texlab/crates/completion/src/providers/environment.rs
+++ b/support/texlab/crates/completion/src/providers/environment.rs
@@ -21,7 +21,7 @@ pub fn complete_environments<'a>(
.and_then(|env| env.begin())
.and_then(|begin| begin.name())
.and_then(|name| name.key())
- .map_or_else(|| String::new(), |name| name.to_string());
+ .map_or_else(String::new, |name| name.to_string());
let mut proc = Processor {
inner: ProviderContext {
@@ -48,7 +48,7 @@ impl<'a, 'b> Processor<'a, 'b> {
for package in included_packages(&self.inner.params.feature) {
let envs_with_score = package.environments.iter().filter_map(|env| {
let matcher = &self.inner.builder.matcher;
- let score = matcher.score(&env, &self.inner.cursor.text)?;
+ let score = matcher.score(env, &self.inner.cursor.text)?;
Some((*env, score))
});
@@ -76,7 +76,7 @@ impl<'a, 'b> Processor<'a, 'b> {
{
let matcher = &self.inner.builder.matcher;
let name = theorem.name.text.as_str();
- if let Some(score) = matcher.score(&name, &self.inner.cursor.text) {
+ if let Some(score) = matcher.score(name, &self.inner.cursor.text) {
let data = CompletionItemData::Environment(EnvironmentData {
name,
package: None,
diff --git a/support/texlab/crates/completion/src/providers/glossary.rs b/support/texlab/crates/completion/src/providers/glossary.rs
index c22f5b5888..d01d62a511 100644
--- a/support/texlab/crates/completion/src/providers/glossary.rs
+++ b/support/texlab/crates/completion/src/providers/glossary.rs
@@ -58,7 +58,7 @@ impl<'a, 'b> Processor<'a, 'b> {
for name in data
.root_node()
.descendants()
- .filter_map(|node| extract(node))
+ .filter_map(&extract)
.filter_map(|name| name.key())
.map(|name| name.to_string())
{
diff --git a/support/texlab/crates/completion/src/providers/import.rs b/support/texlab/crates/completion/src/providers/import.rs
index c506026a99..c0f608f9d2 100644
--- a/support/texlab/crates/completion/src/providers/import.rs
+++ b/support/texlab/crates/completion/src/providers/import.rs
@@ -29,13 +29,13 @@ pub fn complete_imports<'a>(
file_names.insert(file_name);
let stem = &file_name[0..file_name.len() - 4];
if kind == latex::PACKAGE_INCLUDE {
- if let Some(score) = builder.matcher.score(&stem, &cursor.text) {
+ if let Some(score) = builder.matcher.score(stem, &cursor.text) {
let data = CompletionItemData::Package(stem);
builder
.items
.push(CompletionItem::new_simple(score, cursor.range, data));
}
- } else if let Some(score) = builder.matcher.score(&stem, &cursor.text) {
+ } else if let Some(score) = builder.matcher.score(stem, &cursor.text) {
let data = CompletionItemData::DocumentClass(stem);
builder
.items
@@ -51,13 +51,13 @@ pub fn complete_imports<'a>(
{
let stem = &file_name[0..file_name.len() - 4];
if kind == latex::PACKAGE_INCLUDE {
- if let Some(score) = builder.matcher.score(&stem, &cursor.text) {
+ if let Some(score) = builder.matcher.score(stem, &cursor.text) {
let data = CompletionItemData::Package(stem);
builder
.items
.push(CompletionItem::new_simple(score, cursor.range, data));
}
- } else if let Some(score) = builder.matcher.score(&stem, &cursor.text) {
+ } else if let Some(score) = builder.matcher.score(stem, &cursor.text) {
let data = CompletionItemData::DocumentClass(stem);
builder
.items
diff --git a/support/texlab/crates/completion/src/providers/include.rs b/support/texlab/crates/completion/src/providers/include.rs
index 60c432d097..d0a042252f 100644
--- a/support/texlab/crates/completion/src/providers/include.rs
+++ b/support/texlab/crates/completion/src/providers/include.rs
@@ -19,9 +19,7 @@ pub fn complete_includes<'a>(
params: &'a CompletionParams<'a>,
builder: &mut CompletionBuilder<'a>,
) -> Option<()> {
- if params.feature.document.path.is_none() {
- return None;
- }
+ params.feature.document.path.as_ref()?;
let (cursor, group) = find_curly_group_word_list(params)?;
@@ -115,7 +113,7 @@ fn current_dir(
graphics_path: Option<&str>,
) -> Option<PathBuf> {
let workspace = &params.workspace;
- let parent = deps::parents(&workspace, params.document)
+ let parent = deps::parents(workspace, params.document)
.iter()
.next()
.map_or(params.document, Clone::clone);
diff --git a/support/texlab/crates/completion/src/providers/label_ref.rs b/support/texlab/crates/completion/src/providers/label_ref.rs
index 6f71ae3241..8b262f13ca 100644
--- a/support/texlab/crates/completion/src/providers/label_ref.rs
+++ b/support/texlab/crates/completion/src/providers/label_ref.rs
@@ -11,12 +11,30 @@ use crate::{
CompletionItem, CompletionItemData, CompletionParams,
};
+fn trim_prefix<'a>(prefix: Option<&'a str>, text: &'a str) -> &'a str {
+ prefix
+ .and_then(|pref| text.strip_prefix(pref))
+ .unwrap_or(text)
+}
+
pub fn complete_label_references<'a>(
params: &'a CompletionParams<'a>,
builder: &mut CompletionBuilder<'a>,
) -> Option<()> {
- let FindResult { cursor, is_math } =
- find_reference(params).or_else(|| find_reference_range(params))?;
+ let FindResult {
+ cursor,
+ is_math,
+ command,
+ } = find_reference(params).or_else(|| find_reference_range(params))?;
+ let ref_pref = params
+ .feature
+ .workspace
+ .config()
+ .syntax
+ .label_reference_prefixes
+ .iter()
+ .find_map(|(k, v)| if *k == command { Some(v) } else { None })
+ .map(|x| x.as_str());
for document in &params.feature.project.documents {
let DocumentData::Tex(data) = &document.data else {
@@ -29,6 +47,10 @@ pub fn complete_label_references<'a>(
.iter()
.filter(|label| label.kind == LabelKind::Definition)
{
+ if ref_pref.map_or(false, |pref| !label.name.text.starts_with(pref)) {
+ continue;
+ }
+ let labeltext = trim_prefix(ref_pref, &label.name.text);
match render_label(params.feature.workspace, &params.feature.project, label) {
Some(rendered_label) => {
if is_math && !matches!(rendered_label.object, RenderedObject::Equation) {
@@ -41,11 +63,12 @@ pub fn complete_label_references<'a>(
_ => None,
};
- let keywords = format!("{} {}", label.name.text, rendered_label.reference());
+ let keywords = format!("{} {}", labeltext, rendered_label.reference());
if let Some(score) = builder.matcher.score(&keywords, &cursor.text) {
+ let name = trim_prefix(ref_pref, &label.name.text);
let data = CompletionItemData::Label(crate::LabelData {
- name: &label.name.text,
+ name,
header,
footer,
object: Some(rendered_label.object),
@@ -59,12 +82,13 @@ pub fn complete_label_references<'a>(
}
None => {
if let Some(score) = builder.matcher.score(&label.name.text, &cursor.text) {
+ let name = trim_prefix(ref_pref, &label.name.text);
let data = CompletionItemData::Label(crate::LabelData {
- name: &label.name.text,
+ name,
header: None,
footer: None,
object: None,
- keywords: label.name.text.clone(),
+ keywords: labeltext.to_string(),
});
builder
@@ -82,20 +106,26 @@ pub fn complete_label_references<'a>(
struct FindResult {
cursor: Span,
is_math: bool,
+ command: String,
}
fn find_reference(params: &CompletionParams) -> Option<FindResult> {
let (cursor, group) = find_curly_group_word_list(params)?;
let reference = latex::LabelReference::cast(group.syntax().parent()?)?;
let is_math = reference.command()?.text() == "\\eqref";
- Some(FindResult { cursor, is_math })
+ Some(FindResult {
+ cursor,
+ is_math,
+ command: reference.command()?.text()[1..].to_string(),
+ })
}
fn find_reference_range(params: &CompletionParams) -> Option<FindResult> {
let (cursor, group) = find_curly_group_word(params)?;
- latex::LabelReferenceRange::cast(group.syntax().parent()?)?;
+ let refrange = latex::LabelReferenceRange::cast(group.syntax().parent()?)?;
Some(FindResult {
cursor,
is_math: false,
+ command: refrange.command()?.text()[1..].to_string(),
})
}
diff --git a/support/texlab/crates/completion/src/providers/tikz_library.rs b/support/texlab/crates/completion/src/providers/tikz_library.rs
index 10a0aa44ba..4c3d7e8955 100644
--- a/support/texlab/crates/completion/src/providers/tikz_library.rs
+++ b/support/texlab/crates/completion/src/providers/tikz_library.rs
@@ -21,7 +21,7 @@ pub fn complete_tikz_libraries<'a>(
};
for name in libraries {
- if let Some(score) = builder.matcher.score(&name, &cursor.text) {
+ if let Some(score) = builder.matcher.score(name, &cursor.text) {
let data = CompletionItemData::TikzLibrary(name);
builder
.items
diff --git a/support/texlab/crates/completion/src/tests.rs b/support/texlab/crates/completion/src/tests.rs
index c6bed6e08e..8c68b71dd9 100644
--- a/support/texlab/crates/completion/src/tests.rs
+++ b/support/texlab/crates/completion/src/tests.rs
@@ -1,11 +1,17 @@
-use base_db::FeatureParams;
+use base_db::{Config, FeatureParams};
use expect_test::{expect, Expect};
+use parser::SyntaxConfig;
use rowan::TextRange;
use crate::CompletionParams;
-fn check(input: &str, expect: Expect) {
- let fixture = test_utils::fixture::Fixture::parse(input);
+fn check_with_syntax_config(config: SyntaxConfig, input: &str, expect: Expect) {
+ let mut fixture = test_utils::fixture::Fixture::parse(input);
+ fixture.workspace.set_config(Config {
+ syntax: config,
+ ..Config::default()
+ });
+ let fixture = fixture;
let (offset, spec) = fixture
.documents
@@ -37,6 +43,10 @@ fn check(input: &str, expect: Expect) {
expect.assert_debug_eq(&items);
}
+fn check(input: &str, expect: Expect) {
+ check_with_syntax_config(SyntaxConfig::default(), input, expect)
+}
+
#[test]
fn acronym_ref_simple() {
check(
@@ -2134,3 +2144,200 @@ fn issue_885() {
"#]],
);
}
+
+#[test]
+fn test_custom_label_prefix_ref() {
+ let mut config = SyntaxConfig::default();
+ config.label_definition_commands.insert("asm".to_string());
+ config
+ .label_definition_prefixes
+ .push(("asm".to_string(), "asm:".to_string()));
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \end{enumerate}
+
+ \ref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "asm:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "asm:foo",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "baz",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "baz",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_prefix_custom_ref() {
+ let mut config = SyntaxConfig::default();
+ config.label_definition_commands.insert("asm".to_string());
+ config
+ .label_definition_prefixes
+ .push(("asm".to_string(), "asm:".to_string()));
+ config.label_reference_commands.insert("asmref".to_string());
+ config
+ .label_reference_prefixes
+ .push(("asmref".to_string(), "asm:".to_string()));
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \end{enumerate}
+
+ \asmref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_multiple_prefix_custom_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \goal{foo}{what}
+ \end{enumerate}
+
+ \goalref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_multiple_prefix_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \goal{foo}{what}
+ \end{enumerate}
+
+ \ref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "asm:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "asm:foo",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "baz",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "baz",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "goal:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "goal:foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
diff --git a/support/texlab/crates/definition/src/command.rs b/support/texlab/crates/definition/src/command.rs
index 3681cdbaa0..ea7ef8c2c2 100644
--- a/support/texlab/crates/definition/src/command.rs
+++ b/support/texlab/crates/definition/src/command.rs
@@ -28,13 +28,11 @@ pub(super) fn goto_definition(context: &mut DefinitionContext) -> Option<()> {
process_old_definition(node.clone()).or_else(|| process_new_definition(node))
})
.filter(|(_, command)| command.text() == name.text())
- .filter_map(|(target_range, command)| {
- Some(DefinitionResult {
- origin_selection_range,
- target: document,
- target_range,
- target_selection_range: command.text_range(),
- })
+ .map(|(target_range, command)| DefinitionResult {
+ origin_selection_range,
+ target: document,
+ target_range,
+ target_selection_range: command.text_range(),
});
context.results.extend(results);
diff --git a/support/texlab/crates/definition/src/tests.rs b/support/texlab/crates/definition/src/tests.rs
index 26f7c0dc3a..0b3f7fa7cc 100644
--- a/support/texlab/crates/definition/src/tests.rs
+++ b/support/texlab/crates/definition/src/tests.rs
@@ -11,7 +11,7 @@ fn check(input: &str) {
.locations()
.filter(|location| location.document == origin_document)
.find(|location| location.range.contains_inclusive(offset))
- .map_or_else(|| TextRange::default(), |location| location.range);
+ .map_or_else(TextRange::default, |location| location.range);
let mut expected = FxHashSet::default();
for document in &fixture.documents {
diff --git a/support/texlab/crates/diagnostics/src/chktex.rs b/support/texlab/crates/diagnostics/src/chktex.rs
index 195ea968e5..a3f539440d 100644
--- a/support/texlab/crates/diagnostics/src/chktex.rs
+++ b/support/texlab/crates/diagnostics/src/chktex.rs
@@ -74,7 +74,7 @@ impl Command {
.build(stdout),
);
- for line in reader.lines().flatten() {
+ for line in reader.lines().map_while(Result::ok) {
let captures = LINE_REGEX.captures(&line).unwrap();
let line = captures[1].parse::<u32>().unwrap() - 1;
let character = captures[2].parse::<u32>().unwrap() - 1;
diff --git a/support/texlab/crates/diagnostics/src/citations.rs b/support/texlab/crates/diagnostics/src/citations.rs
index 0f09f589be..43d5f495d2 100644
--- a/support/texlab/crates/diagnostics/src/citations.rs
+++ b/support/texlab/crates/diagnostics/src/citations.rs
@@ -24,7 +24,7 @@ pub fn detect_undefined_citations<'a>(
for citation in &data.semantics.citations {
let name = citation.name_text();
- if name != "*" && !entries.contains(name) && !name.contains("#") {
+ if name != "*" && !entries.contains(name) {
let diagnostic = Diagnostic::Tex(citation.name.range, TexError::UndefinedCitation);
results
.entry(document.uri.clone())
@@ -65,8 +65,8 @@ pub fn detect_unused_entries<'a>(
Some(())
}
-pub fn detect_duplicate_entries<'a>(
- workspace: &'a Workspace,
+pub fn detect_duplicate_entries(
+ workspace: &Workspace,
results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) {
for conflict in queries::Conflict::find_all::<Entry>(workspace) {
diff --git a/support/texlab/crates/diagnostics/src/manager.rs b/support/texlab/crates/diagnostics/src/manager.rs
index 3573bc40f2..500dc99c13 100644
--- a/support/texlab/crates/diagnostics/src/manager.rs
+++ b/support/texlab/crates/diagnostics/src/manager.rs
@@ -89,16 +89,12 @@ impl Manager {
let config = &workspace.config().diagnostics;
- results.retain(|uri, _| {
- workspace
- .lookup(uri)
- .map_or(false, |document| Self::is_relevant(document))
- });
+ results.retain(|uri, _| workspace.lookup(uri).map_or(false, Self::is_relevant));
- for (_, diagnostics) in &mut results {
+ for diagnostics in results.values_mut() {
diagnostics.retain(|diagnostic| {
filter_regex_patterns(
- &diagnostic.message(),
+ diagnostic.message(),
&config.allowed_patterns,
&config.ignored_patterns,
)
diff --git a/support/texlab/crates/diagnostics/src/tests.rs b/support/texlab/crates/diagnostics/src/tests.rs
index 3688abeaf4..05ad67fc8b 100644
--- a/support/texlab/crates/diagnostics/src/tests.rs
+++ b/support/texlab/crates/diagnostics/src/tests.rs
@@ -6,14 +6,14 @@ fn check(input: &str, expect: Expect) {
let mut manager = crate::Manager::default();
for document in fixture.workspace.iter() {
- manager.update_syntax(&fixture.workspace, &document);
+ manager.update_syntax(&fixture.workspace, document);
}
let results = manager.get(&fixture.workspace);
let results = results
.iter()
.filter(|(_, diags)| !diags.is_empty())
- .sorted_by(|(uri1, _), (uri2, _)| uri1.cmp(&uri2))
+ .sorted_by(|(uri1, _), (uri2, _)| uri1.cmp(uri2))
.map(|(uri, diags)| (uri.as_str(), diags))
.collect_vec();
diff --git a/support/texlab/crates/distro/Cargo.toml b/support/texlab/crates/distro/Cargo.toml
index eefcea2b49..dea6a56979 100644
--- a/support/texlab/crates/distro/Cargo.toml
+++ b/support/texlab/crates/distro/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.82"
+anyhow = "1.0.86"
rustc-hash = "1.1.0"
[lib]
diff --git a/support/texlab/crates/highlights/src/lib.rs b/support/texlab/crates/highlights/src/lib.rs
index 009dd20807..9d7a63b096 100644
--- a/support/texlab/crates/highlights/src/lib.rs
+++ b/support/texlab/crates/highlights/src/lib.rs
@@ -23,7 +23,7 @@ pub struct HighlightParams<'a> {
pub fn find_all(params: &HighlightParams) -> Vec<Highlight> {
let mut results = Vec::new();
- label::find_highlights(&params, &mut results);
+ label::find_highlights(params, &mut results);
results
}
diff --git a/support/texlab/crates/hover/src/lib.rs b/support/texlab/crates/hover/src/lib.rs
index 2d22d50b0b..dcf4d442a9 100644
--- a/support/texlab/crates/hover/src/lib.rs
+++ b/support/texlab/crates/hover/src/lib.rs
@@ -35,12 +35,12 @@ pub enum HoverData<'db> {
}
pub fn find<'a>(params: &HoverParams<'a>) -> Option<Hover<'a>> {
- citation::find_hover(&params)
- .or_else(|| package::find_hover(&params))
- .or_else(|| entry_type::find_hover(&params))
- .or_else(|| field_type::find_hover(&params))
- .or_else(|| label::find_hover(&params))
- .or_else(|| string_ref::find_hover(&params))
+ citation::find_hover(params)
+ .or_else(|| package::find_hover(params))
+ .or_else(|| entry_type::find_hover(params))
+ .or_else(|| field_type::find_hover(params))
+ .or_else(|| label::find_hover(params))
+ .or_else(|| string_ref::find_hover(params))
}
#[cfg(test)]
diff --git a/support/texlab/crates/inlay-hints/src/label.rs b/support/texlab/crates/inlay-hints/src/label.rs
index 8db852752e..6e29c806b6 100644
--- a/support/texlab/crates/inlay-hints/src/label.rs
+++ b/support/texlab/crates/inlay-hints/src/label.rs
@@ -9,7 +9,6 @@ use crate::{InlayHint, InlayHintBuilder, InlayHintData};
pub(super) fn find_hints(builder: &mut InlayHintBuilder) -> Option<()> {
let definitions = base_db::semantics::tex::Label::find_all(&builder.params.feature.project)
- .into_iter()
.filter(|(_, label)| label.kind == LabelKind::Definition)
.map(|(_, label)| (label.name_text(), label))
.collect::<FxHashMap<_, _>>();
diff --git a/support/texlab/crates/ipc/Cargo.toml b/support/texlab/crates/ipc/Cargo.toml
index ae31dcaf55..1e1ff7a822 100644
--- a/support/texlab/crates/ipc/Cargo.toml
+++ b/support/texlab/crates/ipc/Cargo.toml
@@ -8,8 +8,8 @@ rust-version.workspace = true
[dependencies]
crossbeam-channel = "0.5.12"
-serde = "1.0.199"
-serde_json = "1.0.116"
+serde = "1.0.202"
+serde_json = "1.0.117"
log = "0.4.21"
uds_windows = "1.1.0"
diff --git a/support/texlab/crates/parser/src/build_log.rs b/support/texlab/crates/parser/src/build_log.rs
index 420d2dda20..c1f59bd086 100644
--- a/support/texlab/crates/parser/src/build_log.rs
+++ b/support/texlab/crates/parser/src/build_log.rs
@@ -36,7 +36,7 @@ pub fn parse_build_log(log: &str) -> BuildLog {
let warnings = extract_matches(&log, &ranges, &WARNING_REGEX, BuildErrorLevel::Warning);
let bad_boxes = extract_matches(&log, &ranges, &BAD_BOX_REGEX, BuildErrorLevel::Warning);
- let errors = vec![tex_errors, warnings, bad_boxes].concat();
+ let errors = [tex_errors, warnings, bad_boxes].concat();
BuildLog { errors }
}
diff --git a/support/texlab/crates/parser/src/config.rs b/support/texlab/crates/parser/src/config.rs
index f81083f132..95b3e4eb56 100644
--- a/support/texlab/crates/parser/src/config.rs
+++ b/support/texlab/crates/parser/src/config.rs
@@ -8,7 +8,9 @@ pub struct SyntaxConfig {
pub verbatim_environments: FxHashSet<String>,
pub citation_commands: FxHashSet<String>,
pub label_definition_commands: FxHashSet<String>,
+ pub label_definition_prefixes: Vec<(String, String)>,
pub label_reference_commands: FxHashSet<String>,
+ pub label_reference_prefixes: Vec<(String, String)>,
}
impl Default for SyntaxConfig {
@@ -38,11 +40,21 @@ impl Default for SyntaxConfig {
.map(ToString::to_string)
.collect();
+ let label_definition_prefixes = DEFAULT_LABEL_DEFINITION_PREFIXES
+ .iter()
+ .map(|(x, y)| (ToString::to_string(x), ToString::to_string(y)))
+ .collect();
+
let label_reference_commands = DEFAULT_LABEL_REFERENCE_COMMANDS
.iter()
.map(ToString::to_string)
.collect();
+ let label_reference_prefixes = DEFAULT_LABEL_REFERENCE_PREFIXES
+ .iter()
+ .map(|(x, y)| (ToString::to_string(x), ToString::to_string(y)))
+ .collect();
+
Self {
follow_package_links: false,
math_environments,
@@ -50,7 +62,9 @@ impl Default for SyntaxConfig {
verbatim_environments,
citation_commands,
label_definition_commands,
+ label_definition_prefixes,
label_reference_commands,
+ label_reference_prefixes,
}
}
}
@@ -170,7 +184,9 @@ static DEFAULT_CITATION_COMMANDS: &[&str] = &[
"citeA*",
];
-static DEFAULT_LABEL_DEFINITION_COMMANDS: &[&str] = &["label"];
+static DEFAULT_LABEL_DEFINITION_COMMANDS: &[&str] = &["label", "zlabel"];
+
+static DEFAULT_LABEL_DEFINITION_PREFIXES: &[(&str, &str)] = &[];
static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"ref",
@@ -182,6 +198,10 @@ static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"cref*",
"Cref",
"Cref*",
+ "zcref",
+ "zcref*",
+ "zcpageref",
+ "zcpageref*",
"namecref",
"nameCref",
"lcnamecref",
@@ -192,3 +212,5 @@ static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"labelcpageref",
"eqref",
];
+
+static DEFAULT_LABEL_REFERENCE_PREFIXES: &[(&str, &str)] = &[];
diff --git a/support/texlab/crates/parser/src/latexmkrc.rs b/support/texlab/crates/parser/src/latexmkrc.rs
index 6013a5f646..58c348d01f 100644
--- a/support/texlab/crates/parser/src/latexmkrc.rs
+++ b/support/texlab/crates/parser/src/latexmkrc.rs
@@ -28,9 +28,9 @@ mod v483 {
.current_dir(temp_dir.path())
.output()?;
- let stderr = String::from_utf8_lossy(&output.stderr);
+ let stdout = String::from_utf8_lossy(&output.stdout);
- let (aux_dir, out_dir) = stderr.lines().find_map(extract_dirs).ok_or_else(|| {
+ let (aux_dir, out_dir) = stdout.lines().find_map(extract_dirs).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Normalized aux and out dir were not found in latexmk output",
@@ -106,7 +106,7 @@ mod v484 {
let mut it = lines
.skip_while(|line| !line.starts_with("Latexmk: Normalized aux dir and out dirs:"))
.nth(1)?
- .split(",");
+ .split(',');
let aux_dir = it.next()?.trim().strip_prefix('\'')?.strip_suffix('\'')?;
@@ -133,7 +133,7 @@ pub fn parse_latexmkrc(input: &str, src_dir: &Path) -> std::io::Result<Latexmkrc
.as_ref()
.and_then(|line| Some((line.find("Version")?, line)))
.and_then(|(i, line)| line[i..].trim_end().strip_prefix("Version "))
- .and_then(|text| versions::Versioning::new(text));
+ .and_then(versions::Versioning::new);
let result = if version.map_or(false, |v| v >= versions::Versioning::new("4.84").unwrap()) {
v484::parse_latexmkrc(input, src_dir)
diff --git a/support/texlab/crates/references/src/command.rs b/support/texlab/crates/references/src/command.rs
index 712da20b73..f4504641f2 100644
--- a/support/texlab/crates/references/src/command.rs
+++ b/support/texlab/crates/references/src/command.rs
@@ -32,7 +32,7 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
.collect();
for command in &data.semantics.commands {
- if command.text == &token.text()[1..] {
+ if command.text == token.text()[1..] {
let kind = if defs.contains(command) {
ReferenceKind::Definition
} else {
diff --git a/support/texlab/crates/references/src/entry.rs b/support/texlab/crates/references/src/entry.rs
index c3926058e6..722c96fe4a 100644
--- a/support/texlab/crates/references/src/entry.rs
+++ b/support/texlab/crates/references/src/entry.rs
@@ -30,14 +30,14 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
};
let project = &context.params.feature.project;
- for (document, obj) in queries::objects_with_name::<tex::Citation>(&project, name) {
+ for (document, obj) in queries::objects_with_name::<tex::Citation>(project, name) {
context.results.push(Reference {
location: DocumentLocation::new(document, obj.name.range),
kind: ReferenceKind::Reference,
});
}
- for (document, obj) in queries::objects_with_name::<bib::Entry>(&project, name) {
+ for (document, obj) in queries::objects_with_name::<bib::Entry>(project, name) {
context.results.push(Reference {
location: DocumentLocation::new(document, obj.name.range),
kind: ReferenceKind::Definition,
diff --git a/support/texlab/crates/references/src/label.rs b/support/texlab/crates/references/src/label.rs
index 872ef2dd14..20fc6e0d25 100644
--- a/support/texlab/crates/references/src/label.rs
+++ b/support/texlab/crates/references/src/label.rs
@@ -14,7 +14,7 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
.name_text();
let project = &context.params.feature.project;
- for (document, label) in queries::objects_with_name::<tex::Label>(&project, name) {
+ for (document, label) in queries::objects_with_name::<tex::Label>(project, name) {
let kind = match label.kind {
tex::LabelKind::Definition => ReferenceKind::Definition,
tex::LabelKind::Reference | tex::LabelKind::ReferenceRange => ReferenceKind::Reference,
diff --git a/support/texlab/crates/rename/Cargo.toml b/support/texlab/crates/rename/Cargo.toml
index 1b2b91ee2a..dc7558515a 100644
--- a/support/texlab/crates/rename/Cargo.toml
+++ b/support/texlab/crates/rename/Cargo.toml
@@ -14,6 +14,7 @@ syntax = { path = "../syntax" }
[dev-dependencies]
test-utils = { path = "../test-utils" }
+parser = { path = "../parser" }
[lib]
doctest = false
diff --git a/support/texlab/crates/rename/src/command.rs b/support/texlab/crates/rename/src/command.rs
index edcf7db61e..037e09e4ca 100644
--- a/support/texlab/crates/rename/src/command.rs
+++ b/support/texlab/crates/rename/src/command.rs
@@ -19,7 +19,7 @@ pub(super) fn prepare_rename(params: &RenameParams) -> Option<Span> {
))
}
-pub(super) fn rename<'a>(builder: &mut RenameBuilder) -> Option<()> {
+pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
let name = prepare_rename(&builder.params)?;
for document in &builder.params.feature.project.documents {
@@ -35,7 +35,10 @@ pub(super) fn rename<'a>(builder: &mut RenameBuilder) -> Option<()> {
}
}
- builder.result.changes.insert(*document, edits);
+ builder
+ .result
+ .changes
+ .insert(*document, edits.iter().map(|&x| x.into()).collect());
}
Some(())
diff --git a/support/texlab/crates/rename/src/entry.rs b/support/texlab/crates/rename/src/entry.rs
index c0b508a506..d35d9e9e84 100644
--- a/support/texlab/crates/rename/src/entry.rs
+++ b/support/texlab/crates/rename/src/entry.rs
@@ -30,7 +30,7 @@ pub(super) fn prepare_rename(params: &RenameParams) -> Option<Span> {
}
}
-pub(super) fn rename<'a>(builder: &mut RenameBuilder) -> Option<()> {
+pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
let name = prepare_rename(&builder.params)?;
let project = &builder.params.feature.project;
@@ -42,7 +42,7 @@ pub(super) fn rename<'a>(builder: &mut RenameBuilder) -> Option<()> {
for (document, range) in citations.chain(entries) {
let entry = builder.result.changes.entry(document);
- entry.or_default().push(range);
+ entry.or_default().push(range.into());
}
Some(())
diff --git a/support/texlab/crates/rename/src/label.rs b/support/texlab/crates/rename/src/label.rs
index b21e1b795e..1d82f5e2b4 100644
--- a/support/texlab/crates/rename/src/label.rs
+++ b/support/texlab/crates/rename/src/label.rs
@@ -3,22 +3,65 @@ use base_db::{
util::queries::{self, Object},
};
-use crate::{RenameBuilder, RenameParams};
+use crate::{RenameBuilder, RenameInformation, RenameParams};
+
+struct PrefixInformation<'a> {
+ def_prefixes: &'a Vec<(String, String)>,
+ ref_prefixes: &'a Vec<(String, String)>,
+}
+
+fn label_has_prefix(pref_info: &PrefixInformation, label: &tex::Label) -> Option<String> {
+ match label.kind {
+ tex::LabelKind::Definition => pref_info.def_prefixes.iter(),
+ _ => pref_info.ref_prefixes.iter(),
+ }
+ .find_map(|(k, v)| {
+ if k == &label.cmd.clone().unwrap_or(String::new()) {
+ Some(v)
+ } else {
+ None
+ }
+ })
+ .cloned()
+}
+
+fn find_prefix_in_any(
+ builder: &mut RenameBuilder,
+ pref_info: &PrefixInformation,
+ name: &str,
+) -> Option<String> {
+ let project = &builder.params.feature.project;
+ queries::objects_with_name::<tex::Label>(project, name)
+ .find_map(|(_, label)| label_has_prefix(&pref_info, label))
+}
pub(super) fn prepare_rename(params: &RenameParams) -> Option<Span> {
let data = params.feature.document.data.as_tex()?;
let labels = &data.semantics.labels;
let label = queries::object_at_cursor(labels, params.offset, queries::SearchMode::Name)?;
+
Some(Span::new(label.object.name.text.clone(), label.range))
}
pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
let name = prepare_rename(&builder.params)?;
+ let syn = &builder.params.feature.workspace.config().syntax;
+ let pref_info = PrefixInformation {
+ def_prefixes: &syn.label_definition_prefixes,
+ ref_prefixes: &syn.label_reference_prefixes,
+ };
+ let prefix = find_prefix_in_any(builder, &pref_info, &name.text);
+
let project = &builder.params.feature.project;
for (document, label) in queries::objects_with_name::<tex::Label>(project, &name.text) {
+ let prefix = label_has_prefix(&pref_info, label).map_or(prefix.clone(), |_| None);
+
let entry = builder.result.changes.entry(document);
- entry.or_default().push(label.name_range());
+ entry.or_default().push(RenameInformation {
+ range: label.name_range(),
+ prefix: prefix.clone(),
+ });
}
Some(())
diff --git a/support/texlab/crates/rename/src/lib.rs b/support/texlab/crates/rename/src/lib.rs
index b7dd197ce0..e6c05ad268 100644
--- a/support/texlab/crates/rename/src/lib.rs
+++ b/support/texlab/crates/rename/src/lib.rs
@@ -13,8 +13,14 @@ pub struct RenameParams<'a> {
}
#[derive(Debug, Default)]
+pub struct RenameInformation {
+ pub range: TextRange,
+ pub prefix: Option<String>,
+}
+
+#[derive(Debug, Default)]
pub struct RenameResult<'a> {
- pub changes: FxHashMap<&'a Document, Vec<TextRange>>,
+ pub changes: FxHashMap<&'a Document, Vec<RenameInformation>>,
}
struct RenameBuilder<'a> {
@@ -22,14 +28,28 @@ struct RenameBuilder<'a> {
result: RenameResult<'a>,
}
+impl From<TextRange> for RenameInformation {
+ fn from(range: TextRange) -> Self {
+ RenameInformation {
+ range,
+ prefix: None,
+ }
+ }
+}
+impl PartialEq for RenameInformation {
+ fn eq(&self, other: &Self) -> bool {
+ self.range == other.range
+ }
+}
+
pub fn prepare_rename(params: &RenameParams) -> Option<TextRange> {
- command::prepare_rename(&params)
- .or_else(|| entry::prepare_rename(&params))
- .or_else(|| label::prepare_rename(&params))
+ command::prepare_rename(params)
+ .or_else(|| entry::prepare_rename(params))
+ .or_else(|| label::prepare_rename(params))
.map(|span| span.range)
}
-pub fn rename<'a>(params: RenameParams<'a>) -> RenameResult<'a> {
+pub fn rename(params: RenameParams) -> RenameResult {
let result = RenameResult::default();
let mut builder = RenameBuilder { params, result };
diff --git a/support/texlab/crates/rename/src/tests.rs b/support/texlab/crates/rename/src/tests.rs
index 0f4263033e..4da866fb08 100644
--- a/support/texlab/crates/rename/src/tests.rs
+++ b/support/texlab/crates/rename/src/tests.rs
@@ -1,23 +1,37 @@
use rustc_hash::FxHashMap;
-use crate::RenameParams;
+use base_db::Config;
+use parser::SyntaxConfig;
-fn check(input: &str) {
- let fixture = test_utils::fixture::Fixture::parse(input);
+use crate::{RenameInformation, RenameParams};
+
+fn check_with_syntax_config(config: SyntaxConfig, input: &str) {
+ let mut fixture = test_utils::fixture::Fixture::parse(input);
+ fixture.workspace.set_config(Config {
+ syntax: config,
+ ..Config::default()
+ });
+ let fixture = fixture;
- let mut expected = FxHashMap::default();
+ let mut expected: FxHashMap<_, Vec<RenameInformation>> = FxHashMap::default();
for spec in &fixture.documents {
if !spec.ranges.is_empty() {
let document = fixture.workspace.lookup(&spec.uri).unwrap();
- expected.insert(document, spec.ranges.clone());
+ expected.insert(
+ document,
+ spec.ranges.iter().map(|r| r.clone().into()).collect(),
+ );
}
}
-
let (feature, offset) = fixture.make_params().unwrap();
let actual = crate::rename(RenameParams { feature, offset });
assert_eq!(actual.changes, expected);
}
+fn check(input: &str) {
+ check_with_syntax_config(SyntaxConfig::default(), input)
+}
+
#[test]
fn test_command() {
check(
@@ -78,12 +92,97 @@ fn test_label() {
|
^^^
+%! baz.tex
+\ref{foo}
+
%! bar.tex
\ref{foo}
^^^
+"#,
+ )
+}
+
+#[test]
+fn test_custom_label_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ check_with_syntax_config(
+ config,
+ r#"
+%! foo.tex
+\goal{foo}
+
+\asm{foo}\include{bar}\include{baz}
+ |
+ ^^^
+
+%! bar.tex
+\asmref{foo}
+ ^^^
+
+%! baz.tex
+\ref{foo}
+
+\ref{asm:foo}
+ ^^^^^^^
+
+"#,
+ )
+}
+
+#[test]
+fn test_custom_label_def() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ check_with_syntax_config(
+ config,
+ r#"
+%! foo.tex
+\goal{foo}
+
+\label{asm:foo}\include{bar}\include{baz}
+ |
+ ^^^^^^^
+
+%! bar.tex
+\asmref{foo}
+ ^^^
%! baz.tex
\ref{foo}
+
+\ref{asm:foo}
+ ^^^^^^^
"#,
)
}
diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml
index 4c142a2229..fa419413f5 100644
--- a/support/texlab/crates/texlab/Cargo.toml
+++ b/support/texlab/crates/texlab/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "texlab"
description = "LaTeX Language Server"
-version = "5.16.0"
+version = "5.17.0"
license.workspace = true
readme = "README.md"
authors.workspace = true
@@ -22,7 +22,7 @@ test = false
doctest = false
[dependencies]
-anyhow = "1.0.82"
+anyhow = "1.0.86"
base-db = { path = "../base-db" }
bibfmt = { path = "../bibfmt" }
citeproc = { path = "../citeproc" }
@@ -47,17 +47,17 @@ lsp-server = "0.7.6"
lsp-types = "0.95.1"
notify = "6.1.1"
notify-debouncer-full = "0.3.1"
-parking_lot = "0.12.1"
+parking_lot = "0.12.3"
parser = { path = "../parser" }
references = { path = "../references" }
regex = "1.10.4"
rename = { path = "../rename" }
rowan = "0.15.15"
rustc-hash = "1.1.0"
-serde = "1.0.195"
-serde_json = "1.0.115"
+serde = "1.0.202"
+serde_json = "1.0.117"
serde_regex = "1.1.0"
-serde_repr = "0.1.18"
+serde_repr = "0.1.19"
symbols = { path = "../symbols" }
syntax = { path = "../syntax" }
tempfile = "3.10.1"
diff --git a/support/texlab/crates/texlab/src/features/folding.rs b/support/texlab/crates/texlab/src/features/folding.rs
index b19fa8a4da..3669021201 100644
--- a/support/texlab/crates/texlab/src/features/folding.rs
+++ b/support/texlab/crates/texlab/src/features/folding.rs
@@ -9,7 +9,7 @@ pub fn find_all(
) -> Option<Vec<serde_json::Value>> {
let params = from_proto::feature_params(workspace, params.text_document)?;
- let foldings = folding::find_all(&params.document)
+ let foldings = folding::find_all(params.document)
.into_iter()
.filter_map(|folding| {
to_proto::folding_range(folding, &params.document.line_index, client_flags)
diff --git a/support/texlab/crates/texlab/src/features/rename.rs b/support/texlab/crates/texlab/src/features/rename.rs
index b905a7105b..a65f42143b 100644
--- a/support/texlab/crates/texlab/src/features/rename.rs
+++ b/support/texlab/crates/texlab/src/features/rename.rs
@@ -18,5 +18,5 @@ pub fn rename_all(
let new_name = &params.new_name;
let params = from_proto::rename_params(workspace, params.text_document_position)?;
let result = rename::rename(params);
- Some(to_proto::workspace_edit(result, &new_name))
+ Some(to_proto::workspace_edit(result, new_name))
}
diff --git a/support/texlab/crates/texlab/src/main.rs b/support/texlab/crates/texlab/src/main.rs
index ceca02b7f7..d9bf6833d8 100644
--- a/support/texlab/crates/texlab/src/main.rs
+++ b/support/texlab/crates/texlab/src/main.rs
@@ -110,6 +110,7 @@ fn setup_logger(opts: &Opts) {
OpenOptions::new()
.write(true)
.create(true)
+ .truncate(true)
.open(log_file)
.expect("failed to open log file"),
),
diff --git a/support/texlab/crates/texlab/src/server.rs b/support/texlab/crates/texlab/src/server.rs
index ef70c42c71..ff3c7904d3 100644
--- a/support/texlab/crates/texlab/src/server.rs
+++ b/support/texlab/crates/texlab/src/server.rs
@@ -46,7 +46,7 @@ use self::{
#[derive(Debug)]
enum InternalMessage {
SetDistro(Distro),
- SetOptions(Options),
+ SetOptions(Box<Options>),
FileEvent(Vec<DebouncedEvent>),
Diagnostics,
ChktexFinished(Url, Vec<diagnostics::Diagnostic>),
@@ -309,7 +309,9 @@ impl Server {
.parse_options(json.pop().expect("invalid configuration request"))
.unwrap();
- sender.send(InternalMessage::SetOptions(options)).unwrap();
+ sender
+ .send(InternalMessage::SetOptions(Box::new(options)))
+ .unwrap();
}
Err(why) => {
log::error!("Retrieving configuration failed: {}", why);
@@ -700,19 +702,19 @@ impl Server {
let status = if pending_builds.lock().remove(&pid) {
if result?.success() {
- BuildStatus::SUCCESS
+ BuildStatus::Success
} else {
- BuildStatus::ERROR
+ BuildStatus::Error
}
} else {
- BuildStatus::CANCELLED
+ BuildStatus::Cancelled
};
Ok(status)
})
.unwrap_or_else(|why| {
log::error!("Failed to compile document \"{uri}\": {why}");
- BuildStatus::FAILURE
+ BuildStatus::Failure
});
drop(progress_reporter);
@@ -723,7 +725,7 @@ impl Server {
let _ = client.send_response(lsp_server::Response::new_ok(id, result));
}
- if fwd_search_after && status != BuildStatus::CANCELLED {
+ if fwd_search_after && status != BuildStatus::Cancelled {
let _ = internal.send(InternalMessage::ForwardSearch(uri, params.position));
}
});
@@ -760,7 +762,7 @@ impl Server {
self.pool.execute(move || {
let status = match command.and_then(ForwardSearch::run) {
- Ok(()) => ForwardSearchStatus::SUCCESS,
+ Ok(()) => ForwardSearchStatus::Success,
Err(why) => {
log::error!("Failed to execute forward search: {why}");
ForwardSearchStatus::from(why)
@@ -1071,7 +1073,7 @@ impl Server {
self.workspace.write().set_distro(distro);
}
InternalMessage::SetOptions(options) => {
- self.update_options(options);
+ self.update_options(*options);
}
InternalMessage::FileEvent(events) => {
for event in events {
diff --git a/support/texlab/crates/texlab/src/server/extensions.rs b/support/texlab/crates/texlab/src/server/extensions.rs
index ce876c7892..8fa78ef3d2 100644
--- a/support/texlab/crates/texlab/src/server/extensions.rs
+++ b/support/texlab/crates/texlab/src/server/extensions.rs
@@ -33,10 +33,10 @@ pub struct BuildResult {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
#[repr(i32)]
pub enum BuildStatus {
- SUCCESS = 0,
- ERROR = 1,
- FAILURE = 2,
- CANCELLED = 3,
+ Success = 0,
+ Error = 1,
+ Failure = 2,
+ Cancelled = 3,
}
pub struct ForwardSearchRequest;
@@ -52,21 +52,21 @@ impl lsp_types::request::Request for ForwardSearchRequest {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
#[repr(i32)]
pub enum ForwardSearchStatus {
- SUCCESS = 0,
- ERROR = 1,
- FAILURE = 2,
- UNCONFIGURED = 3,
+ Success = 0,
+ Error = 1,
+ Failure = 2,
+ Unconfigured = 3,
}
impl From<ForwardSearchError> for ForwardSearchStatus {
fn from(why: ForwardSearchError) -> Self {
match why {
- ForwardSearchError::Unconfigured => ForwardSearchStatus::UNCONFIGURED,
- ForwardSearchError::NotLocal(_) => ForwardSearchStatus::FAILURE,
- ForwardSearchError::InvalidPath(_) => ForwardSearchStatus::ERROR,
- ForwardSearchError::TexNotFound(_) => ForwardSearchStatus::FAILURE,
- ForwardSearchError::PdfNotFound(_) => ForwardSearchStatus::ERROR,
- ForwardSearchError::LaunchViewer(_) => ForwardSearchStatus::ERROR,
+ ForwardSearchError::Unconfigured => ForwardSearchStatus::Unconfigured,
+ ForwardSearchError::NotLocal(_) => ForwardSearchStatus::Failure,
+ ForwardSearchError::InvalidPath(_) => ForwardSearchStatus::Error,
+ ForwardSearchError::TexNotFound(_) => ForwardSearchStatus::Failure,
+ ForwardSearchError::PdfNotFound(_) => ForwardSearchStatus::Error,
+ ForwardSearchError::LaunchViewer(_) => ForwardSearchStatus::Error,
}
}
}
diff --git a/support/texlab/crates/texlab/src/server/options.rs b/support/texlab/crates/texlab/src/server/options.rs
index 02200392f6..1640c9cf7a 100644
--- a/support/texlab/crates/texlab/src/server/options.rs
+++ b/support/texlab/crates/texlab/src/server/options.rs
@@ -1,11 +1,11 @@
-use regex::Regex;
use serde::{Deserialize, Serialize};
+use regex::Regex;
+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct Options {
- pub root_directory: Option<String>,
pub aux_directory: Option<String>,
pub bibtex_formatter: BibtexFormatter,
pub latex_formatter: LatexFormatter,
@@ -126,7 +126,9 @@ pub struct ExperimentalOptions {
pub verbatim_environments: Vec<String>,
pub citation_commands: Vec<String>,
pub label_definition_commands: Vec<String>,
+ pub label_definition_prefixes: Vec<(String, String)>,
pub label_reference_commands: Vec<String>,
+ pub label_reference_prefixes: Vec<(String, String)>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
diff --git a/support/texlab/crates/texlab/src/util.rs b/support/texlab/crates/texlab/src/util.rs
index d9ec5a2fb1..c301dc7722 100644
--- a/support/texlab/crates/texlab/src/util.rs
+++ b/support/texlab/crates/texlab/src/util.rs
@@ -22,7 +22,7 @@ pub fn normalize_uri(uri: &mut lsp_types::Url) {
}
fn fix_drive_letter(text: &str) -> Option<String> {
- if !text.is_ascii() || text.len() == 0 {
+ if !text.is_ascii() || text.is_empty() {
return None;
}
diff --git a/support/texlab/crates/texlab/src/util/client_flags.rs b/support/texlab/crates/texlab/src/util/client_flags.rs
index 842dbb1eae..2829041832 100644
--- a/support/texlab/crates/texlab/src/util/client_flags.rs
+++ b/support/texlab/crates/texlab/src/util/client_flags.rs
@@ -20,18 +20,12 @@ pub struct ClientFlags {
/// If not set, then fuzzy citation completion will not work.
pub completion_always_incomplete: bool,
- /// If `true`, the server can include markdown in hover responses.
- pub hover_markdown: bool,
-
/// If `true`, the server can pull the configuration from the client.
pub configuration_pull: bool,
/// If `true`, the client notifies the server when the configuration changes.
pub configuration_push: bool,
- /// If `true`, the client can return `LocationLink` instead of `Location`.
- pub definition_link: bool,
-
/// If `true`, the server can return custom kinds like `section`.
pub folding_custom_kinds: bool,
diff --git a/support/texlab/crates/texlab/src/util/from_proto.rs b/support/texlab/crates/texlab/src/util/from_proto.rs
index db4f3a5b39..b55e3cb0e3 100644
--- a/support/texlab/crates/texlab/src/util/from_proto.rs
+++ b/support/texlab/crates/texlab/src/util/from_proto.rs
@@ -56,15 +56,6 @@ pub fn client_flags(
let completion_always_incomplete = info.map_or(false, |info| info.name == "Visual Studio Code");
- let hover_markdown = capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.hover.as_ref())
- .and_then(|cap| cap.content_format.as_ref())
- .map_or(false, |formats| {
- formats.contains(&lsp_types::MarkupKind::Markdown)
- });
-
let configuration_pull = capabilities
.workspace
.as_ref()
@@ -78,13 +69,6 @@ pub fn client_flags(
.and_then(|cap| cap.dynamic_registration)
.unwrap_or(false);
- let definition_link = capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.definition)
- .and_then(|cap| cap.link_support)
- .unwrap_or(false);
-
let folding_custom_kinds = capabilities
.text_document
.as_ref()
@@ -111,30 +95,25 @@ pub fn client_flags(
completion_snippets,
completion_kinds,
completion_always_incomplete,
- hover_markdown,
configuration_pull,
configuration_push,
- definition_link,
folding_custom_kinds,
progress,
show_document,
}
}
-pub fn rename_params<'a>(
- workspace: &'a Workspace,
+pub fn rename_params(
+ workspace: &Workspace,
params: lsp_types::TextDocumentPositionParams,
-) -> Option<RenameParams<'a>> {
+) -> Option<RenameParams> {
let (feature, offset) =
feature_params_offset(workspace, params.text_document, params.position)?;
Some(RenameParams { feature, offset })
}
-pub fn hover_params<'a>(
- workspace: &'a Workspace,
- params: lsp_types::HoverParams,
-) -> Option<HoverParams<'a>> {
+pub fn hover_params(workspace: &Workspace, params: lsp_types::HoverParams) -> Option<HoverParams> {
let (feature, offset) = feature_params_offset(
workspace,
params.text_document_position_params.text_document,
@@ -144,8 +123,8 @@ pub fn hover_params<'a>(
Some(HoverParams { feature, offset })
}
-pub fn inlay_hint_params<'a>(
- workspace: &'a Workspace,
+pub fn inlay_hint_params(
+ workspace: &Workspace,
params: lsp_types::InlayHintParams,
) -> Option<InlayHintParams> {
let feature = feature_params(workspace, params.text_document)?;
@@ -153,10 +132,10 @@ pub fn inlay_hint_params<'a>(
Some(InlayHintParams { feature, range })
}
-pub fn highlight_params<'a>(
- workspace: &'a Workspace,
+pub fn highlight_params(
+ workspace: &Workspace,
params: lsp_types::DocumentHighlightParams,
-) -> Option<HighlightParams<'a>> {
+) -> Option<HighlightParams<'_>> {
let (feature, offset) = feature_params_offset(
workspace,
params.text_document_position_params.text_document,
@@ -166,10 +145,10 @@ pub fn highlight_params<'a>(
Some(HighlightParams { feature, offset })
}
-pub fn definition_params<'a>(
- workspace: &'a Workspace,
+pub fn definition_params(
+ workspace: &Workspace,
params: lsp_types::GotoDefinitionParams,
-) -> Option<DefinitionParams<'a>> {
+) -> Option<DefinitionParams> {
let (feature, offset) = feature_params_offset(
workspace,
params.text_document_position_params.text_document,
@@ -179,10 +158,10 @@ pub fn definition_params<'a>(
Some(DefinitionParams { feature, offset })
}
-pub fn completion_params<'a>(
- workspace: &'a Workspace,
+pub fn completion_params(
+ workspace: &Workspace,
params: lsp_types::CompletionParams,
-) -> Option<CompletionParams<'a>> {
+) -> Option<CompletionParams> {
let (feature, offset) = feature_params_offset(
workspace,
params.text_document_position.text_document,
@@ -192,10 +171,10 @@ pub fn completion_params<'a>(
Some(CompletionParams { feature, offset })
}
-pub fn reference_params<'a>(
- workspace: &'a Workspace,
+pub fn reference_params(
+ workspace: &Workspace,
params: lsp_types::ReferenceParams,
-) -> Option<ReferenceParams<'a>> {
+) -> Option<ReferenceParams> {
let (feature, offset) = feature_params_offset(
workspace,
params.text_document_position.text_document,
@@ -210,19 +189,19 @@ pub fn reference_params<'a>(
})
}
-pub fn feature_params<'a>(
- workspace: &'a Workspace,
+pub fn feature_params(
+ workspace: &Workspace,
text_document: lsp_types::TextDocumentIdentifier,
-) -> Option<FeatureParams<'a>> {
+) -> Option<FeatureParams> {
let document = workspace.lookup(&text_document.uri)?;
Some(FeatureParams::new(workspace, document))
}
-pub fn feature_params_offset<'a>(
- workspace: &'a Workspace,
+pub fn feature_params_offset(
+ workspace: &Workspace,
text_document: lsp_types::TextDocumentIdentifier,
position: lsp_types::Position,
-) -> Option<(FeatureParams<'a>, TextSize)> {
+) -> Option<(FeatureParams, TextSize)> {
let feature = feature_params(workspace, text_document)?;
let offset = feature.document.line_index.offset_lsp(position)?;
Some((feature, offset))
@@ -236,7 +215,6 @@ pub fn completion_resolve_info(item: &mut lsp_types::CompletionItem) -> Option<R
pub fn config(value: Options) -> Config {
let mut config = Config::default();
- config.root_dir = value.root_directory;
config.build.program = value.build.executable.unwrap_or(config.build.program);
config.build.args = value.build.args.unwrap_or(config.build.args);
@@ -362,8 +340,18 @@ pub fn config(value: Options) -> Config {
config
.syntax
+ .label_definition_prefixes
+ .extend(value.experimental.label_definition_prefixes);
+
+ config
+ .syntax
.label_reference_commands
.extend(value.experimental.label_reference_commands);
config
+ .syntax
+ .label_reference_prefixes
+ .extend(value.experimental.label_reference_prefixes);
+
+ config
}
diff --git a/support/texlab/crates/texlab/src/util/to_proto.rs b/support/texlab/crates/texlab/src/util/to_proto.rs
index f5cf2edf8b..d2c261c8fb 100644
--- a/support/texlab/crates/texlab/src/util/to_proto.rs
+++ b/support/texlab/crates/texlab/src/util/to_proto.rs
@@ -396,8 +396,15 @@ pub fn workspace_edit(result: RenameResult, new_name: &str) -> lsp_types::Worksp
let mut edits = Vec::new();
ranges
.into_iter()
- .filter_map(|range| document.line_index.line_col_lsp_range(range))
- .for_each(|range| edits.push(lsp_types::TextEdit::new(range, new_name.into())));
+ .filter_map(|info| {
+ document.line_index.line_col_lsp_range(info.range).map(|i| {
+ (
+ i,
+ info.prefix.map_or(new_name.into(), |p| p + new_name.into()),
+ )
+ })
+ })
+ .for_each(|(range, new_name)| edits.push(lsp_types::TextEdit::new(range, new_name)));
changes.insert(document.uri.clone(), edits);
}
diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1
index 2d4e412dc9..d829a081f9 100644
--- a/support/texlab/texlab.1
+++ b/support/texlab/texlab.1
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
-.TH TEXLAB "1" "May 2024" "texlab 5.16.0" "User Commands"
+.TH TEXLAB "1" "June 2024" "texlab 5.17.0" "User Commands"
.SH NAME
-texlab \- manual page for texlab 5.16.0
+texlab \- manual page for texlab 5.17.0
.SH SYNOPSIS
.B texlab
[\fI\,OPTIONS\/\fR] [\fI\,COMMAND\/\fR]
diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf
index fe59b1f434..828032ce0c 100644
--- a/support/texlab/texlab.pdf
+++ b/support/texlab/texlab.pdf
Binary files differ
diff --git a/support/texlogfilter/README b/support/texlogfilter/README
index d621a2aeb4..e2f626bed7 100644
--- a/support/texlogfilter/README
+++ b/support/texlogfilter/README
@@ -66,10 +66,13 @@ texlogfilter
of all distributions of LaTeX version 2005/12/01 or later.
VERSION
- 1.1
+ 1.3.1
HISTORY
- * 2024, February, version 1.3: better detect the current file name.
+ * 2024, June, versions 1.4: add warning patterns.
+
+ * 2024, February, versions 1.3 and 1.3.1: better detect the current
+ file name.
* 2024, February, version 1.2: fix duplicate or missing lines; handle
package and class names with hyphen; add info and warning patterns
diff --git a/support/texlogfilter/texlogfilter b/support/texlogfilter/texlogfilter
index 341318e576..d5086b75e8 100755
--- a/support/texlogfilter/texlogfilter
+++ b/support/texlogfilter/texlogfilter
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
################################################################################
# texlogfilter - filter latex engines output or log file
-# Julien Labbé, 2021
+# Julien Labbé, 2021-2024
#
# This work may be distributed and/or modified under the conditions of the LaTeX
# Project Public License, either version 1.3 of this license or (at your option)
@@ -16,7 +16,7 @@ use Getopt::Long;
use Term::ANSIColor;
my $name = "texlogfilter";
-my $version = "1.3";
+my $version = "1.4";
# options
my @userfilters;
@@ -188,7 +188,7 @@ while (<>) {
# assume currentfile is given in the last open parenthesis
# (works badly for packages)
if (/^[^(]*\)/) {$currentfile = ""; $lastfile = "";}
- if (/\(([^)]+($extpattern))$/) {$currentfile = $1;}
+ if (/\(([^)]+($extpattern))[^)]*$/) {$currentfile = $1;}
# try to show usefull lines following some warnings or errors (starting with
# whitespaces or package name)
@@ -209,12 +209,13 @@ while (<>) {
elsif (/^(!|.*?:\d+:)/i) { handle_error(); }
elsif (/^No pages of output/i) { handle_error(); }
- # find warning
+ # find warnings
elsif (/^(!\s+)?(Class|Package)\s+(\S+)?\s*Warning/i) { if ($3){$currentpackage=$3}; handle_warning(0, "nofilename"); }
elsif (/^(!\s+)?(LaTeX|\* LaTeX) Warning: (Citation|Reference)/i) { if ($showrefmsg) {handle_warning();} }
elsif (/^(!\s+)?(LaTeX|\* LaTeX) Font Warning/i) { $currentpackage="Font"; handle_warning(); }
elsif (/^(!\s+)?(LaTeX|\* LaTeX) Warning/i) { handle_warning(); }
- elsif (/Runaway argument\?/i) { handle_warning(1); }
+ elsif (/Runaway (definition|argument|preamble|text)\?/i) { handle_warning(1); }
+ elsif (/Missing character: There is no /i) { handle_warning(); }
elsif (/(overfull|underfull|badbox)/i) { if ($showboxmsg){handle_warning(1);} }
# find infos
@@ -336,13 +337,15 @@ distributions of LaTeX version 2005/12/01 or later.
=head2 VERSION
-1.1
+1.3.1
=head2 HISTORY
=over
-=item * 2024, February, version 1.3: better detect the current file name.
+=item * 2024, June, versions 1.4: add warning patterns.
+
+=item * 2024, February, versions 1.3 and 1.3.1: better detect the current file name.
=item * 2024, February, version 1.2: fix duplicate or missing lines; handle
package and class names with hyphen; add info and warning patterns for fonts.
diff --git a/support/texlogfilter/texlogfilter.html b/support/texlogfilter/texlogfilter.html
index 350951829e..1df9cdb065 100644
--- a/support/texlogfilter/texlogfilter.html
+++ b/support/texlogfilter/texlogfilter.html
@@ -88,13 +88,16 @@
<h2 id="VERSION">VERSION</h2>
-<p>1.1</p>
+<p>1.3.1</p>
<h2 id="HISTORY">HISTORY</h2>
<ul>
-<li><p>2024, February, version 1.3: better detect the current file name.</p>
+<li><p>2024, June, versions 1.4: add warning patterns.</p>
+
+</li>
+<li><p>2024, February, versions 1.3 and 1.3.1: better detect the current file name.</p>
</li>
<li><p>2024, February, version 1.2: fix duplicate or missing lines; handle package and class names with hyphen; add info and warning patterns for fonts.</p>
diff --git a/support/texshop/README.txt b/support/texshop/README.txt
index 6f4fffab08..f8c0d70436 100644
--- a/support/texshop/README.txt
+++ b/support/texshop/README.txt
@@ -7,4 +7,4 @@ The main author is Richard Koch, koch@uoregon.edu, with supporting contributions
Consult the program web site, https://pages.uoregon.edu/koch/texshop/texshop.html,
for full source code, an extensive Changes document, and other information.
-The current version, 5.33, was released on April 24, 2024. \ No newline at end of file
+The current version, 5.36, was released on May 26, 2024. \ No newline at end of file
diff --git a/support/texshop/texshop533.html b/support/texshop/texshop533.html
deleted file mode 100644
index 84a8babdd5..0000000000
--- a/support/texshop/texshop533.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title>TeXShop</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <style type="text/css" media="screen">@import "v1.css";</style>
-</head>
-
-<body>
-
-There are three changes in version 5.33:
-<ul>
-<p><li> When a new source file is first typeset, the output will appear in the Preview window scrolled to the top of the first page. Previously, it might be scrolled partly down this page.
-<p><li> When a preview window is closed and later the document is typeset, the preview window will reappear scrolled to the top of the first page. Previously it might be scrolled to a position in the middle of the document.
-<p><li> John Collin's latexmk has been updated to version 4.85.
-</ul>
-<p> TeXShop was only possible because Apple provided developers with pre-built objects for crucial tasks: NSTextView for an editor, and PdfKit for a preview window. When the project started, I anxiously looked through the Pdf API's to see if Apple provided a routine to replace the old pdf file being displayed by a new version of the file; they did.
-<p> Apple cannot anticipate or fully support all possible uses of their objects. When a new pdf is displayed in a window, it is always opened at the top of the file. If the view should be scrolled to a new position, I have to do that myself. But the API's assume that scroll bars are mostly manipulated by users, and provide only a vague "scroll region to visible" command for programmers to scroll the preview window. Moreover, if the programmer tries to scroll the pdf when it is opened, that scroll produces an annoying flash. I wrote Apple complaining about the flash, and they told me that there is nothing they can do to fix it. So I have to fix it at my end.
-<p> When a LaTeX source file is opened, TeXShop reads the file and displays the text in a source window. Then it checks to see if a related pdf file is available. If so, TeXShop opens the pdf in a preview window using a routine I wrote named
-"showWithPath". Later when the user typesets, TeXShop switches from the original pdf to the new pdf using a routine I wrote named "reShowWithPath".
-<p>The "showWithPath" code is straightforward and I have no problems revising it. But "reShowWithPath" is an entirely different matter and I dread having to even look at it. This is the piece of code that determines the scroll location of the old pdf, loads the new pdf, and then scrolls the new pdf to that same location. It also contains code which hides the screen for a fraction of a second so nobody sees the flash and then uncovers the screen before the user notices a pause and complains. All that scrolling is far from trivial because Apple doesn't provide code to do it automatically. If the user has eliminated part of the text before typesetting, the old scroll location may no longer occur
-and the code has to gracefully adjust. Just writing about "reShowWithPath" gives me the shivers, and having to modify it leads to nightmares. I hope I never have to touch it again.
-<p> The bugs fixed in version 5.33 are related to these routines. If you receive the source code of a document from a friend and open it in TeXShop, there is no pdf file to display and so "showWithPath" is never called. When you typeset, TeXShop calls "reShowWithPath", but there is no previous version and thus no previous scroll position. In this special situation,
-the revised "reShowWithPath" just initializes the pdf and displays it without scrolling. That same situation occurs when you begin writing a new document in TeXShop and haven't yet typeset it.
-<p> Each source document in TeXShop corresponds to an NSDocument object in computer memory. This object contains the source text and all the windows which might be needed to process it: source window, log window, console window, preview window, etc. If you close the source window, then all of this data is removed from computer memory. But if you close one of the auxiliary windows, like the preview window, it is removed from the screen, but all the data in NSDocument still exists in memory. If you typeset again, the preview window will reappear in its old position. This is not what users expect, since they believe that closing the window made it go away entirely. The final bug fix maintains that illusion by opening the window at its beginning, as though it were being opened for the first time.
-
-</body>
-</html>
diff --git a/support/texshop/texshop536.html b/support/texshop/texshop536.html
new file mode 100644
index 0000000000..705e6546b3
--- /dev/null
+++ b/support/texshop/texshop536.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>TeXShop</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+
+<body>
+
+
+<!-- main content -->
+<div id="main">
+
+Version 5.36 has one minor bug fix and a major improvement of the PageNumber correction introduced in version 5.35.
+<ul>
+<p><li> In a document with over a thousand pages, the PageNumber box in the toolbar displays the number with a comma, as in 1,325. But users who want to go to a different page must enter the new page number without a comma. This makes it impossible to edit the existing number, say by changing 25 to 17 to go to page 1,317. This is fixed.
+<p><li> Suppose a document has several pages of preliminary material before the main text begins. Perhaps these preliminary pages are numbered i, ii, iii, iv, v, ... and the main pages are numbered 1, 2, 3, 4, 5, ... Then entries in the PageNumber box will not be in sync with the actual page numbers in the text. The previous version of TeXShop introduced a fix for this problem, which required the user to insert a magic comment line and manually indicate the number of preliminary pages. The fix then numbered the preliminary pages 1#, 2#, 3#, ... and the main pages 1, 2, 3, ...
+Moreover, users could enter a number like 17 in the box to go to main page 17, and 2# in the box to go to the second preliminary page.
+
+<p> This fix is still present in TeXShop 5.36, but the method of turning it on has been supplanted by a better method which does not require a magic comment line. The new method adds a macro to the source file which inserts an extra line in the console output and log file
+during typesetting. That line reads "Start of main material: 3." Here 3 is replaced with the page number of the first main page. TeXShop looks for this line during typesetting; if it occurs, the PageNumber is modified as in the old method. A big advantage is that as the preliminary material grows during editing, the fix automatically adjusts without user intervention.
+
+<p> To activate this fix when using LaTeX and related engines, add the line
+<pre>
+ \write128{Start of main material: \the\ReadonlyShipoutCounter.}
+</pre>
+to a spot in the source just after the main material is introduced.
+
+<p> If instead you are using plain TeX or related engines, add the line
+<pre>
+ \write128{Start of main material: \the\pageno.}
+</pre>
+to a spot in the source just after the main material is introduced.
+
+
+<p> TeXShop users need to find a way to remember these additional lines. Some may add items to the Macro
+menu, while others may modify their templates. It is also possible to add appropriate items to the Command Completion dictionary.
+
+<p> After these lines have been added to the source, it is necessary to typeset to see changes in the PageNumber box. A lot of effort has gone into modifying the PageNumber whenever appropriate information is available in the log file. When TeXShop opens a new document, it checks to see if a log file is present, and if so it reads the log file to adjust the PageNumber box. If TeXShop is closed while documents are open, the documents will reappear the next time TeXShop starts with correct PageNumber entries.
+
+<p> Suppose a situation I did not anticipate causes the new code to crash the program when reading an old document, even when the extra lines above have not been added to the source. In that case, write me immediately and I'll fix the problem. But in the meantime, you can fix the crash. Add the magic comment below to the top of the source. This comment completely cancels all of the new code, and the number 0 in the comment tells it to make no changes in the numbering.
+<pre>
+ % !TEX numberingCorrection = 0 + current - desired
+</pre>
+
+<p> Fixing Page Number boxes is a standard feature of pdf display programs like Preview, Skim, and Adobe Acrobat. These programs do not have access to the source file, and often work by parsing the table of contents information in the pdf file. TeXShop is a program for authors rather than a pdf display program, so it is natural for it to find the information to fix the Page Number box in the source file.
+
+<p> Some users may prefer to view pdf files in TeXShop. If these users have access to the Log file associated with the pdf, they can get Number Box correction without using the source file. Just place the Log file in the same location as the pdf file, and TeXShop will automatically open and parse it, and adjust Page Numbers accordingly.
+
+<p> This feature is even available if you do not have access to the Log file. For example, the Driver Manual for my car is a pdf file with two preliminary pages and then the main pages numbered 1, 2, 3, ... Using Apple's Text Edit in plain text mode, I created a small file with the same name as the pdf manual, but extension ".log". The complete contents of this file were
+<pre>
+ Start of main material: 3.
+</pre>
+After this file was placed in the location of the manual, opening the manual in TeXShop provided PageNumber boxes with the correct numbering.
+</ul>
+
+<p>
+<p>
+</div>
+
+
+</body>
+</html> \ No newline at end of file