From 84f03266593d0aeb4f714b3f4b76f2d1ea4f4bd6 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 20 Jun 2016 22:24:28 +0000 Subject: autobreak (20jun16) git-svn-id: svn://tug.org/texlive/trunk@41507 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/latex/autobreak/autobreak.dtx | 1130 ++++++++++++++++++++ .../source/latex/autobreak/autobreak.ins | 70 ++ 2 files changed, 1200 insertions(+) create mode 100644 Master/texmf-dist/source/latex/autobreak/autobreak.dtx create mode 100644 Master/texmf-dist/source/latex/autobreak/autobreak.ins (limited to 'Master/texmf-dist/source') diff --git a/Master/texmf-dist/source/latex/autobreak/autobreak.dtx b/Master/texmf-dist/source/latex/autobreak/autobreak.dtx new file mode 100644 index 00000000000..cb372c15e87 --- /dev/null +++ b/Master/texmf-dist/source/latex/autobreak/autobreak.dtx @@ -0,0 +1,1130 @@ +% \iffalse meta-comment +% +% Copyright (C) 2016 by Takahiro Ueda +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, either version 1.3 of this license +% or (at your option) any later version. 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 +% version 2005/12/01 or later. +% +% To typeset this document, type the following commands: +% latex autobreak.dtx +% makeindex -s gind.ist autobreak.idx +% makeindex -s gglo.ist -o autobreak.gls autobreak.glo +% latex autobreak.dtx +% latex autobreak.dtx +% +%<*ignore> +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +% +%<*install> + +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble + +This is a generated file. + +Copyright (C) 2016 by Takahiro Ueda + +This file may be distributed and/or modified under the conditions of +the LaTeX Project Public License, either version 1.3 of this license +or (at your option) any later version. 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 +version 2005/12/01 or later. + +\endpreamble + +\generate{ + \usedir{tex/latex/autobreak} + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} + +% +%<*ignore> +\iffalse +% +%<*install> + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* autobreak.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file autobreak.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile + +% +%<*ignore> +\fi +\generate{ + \file{\jobname.ins}{\from{\jobname.dtx}{install}} +} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +% +%<*driver> +\documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{hypdoc} +\usepackage{amsmath} +\usepackage{autobreak} +\EnableCrossrefs +\CodelineIndex +\RecordChanges + +\allowdisplaybreaks + +% The default value of IndexColumns=3 never fits in pages. +\setcounter{IndexColumns}{2} + +\providecommand\env[1]{\texttt{#1}} +\providecommand\pkg[1]{\textsf{#1}} + +\usepackage{fancyvrb} + +\edef\examplefilename{\jobname.tmp} + +\newenvironment{example}{% + \VerbatimEnvironment + \begin{VerbatimOut}[gobble=2]{\examplefilename}% +}{% + \end{VerbatimOut}% + \smallskip + \noindent + \begin{list}{}{}\item + \begin{minipage}[t]{0.45\linewidth}% + \VerbatimInput{\examplefilename}% + \end{minipage}% + \begin{minipage}[t]{0.5\linewidth}% + \input{\examplefilename}% + \end{minipage}% + \end{list}% + \smallskip + \noindent +} + +\newenvironment{example*}{% + \VerbatimEnvironment + \begin{VerbatimOut}[gobble=2]{\examplefilename}% +}{% + \end{VerbatimOut}% + \smallskip + \noindent + \begin{list}{}{}\item + \begin{minipage}[t]{0.95\linewidth}% + \VerbatimInput{\examplefilename}% + \end{minipage}% + \end{list}% + \smallskip + \noindent +} + +\newenvironment{example**}{% + \VerbatimEnvironment + \begin{VerbatimOut}[gobble=2]{\examplefilename}% +}{% + \end{VerbatimOut}% + \smallskip + \noindent + \begin{list}{}{}\item + \begin{minipage}[t]{0.95\linewidth}% + \VerbatimInput{\examplefilename}% + \end{minipage} \\ + \begin{minipage}[t]{0.95\linewidth}% + \input{\examplefilename}% + \end{minipage}% + \end{list}% + \smallskip + \noindent +} + +% decl from ltxguide[2001/05/28] +\newenvironment{decl}[1][]% + {\par\small\addvspace{4.5ex plus 1ex}% + \vskip -\parskip + \ifx\relax#1\relax + \def\@decl@date{}% + \else + \def\@decl@date{\NEWfeature{#1}}% + \fi + \noindent\hspace{-\leftmargini}% + \begin{tabular}{|l|}\hline\ignorespaces}% + {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak + \vspace{2.3ex}\vskip -\parskip} + +\newcommand\NumberedBox[1]{% + \, \framebox[25pt]{#1} \,% +} + +\newcommand\LongerNumberedBox[1]{% + \, \framebox[30pt]{#1} \,% +} + +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% +% \CheckSum{336} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \GetFileInfo{\jobname.sty} +% +% \title{The \pkg{autobreak} package\thanks{This document corresponds +% to \pkg{autobreak}~\fileversion, dated \filedate.}} +% \author{Takahiro Ueda} +% +% \date{19 June 2016} +% +% \maketitle +% +% \begin{abstract} +% This package implements a simple mechanism of line/page breaking +% within the \env{align} environment of the \pkg{amsmath} package; new +% line characters are considered as possible candidates for the breaks +% and the package tries to put breaks at adequate places. +% It is suitable for computer-generated long formulae with many terms. +% \end{abstract} +% +% \changes{v0.1}{2016/06/03}{Initial version} +% +% \tableofcontents +% +% \section{Introduction} +% +% Sometimes people want to put long formulae in their documents, which +% do not fit in a line and may span over multiple pages. +% The following is an equation of explicitly writing down the first 50 +% terms in the sum of the well-known Basel problem: +% \begin{align} +% \begin{autobreak} +% \zeta(2) = +% 1 +% + \frac{1}{4} +% + \frac{1}{9} +% + \frac{1}{16} +% + \frac{1}{25} +% + \frac{1}{36} +% + \frac{1}{49} +% + \frac{1}{64} +% + \frac{1}{81} +% + \frac{1}{100} +% + \frac{1}{121} +% + \frac{1}{144} +% + \frac{1}{169} +% + \frac{1}{196} +% + \frac{1}{225} +% + \frac{1}{256} +% + \frac{1}{289} +% + \frac{1}{324} +% + \frac{1}{361} +% + \frac{1}{400} +% + \frac{1}{441} +% + \frac{1}{484} +% + \frac{1}{529} +% + \frac{1}{576} +% + \frac{1}{625} +% + \frac{1}{676} +% + \frac{1}{729} +% + \frac{1}{784} +% + \frac{1}{841} +% + \frac{1}{900} +% + \frac{1}{961} +% + \frac{1}{1024} +% + \frac{1}{1089} +% + \frac{1}{1156} +% + \frac{1}{1225} +% + \frac{1}{1296} +% + \frac{1}{1369} +% + \frac{1}{1444} +% + \frac{1}{1521} +% + \frac{1}{1600} +% + \frac{1}{1681} +% + \frac{1}{1764} +% + \frac{1}{1849} +% + \frac{1}{1936} +% + \frac{1}{2025} +% + \frac{1}{2116} +% + \frac{1}{2209} +% + \frac{1}{2304} +% + \frac{1}{2401} +% + \frac{1}{2500} +% + \dots +% \end{autobreak} +% \end{align} +% The above example might seem nonsense, but putting long formulae may +% have a meaning in some cases and become inevitable for completeness of +% documents, writing self-contained papers, or just to impress readers. +% They are typically generated as outputs of computer algebra systems, +% and would have the form of a sum of many terms while each term is +% short. +% +% Then, the question is how to break long formulae in such a way that +% the expressions do not make any overfull lines for \LaTeX{}. +% Certainly, one can attempt to manually insert line breaks by trial and +% error, checking whether \LaTeX{} warns overfull lines, and this +% process could be automatized by external scripts at some extent. +% A shortcoming of such `manual' approaches is that line breaks have to +% be reexamined whenever the layout of the document is changed, e.g., +% replacing the document class or reusing existing equations into +% another document with a different format. +% +% The goal of the \pkg{autobreak} package is to give a reasonably simple +% solution for (semi-)automatic line breaking of long formulae within +% \LaTeX{}^^A +% \footnote{^^A +% There is another package \pkg{breqn} +% (\url{https://www.ctan.org/pkg/breqn}), which adopts a more +% automatic fashion and is useful for more sophisticated line +% breaking, unless you get ``Dimension too large'' error for really +% big expressions. +% }. +% +% \section{Usage} +% +% The \pkg{autobreak} package is supposed to be used together with the +% \pkg{amsmath} package^^A +% \footnote{^^A +% \url{https://www.ctan.org/pkg/amsmath}. +% }^^A +% \footnote{^^A +% Actually \pkg{autobreak} internally loads \pkg{amsmath}, but it is +% still a good practice to explicitly include all packages providing +% macros used in your document. +% }: +% \begin{example*} +% \usepackage{amsmath} +% \usepackage{autobreak} +% \end{example*} +% When your document contains long equations over multiple pages, +% you might want to use \cs{allowdisplaybreaks} of \pkg{amsmath} +% package: +% \begin{example*} +% \allowdisplaybreaks +% \end{example*} +% +% \begin{decl} +% |\begin{autobreak}| \\ +% \meta{long-equations} \\ +% |\end{autobreak}| +% \end{decl} +% \SpecialEnvIndex{autobreak} +% The \env{autobreak} environment is used for breaking lines in long +% formulae in the \env{align} environment of \pkg{amsmath}^^A +% \footnote{^^A +% Technically, \env{align} (with \cs{notag} to suppress equation +% numbers except the last line) is the only option we can use for +% page-break aligned equations within \pkg{amsmath} because +% \env{split}, \env{gathered}, \env{aligned} and \env{alginedat} do +% not allow page breaking. +% \env{dmath} of \env{breqn} with \cs{eqinterlinepenalty}\texttt{=0} +% allows page breaking, but may fail to find a reasonable tag place. +% }. +% \begin{example} +% \begin{align} +% \begin{autobreak} +% \zeta(3) = +% 1 +% + \frac{1}{8} +% + \frac{1}{27} +% + \frac{1}{64} +% + \frac{1}{125} +% + \frac{1}{216} +% + \frac{1}{343} +% + \frac{1}{512} +% + \frac{1}{729} +% + \frac{1}{1000} +% + \frac{1}{1331} +% + \frac{1}{1728} +% + \frac{1}{2197} +% + \frac{1}{2744} +% + \frac{1}{3375} +% + \frac{1}{4096} +% + \frac{1}{4913} +% + \frac{1}{5832} +% + \frac{1}{6859} +% + \frac{1}{8000} +% + \dots +% \end{autobreak} +% \end{align} +% \end{example} +% The magic happens from the simple fact that \env{autobreak} interprets +% all new line characters appearing between |\begin{autobreak}| and +% |\end{autobreak}| as \textit{breakable points}, at which any line +% breaks can be logically inserted. To be more exact, the first +% non-empty block, separated from the rest by a new line character, +% determines the indentation of the successive lines. Then +% \env{autobreak} tries to fill the line with the rest of the blocks, +% and puts a line break when they do not fit in a line. This is +% clarified by the following example: +% \begin{example} +% \begin{align} +% \begin{autobreak} +% \NumberedBox{1} +% \NumberedBox{2} +% \NumberedBox{3} +% \NumberedBox{4} +% \NumberedBox{5} +% \NumberedBox{6} +% \NumberedBox{7} +% \NumberedBox{8} +% \NumberedBox{9} +% \NumberedBox{10} +% \NumberedBox{11} +% \end{autobreak} +% \end{align} +% \end{example} +% +% It is also possible to put more than one \env{autobreak} in one +% \env{align}: +% \begin{example} +% \begin{align} +% \begin{autobreak} +% \NumberedBox{1} = +% \NumberedBox{2} +% + \NumberedBox{3} +% + \NumberedBox{4} +% + \NumberedBox{5} +% + \NumberedBox{6} +% + \NumberedBox{7} +% + \NumberedBox{8} +% + \NumberedBox{9} +% + \NumberedBox{10} , +% \end{autobreak} +% \\ +% \begin{autobreak} +% \LongerNumberedBox{1} = +% \NumberedBox{2} +% + \NumberedBox{3} +% + \NumberedBox{4} +% + \NumberedBox{5} +% + \NumberedBox{6} +% + \NumberedBox{7} +% + \NumberedBox{8} +% + \NumberedBox{9} +% + \NumberedBox{10} . +% \end{autobreak} +% \end{align} +% \end{example} +% For a technical reason, it often requires more than one run of +% \LaTeX{}, and in such cases one will get informed by the following +% warning: +% \begin{example*} +% Package autobreak Warning: Layout may have changed. +% (autobreak) Rerun to get layout correct. +% \end{example*} +% In the next run, the layout of the equations will be corrected. +% +% \begin{decl} +% |\everybeforeautobreak| \marg{tokens} \\ +% |\everyaftereautobreak| \marg{tokens} +% \end{decl} +% \SpecialUsageIndex{\everybeforeautobreak} +% \SpecialUsageIndex{\everyafterautobreak} +% They specify token lists inserted before and after automatically +% inserted line breaks in \env{autobreak}. For example, +% \begin{example**} +% \begin{align} +% \everyafterautobreak{\times} +% \begin{autobreak} +% \cos\left(\frac{\pi x}{2}\right) = +% \left(1-x^2\right) +% \left(1-\frac{x^2}{9}\right) +% \left(1-\frac{x^2}{25}\right) +% \left(1-\frac{x^2}{49}\right) +% \left(1-\frac{x^2}{81}\right) +% \left(1-\frac{x^2}{121}\right) +% \left(1-\frac{x^2}{169}\right) +% \left(1-\frac{x^2}{225}\right) +% \left(1-\frac{x^2}{289}\right) +% \left(1-\frac{x^2}{361}\right) +% \left(1-\frac{x^2}{441}\right) +% \dots +% \end{autobreak} +% \end{align} +% \end{example**} +% +% \section{Caveats} +% +% Because \env{autobreak} tries to insert line breaks at any of new line +% characters, you must not make any new lines at which the line cannot +% be broken^^A +% \footnote{^^A +% You may put "\%" at the end of the line to avoid a new line. +% }. +% For example +% \begin{example*} +% \begin{align} +% \begin{autobreak} +% x = +% % A problematic line break. +% \frac{1} +% {2} . +% \end{autobreak} +% \end{align} +% \end{example*} +% gives an error in the typesetting: +% \begin{example*} +% ! Missing } inserted. +% +% } +% l.8 \end{align} +% \end{example*} +% +% Putting `|\\|' or `|&|' inside \env{autobreak}, which tries to insert +% these special stuffs automatically, also causes typesetting errors. +% +% The \env{autobreak} environment uses \cs{linewidth} as the maximum +% width that expressions in its body can occupy. There is no way for +% \env{autobreak} to know how much other formulae consume the space +% outside it. Therefore it fails to determine the adequate maximum +% width when there are expressions outside \env{autobreak} and +% then \LaTeX{} gives overfull line warnings: +% \begin{example*} +% \begin{align} +% \text{some stuff outside autobreak} +% \begin{autobreak} +% \text{LHS} = +% ... +% \end{autobreak} . % Even just a "." can be problematic. +% \end{align} +% % May give overfull line warnings +% \end{example*} +% +% One may want to separate long formulae from the main document file to +% other files and include them via \cs{input}\marg{file}, for example, +% \begin{example*} +% \begin{align} +% \begin{autobreak} +% \input{longeqn.inc} % It works! +% \end{autobreak} +% \end{align} +% +% \begin{align} +% \begin{autobreak} +% lhs = +% \input{longrhs.inc} % It also works! +% . +% \end{autobreak} +% \end{align} +% \end{example*} +% The current version of \env{autobreak} supports these cases: the file +% content of \cs{input}\marg{file} is expanded before recognizing the +% lines, with the help of the \pkg{catchfile} package^^A +% \footnote{^^A +% \url{https://www.ctan.org/pkg/catchfile}. +% }, +% when it appears at the beginning of each line. But it does not support +% \cs{input}\marg{file} in the middle of the lines: +% \begin{example*} +% \begin{align} +% \begin{autobreak} +% x + \input{longexpr.inc} % Sorry, it does not work. +% \end{autobreak} +% \end{align} +% \end{example*} +% The difficulty comes from the fact that it needs to be expanded before +% \env{autobreak} scans lines. By the same reason, \env{autobreak} fails +% to detect new lines defined inside macros^^A +% \footnote{^^A +% Actually, when the definition of \cs{foo} is parsed, the new line +% characters inside it are usually lost. +% }: +% \begin{example*} +% \newcommand{\foo}{ +% a +% + b +% + c +% + d +% } +% \begin{align} +% \begin{autobreak} +% \foo + \foo + \foo + \foo % No new lines can be detected. +% \end{autobreak} +% \end{align} +% \end{example*} +% +% \StopEventually{^^A +% \PrintChanges +% \PrintIndex +% } +% +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{autobreak}% + [2016/06/03 v0.1 simple line breaking of long formulae] +% \end{macrocode} +% +% \subsection{Registers and constants} +% +% \begin{macro}{\everybeforeautobreak} +% The list of tokens that gets inserted before every line break generated +% by \env{autobreak}. +% \begin{macrocode} +\newtoks\everybeforeautobreak +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\everyafterautobreak} +% The list of tokens that gets inserted after every line break generated +% by \env{autobreak}. +% \begin{macrocode} +\newtoks\everyafterautobreak +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@alltoks} +% The token register to store the whole result of \env{autobreak}. +% \begin{macrocode} +\newtoks\@autobreak@alltoks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@linetoks} +% The token register for the current line. +% \begin{macrocode} +\newtoks\@autobreak@linetoks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@lhswidth} +% The width of the current left-hand side. +% \begin{macrocode} +\newdimen\@autobreak@lhswidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@rhswidth} +% The width of the current right-hand side. +% \begin{macrocode} +\newdimen\@autobreak@rhswidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@maxlhswidth} +% The width of the longest left-hand side occupied. Affected by the +% |.aux| file generated in the previous run. +% \begin{macrocode} +\newdimen\@autobreak@maxlhswidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@realmaxlhswidth} +% The width of the longest left-hand side occupied. Not affected by the +% |.aux| file generated in the previous run. +% \begin{macrocode} +\newdimen\@autobreak@realmaxlhswidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@maxrhswidth} +% The maximum width that the right-hand sides can occupy. +% \begin{macrocode} +\newdimen\@autobreak@maxrhswidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@sep} +% The additional space needed for putting the left-hand side and the +% right-hand side in one line, in other words, the separation for |&|. +% TODO: how can we know the exact extra space to be inserted? +% \begin{macrocode} +\def\@autobreak@sp{7\p@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@newlinechar} +% The macro representing an active |^^M|. +% \begin{macrocode} +\begingroup + \catcode`\^^M=\active + \gdef\@autobreak@newlinechar{^^M} +\endgroup +% \end{macrocode} +% \end{macro} +% +% \subsection{Interaction with \texttt{.aux} files} +% +% When there are two or more \env{autobreak} in one \env{align}, each +% \env{autobreak} has to know the maximum width of the left-hand side of +% the all \env{autobreak} in the same \env{align}. Instead of violating +% `causality' (e.g., how \LaTeX{} parses a file from the beginning to +% the end), we use |.aux| file to store the maximum left-hand side +% width, which provides the correct value in the next run. +% +% \begin{macro}{\if@autobreak@invalidlayout} +% The switch to be turned on when an invalid layout is detected. +% \begin{macrocode} +\newif\if@autobreak@invalidlayout +\@autobreak@invalidlayoutfalse +% \end{macrocode} +% \end{macro} +% Show a warning if the user needs to rerun. +% \begin{macrocode} +\AtEndDocument{% + \if@autobreak@invalidlayout + \if@filesw + \PackageWarningNoLine{autobreak}{Layout may have changed. + \MessageBreak Rerun to get layout correct}% + \else + \PackageWarningNoLine{autobreak}{Layout may be wrong}% + \fi + \fi +} +% \end{macrocode} +% \begin{macro}{\@autobreak@getmaxlhswidth} +% To be expanded to a value saved in |.aux| in the previous run, or +% |0pt| if not found. +% \begin{macrocode} +\def\@autobreak@getmaxlhswidth#1{% + \@ifundefined{@autobreak@w@#1}{% + \z@ + }{% + \@nameuse{@autobreak@w@#1}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@setmaxlhswidth} +% Called in |.aux|. +% \begin{macrocode} +\def\@autobreak@setmaxlhswidth#1#2{% + \global\@namedef{@autobreak@w@#1}{#2}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{@autobreak@eqnindex} +% The counter to identify each \env{align}. +% \begin{macrocode} +\newcounter{@autobreak@eqnindex} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{@autobreak@subeqnindex} +% The counter to store the number of \env{autobreak} in an \env{align}. +% \begin{macrocode} + \newcounter{@autobreak@subeqnindex}[@autobreak@eqnindex]% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@loadmaxlhswidth} +% Loads \cs{@autobreak@maxlhswidth} for the next \env{align}. +% \begin{macrocode} +\def\@autobreak@loadmaxlhswidth{% + \stepcounter{@autobreak@eqnindex}% + \@autobreak@maxlhswidth=% + \@autobreak@getmaxlhswidth{\arabic{@autobreak@eqnindex}}% + \@autobreak@realmaxlhswidth=\z@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@savemaxlhswidth} +% Saves \cs{@autobreak@realmaxlhswidth} for the next run. +% \begin{macrocode} +\def\@autobreak@savemaxlhswidth{% + \ifnum\arabic{@autobreak@subeqnindex}>0 + \ifdim\@autobreak@maxlhswidth=\@autobreak@realmaxlhswidth + \else +% \end{macrocode} +% We have used the wrong value of \cs{@autobreak@maxlhswidth} (was too +% much). Need to rerun. +% \begin{macrocode} + \global\@autobreak@invalidlayouttrue + \fi +% \end{macrocode} +% Note that \cs{@autobreak@maxlhswidth} becomes problematic only when +% two or more \env{autobreak} appear in one \env{align}. In the case +% with one \env{autobreak}, the default value |0pt| is safe for the next +% run. +% \begin{macrocode} + \ifnum\arabic{@autobreak@subeqnindex}>1 + \if@filesw +% \end{macrocode} +% We should provide \cs{@autobreak@setmaxlhswidth} in |.aux|. +% \begin{macrocode} + \@ifundefined{@autobreak@auxinited}{% + \immediate\write\@mainaux{% + \string\providecommand + \string\@autobreak@setmaxlhswidth[2]{}% + }% + \gdef\@autobreak@auxinited{}% + }{}% + \immediate\write\@auxout{% + \string\@autobreak@setmaxlhswidth% + {\arabic{@autobreak@eqnindex}}% + {\the\@autobreak@realmaxlhswidth}% + }% + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Hacking \pkg{amsmath}} +% +% \begin{macrocode} +\RequirePackage{amsmath} +% \end{macrocode} +% +% \begin{macro}{\if@autobreak@newlinedef} +% The switch to be turned on when \cs{@autobreak@newlinedef} applies. +% \begin{macrocode} +\newif\if@autobreak@newlinedef +\@autobreak@newlinedeffalse +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@newlinedef} +% Installs the definition of |^^M| as a space. This is virtually +% harmless in math mode. +% \begin{macrocode} +\begingroup + \catcode`\^^M=\active + \gdef\@autobreak@newlinedef{% + \def^^M{ }% + \@autobreak@newlinedeftrue + } +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\collect@body} +% We need to override \cs{collect@body} such that it keeps |^^M|. +% \begin{macrocode} +\def\collect@body#1{% + \@envbody={\expandafter#1\expandafter{\the\@envbody}}% + \edef\process@envbody{% + \the\@envbody\noexpand\end{\@currenvir}% + }% + \@envbody=\@emptytoks + \def\begin@stack{b}% + \begingroup +% \end{macrocode} +% Actually, the following three lines need to be inserted to the +% original code. +% \begin{macrocode} + \if@autobreak@newlinedef + \catcode`\^^M=\active + \fi + \expandafter\let\csname\@currenvir\endcsname=\collect@@body + \edef\process@envbody{% + \expandafter\noexpand\csname\@currenvir\endcsname + }% + \process@envbody +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{align} +% Hack \env{align} of \pkg{amsmath}. +% \begin{macrocode} +\let\@autobreak@oldstart@align=\start@align +\def\start@align{% + \@autobreak@loadmaxlhswidth + \@autobreak@newlinedef + \@autobreak@oldstart@align +} +% \end{macrocode} +% \begin{macrocode} +\let\@autobreak@oldendalign=\endalign +\def\endalign{% + \@autobreak@savemaxlhswidth + \@autobreak@oldendalign +} +% \end{macrocode} +% \end{environment} +% +% \subsection{\env{autobreak} environment} +% +% \begin{environment}{autobreak} +% Checks if we are in \env{align} (and \cs{@autobreak@newlinedef} is +% applied), increments the counter and collects its body via +% \cs{collect@body}. +% \begin{macrocode} +\newenvironment{autobreak}{% + \if@autobreak@newlinedef + \else + \PackageError{autobreak}{% + autobreak is not allowed here + }{% + Use autobreak inside align. + }% + \fi + \stepcounter{@autobreak@subeqnindex}% + \collect@body\@autobreak +}{} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\@autobreak} +% Called from \cs{collect@body}. The parameter |#1| is the whole body. +% It takes also |#2| and |#3|, which are always \cs{end} and +% |autobreak|, to remove them from the successive tokens. +% \begin{macrocode} +\def\@autobreak#1#2#3{% +% \end{macrocode} +% First, close the group of \env{autobreak}. +% \begin{macrocode} + \end{autobreak}% +% \end{macrocode} +% Then parse the given body of the environment and construct lines to be +% passed to \env{align}. +% \begin{macrocode} + \@autobreak@init + \def\@tempa{\expandafter\@autobreak@scanline + \@autobreak@newlinechar#1}% + \expandafter\@tempa\@autobreak@newlinechar\@autobreak@end +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@init} +% Initialization. +% \begin{macrocode} +\def\@autobreak@init{% + \@autobreak@alltoks={}% + \@autobreak@linetoks={}% + \@autobreak@lhswidth=\z@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@end} +% Finalization. It generates the whole lines in one go. +% \begin{macrocode} +\def\@autobreak@end{% + \expandafter\@autobreak@addtoks\expandafter\@autobreak@alltoks + \expandafter{\the\@autobreak@linetoks}% + \the\@autobreak@alltoks +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@scanline} +% Takes a line from the input stream. Here a line ends with |^^M|. +% \begin{macrocode} +\begingroup + \catcode`\^^M=\active + \gdef\@autobreak@scanline#1^^M{\@autobreak@scanline@{#1}} +\endgroup +% \end{macrocode} +% If the next token is a punctuation, then we merge it into the current +% line. (Otherwise it can make a line only with a period, for example). +% \begin{macrocode} +\def\@autobreak@scanline@#1{% + \@autobreak@ifnextpunct{% + \@autobreak@scanline@gobble{#1}% + }{% + \@autobreak@scanline@@{#1}% + }% +} +% \end{macrocode} +% A helper macro of \cs{@ifnextpunct}\marg{if-yes}\marg{if-no}. +% \begin{macrocode} +\def\@autobreak@ifnextpunct#1#2{% + \@ifnextchar.{% + #1% + }{% + \@ifnextchar,{% + #1% + }{% + \@ifnextchar;{% + #1% + }{% + \@ifnextchar:{% + #1% + }{% + #2% + }% + }% + }% + }% +} +% \end{macrocode} +% Merge punctuations as possible (usually there is only one period in a +% line, though). +% \begin{macrocode} +\def\@autobreak@scanline@gobble#1#2{% + \@autobreak@ifnextpunct{% + \@autobreak@scanline@gobble{#1#2}% + }{% + \@autobreak@scanline@@{#1#2}% + }% +} +% \end{macrocode} +% Pass the current line to \cs{@autobreak@processline}. Then, repeat +% scanning lines until \cs{@autobreak@end} appears as the next token. +% \begin{macrocode} +\def\@autobreak@scanline@@#1{% + \@autobreak@processline{#1}% + \@ifnextchar\@autobreak@end{}{% + \@autobreak@scanline@@@ + }% +} +% \end{macrocode} +% One may expect \cs{input}\marg{file} in \env{autobreak} is expanded by +% the file content and \env{autobreak} treats new lines in it correctly. +% But it needs more work. Because handling of \cs{input} in the middle +% of the lines is rather involved, for now we support only \cs{input} at +% the beginning of each line (which is what sane people usually do). +% This can be done via the \pkg{catchfile} package. +% \begin{macrocode} +\IfFileExists{catchfile.sty}{ + \RequirePackage{catchfile} + \def\@autobreak@scanline@@@{% + \@ifnextchar\input{% + \@autobreak@scanline@input + }{% + \@autobreak@scanline + }% + } +}{ + \def\@autobreak@scanline@@@{% + \@ifnextchar\input{% + \PackageWarning{autobreak}{% + Cannot handle new lines in a file via \protect\input, + \MessageBreak which requires the catchfile package + }% + }% + \@autobreak@scanline + } +} +% \end{macrocode} +% The argument |#1| is \cs{input} and |#2| is the file name. +% \begin{macrocode} +\def\@autobreak@scanline@input#1#2{% + \CatchFileDef\@tempa{#2}{\catcode`\^^M=\active}% + \expandafter\@autobreak@scanline\@tempa +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@processline} +% Each line from \cs{autobreak@scanline} should be regarded as a `block' +% in the equation. The first block (typically the left-hand side $+$ +% `=') determines the indentation for the successive lines. From the +% second block, try to append the block to the end of the line and +% insert a line break if it does not fit in a line. +% \begin{macrocode} +\def\@autobreak@processline#1{% + \ifdim\@autobreak@lhswidth=\z@ +% \end{macrocode} +% For the first block. The rest of the width for the right-hand sides +% is determined from \cs{linewidth} and \cs{@autobreak@maxlhswidth}. +% \begin{macrocode} + \@autobreak@settowidth\@autobreak@lhswidth{#1}% + \ifdim\@autobreak@lhswidth>\z@ + \ifdim\@autobreak@lhswidth>\@autobreak@maxlhswidth + \ifdim\@autobreak@maxlhswidth>\z@ +% \end{macrocode} +% The previous one used the wrong value of \cs{@autobreak@maxlhswidth} +% (was too short). Need to rerun. +% \begin{macrocode} + \global\@autobreak@invalidlayouttrue + \fi + \global\@autobreak@maxlhswidth=\@autobreak@lhswidth + \fi + \ifdim\@autobreak@lhswidth>\@autobreak@realmaxlhswidth + \global\@autobreak@realmaxlhswidth=\@autobreak@lhswidth + \fi + \@autobreak@maxrhswidth=\linewidth + \advance\@autobreak@maxrhswidth by -\@autobreak@maxlhswidth + \advance\@autobreak@maxrhswidth by -\@autobreak@sp + \@autobreak@alltoks={#1{}&}% + \fi + \else +% \end{macrocode} +% For the rest of the blocks. +% \begin{macrocode} + \@autobreak@settowidth\@autobreak@rhswidth + {\the\@autobreak@linetoks#1\the\everybeforeautobreak}% + \ifdim\@autobreak@rhswidth>\@autobreak@maxrhswidth +% \end{macrocode} +% Adding the next block gives an overfull line. Need a line break. +% \begin{macrocode} + \edef\@tempa{\the\@autobreak@linetoks\the\everybeforeautobreak}% + \expandafter\@autobreak@addtoks\expandafter\@autobreak@alltoks + \expandafter{\@tempa\notag\\&}% + \@autobreak@linetoks=\everyafterautobreak + \fi + \@autobreak@addtoks\@autobreak@linetoks{#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@addtoks} +% Appends |#2| to the token register |#1|. +% \begin{macrocode} +\def\@autobreak@addtoks#1#2{% + #1=\expandafter{\the#1#2}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@autobreak@settowidth} +% Same as \cs{settowidth} but in math mode. We assume \cs{displaystyle}. +% (Anyway \env{align} issues \cs{displaystyle} at the beginning of every +% cell.) +% \begin{macrocode} +\def\@autobreak@settowidth#1#2{% + \settowidth#1{$\displaystyle#2$}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +% +% \end{macrocode} +% \Finale +\endinput diff --git a/Master/texmf-dist/source/latex/autobreak/autobreak.ins b/Master/texmf-dist/source/latex/autobreak/autobreak.ins new file mode 100644 index 00000000000..297a2a52133 --- /dev/null +++ b/Master/texmf-dist/source/latex/autobreak/autobreak.ins @@ -0,0 +1,70 @@ +%% +%% This is file `autobreak.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% autobreak.dtx (with options: `install') +%% +%% This is a generated file. +%% +%% Copyright (C) 2016 by Takahiro Ueda +%% +%% This file may be distributed and/or modified under the conditions of +%% the LaTeX Project Public License, either version 1.3 of this license +%% or (at your option) any later version. 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 +%% version 2005/12/01 or later. +%% + +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble + +This is a generated file. + +Copyright (C) 2016 by Takahiro Ueda + +This file may be distributed and/or modified under the conditions of +the LaTeX Project Public License, either version 1.3 of this license +or (at your option) any later version. 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 +version 2005/12/01 or later. + +\endpreamble + +\generate{ + \usedir{tex/latex/autobreak} + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} + + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* autobreak.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file autobreak.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile + +\endinput +%% +%% End of file `autobreak.ins'. -- cgit v1.2.3