\ProvidesFile{makedoc.doc}[2009/04/16 automatically generated with makedoc.sty] \begin{packagecode} %% Macro package `makedoc.sty' for LaTeX2e, %% copyright (C) 2009 Uwe L\"uck, %% http://www.contact-ednotes.sty.de.vu %% -- author-maintained in the sense of LPPL below -- %% for preparing documentations from packages. \def\fileversion{0.2} \def\filedate{2009/04/13} %% This file can be redistributed and/or modified under %% the terms of the LaTeX Project Public License; either %% version 1.3a of the License, or any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% We did our best to help you, but there is NO WARRANTY. %% %% Please report bugs, problems, and suggestions via %% %% http://www.contact-ednotes.sty.de.vu %% \NeedsTeXFormat{LaTeX2e}[1994/12/01] % 1994/12/01: \newcommand* etc. \ProvidesPackage{makedoc}[\filedate\space v\fileversion\space TeX input from *.sty (UL)] \end{packagecode} |\PackageCodeTrue| and |\PackageCodeFalse| set `\ifPackageCode' globally, so redefinition of `~' may be kept local. Note the capital `T' and `F'! \begin{packagecode} \newcommand*{\PackageCodeTrue} {\global\let\ifPackageCode\iftrue} \newcommand*{\PackageCodeFalse}{\global\let\ifPackageCode\iffalse} \end{packagecode} |\ifPackageCode| is used to determine whether a listing environment must be `\beg'un or `\end'ed. You may also want to suppress empty code lines, while empty lines should issue a `\par' break in ``comment'' mode. Since `\newif' is not used, `\ifPackageCode' must be declared explicitly. Declaration of new `\if's must be early in case they occur in code that is skipped by another `\if'\dots \begin{packagecode} \PackageCodeFalse \end{packagecode} 'makedoc' is an extension of 'fifinddo' on which it depends. \begin{packagecode} \RequirePackage{fifinddo}[2009/04/13] \end{packagecode} Both 'fifinddo' and 'makedoc' use the ``underscore'' as ``private letter'' and make it ``other'' at their end (functionality as with ``at'' and `\RequirePackage' is missing here). So after loading 'fifinddo', I must restore the new private letter. \begin{packagecode} \catcode`\_=11 %% underscore used in control words \end{packagecode} \subsection{&\MakeDocCorrectHook} |\MakeDocCorrectHook| is predefined to leave its argument without the enclosing braces, otherwise unchanged: \begin{packagecode} \let\MakeDocCorrectHook\@firstofone \end{packagecode} Less efficiently, the same could have been set up as \begin{packagecode} % \newcommand*{\MakeDocCorrectHook}[1]{\ProcessStringWith{#1}{LEAVE}} \end{packagecode} according to 'fifinddo'. It may be \emph{redefined} in a \emph{configuration} file like 'makedoc.cfg' or the 'makedoc' script file applying to a single package file in order to, e.g., converting plain text to \TeX\ input conforming to typographical conventions, making `$\dots$' from `$\dots$', e.g. Replace `LEAVE' in the previous suggestion by an identifier whose job you have defined before, and use `\renewcommand' in place of `\newcommand'. See an example in 'makedoc.cfg'. You can \emph{test} your own `\MakeDocCorrectHook' by \[`\typeout{\MakeDocCorrectHook{}}'\] $\dots$ provided (sometimes) `\MakeOther\ ' $\dots$ You can even change it using `\IfInputLine' from 'fifinddo' in the midst of preprocessing a package documentation. \subsection{Distinguish package code from comments}%% <- wiki style breaks in self-doc. Use of comment marks is a matter of personal style. Only lines starting with the sequence `%% ' are typeset in \TeX\ quality under the present release. Lines just containing `%%' (without the space) are used to suppress empty code lines preceding section titles (while keeping some visual space in the package file). There is a preferable way to do this, however not in the present release \dots The parsing macros must be set up reading `%' and ` ' as ``other'' characters. Using the optional arguments for this creates difficulties that can be somewhat avoided by redefining |\PatternCodes|. \begin{packagecode} \renewcommand*{\PatternCodes}{\MakeOther\%\MakeOther\ }%% 2009/04/02 \end{packagecode} Look here: the line became too long and could not be broken. Must we really introduce new comment marks? \begin{packagecode} % \MakeSetupSubstringCondition{comment}[\MakeOther\%\MakeOther\ ] \end{packagecode} The next line sets the ``sandbox'' for the detecting macro, as it is coined in the documentation of 'fifinddo', with ``identifier'' |PPScomment|. \begin{packagecode} \MakeSetupSubstringCondition{PPScomment}{%% }{{#1}} \end{packagecode} The last argument stores the expanded input line for reference by macros called. The next line is a test whether the setup works. \begin{packagecode} % \expandafter \show \csname \setup_substr_cond PPScomment\endcsname \end{packagecode} Here comes the definition of the corresponding testing macro. #3 is the expanded input line from above. The `\If'\dots commands, `\fdInputLine', `\fdInputLine', and `\RemoveDummyPatternArg' are from 'fifinddo'. \begin{packagecode} % \MakeSubstringConditional{comment}[\MakeOther\%\MakeOther\ ] \MakeSubstringConditional{PPScomment}{%% }#3{%% #3 entire test string \IfFDinputEmpty{\OnEmptyInputLine}{% \end{packagecode} The empty line test comes early to offer control with `\OnEmptyInputLine' both code and comment mode. Maybe it should always? %% TODO 2009/04/13 \begin{packagecode} \IfFDempty{#1}%% {\TreatAsComment{% \RemoveDummyPatternArg\MakeDocCorrectHook{#2}}}% {\ifx\fdInputLine\PPstring \ifPackageCode\else \WriteResult{}\fi%% 2009/04/05 %% <- allow paragraphs in comments \else \TreatAsCode{#3}\fi}}} % \expandafter \show \csname \substr_cond PPScomment\endcsname \end{packagecode} |\PPstring| stores the line suppressing empty code lines. \begin{packagecode} \newcommand*{\PPstring}{} \xdef\PPstring{\PercentChar\PercentChar} \end{packagecode} |comment| will be a ``generic'' identifier to call a comment line detector. It might be predefined to issue an ``undifined'' error; however this release predefines it to behave like `PPScomment'. \begin{packagecode} \CopyFDconditionFromTo{PPScomment}{comment} \end{packagecode} Alternative still to be considered: \begin{packagecode} % \@namedef{\setup_substr_cond comment}{% % \PackageError{makedoc}{Job `comment' not defined}% % {Use \string\CopyFDconditionFromTo{comment}}} \end{packagecode} \subsection{Dealing with comments} |\TreatAsComment{}| writes to the documentation file. If we had ``package code'' (were in ``code mode'') so far, the listing environment is ended first. \begin{packagecode} \newcommand*{\TreatAsComment}[1]{% \ifPackageCode \WriteResult{\string\end{packagecode\@empty}}% \end{packagecode} The `\@empty' here is a lazy trick to save self-documentation fighting 'verbatim''s ``highlight'' of finding ends of listings (to be improved). %% We always use `\string' to prevent macro expansion in `\write'ing in place of \LaTeX's `\protect', as long as 'fifinddo' simply uses the primitive `\write' in place of \LaTeX's `\proteced@write' \dots %% todo 2009/04/08 \begin{packagecode} \PackageCodeFalse \EveryComment % \_empty_code_lines_false \fi \WriteResult{#1}} \end{packagecode} Here, |\EveryComment| is a macro hook for inserting material that should not appear in a listing environment. \begin{packagecode} \global\let\EveryComment\relax %% should be changed globally. \end{packagecode} \subsection{Sectioning} \label{sec:secparsers} We provide a facility from 'wiki.sty' that imitates the sectioning syntax used in editing \emph{Wikipedia} pages, in a different implementation (better compatibility) and in a more general way. On Wikipedia, `== Definition ==' works similar as `\section{Definition}' does with \LaTeX. With the present implementation, you can type, e.g., \[`%%%%%%%%%%%%%%%%%%%%%% == Definition == %%%%%%%%%%%%%%%%%%%%%%'\] to get a similar result. The number of `%' characters doesn't matter, and there can be other stuff, however: additional `=' symbols may harm. Three sectioning levels are supported, through `====', `======', and `========' (deepest). There are three detector macros made for programmers. The most general one is In the following definitions, there is a single tilde to prevent `=' symbols being gobbled by the test (realized by accident). %% 2009/04/13 |\SectionLevelThreeParseInput|: \begin{packagecode} \newcommand*{\SectionLevelThreeParseInput}{% \expandafter \test_sec_level_iii \fdInputLine ~========&} \end{packagecode} |\SectionLevelTwoParseInput| \begin{packagecode} \newcommand*{\SectionLevelTwoParseInput}{% \expandafter \test_sec_level_ii \fdInputLine ~======&} \end{packagecode} and |\SectionLevelOneParseInput| \begin{packagecode} \newcommand*{\SectionLevelOneParseInput}{% \expandafter \test_sec_level_i \fdInputLine ~====&} \end{packagecode} allow skipping deeper levels for efficiency. % TODO in fifinddo: setup for 2 strings in 1 line 2009/04/13 In the terminology of the 'fifinddo' documentation, the previous three commands are ``sandbox builders.'' The following three commands are the corresponding ``substring conditionals.'' However, 'fifinddo' so far %% todo 2009/04/08 only deals with \emph{single} substrings, while here we are dealing with \emph{pairs} of substrings. We are not using general setup macros, but define the parsing macros ``manually,'' as it is typical in many other macros in 'latex.ltx' and other \LaTeX\ packages. You can fool our macros easily, there is no syntax check. %% todo 2009/04/08 \begin{packagecode} \def\test_sec_level_iii#1====#2====#3&{% \IfFDempty{#2}% {\test_sec_level_ii #1======&}% {\WriteSection\mdSectionLevelThree{#2}}} \def\test_sec_level_ii#1===#2===#3&{% \IfFDempty{#2}% {\test_sec_level_i #1====&}% {\WriteSection\mdSectionLevelTwo{#2}}} \def\test_sec_level_i#1==#2==#3&{% \IfFDempty{#2}% {\RemoveTildeArg \ProcessStringWith{#1}{comment}}% {\WriteSection\mdSectionLevelOne{#2}}} \end{packagecode} `\ProcessStringWith' here passes the expanded `\fdInputLine' to the general comment detector. |\WriteSection{}{}| replaces an input line with a line \[`{\hspace{1sp}\ignorespaces \unskip }'\] in the documentation file and switches into ``comment mode.'' `\hspace{1sp}' ensures that 'niceverb''s package name feature works. `\ignorespaces' and `\unskip' undo the spaces between title text and the `=' symbols that usually are typed for readability. \begin{packagecode} \newcommand*{\WriteSection}[2]{% \TreatAsComment{% ^^J#1{\string\hspace{1sp}\ignorespaces \MakeDocCorrectHook{#2}\unskip}^^J}} \end{packagecode} We insert `\section' using |\mdSectionLevelOne| etc.\ which the programmer can redefine, e.g., when the documentation is part of a `\section' (or even deeper) according to the ``documentation driver'' file. \begin{packagecode} \newcommand*\mdSectionLevelOne {\string\section} \newcommand*\mdSectionLevelTwo {\string\subsection} \newcommand*\mdSectionLevelThree{\string\subsubsection} \end{packagecode} This sectioning feature is not used in 'makedoc.sty' since the \emph{definitions} of the parsing macros fool the same macros \dots \subsection{Commented code} |\TreatAsCode{}| is the opposite to `\TreatAsComment{}': \begin{packagecode} \newcommand*{\TreatAsCode}[1]{% \ifPackageCode % \_empty_code_lines_true \else \WriteResult{\string\begin{packagecode}}% \PackageCodeTrue \fi \WriteResult{#1}% % \WriteResult{\maybe_result_empty_line #1}% % \let\maybe_result_empty_line\empty } \end{packagecode} \subsection{Dealing with empty input lines} |\OnEmptyInputLine| is a default setting (or hook) for what to do with empty lines in the input file. The default is to insert an empty line in the output file: \begin{packagecode} \newcommand*{\OnEmptyInputLine}{\WriteResult{}} \end{packagecode} |\NoEmptyCodeLines| changes the setting to suppressing empty code lines, while in ``comment mode'' an empty input line \emph{does} insert an empty line, for starting a new paragraph: \begin{packagecode} \newcommand*{\NoEmptyCodeLines}{%% suppress empty code lines \renewcommand*{\OnEmptyInputLine}{% \ifPackageCode \else \WriteResult{}\fi}} \end{packagecode} There is a better policy---didn't work so far \dots \subsection{Bundling typical things: script commands} \label{sec:script} First practical experiences suggest the following shorthands. They should simplify matters so much that the 'makedoc' script for a single package really should need about five lines only, %% <- TODO check 2009/04/08 and even \emph{they} should be so simple that you should hardly spend a minute about them. |\LaTeXresultFile{}| saves you the extra line for inserting the `\ProvidesFile' line $\dots$ no, actually it is 'makedoc' that wants to be mentioned with `\ProvidesFile' $\dots$ (otherwise copied from 'fifinddo') \dots \begin{packagecode} \newcommand*{\LaTeXresultFile}[1]{% \ResultFile{#1}%%% \WriteProvides} \WriteResult{% \string\ProvidesFile{\result_file_name}% [\the\year/\two@digits\month/\two@digits\day\space automatically generated with makedoc.sty]}}% \end{packagecode} |\MakeDoc{}| preprocesses to render input for \LaTeX, considering what is typical for a \LaTeX\ package as the one here: \begin{packagecode} \newcommand*{\MakeDoc}[1]{% \end{packagecode} In case of a ``header'' (see below) we change into ``code mode'': \begin{packagecode} \ifnum\header_lines>\z@ \WriteResult{\string\begin{packagecode}}% \PackageCodeTrue %% TODO both lines makedoc command!? %% 2009/04/08 \else \PackageCodeFalse \fi \end{packagecode} The loop follows. There is a placeholder `\makd_doc_line_body' that is predefined below and can be changed while processing the file. \begin{packagecode} \ProcessFileWith{#1}{% \CountInputLines %% stepping line counter is standard \make_doc_line_body \process_line_message}% \end{packagecode} Currently the ``VERSION HISTORY'' is typeset verbatim (for ``tabbing''), we then must leave ``code mode'' here: \begin{packagecode} \ifPackageCode \WriteResult{\string\end{packagecode\@empty}}%% self-doc-trick \PackageCodeFalse %% TODO both lines makedoc command!? 2009/04/08 \fi \end{packagecode} When the file has been processed, certain default settings might be restored---in case another file is processed for the same documentation document: \begin{packagecode} % \HeaderLines{0}% % \MainDocParser{\SectionLevelThreeParseInput}%% TODO!? 2009/04/08 } \end{packagecode} \subsubsection{File preamble} A \LaTeX\ package typically has a ``header'' or ``preamble'' (automatically inserted by 'docstrip') with very scarce information on which file it is and what it provides, and with much more Legalese. Typesetting it in \TeX\ quality may be more misleading than typesetting it \emph{verbatim}. So we typeset it \emph{verbatim}. Now: where does the ``header'' end? `\NeedsTeXFormat' might be considered the border.---Yet it seems to be more simple and reliable just to act in terms of the \emph{number of lines} that the header should be long. This length is declared by |\HeaderLines{}|: \begin{packagecode} \newcommand*{\HeaderLines}{\def\header_lines} \HeaderLines{0} \end{packagecode} So the default is that there aren't any header lines, unless another `\HeaderLines' is issued before some `\MakeDoc'. The way input is parsed after the ``header'' is set by |\MainDocParser{}|. \begin{packagecode} \newcommand*{\MainDocParser}{\def\main_doc_parser} \end{packagecode} `\SectionLevelThreeParseInput' from section~\ref{sec:secparsers} is the default, two alternatives are defined there, another one is `\ProcessInputWith{comment}' from 'fifinddo'. \begin{packagecode} \MainDocParser{\SectionLevelThreeParseInput} \end{packagecode} Here is how `\HeaderLines' and `\MainDocParser' act: \begin{packagecode} \def\make_doc_line_body{% \IfInputLine{>\header_lines}% {\let\make_doc_line_body\main_doc_parser \make_doc_line_body}% %% switch to deciding {\TreatAsCode{\fdInputLine}}} %% header verbatim \end{packagecode} |\ProcessLineMessage{}| is designed to define a screen (or log) message . % A simple setting may be \[`\ProcessLineMessage{\message{.}}'\] with `\ProcessLineMessage{\message{.}}' has a result like with 'docstrip'. You just get one dot on screen per input line as a simple confirmation that the program is not hung up. %% TODO phrase!? 2009/04/08 However, the message may slow down a run considerably (if so, choose `\ProcessLineMessage{}' in the script). % , you really have to % wait about a second while you hardly notice the 'makedoc' run % without screen messages. Therefore, the default is \emph{not} % to issue any screen message.%% TODO more complex procedures!? 2009/04/08 %---No! But it is better for beginner users of the package, so made default. %% 2009/04/09 \begin{packagecode} \newcommand*{\ProcessLineMessage}{\def\process_line_message} % % \ProcessLineMessage{} %% no, still more efficient: % \let\process_line_message\relax \ProcessLineMessage{\message{.}} \end{packagecode} \subsection{Leave the package} \begin{packagecode} \catcode`\_=8 %% restores underscore use for subscripts \endinput \end{packagecode} \subsection{VERSION HISTORY} \begin{packagecode} v0.1 2009/04/03 very first version, tested on morgan.sty v0.2 2009/04/05 \OnEmptyInputLine, \NoEmptyCodeLines comment -> PPScomment, \IfFDinputEmpty, \EveryComment, \PPstring may be par break 2009/04/08 \InputString -> \fdInputLine, \section -> \subsection; documentation! 2009/04/08f. \MakeDoc 2009/04/12 ``line too long'' w/o redefining \PatternCodes; \MakeDocCorrectHook 2009/04/13 tilde with sectioning \end{packagecode}