From d79ba8ae2d18f466586fdaf01f9926502b31e1a3 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 9 Jul 2024 20:17:49 +0000 Subject: typog (9jul24) git-svn-id: svn://tug.org/texlive/trunk@71756 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/typog/LICENSE | 415 +++ Master/texmf-dist/doc/latex/typog/README.md | 4 + Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md | 51 - .../doc/latex/typog/crooked-paragraphs.mp | 10 +- Master/texmf-dist/doc/latex/typog/index.md | 5 - Master/texmf-dist/doc/latex/typog/slant-angle.mp | 10 +- .../texmf-dist/doc/latex/typog/smooth-parshapes.mp | 10 +- .../texmf-dist/doc/latex/typog/teximan2latex.sed | 30 +- Master/texmf-dist/doc/latex/typog/title.mp | 10 +- .../texmf-dist/doc/latex/typog/typog-example.pdf | Bin 392419 -> 402037 bytes .../texmf-dist/doc/latex/typog/typog-example.tex | 250 +- Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf | Bin 511632 -> 514141 bytes Master/texmf-dist/doc/latex/typog/typog-grep.pl.in | 682 +++++ Master/texmf-dist/doc/latex/typog/typog-grep.pod | 284 +- .../doc/latex/typog/typog-grep.version.sed | 3 + .../doc/latex/typog/typog-minimal-test.tex | 50 + Master/texmf-dist/doc/latex/typog/typog-nomt.tex | 73 - .../latex/typog/typog-without-microtype-test.tex | 108 + Master/texmf-dist/doc/latex/typog/typog.gst | 48 + Master/texmf-dist/doc/latex/typog/typog.ist | 17 +- Master/texmf-dist/doc/latex/typog/typog.pdf | Bin 902362 -> 996908 bytes Master/texmf-dist/doc/man/man1/typog-grep.1 | 397 +-- Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf | Bin 38115 -> 44396 bytes Master/texmf-dist/scripts/typog/typog-grep.pl | 166 +- Master/texmf-dist/source/latex/typog/Makefile | 183 +- Master/texmf-dist/source/latex/typog/typog.dtx | 3235 ++++++++++++++++---- Master/texmf-dist/source/latex/typog/typog.ins | 30 +- Master/texmf-dist/tex/latex/typog/typog.sty | 484 ++- 28 files changed, 5232 insertions(+), 1323 deletions(-) create mode 100644 Master/texmf-dist/doc/latex/typog/LICENSE delete mode 100644 Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md delete mode 100644 Master/texmf-dist/doc/latex/typog/index.md create mode 100644 Master/texmf-dist/doc/latex/typog/typog-grep.pl.in create mode 100644 Master/texmf-dist/doc/latex/typog/typog-grep.version.sed create mode 100644 Master/texmf-dist/doc/latex/typog/typog-minimal-test.tex delete mode 100644 Master/texmf-dist/doc/latex/typog/typog-nomt.tex create mode 100644 Master/texmf-dist/doc/latex/typog/typog-without-microtype-test.tex create mode 100644 Master/texmf-dist/doc/latex/typog/typog.gst (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/typog/LICENSE b/Master/texmf-dist/doc/latex/typog/LICENSE new file mode 100644 index 00000000000..888d9e68e7a --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/LICENSE @@ -0,0 +1,415 @@ +The LaTeX Project Public License +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +LPPL Version 1.3c 2008-05-04 + +Copyright 1999 2002-2008 LaTeX3 Project + Everyone is allowed to distribute verbatim copies of this + license document, but modification of it is not allowed. + + +PREAMBLE +======== + +The LaTeX Project Public License (LPPL) is the primary license under +which the LaTeX kernel and the base LaTeX packages are distributed. + +You may use this license for any work of which you hold the copyright +and which you wish to distribute. This license may be particularly +suitable if your work is TeX-related (such as a LaTeX package), but +it is written in such a way that you can use it even if your work is +unrelated to TeX. + +The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', +below, gives instructions, examples, and recommendations for authors +who are considering distributing their works under this license. + +This license gives conditions under which a work may be distributed +and modified, as well as conditions under which modified versions of +that work may be distributed. + +We, the LaTeX3 Project, believe that the conditions below give you +the freedom to make and distribute modified versions of your work +that conform with whatever technical specifications you wish while +maintaining the availability, integrity, and reliability of +that work. If you do not see how to achieve your goal while +meeting these conditions, then read the document `cfgguide.tex' +and `modguide.tex' in the base LaTeX distribution for suggestions. + + +DEFINITIONS +=========== + +In this license document the following terms are used: + + `Work' + Any work being distributed under this License. + + `Derived Work' + Any work that under any applicable law is derived from the Work. + + `Modification' + Any procedure that produces a Derived Work under any applicable + law -- for example, the production of a file containing an + original file associated with the Work or a significant portion of + such a file, either verbatim or with modifications and/or + translated into another language. + + `Modify' + To apply any procedure that produces a Derived Work under any + applicable law. + + `Distribution' + Making copies of the Work available from one person to another, in + whole or in part. Distribution includes (but is not limited to) + making any electronic components of the Work accessible by + file transfer protocols such as FTP or HTTP or by shared file + systems such as Sun's Network File System (NFS). + + `Compiled Work' + A version of the Work that has been processed into a form where it + is directly usable on a computer system. This processing may + include using installation facilities provided by the Work, + transformations of the Work, copying of components of the Work, or + other activities. Note that modification of any installation + facilities provided by the Work constitutes modification of the Work. + + `Current Maintainer' + A person or persons nominated as such within the Work. If there is + no such explicit nomination then it is the `Copyright Holder' under + any applicable law. + + `Base Interpreter' + A program or process that is normally needed for running or + interpreting a part or the whole of the Work. + + A Base Interpreter may depend on external components but these + are not considered part of the Base Interpreter provided that each + external component clearly identifies itself whenever it is used + interactively. Unless explicitly specified when applying the + license to the Work, the only applicable Base Interpreter is a + `LaTeX-Format' or in the case of files belonging to the + `LaTeX-format' a program implementing the `TeX language'. + + + +CONDITIONS ON DISTRIBUTION AND MODIFICATION +=========================================== + +1. Activities other than distribution and/or modification of the Work +are not covered by this license; they are outside its scope. In +particular, the act of running the Work is not restricted and no +requirements are made concerning any offers of support for the Work. + +2. You may distribute a complete, unmodified copy of the Work as you +received it. Distribution of only part of the Work is considered +modification of the Work, and no right to distribute such a Derived +Work may be assumed under the terms of this clause. + +3. You may distribute a Compiled Work that has been generated from a +complete, unmodified copy of the Work as distributed under Clause 2 +above, as long as that Compiled Work is distributed in such a way that +the recipients may install the Compiled Work on their system exactly +as it would have been installed if they generated a Compiled Work +directly from the Work. + +4. If you are the Current Maintainer of the Work, you may, without +restriction, modify the Work, thus creating a Derived Work. You may +also distribute the Derived Work without restriction, including +Compiled Works generated from the Derived Work. Derived Works +distributed in this manner by the Current Maintainer are considered to +be updated versions of the Work. + +5. If you are not the Current Maintainer of the Work, you may modify +your copy of the Work, thus creating a Derived Work based on the Work, +and compile this Derived Work, thus creating a Compiled Work based on +the Derived Work. + +6. If you are not the Current Maintainer of the Work, you may +distribute a Derived Work provided the following conditions are met +for every component of the Work unless that component clearly states +in the copyright notice that it is exempt from that condition. Only +the Current Maintainer is allowed to add such statements of exemption +to a component of the Work. + + a. If a component of this Derived Work can be a direct replacement + for a component of the Work when that component is used with the + Base Interpreter, then, wherever this component of the Work + identifies itself to the user when used interactively with that + Base Interpreter, the replacement component of this Derived Work + clearly and unambiguously identifies itself as a modified version + of this component to the user when used interactively with that + Base Interpreter. + + b. Every component of the Derived Work contains prominent notices + detailing the nature of the changes to that component, or a + prominent reference to another file that is distributed as part + of the Derived Work and that contains a complete and accurate log + of the changes. + + c. No information in the Derived Work implies that any persons, + including (but not limited to) the authors of the original version + of the Work, provide any support, including (but not limited to) + the reporting and handling of errors, to recipients of the + Derived Work unless those persons have stated explicitly that + they do provide such support for the Derived Work. + + d. You distribute at least one of the following with the Derived Work: + + 1. A complete, unmodified copy of the Work; + if your distribution of a modified component is made by + offering access to copy the modified component from a + designated place, then offering equivalent access to copy + the Work from the same or some similar place meets this + condition, even though third parties are not compelled to + copy the Work along with the modified component; + + 2. Information that is sufficient to obtain a complete, + unmodified copy of the Work. + +7. If you are not the Current Maintainer of the Work, you may +distribute a Compiled Work generated from a Derived Work, as long as +the Derived Work is distributed to all recipients of the Compiled +Work, and as long as the conditions of Clause 6, above, are met with +regard to the Derived Work. + +8. The conditions above are not intended to prohibit, and hence do not +apply to, the modification, by any method, of any component so that it +becomes identical to an updated version of that component of the Work as +it is distributed by the Current Maintainer under Clause 4, above. + +9. Distribution of the Work or any Derived Work in an alternative +format, where the Work or that Derived Work (in whole or in part) is +then produced by applying some process to that format, does not relax or +nullify any sections of this license as they pertain to the results of +applying that process. + +10. a. A Derived Work may be distributed under a different license + provided that license itself honors the conditions listed in + Clause 6 above, in regard to the Work, though it does not have + to honor the rest of the conditions in this license. + + b. If a Derived Work is distributed under a different license, that + Derived Work must provide sufficient documentation as part of + itself to allow each recipient of that Derived Work to honor the + restrictions in Clause 6 above, concerning changes from the Work. + +11. This license places no restrictions on works that are unrelated to +the Work, nor does this license place any restrictions on aggregating +such works with the Work by any means. + +12. Nothing in this license is intended to, or may be used to, prevent +complete compliance by all parties with all applicable laws. + + +NO WARRANTY +=========== + +There is no warranty for the Work. Except when otherwise stated in +writing, the Copyright Holder provides the Work `as is', without +warranty of any kind, either expressed or implied, including, but not +limited to, the implied warranties of merchantability and fitness for a +particular purpose. The entire risk as to the quality and performance +of the Work is with you. Should the Work prove defective, you assume +the cost of all necessary servicing, repair, or correction. + +In no event unless required by applicable law or agreed to in writing +will The Copyright Holder, or any author named in the components of the +Work, or any other party who may distribute and/or modify the Work as +permitted above, be liable to you for damages, including any general, +special, incidental or consequential damages arising out of any use of +the Work or out of inability to use the Work (including, but not limited +to, loss of data, data being rendered inaccurate, or losses sustained by +anyone as a result of any failure of the Work to operate with any other +programs), even if the Copyright Holder or said author or said other +party has been advised of the possibility of such damages. + + +MAINTENANCE OF THE WORK +======================= + +The Work has the status `author-maintained' if the Copyright Holder +explicitly and prominently states near the primary copyright notice in +the Work that the Work can only be maintained by the Copyright Holder +or simply that it is `author-maintained'. + +The Work has the status `maintained' if there is a Current Maintainer +who has indicated in the Work that they are willing to receive error +reports for the Work (for example, by supplying a valid e-mail +address). It is not required for the Current Maintainer to acknowledge +or act upon these error reports. + +The Work changes from status `maintained' to `unmaintained' if there +is no Current Maintainer, or the person stated to be Current +Maintainer of the work cannot be reached through the indicated means +of communication for a period of six months, and there are no other +significant signs of active maintenance. + +You can become the Current Maintainer of the Work by agreement with +any existing Current Maintainer to take over this role. + +If the Work is unmaintained, you can become the Current Maintainer of +the Work through the following steps: + + 1. Make a reasonable attempt to trace the Current Maintainer (and + the Copyright Holder, if the two differ) through the means of + an Internet or similar search. + + 2. If this search is successful, then enquire whether the Work + is still maintained. + + a. If it is being maintained, then ask the Current Maintainer + to update their communication data within one month. + + b. If the search is unsuccessful or no action to resume active + maintenance is taken by the Current Maintainer, then announce + within the pertinent community your intention to take over + maintenance. (If the Work is a LaTeX work, this could be + done, for example, by posting to comp.text.tex.) + + 3a. If the Current Maintainer is reachable and agrees to pass + maintenance of the Work to you, then this takes effect + immediately upon announcement. + + b. If the Current Maintainer is not reachable and the Copyright + Holder agrees that maintenance of the Work be passed to you, + then this takes effect immediately upon announcement. + + 4. If you make an `intention announcement' as described in 2b. above + and after three months your intention is challenged neither by + the Current Maintainer nor by the Copyright Holder nor by other + people, then you may arrange for the Work to be changed so as + to name you as the (new) Current Maintainer. + + 5. If the previously unreachable Current Maintainer becomes + reachable once more within three months of a change completed + under the terms of 3b) or 4), then that Current Maintainer must + become or remain the Current Maintainer upon request provided + they then update their communication data within one month. + +A change in the Current Maintainer does not, of itself, alter the fact +that the Work is distributed under the LPPL license. + +If you become the Current Maintainer of the Work, you should +immediately provide, within the Work, a prominent and unambiguous +statement of your status as Current Maintainer. You should also +announce your new status to the same pertinent community as +in 2b) above. + + +WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE +====================================================== + +This section contains important instructions, examples, and +recommendations for authors who are considering distributing their +works under this license. These authors are addressed as `you' in +this section. + +Choosing This License or Another License +---------------------------------------- + +If for any part of your work you want or need to use *distribution* +conditions that differ significantly from those in this license, then +do not refer to this license anywhere in your work but, instead, +distribute your work under a different license. You may use the text +of this license as a model for your own license, but your license +should not refer to the LPPL or otherwise give the impression that +your work is distributed under the LPPL. + +The document `modguide.tex' in the base LaTeX distribution explains +the motivation behind the conditions of this license. It explains, +for example, why distributing LaTeX under the GNU General Public +License (GPL) was considered inappropriate. Even if your work is +unrelated to LaTeX, the discussion in `modguide.tex' may still be +relevant, and authors intending to distribute their works under any +license are encouraged to read it. + +A Recommendation on Modification Without Distribution +----------------------------------------------------- + +It is wise never to modify a component of the Work, even for your own +personal use, without also meeting the above conditions for +distributing the modified component. While you might intend that such +modifications will never be distributed, often this will happen by +accident -- you may forget that you have modified that component; or +it may not occur to you when allowing others to access the modified +version that you are thus distributing it and violating the conditions +of this license in ways that could have legal implications and, worse, +cause problems for the community. It is therefore usually in your +best interest to keep your copy of the Work identical with the public +one. Many works provide ways to control the behavior of that work +without altering any of its licensed components. + +How to Use This License +----------------------- + +To use this license, place in each of the components of your work both +an explicit copyright notice including your name and the year the work +was authored and/or last substantially modified. Include also a +statement that the distribution and/or modification of that +component is constrained by the conditions in this license. + +Here is an example of such a notice and statement: + + %% pig.dtx + %% Copyright 2005 M. Y. Name + % + % This work may be distributed and/or modified under the + % conditions of the LaTeX Project Public License, either version 1.3c + % of this license or (at your option) any later version. + % The latest version of this license is in + % https://www.latex-project.org/lppl.txt + % and version 1.3c or later is part of all distributions of LaTeX + % version 2005/12/01 or later. + % + % This work has the LPPL maintenance status `maintained'. + % + % The Current Maintainer of this work is M. Y. Name. + % + % This work consists of the files pig.dtx and pig.ins + % and the derived file pig.sty. + +Given such a notice and statement in a file, the conditions +given in this license document would apply, with the `Work' referring +to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being +generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' +referring to any `LaTeX-Format', and both `Copyright Holder' and +`Current Maintainer' referring to the person `M. Y. Name'. + +If you do not want the Maintenance section of LPPL to apply to your +Work, change `maintained' above into `author-maintained'. +However, we recommend that you use `maintained', as the Maintenance +section was added in order to ensure that your Work remains useful to +the community even when you can no longer maintain and support it +yourself. + +Derived Works That Are Not Replacements +--------------------------------------- + +Several clauses of the LPPL specify means to provide reliability and +stability for the user community. They therefore concern themselves +with the case that a Derived Work is intended to be used as a +(compatible or incompatible) replacement of the original Work. If +this is not the case (e.g., if a few lines of code are reused for a +completely different task), then clauses 6b and 6d shall not apply. + + +Important Recommendations +------------------------- + + Defining What Constitutes the Work + + The LPPL requires that distributions of the Work contain all the + files of the Work. It is therefore important that you provide a + way for the licensee to determine which files constitute the Work. + This could, for example, be achieved by explicitly listing all the + files of the Work near the copyright notice of each file or by + using a line such as: + + % This work consists of all files listed in manifest.txt. + + in that place. In the absence of an unequivocal list it might be + impossible for the licensee to determine what is considered by you + to comprise the Work and, in such a case, the licensee would be + entitled to make reasonable conjectures as to which files comprise + the Work. diff --git a/Master/texmf-dist/doc/latex/typog/README.md b/Master/texmf-dist/doc/latex/typog/README.md index fb55ccb1e12..c67519bffc6 100644 --- a/Master/texmf-dist/doc/latex/typog/README.md +++ b/Master/texmf-dist/doc/latex/typog/README.md @@ -1,3 +1,6 @@ +![distcheck status](https://github.com/cspiel/typog/actions/workflows/distcheck.yml/badge.svg) + + # TypoG – Typographic Fine-Tuning for LaTeX LaTeX package `typog` provides macros for (micro-)typographic enhancements; @@ -8,6 +11,7 @@ it covers a variety of topics: * Manual italic correction * Extra kerning for slash and hyphen * Raising selected characters (e.g. hyphen, en-dash, and em-dash) +* Adjusting the vertical position of `itemize`'s labels * Aligning of the last line of a paragraph * Filling of the last line last line of a paragraph * Word spacing control diff --git a/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md b/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md deleted file mode 100644 index 13435ef66d5..00000000000 --- a/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md +++ /dev/null @@ -1,51 +0,0 @@ -# How to prepare a new release - -... and not make too many mistakes. - - -1. Check that the work-area is clean with respect to **git**-tracked - files. - - ``` git status ``` - -1. Update the date stamp of `\ProvidesPackage`. - -1. (Temporarily) Zero the `\overfullrule`s of the documentation and - the example files. - -1. Thoroughly clean the work-area: - - ```make maintainer-clean``` - -1. Rebuild: - - ```make``` - -1. Check that all _*.sty_ and _*.pdf_ files are in good shape. - -1. Push the documentation files created in the previous step down into - the *docs* directory: - - ```make update-docs``` - -1. Undo the `\overfullrule` change. - -1. Commit the changes: - - ``` - git add . - ``` - - and finally - - ``` - git commit - ``` - -1. Tag the commit with the version string of `\ProvidesPackage`: - - ```git tag v1.23``` - -1. Push the changes to the public repository: - - ```git push origin master --tags``` diff --git a/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp b/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp index 778a3bc3846..7667b66b1d6 100644 --- a/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp +++ b/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp @@ -11,11 +11,11 @@ %% Copyright (C) 2024 by Ch. L. Spiel %% %% This work may be distributed and/or modified under the conditions -%% of the LaTeX Project Public License, either version 1.3 of this +%% of the LaTeX Project Public License, either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX %% version 2003/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. @@ -25,7 +25,9 @@ %% This work consists of the files typog.dtx and typog.ins %% and the derived files typog.sty, slant-angle.mp, %% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, -%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-example.tex, typog-minimal-test.tex, +%% typog-without-microtype-test.tex +%% typog-grep.pl.in, typog-grep.pl, %% typog-grep.pod, and teximan2latex.sed. %% %% diff --git a/Master/texmf-dist/doc/latex/typog/index.md b/Master/texmf-dist/doc/latex/typog/index.md deleted file mode 100644 index f4dc2e8bd9a..00000000000 --- a/Master/texmf-dist/doc/latex/typog/index.md +++ /dev/null @@ -1,5 +0,0 @@ -### Package Documentation - -- Comprehensive `typog` documentation: [typog.pdf](https://cspiel.github.io/typog/typog.pdf) -- `typog` examples and tests: [typog-example.pdf](https://cspiel.github.io/typog/typog-example.pdf) -- **typog-grep** manual page: [typog-grep.1](https://cspiel.github.io/typog/typog-grep.1) and as PDF: [typog-grep.1.pdf](https://cspiel.github.io/typog/typog-grep.1.pdf) diff --git a/Master/texmf-dist/doc/latex/typog/slant-angle.mp b/Master/texmf-dist/doc/latex/typog/slant-angle.mp index f25f790ea6f..61f2d248e22 100644 --- a/Master/texmf-dist/doc/latex/typog/slant-angle.mp +++ b/Master/texmf-dist/doc/latex/typog/slant-angle.mp @@ -11,11 +11,11 @@ %% Copyright (C) 2024 by Ch. L. Spiel %% %% This work may be distributed and/or modified under the conditions -%% of the LaTeX Project Public License, either version 1.3 of this +%% of the LaTeX Project Public License, either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX %% version 2003/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. @@ -25,7 +25,9 @@ %% This work consists of the files typog.dtx and typog.ins %% and the derived files typog.sty, slant-angle.mp, %% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, -%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-example.tex, typog-minimal-test.tex, +%% typog-without-microtype-test.tex +%% typog-grep.pl.in, typog-grep.pl, %% typog-grep.pod, and teximan2latex.sed. %% %% diff --git a/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp b/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp index ce47135a56e..dcf66fd0527 100644 --- a/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp +++ b/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp @@ -11,11 +11,11 @@ %% Copyright (C) 2024 by Ch. L. Spiel %% %% This work may be distributed and/or modified under the conditions -%% of the LaTeX Project Public License, either version 1.3 of this +%% of the LaTeX Project Public License, either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX %% version 2003/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. @@ -25,7 +25,9 @@ %% This work consists of the files typog.dtx and typog.ins %% and the derived files typog.sty, slant-angle.mp, %% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, -%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-example.tex, typog-minimal-test.tex, +%% typog-without-microtype-test.tex +%% typog-grep.pl.in, typog-grep.pl, %% typog-grep.pod, and teximan2latex.sed. %% %% diff --git a/Master/texmf-dist/doc/latex/typog/teximan2latex.sed b/Master/texmf-dist/doc/latex/typog/teximan2latex.sed index b329ac3845f..ff0a7e65328 100644 --- a/Master/texmf-dist/doc/latex/typog/teximan2latex.sed +++ b/Master/texmf-dist/doc/latex/typog/teximan2latex.sed @@ -10,35 +10,49 @@ /@menu/,/@end menu/d ## Convert sectioning macros to our own hierarchy. -s/^@chapter \(.*\)$/\\subsection*{\\textls[40]{\1}}/ -s/^@section \(.*\)$/\\subsubsection*{\1}/ +s/^@chapter \(.*\)$/\\subsection{\\titlecase{\1}\\label{\1}}/ +s/^@section \(.*\)$/\\subsubsection{\\titlecase{\1}}\\label{\1}/ ## Make `@asis' list resemble the Texinfo format. s/@table @asis/\\begin{list}{}{\\itemindent=-20pt\\leftmargin=20pt}/ s/@end table/\\end{list}/ +## We substitute our maxipage environment for @display. +s/@display/\\begin{maxipage}/ +s/@end display/\\end{maxipage}/ + +## Translate `@example' environments. +s/@example/\\begin{quote}\\tt\\obeylines/ +s/@end example/\\end{quote}\n\n/ + ## Indenting by four spaces generates a `verbatim' environment. s/@verbatim/\\begin{verbatim}/ s/@end verbatim/\\end{verbatim}/ -## We substitute @display for our maxipage environment. -s/@display/\\begin{maxipage}/ -s/@end display/\\end{maxipage}/ - ## The argument format of the URL macro is different. s/@url{\([^,]*\), \([^}]*\)}/\\href{\1}{\2}/g ## Use our own markup. s/\.\.\./\\dots{}/g s/LaTeX/\\LaTeX{}/g -s/@file/\\textit/g +s/@file/\\emph/g s/@strong/\\textbf/g +s/@var/\\emph/g s/[w]{/mbox{/g +## Translate some Texinfo macros. +s/@backslashchar/\\char`\\\\/g +s/@lbracechar/\\{/g +s/@noindent/\\noindent/g +s/@rbracechar/\\}/g + ## Quote some special characters. s/%/\\%/g s/_/\\_/g +## Add space around alternative-indicators. +s/[|]/\\,|\\,/g + ## Adapt to how a man-page is typeset. ## En-dashes in front of long options really suck! s/--/-\\nolig*-/g @@ -52,4 +66,4 @@ s/@@/@/g s/\\jobname/\\textbackslash jobname/g ## Make qualified Perl names breakable. -s/::/::\\discretionary{}{}{}/g +s/::/::\\breakpoint*/g diff --git a/Master/texmf-dist/doc/latex/typog/title.mp b/Master/texmf-dist/doc/latex/typog/title.mp index 2fd74e91f9d..21e47883ee5 100644 --- a/Master/texmf-dist/doc/latex/typog/title.mp +++ b/Master/texmf-dist/doc/latex/typog/title.mp @@ -11,11 +11,11 @@ %% Copyright (C) 2024 by Ch. L. Spiel %% %% This work may be distributed and/or modified under the conditions -%% of the LaTeX Project Public License, either version 1.3 of this +%% of the LaTeX Project Public License, either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX %% version 2003/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. @@ -25,7 +25,9 @@ %% This work consists of the files typog.dtx and typog.ins %% and the derived files typog.sty, slant-angle.mp, %% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, -%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-example.tex, typog-minimal-test.tex, +%% typog-without-microtype-test.tex +%% typog-grep.pl.in, typog-grep.pl, %% typog-grep.pod, and teximan2latex.sed. %% %% diff --git a/Master/texmf-dist/doc/latex/typog/typog-example.pdf b/Master/texmf-dist/doc/latex/typog/typog-example.pdf index 621ac319d20..48a8a506e14 100644 Binary files a/Master/texmf-dist/doc/latex/typog/typog-example.pdf and b/Master/texmf-dist/doc/latex/typog/typog-example.pdf differ diff --git a/Master/texmf-dist/doc/latex/typog/typog-example.tex b/Master/texmf-dist/doc/latex/typog/typog-example.tex index af04d490094..470bd830723 100644 --- a/Master/texmf-dist/doc/latex/typog/typog-example.tex +++ b/Master/texmf-dist/doc/latex/typog/typog-example.tex @@ -11,11 +11,11 @@ %% Copyright (C) 2024 by Ch. L. Spiel %% %% This work may be distributed and/or modified under the conditions -%% of the LaTeX Project Public License, either version 1.3 of this +%% of the LaTeX Project Public License, either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX %% version 2003/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. @@ -25,7 +25,9 @@ %% This work consists of the files typog.dtx and typog.ins %% and the derived files typog.sty, slant-angle.mp, %% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, -%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-example.tex, typog-minimal-test.tex, +%% typog-without-microtype-test.tex +%% typog-grep.pl.in, typog-grep.pl, %% typog-grep.pod, and teximan2latex.sed. %% %% @@ -42,10 +44,14 @@ \usepackage{fullwidth} \usepackage{hyphenat} \usepackage{mathtools} -\usepackage[activate=true, verbose=true]{microtype} +\usepackage[activate=true, verbose=false]{microtype} \usepackage{ragged2e} \usepackage[nobottomtitles*]{titlesec}\renewcommand*{\bottomtitlespace}{.2\textheight} -\usepackage[debug, trackingttspacing]{typog} +\usepackage{trace} +\usepackage[debug, + trackingttspacing, + uppercaselabelitemadjustments={0pt, .1em, .15em, .1em}, + lowercaselabelitemadjustments={-.0667em, 0pt, .1em, 0pt}]{typog} \usepackage{xcolor} \usepackage[loosest, proportional, scaled=1.064]{erewhon} @@ -55,49 +61,42 @@ \usepackage{setspace}\setstretch{1.08333} \def\xsfdefault{\relax} -{ - \def\examplefont{6} - - \ifcase\examplefont % 0 -- document's default sans-serif font (e.g., ecrm1000) - \gdef\examplefontname{default} - \global\let\xsf=\sf - \global\let\xsfdefault=\sfdefault - \or % 1 -- Nunito - \gdef\examplefontname{Nunito} - \usepackage{nunito} - \xdef\xsfdefault{\rmdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \or % 2 -- OpenSans - \gdef\examplefontname{OpenSans} - \usepackage[defaultsans]{opensans} - \xdef\xsfdefault{\sfdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \or % 3 -- Noto Sans - \gdef\examplefontname{OpenSans} - \usepackage[sfdefault]{noto} - \xdef\xsfdefault{\sfdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \or % 4 -- Roboto - \gdef\examplefontname{Roboto} - \usepackage[sfdefault]{roboto} - \xdef\xsfdefault{\sfdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \or % 5 -- Montserrat - \gdef\examplefontname{Montserrat Alternate} - \usepackage[alternates]{montserrat} - \xdef\xsfdefault{\sfdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \or % 6 -- Inter - \gdef\examplefontname{Inter} - \usepackage[sfdefault]{inter} - \xdef\xsfdefault{\sfdefault} - \gdef\xsf{\let\sfdefault=\xsfdefault\sf} - \else - \SelectedUnknownExampleFont - \fi - \typeout{typog-example: font for examples: `\xsfdefault'}% -} +\def\examplefont{6} + +\ifcase\examplefont % 0 -- document's default sans-serif font (e.g., ecrm1000) + \def\examplefontname{default} + \let\xsf=\sf + \let\xsfdefault=\sfdefault +\or % 1 -- Nunito + \def\examplefontname{Nunito} + \def\xsfdefault{Nunito-TOsF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\or % 2 -- OpenSans + \def\examplefontname{OpenSans} + \def\xsfdefault{opensans-TLF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\or % 3 -- Noto Sans + \def\examplefontname{Noto Sans} + \def\xsfdefault{NotoSans-TLF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\or % 4 -- Roboto + \def\examplefontname{Roboto} + \def\xsfdefault{Roboto-LF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\or % 5 -- Montserrat + \def\examplefontname{Montserrat Alternates} + \def\xsfdefault{MontserratAlternates-LF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\or % 6 -- Inter + \def\examplefontname{Inter} + \def\xsfdefault{Inter-LF} + \def\xsf{\let\sfdefault=\xsfdefault\sf} +\else + \SelectedUnknownExampleFont +\fi + +\typeout{typog-example: font for examples: `\xsfdefault'}% \usepackage{hyperref} \usepackage{cleveref} @@ -204,7 +203,6 @@ concentrate all the badness in one place, making one truly unsightly line instead of two moderately bad ones, because a single ``write-off'' produces fewest total demerits according to the rules.} - %There is a much better way to get the desired effect:~[\dots] \newcommand*{\texbooktolerancesamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~107]{knuth:1986}.}} @@ -212,7 +210,7 @@ \newcommand*{\texbookparfillskipsample} {We still haven't discussed the special trick that allows the final line of a paragraph to be shorter than the others. Just before \TeX{} begins to choose breakpoints, - it does two important things: [\dots]} + it does two important things: [\dots\itcorr{-4}]} \newcommand*{\texbooklongparfillskipsample} {We still haven't discussed the special trick that allows the final line of a paragraph to be shorter than the others. Just before \TeX{} begins to choose breakpoints, @@ -220,7 +218,7 @@ that glue is discarded. (The reason is that a blank space often gets into a token list just before \code{\char92par} or just before \code{\char36\char36}, and this blank space should not be part of the paragraph.) (2)~Three or more items are put at the end of the - current horizontal list~[\dots]} + current horizontal list~[\dots\itcorr{-4}]} \newcommand*{\texbookparfillskipsamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~99n]{knuth:1986}.}} @@ -271,7 +269,7 @@ The font used in this example is \exfontnameinfo, \exfontsizeinfo*.} \setcounter{tocdepth}{1} -\setlength{\overfullrule}{3pt} +\setlength{\overfullrule}{0pt} \hbadness=-1 \input{ushyphex} @@ -383,7 +381,74 @@ in the official documentation of package~\packagename{typog}. \noindent Unless otherwise noted the font used in the examples is \singlequotes{\examplefontname}. -\bigskip +\section{Setup and Reconfiguration} + +\noindent +\code{\char`\\ typogget} + +\begin{list}{}{} + \newcommand*{\expandsto}{$\mathbin{\mapsto}$} +\item \code{breakpenalty} \expandsto{} \the\typogget{breakpenalty} +\item \code{ligaturekern} \expandsto{} \milliem{\typogget{ligaturekern}} +\item \code{lowercaselabelitemadjustments} \expandsto{} \typogget{lowercaselabelitemadjustments} +\item \code{mathitalicscorrection} \expandsto{} \the\typogget{mathitalicscorrection} +\item \code{raisecapitaldash} \expandsto{} \the\typogget{raisecapitaldash} +\item \code{raisecapitalguillemets} \expandsto{} \the\typogget{raisecapitalguillemets} +\item \code{raisecapitalhyphen} \expandsto{} \the\typogget{raisecapitalhyphen} +\item \code{raisecapitaltimes} \expandsto{} \the\typogget{raisecapitaltimes} +\item \code{raisefiguredash} \expandsto{} \the\typogget{raisefiguredash} +\item \code{raiseguillemets} \expandsto{} \the\typogget{raiseguillemets} +\item \code{shrinklimits} \expandsto{} \typogget{shrinklimits} +\item \code{slashkern} \expandsto{} \the\typogget{slashkern} +\item \code{stretchlimits} \expandsto{} \typogget{stretchlimits} +\item \code{textitalicscorrection} \expandsto{} \the\typogget{textitalicscorrection} +\item \code{trackingttspacing} \expandsto{} \typogget{trackingttspacing} +\item \code{uppercaselabelitemadjustments} \expandsto{} \typogget{uppercaselabelitemadjustments} +\end{list} + +\begingroup + \dimen0=\typogget{raisecapitaldash}% + \setbox0=\hbox to \typogget{ligaturekern} {}% +\endgroup + +\noindent +\code{\char`\\ typoggetnth} + +\begin{list}{}{} +\item + Elements of \code{lowercaselabelitemadjustments}: + (1)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{1}\the\dimen0, + (2)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{2}\the\dimen0, + (3)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{3}\the\dimen0, and + (4)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{4}\the\dimen0. + + Same elements now accessed from the right-hand-side, i.\,e.~with negative indices: + (\textminus4)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-4}\nth, + (\textminus3)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-3}\nth, + (\textminus2)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-2}\nth, and + (\textminus1)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-1}\nth. + +\item Elements of \code{shrinklimits}: + (1)~\typoggetnth{nth}{shrinklimits}{1}\nth, + (2)~\typoggetnth{nth}{shrinklimits}{2}\nth, and + (3)~\typoggetnth{nth}{shrinklimits}{3}\nth. + +\item Elements of \code{stretchlimits}: + (1)~\typoggetnth{nth}{stretchlimits}{1}\nth, + (2)~\typoggetnth{nth}{stretchlimits}{2}\nth, and + (3)~\typoggetnth{nth}{stretchlimits}{3}\nth. + +\item Elements of \code{trackingttspacing}: + (1)~\typoggetnth{nth}{trackingttspacing}{1}\nth, + (2)~\typoggetnth{nth}{trackingttspacing}{2}\nth, and + (3)~\typoggetnth{nth}{trackingttspacing}{3}\nth. + +\item Elements of \code{uppercaselabelitemadjustments}: + (1)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{1}\the\dimen0, + (2)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{2}\the\dimen0, + (3)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{3}\the\dimen0, and + (4)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{4}\the\dimen0. +\end{list} \section{Information} @@ -864,6 +929,81 @@ We again compare the default implementation with the adjusted one. \parbox[t]{0pt}{\FrenchdoublequotesFR{\samplestring}} \end{quote} +\section{Label Items} + +The current configurations for the uppercase and lowercase adjustments are +\{\typogget{uppercaselabelitemadjustments}\} and \{\typogget{lowercaselabelitemadjustments}\}, +respectively. + +\begin{center} + \makeatletter + \noindent + A\raisebox{\typog@adjust@uppercase@labelitemi}{\labelitemi}% + B\raisebox{\typog@adjust@uppercase@labelitemii}{\labelitemii}% + E\raisebox{\typog@adjust@uppercase@labelitemiii}{\labelitemiii}% + G\raisebox{\typog@adjust@uppercase@labelitemiv}{\labelitemiv}H \\ + a\raisebox{\typog@adjust@lowercase@labelitemi}{\labelitemi}% + b\raisebox{\typog@adjust@lowercase@labelitemii}{\labelitemii}% + c\raisebox{\typog@adjust@lowercase@labelitemiii}{\labelitemiii}% + e\raisebox{\typog@adjust@lowercase@labelitemiv}{\labelitemiv}g + \makeatother +\end{center} + +For the following nested lists we adjust levels one and three for uppercase and levels two and +four for lowercase. + +\begingroup + \uppercaseadjustlabelitems{1,3} + \lowercaseadjustlabelitems{2,4} + \setlength{\itemsep}{0pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \begin{itemize} + \item A + \item B + \item C + \begin{itemize} + \item d + \item e + \item f + \begin{itemize} + \item G + \item H + \item I + \begin{itemize} + \item j + \item k + \item l + \end{itemize} + \end{itemize} + \end{itemize} + \end{itemize} +\endgroup +\noadjustlabelitems{*}% not necessary, but we want to exercise the macro + +The left example shows the result of \code{\string\typogadjuststairs\{.25pt\}\{11\}\{ABC\}} and +the one on the right hand side just uses the same parameters except for the sample~\sample{ace}, +this is, only lowercase letters. + +\begin{center} + \begin{minipage}[t]{12em} + \centering + \typogadjuststairs{.25pt}{11}{ABC} + \end{minipage} + \begin{minipage}[t]{12em} + \centering + \typogadjuststairs{.25pt}{11}{ace} + \end{minipage} +\end{center} + +For this document the calls +\code{\string\typoguppercaseadjustcheck\{ABC\-DEF\-GHI\-JKL\-MNO\-PQR\-STU\-VWX\-YZ\}} and +\code{\string\typoglowercaseadjustcheck\{ace\-gmn\-opq\-rsu\-vwx\-yz\}} yield +\sample{\typoguppercaseadjustcheck{ABCDEFGHIJKLMNOPQRSTUVWXYZ}} and +\sample{\typoglowercaseadjustcheck{acegmnopqrsuvwxyz}}, where the adjustments in effect are +\code{\{\typogget{uppercaselabelitemadjustments}\}} and +\code{\{\typogget{lowercaselabelitemadjustments}\}}, respectively. + \clearpage \section{Align Last Line} @@ -1085,7 +1225,7 @@ consult \propername{David Carlisle's} excellent post on \propername{StackExchang \begin{center} \setlength{\overfullrule}{0pt} - \newcommand*{\spacesampletext}[1]{some#1text#1with#1spaces\rule{0.1pt}{1em}} + \newcommand*{\spacesampletext}[1]{some#1text#1with#1spaces\rule{.1pt}{1em}} \newsavebox{\narrowspacesample} \sbox{\narrowspacesample}{\spacesampletext{\narrowspace}} \newsavebox{\widespacesample} @@ -1488,7 +1628,7 @@ New settings: \baselinesetsize. \newcommand*{\relbls}{130} \paragraph{\code{\string\setbaselineskippercentage\{\relbls\}}} -\setbaselineskippercentage{1 + 2 + .3333 * 100 + 100 * 0.6667}% float expression +\setbaselineskippercentage{1 + 2 + .3333 * 100 + 100 * .6667}% float expression \setbaselineskippercentage{\relbls} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. diff --git a/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf b/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf index 09647860d5d..9a430085081 100644 Binary files a/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf and b/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf differ diff --git a/Master/texmf-dist/doc/latex/typog/typog-grep.pl.in b/Master/texmf-dist/doc/latex/typog/typog-grep.pl.in new file mode 100644 index 00000000000..39d64aec1ae --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-grep.pl.in @@ -0,0 +1,682 @@ +#! /usr/bin/env perl + +use autodie qw(:all); +use strict; +use warnings; + +use Data::Dumper (); +use Encode (); +use English; +use File::Basename (); +use Getopt::Long; +use IO::File; +use IO::Handle; +use Term::ANSIColor (); + +use constant COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); + +my $DEBUG = 0; +my $MATCH_COUNT = 0; +my $OUTPUT_IS_REDIRECTED; + +sub fail_with_error { + print STDERR join('', COMMAND_NAME, ': ', @_, "\n"); + exit 2; +} + +sub issue_warning { + print STDERR join('', COMMAND_NAME, ': warning: ', @_, "\n"); +} + +sub debug_print { + return unless $DEBUG; + print STDERR "+ @_\n"; +} + +sub quote_filesystem {qq("$_[0]")} +sub quote_literal {qq(`$_[0]')} + +sub limit_string_length { + my ($a_string, $a_maximum_length) = @_; + + if (length $a_string <= $a_maximum_length) { + $a_string; + } else { + substr($a_string, 0, $a_maximum_length - 3) . '...'; + } +} + +## We set all colors to `undef' and fill them later with the values +## of the actual configuration. +my $highlight_patterns = { + PARTIAL_LINE => { + FONT_SPEC => [qr# + \\ + (?: OMS | OMX | OT1 | T1 | TS1 | U ) + (?: /[^/]+ ){5} / \S+ \s + (?: \([+-]\d+\) )? + #x, undef], + MATH => [qr# + \$ + \\ + (?: LMS | OML ) + (?: /[^/]+ ){5} / \S+ \s + (?: \([+-]\d+\) )? + .*? + \$ + #x, undef] + }, + WHOLE_LINE => { + FILL_STATE => [qr#^(?:Under|Over)full \\hbox .*$#, undef], + FIRST_VBOX => [qr#^%%#, undef], + HORIZONTAL_BREAKPOINT => [qr#^@@\d+:.*$#, undef], + HORIZONTAL_BREAK_CANDIDATE => [qr#^@[\\ ].*$#, undef], + LINE_BREAK_PASS => [qr#^@[a-z]+?pass#, undef], + TIGHTNESS => [qr#^(?:Loose|Tight) \\hbox .*$#, undef], + VERTICAL_BREAKPOINT => [qr#^% t=\d+.*$#, undef] + } +}; + +sub colorize_line { + my ($configuration, $line) = @_; + + foreach my $pattern_color_pair (values %{$highlight_patterns->{WHOLE_LINE}}) { + next unless $pattern_color_pair->[1]; + return Term::ANSIColor::colored($line, $pattern_color_pair->[1]) + if $line =~ $pattern_color_pair->[0]; + } + return $line if $line =~ m#^\.#; # we do not paint box contents yet + + $line =~ s#$highlight_patterns->{PARTIAL_LINE}->{MATH}->[0] + #Term::ANSIColor::colored($MATCH, $highlight_patterns->{PARTIAL_LINE}->{MATH}->[1]) + #egx; + + $line =~ s#$highlight_patterns->{PARTIAL_LINE}->{FONT_SPEC}->[0] + #Term::ANSIColor::colored($MATCH, $highlight_patterns->{PARTIAL_LINE}->{FONT_SPEC}->[1]) + #egx; + + return $line; +} + +my $open_or_close_tag_regexp = qr#^]#; # somewhat sloppy definition +my $close_tag_regexp = qr#^#; +my $open_tag_regexp = + qr#^ + #x; + +sub find_encoder { + my $encoding = shift; + + my $encoder; + + if ($encoding) { + $encoder = Encode::find_encoding($encoding); + if (!$encoder) { + issue_warning("encoding @{[quote_literal($encoding)]} unknown; proceeding without decoder"); + } + } + + return $encoder; +} + +sub grep_log_file { + my ($options, $configuration, $file, $filename, $id_regexp) = @_; + + my $encoder = find_encoder($options->{ENCODING}); + my $job_name; + my $line_number = 0; # line number in the log file we are inspecting, i.e., $filename + my $match_count = 0; + my $source_line_number; # line number in TeX file the log refers to, i.e., "$job_name.tex" + my $page_number; + my $regexp_modifier = $options->{IGNORE_CASE} ? 'i' : ''; + my $id_value; + my @nesting_levels; + + if ($options->{WORD_REGEXP}) { + $id_regexp = "\\b$id_regexp\\b"; + } + + while (my $line = readline $file) { + chomp $line; + $line_number++; + + $line = Encode::encode_utf8($encoder->decode($line, Encode::FB_CROAK)) if $encoder; + + if ($line =~ $close_tag_regexp) { + fail_with_error("$filename: $line_number: mismatched open/close tags") unless @nesting_levels; + pop @nesting_levels; + } + + if (@nesting_levels and $nesting_levels[-1] and $line !~ $open_or_close_tag_regexp) { + if ($options->{LOG_LINE_NUMBER}) { + my $formatted_log_line_number = + sprintf $configuration->{LOG_LINE_NUMBER_FORMAT}, $line_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_log_line_number = + Term::ANSIColor::colored($formatted_log_line_number, + $configuration->{COLORS}->{LOG_LINE_NUMBER}); + } + print $formatted_log_line_number, ' '; + } + + print "$job_name: " if $options->{JOB_NAME}; + + if ($options->{LINE_NUMBER}) { + my $formatted_line_number = sprintf $configuration->{LINE_NUMBER_FORMAT}, $source_line_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_line_number = + Term::ANSIColor::colored($formatted_line_number, + $configuration->{COLORS}->{LINE_NUMBER}); + } + print $formatted_line_number, ' '; + } + + if ($options->{PAGE_NUMBER}) { + my $formatted_page_number = sprintf $configuration->{PAGE_NUMBER_FORMAT}, $page_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_page_number = + Term::ANSIColor::colored($formatted_page_number, + $configuration->{COLORS}->{PAGE_NUMBER}); + } + print $formatted_page_number, ' '; + } + + if ($options->{ID} and not $configuration->{PRINT_ID_AS_HEADING}) { + my $formatted_id = sprintf $configuration->{ID_INLINE_FORMAT}, $id_value; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_id = Term::ANSIColor::colored($formatted_id , + $configuration->{COLORS}->{ID_COLOR}); + } + print $formatted_id, ' '; + } + + if ($options->{COLORIZE_OUTPUT}) { + print colorize_line($configuration, $line); + } else { + print $line; + } + print "\n"; + } + + if ($line =~ $open_tag_regexp) { + $id_value = limit_string_length($+{id_match}, $configuration->{ID_MAX_LENGTH}); + $job_name = $+{job_match}; + $source_line_number = $+{line_match}; + $page_number = $+{page_match}; + + my $found_matching_id = ($id_value =~ m/(?$regexp_modifier)$id_regexp/) ? 1 : 0; + push @nesting_levels, $found_matching_id; + if ($found_matching_id) { + ++$MATCH_COUNT; # global count -- needed for return code of program + ++$match_count; # per file count -- needed to be able to separate the hunks + + print "\n" if $match_count >= 2; + if ($options->{ID} and $configuration->{PRINT_ID_AS_HEADING}) { + my $formatted_id = sprintf $configuration->{ID_HEADING_FORMAT}, $id_value; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_id = + Term::ANSIColor::colored($formatted_id, + $configuration->{COLORS}->{ID_HEADING_COLOR}); + } + print $formatted_id, "\n"; + } + } + } + } + + return $match_count; +} + +sub show_ids_in_file { + my ($options, $configuration, $file, $filename, $id_regexp) = @_; + + my $encoder = find_encoder($options->{ENCODING}); + my $line_number = 0; + my $match_count = 0; + my @nesting_levels; + + while (my $line = readline $file) { + chomp $line; + $line_number++; + + $line = Encode::encode_utf8($encoder->decode($line, Encode::FB_CROAK)) if $encoder; + + if ($line =~ $close_tag_regexp) { + fail_with_error("$filename: $line_number: mismatched open/close tags") unless @nesting_levels; + pop @nesting_levels; + } + + if ($line =~ $open_tag_regexp) { + my $id_value = limit_string_length($+{id_match}, $configuration->{ID_MAX_LENGTH}); + my $job_name = $+{job_match}; + my $source_line_number = $+{line_match}; + my $page_number = $+{page_match}; + + ++$MATCH_COUNT; + ++$match_count; + push @nesting_levels, 1; + + if ($options->{LOG_LINE_NUMBER}) { + my $formatted_log_line_number = + sprintf $configuration->{LOG_LINE_NUMBER_FORMAT}, $line_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_log_line_number = + Term::ANSIColor::colored($formatted_log_line_number, + $configuration->{COLORS}->{LOG_LINE_NUMBER}); + } + print $formatted_log_line_number, ' '; + } + + print "$job_name: " if $options->{JOB_NAME}; + + if ($options->{LINE_NUMBER}) { + my $formatted_line_number = sprintf $configuration->{LINE_NUMBER_FORMAT}, $source_line_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_line_number = + Term::ANSIColor::colored($formatted_line_number, + $configuration->{COLORS}->{LINE_NUMBER}); + } + print $formatted_line_number, ' '; + } + + if ($options->{PAGE_NUMBER}) { + my $formatted_page_number = sprintf $configuration->{PAGE_NUMBER_FORMAT}, $page_number; + if ($options->{COLORIZE_OUTPUT}) { + $formatted_page_number = + Term::ANSIColor::colored($formatted_page_number, + $configuration->{COLORS}->{PAGE_NUMBER}); + } + print $formatted_page_number, ' '; + } + + my $indent = $configuration->{ID_INDENT} * (@nesting_levels - 1); + print ' ' x $indent, $id_value, "\n"; + } + } + + return $match_count; +} + +sub open_file_for_reading { + my $filename = shift; + + my $file; + + if ($filename eq 'stdin') { + $file = IO::Handle->new(); + $file->fdopen(fileno(STDIN), 'r') or + fail_with_error("cannot open stdin: $OS_ERROR"); + } else { + $file = IO::File->new($filename, 'r') or + fail_with_error("cannot open @{[quote_filesystem($filename)]}: $OS_ERROR"); + } + + return $file; +} + +sub close_file { + my ($file, $filename) = shift; + + $file->close or + issue_warning("problems while closing @{[quote_filesystem($filename)]}: $OS_ERROR"); +} + +sub grep_or_show { + my ($options, $configuration, $file, $filename, $id_regexp) = @_; + + if ($options->{SHOW_ALL_IDS}) { + return show_ids_in_file($options, $configuration, $file, $filename, $id_regexp); + } else { + return grep_log_file($options, $configuration, $file, $filename, $id_regexp); + } +} + +sub scan_files { + my ($options, $configuration, $id_regexp, $log_filenames) = @_; + + my $match_count = 0; + + if (@$log_filenames) { + foreach my $log_filename (@$log_filenames) { + $log_filename = 'stdin' if $log_filename eq '-'; + if (@$log_filenames >= 2) { + print "\n" unless $log_filename eq $log_filenames->[0]; + my $filename_header = "==> $log_filename <==\n"; + $filename_header = Term::ANSIColor::colored($filename_header, + $configuration->{COLORS}->{FILE_HEADER}) + if $options->{COLORIZE_OUTPUT}; + print $filename_header; + } + my $file = open_file_for_reading($log_filename); + $match_count += grep_or_show($options, $configuration, $file, $log_filename, $id_regexp); + close_file($file, $log_filename); + } + } else { + my $log_filename = 'stdin'; + my $file = open_file_for_reading($log_filename); + $match_count = grep_or_show($options, $configuration, $file, $log_filename, $id_regexp); + close_file($file, $log_filename); + } + + return $match_count; +} + +sub redirect_and_scan_files { + my ($options, $configuration, $id_regexp, $log_filenames) = @_; + + my $pager; + + my $pid = open($pager, '|-', $configuration->{PAGER}, $configuration->{PAGER_FLAGS}); + fail_with_error('failed to redirect to pager ', quote_literal($configuration->{PAGER}), + ' with flags ', quote_literal($configuration->{PAGER_FLAGS}), + ": $OS_ERROR") + unless defined $pid; + my $stdout = select $pager; + + $pager->autoflush; + my $match_count = scan_files($options, $configuration, $id_regexp, $log_filenames); + + close $pager or issue_warning "error occurred while closing the pager (pid: $pid) pipe: $OS_ERROR"; + select $stdout; + + return $match_count; +} + +######################################################################## + +my $configuration_key_map = { + 'id-format' => 'ID_INLINE_FORMAT', + 'id-indent' => 'ID_INDENT', + 'id-heading' => 'PRINT_ID_AS_HEADING', + 'id-heading-format' => 'ID_HEADING_FORMAT', + 'id-max-length' => 'ID_MAX_LENGTH', + 'line-number-format' => 'LINE_NUMBER_FORMAT', + 'log-line-number-format' => 'LOG_LINE_NUMBER_FORMAT', + 'page-number-format' => 'PAGE_NUMBER_FORMAT', + + 'file-header-color' => 'FILE_HEADER', + 'fill-state-color' => 'FILL_STATE', + 'first-vbox-color' => 'FIRST_VBOX', + 'font-spec-color' => 'FONT_SPEC', + 'horizontal-break-candidate-color' => 'HORIZONTAL_BREAK_CANDIDATE', + 'horizontal-breakpoint-color' => 'HORIZONTAL_BREAKPOINT', + 'id-color' => 'ID_COLOR', + 'id-heading-color' => 'ID_HEADING_COLOR', + 'line-break-pass-color' => 'LINE_BREAK_PASS', + 'line-number-color' => 'LINE_NUMBER', + 'log-line-number-color' => 'LOG_LINE_NUMBER', + 'math-color' => 'MATH', + 'page-number-color' => 'PAGE_NUMBER', + 'pager' => 'PAGER', + 'pager-flags' => 'PAGER_FLAGS', + 'tightness-color' => 'TIGHTNESS', + 'vertical-breakpoint-color' => 'VERTICAL_BREAKPOINT' +}; + +my $default_configuration = { + COLORS => { + FILE_HEADER => 'bold black', + FILL_STATE => 'bold magenta', + FIRST_VBOX => 'bold red', + FONT_SPEC => 'grey12', + HORIZONTAL_BREAKPOINT => 'bold green', + HORIZONTAL_BREAK_CANDIDATE => 'blue', + ID_COLOR => 'white on_black', + ID_HEADING_COLOR => 'white on_black', + LINE_BREAK_PASS => 'bold green', + LINE_NUMBER => 'bold black', + LOG_LINE_NUMBER => 'italic black', + MATH => 'yellow', + PAGE_NUMBER => 'bold white on_red', + TIGHTNESS => 'bold cyan', + VERTICAL_BREAKPOINT => 'red' + }, + ID_INLINE_FORMAT => '%s:', + ID_HEADING_FORMAT => '--> %s <--', + ID_INDENT => 8, + ID_MAX_LENGTH => 40, + LINE_NUMBER_FORMAT => '%5d', + LOG_LINE_NUMBER_FORMAT => '%6d', + PAGE_NUMBER_FORMAT => '[%3d]', + PAGER => 'less', + PAGER_FLAGS => '--quit-if-one-screen', + PRINT_ID_AS_HEADING => 0 +}; + +sub initialize_highlighting_from_configuration { + my $configuration = shift; + + while (my (undef, $assoc) = each %$highlight_patterns) { + while (my ($name, $pattern_color_pair) = each %$assoc) { + $pattern_color_pair->[1] = $configuration->{COLORS}->{$name}; + } + } +} + +sub modify_configuration { + my ($configuration, $key, $value) = @_; + + fail_with_error('malformed KEY=VALUE pair -- missing key') unless $key; + + if (defined $configuration_key_map->{$key}) { + if ($key =~ m/-color$/) { + $configuration->{COLORS}->{$configuration_key_map->{$key}} = $value; + } else { + $configuration->{$configuration_key_map->{$key}} = $value; + } + } else { + fail_with_error("@{[quote_literal($key)]} is not a valid configuration KEY"); + } +} + +sub setup_configuation { + my ($config_spec, $configuration) = @_; + + foreach my $spec (split ':', $config_spec) { + my ($key, $value) = split '=', $spec; + modify_configuration($configuration, $key, $value); + } +} + +my $default_options = { + COLORIZE_MODE => 'auto', + DEBUG => 0, + ENCODING => undef, + ID => 0, + IGNORE_CASE => 0, + JOB_NAME => 0, + LINE_NUMBER => 0, + LOG_LINE_NUMBER => 0, + PAGE_NUMBER => 0, + REQUEST_PAGER => 1, + WORD_REGEXP => 0 +}; + +sub show_help { + print <encodings(':all'); + + foreach my $encoding (@all_encodings) { + print "$encoding\n"; + } + + exit 0; +} + +sub show_configuration { + my $format_string_value = sub {quote_literal($default_configuration->{$_[0]})}; + + print <('ID_INLINE_FORMAT')]} +id-heading $default_configuration->{PRINT_ID_AS_HEADING} +id-heading-format @{[$format_string_value->('ID_HEADING_FORMAT')]} +id-indent $default_configuration->{ID_INDENT} +id-max-length $default_configuration->{ID_MAX_LENGTH} +line-number-format @{[$format_string_value->('LINE_NUMBER_FORMAT')]} +log-line-number-format @{[$format_string_value->('LOG_LINE_NUMBER_FORMAT')]} +page-number-format @{[$format_string_value->('PAGE_NUMBER_FORMAT')]} +pager @{[$format_string_value->('PAGER')]} +pager-flags @{[$format_string_value->('PAGER_FLAGS')]} + +FIXED_CONFIGURATION_TEXT + + foreach my $configuration_key (sort keys %$configuration_key_map) { + next unless $configuration_key =~ m/-color$/; + printf("%-36s %s\n", + $configuration_key, + quote_literal($default_configuration-> + {COLORS}-> + {$configuration_key_map->{$configuration_key}})); + } + + exit 0; +} + +sub show_version { + print < \$options->{SHOW_ALL_IDS}, + 'color|colour=s' => \$options->{COLORIZE_MODE}, + 'C|configuration=s' => sub{setup_configuation($_[1], $configuration)}, + 'debug+' => \$DEBUG, + 'E|encoding=s' => \$options->{ENCODING}, + 'h|help' => \&show_help, + 'i|id!' => \$options->{ID}, + 'y|ignore-case!' => \$options->{IGNORE_CASE}, + 'j|job-name!' => \$options->{JOB_NAME}, + 'n|line-number!' => \$options->{LINE_NUMBER}, + 'N|log-line-number!' => \$options->{LOG_LINE_NUMBER}, + 'p|page-number!' => \$options->{PAGE_NUMBER}, + 'P|pager!' => \$options->{REQUEST_PAGER}, + 'show-encodings' => \&show_encodings, + 'show-config' => \&show_configuration, + 'V|version' => \&show_version, + 'w|word-regexp!' => \$options->{WORD_REGEXP}) or + fail_with_error('problems while parsing options'); + + if ($options->{COLORIZE_MODE}) { + fail_with_error("unknown colorize mode @{[quote_literal($options->{COLORIZE_MODE})]}") + unless $options->{COLORIZE_MODE} =~ m/^(?:always|auto|never)$/i; + } else { + $options->{COLORIZE_MODE} = 'auto'; + } +} + +sub do_colorize { + my $colorize_mode = shift; + + if ($colorize_mode =~ m/never/i) { + 0; + } elsif ($colorize_mode =~ m/always/i) { + 1; + } elsif ($colorize_mode =~ m/auto/i) { + not $OUTPUT_IS_REDIRECTED; + } +} + +## For the comparison with the POSIX spec of grep(1) consult +## https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html + +sub main { + $OUTPUT_IS_REDIRECTED = -t STDOUT ? 0 : 1; + + my $configuration = {%$default_configuration}; + my $options = {%$default_options}; + debug_print(Data::Dumper::Dumper(['Default Configuration', $configuration])); + debug_print(Data::Dumper::Dumper(['Default Options', $options])); + + my $user_options = {}; + my $user_configuration = {}; + get_options($user_options, $user_configuration); + debug_print(Data::Dumper::Dumper(['User Configuration', $user_configuration])); + debug_print(Data::Dumper::Dumper(['User Options', $user_options])); + while (my ($key, $value) = each %$user_options) { + $options->{$key} = $value if $value; + } + while (my ($key, $value) = each %$user_configuration) { + $configuration->{$key} = $value if $value; + } + debug_print(Data::Dumper::Dumper(['Final Configuration', $configuration])); + debug_print(Data::Dumper::Dumper(['Final Options', $options])); + + $options->{COLORIZE_OUTPUT} = do_colorize($options->{COLORIZE_MODE}); + initialize_highlighting_from_configuration($configuration); + + my $id_regexp; + if ($options->{SHOW_ALL_IDS}) { + $id_regexp = '^'; + issue_warning("option @{[quote_literal('--id')]} ignored in @{[quote_literal('--all')]} mode") + if $options->{ID}; + } else { + fail_with_error('missing ID-REGEXP') unless @ARGV >= 1; + $id_regexp = shift @ARGV; + } + + if ($user_options->{REQUEST_PAGER} && $OUTPUT_IS_REDIRECTED) { + issue_warning("option @{[quote_literal('--pager')]} ignored because output is redirected"); + } + my $use_pager = $options->{REQUEST_PAGER} && !$OUTPUT_IS_REDIRECTED; + my $match_count; + if ($use_pager) { + $match_count = redirect_and_scan_files($options, $configuration, $id_regexp, \@ARGV); + } else { + $match_count = scan_files($options, $configuration, $id_regexp, \@ARGV); + } + + exit ($match_count == 0); +} + +main(); diff --git a/Master/texmf-dist/doc/latex/typog/typog-grep.pod b/Master/texmf-dist/doc/latex/typog/typog-grep.pod index 83f4f11f474..eba8297f807 100644 --- a/Master/texmf-dist/doc/latex/typog/typog-grep.pod +++ b/Master/texmf-dist/doc/latex/typog/typog-grep.pod @@ -7,7 +7,7 @@ =head1 NAME -typog-grep - grep for typog-inspect elements in LaTeX log files +typog-grep - specialized grep for typog-inspect elements in LaTeX log files =head1 SYNOPSIS @@ -19,9 +19,70 @@ typog-grep - grep for typog-inspect elements in LaTeX log files =back -The first form shows all Ctypog-inspect id="I" ...E> elements in F. +The first form, ``discovery mode'', shows all Is of -The second form shows the contents of Ctypog-inspect id="I" ...E> elements +=begin text + + + +=end text + +=begin man + +.RS +.EX + +.EE +.RE + +=end man + +=begin texinfo + +@example + +@end example +@noindent + +=end texinfo + +Z<> +elements in F. + +The second form shows the contents, I, of the elements + +=begin text + + +LOG-DATA + + +=end text + +=begin man + +.RS +.EX + +\fILOG-DATA\fP + +.EE +.RE + +=end man + +=begin texinfo + +@example + +@var{LOG-DATA} + +@end example +@noindent + +=end texinfo + +Z<> whose Is match I in F. If no F is given read from F. @@ -29,57 +90,101 @@ The S> is synonymous to F. =head1 DESCRIPTION -B is a tailored post-processor for LaTeX log files -and the C environment as provided by S. +B is a tailored post-processor for LaTeX S files> +and the C environment as provided by the S. It shares more with the venerable L|https://www.cs.helsinki.fi/u/jjaakkol/sgrep.html> than with S|https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html>>. -The LaTeX user brackets her text in +In the LaTeX source file the user brackets her text or code +in a C environment: + +=begin text - \begin{typoginspect}{ID} - Text and code to investigate - \end{typoginspect} +\begin{typoginspect}{ID} + TEXT-OR-CODE-TO-INVESTIGATE +\end{typoginspect} + +=end text + +=begin man + +.RS +.EX +\ebegin{typoginspect}{\fI\,ID\/\fP} +\fITEXT-OR-CODE-TO-INVESTIGATE\fP +\eend{typoginspect} +.EE +.RE + +=end man +=begin texinfo + +@example +@backslashchar{}begin@lbracechar{}typoginspect@rbracechar{}@lbracechar{}@var{ID}@rbracechar{} +@var{TEXT-OR-CODE-TO-INVESTIGATE} +@backslashchar{}end@lbracechar{}typoginspect@rbracechar{} +@end example +@noindent + +=end texinfo + +Z<> where I is used to identify one or more bracketed snippets. I does not have to be unique. The I mechanism makes it easy to select groups of related Is if they are named accordingly. -In F the environment shows up, packed with tracing information, as +In F the result of the environment shows up, +packed with tracing information, as -=begin texinfo +=begin text -@display -@relax + + LOG-DATA + -=end texinfo +=end text + +=begin man - - Trace Data - +.RS +.EX + +\fILOG-DATA\fP + +.EE +.RE + +=end man =begin texinfo -@end display -@relax +@example + +@var{LOG-DATA} + +@end example +@noindent =end texinfo +Z<> where all the capital-letter sequences are meta-variables and in particular I is the expansion of C<\jobname>, I is the LaTeX source file line number of the beginning of the C environment, and I is the page where -the output of S> occurs. +the output of S> occurs. B reveals the contents of F between Ctypog-inspect id="I" ...E> -and C/typog-inspectE> excluding the XML-tags. +and C/typog-inspectE> excluding the XML-tags themselves. Access the I, I, and I with the commandline options -B<--job-name>, B<--line-number>, and B<--page-number>, respectively. +B<--job-name>, B<--line-number>, and B<--page-number>, respectively. Use B<--id> to show the name of the IDs that matched I. C environments can be nested. @@ -96,11 +201,18 @@ The list of options is sorted by the names of the long options. =item B<-a>, B<--all>, B<--any> ID-discovery mode: -Show all C elements independent of any matching patterns. +Discover all C elements independent of any matching patterns +and print their Is. +The results are printed in their order of occurrence in the respective Fs. +Pipe the output into B to get alphabetically ordered Is. + +Augment with options +B<--job-name>, B<--line-number>, B<--log-line-number>, or S> +for more information. =item B<--color>, B I -Colorize specific log contents for the matching ids. +Colorize specific log contents for the matching Is. The S> determines when to apply color: C, C, S>. The setting C checks whether standard output has been redirected. @@ -109,29 +221,45 @@ This is the default. =item B<-C>, B<--config> I=I[:I=I[:...]] Set one or more configuration I to I pairs. -See S below for a description of all available configuration items. -Use option B<--show-config> to display the default configuration. +See section L for a description +of all available configuration items. +Use S