\NeedsTeXFormat{LaTeX2e}[1994/12/01] %% \newcommand* etc. \ProvidesPackage{blogexec}[2012/12/20 v0.21 assignments with blog.sty (UL)] %% copyright (C) 2011 Uwe Lueck, %% http://www.contact-ednotes.sty.de.vu %% -- author-maintained in the sense of LPPL below. %% %% This file can be redistributed and/or modified under %% the terms of the LaTeX Project Public License; either %% version 1.3c 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 %% %% == Requirements == %% The \ctanpkgref{dowith} package is needed for managing %% and running lists of macros to be intercepted: \RequirePackage{dowith} %% Admittedly, `\do' and `\@elt' lists (as discussed in `dowith.pdf') %% would be faster than the 'dowith' method, which might be relevant %% here (TODO: how much?). I may abandon 'dowith' later, I just cannot %% afford removing it now (2011/11/05, TODO). %% %% == Processing Source Files == %% With |\BlogInterceptExtra|, 'blog.sty' %% deals with \emph{empty} input lines just like %% \[`\BlogCopyFile[]{}'\] %% does; \emph{otherwise} the content of `\fdInputLine' is copied to %% |\fdOutputCode|. Before the latter is writen to the output file %% (as determined by a recent `\ResultFile{}'), %% |\BlogInterceptions| is run, its purpose is to extract assignment and other %% ``execution" commands and to turn `\fdOutputCode' into an %% expandable macro. We use `\def' because 'blog.sty' may have %% provided a preliminary definition earlier: \def\blog@icl@xtra{% \let\BlogProcessLine\BlogAllowIntercepting \let\BlogInterceptions\AllBlogInterceptions} \def\BlogInterceptExtra{\@ifstar@intercept@hash\blog@icl@xtra} \def\@ifstar@intercept@hash#1{\@ifstar{#1\BlogInterceptHash}#1} %% And this is the default setting (TODO!?): \BlogInterceptExtra %% Below, there are commands for restricted (faster---TODO: relevant? %% or less complex, to reduce danger) %% interception functionality. (Maybe the file should be restructured.) %% |\AllBlogInterceptions| first is nothing: \InitializeListMacro\AllBlogInterceptions %% ---and should become more below. %% %% |\BlogAllowIntercepting| stores the difference to 'blog.sty': \newcommand*{\BlogAllowIntercepting}{% \let\fdOutputCode\fdInputLine \BlogInterceptions %% When, after removing the intercepted command, the line is %% empty, it is \emph{not} written into output: \ifx\fdOutputCode\@empty \else \WriteResult{% \ProcessExpandedWith\fdOutputCode\BlogOutputJob}% %% ... enabling ``ligatures" with 'blog.sty' v0.7. %% 2011/11/21 \fi} %% ... TODO: in 'fifinddo' with something like `\fdInterceptions'? %% %% Especially for storing file-specific macro definitions %% with `\EXECUTE' (below), a parameter character %% (usually hash mark) is needed. %% %% mod. 2011/11/20: %% 'fifinddo.sty' (so far---2011/11/20) %% does not include it with `\BasicNormalCatCodes', %% and 'blog.sty' %% does not include it with `\BlogCodes' %% ---the following |\BlogInterceptHash| does. %% Moreover, |\MakeHashParameter| enables such definitions %% when placed in a source file within the argument of a %% separate(!) `\EXECUTE'. \providecommand*{\MakeHashParameter}{\catcode`\#6 } \def\BlogInterceptHash{% \ToListMacroAdd\BlogCodes\MakeHashParameter \MakeHashParameter} %% TODO: default? 0-arg interception? %% %% == Intercepting Single-Parameter Commands == %% === The General Method === %% Macros to be intercepted that have a single argument will be %% collected in |\blogOneArgInterceptions|: \InitializeListMacro\blogOneArgInterceptions \ToListMacroAdd\AllBlogInterceptions{% \DoWithAllIn\blogTryOneArgCmd \blogOneArgInterceptions} %% Here |\blogTryOneArgCmd{}| creates a ``sandbox" for parsing %% in a similar way as 'fifinddo' does it, searching for . %% The method there was made thinking of reading files with %% ``plain text" category codes, not aware of 'blog.sty'. %% Maybe this was a mistake, and I will reconsider it. %% There I also introduce a separate sandbox macro %% for each search pattern, thinking of different types of sandboxes. %% This is not done/needed here (strangely, TODO).---The sandbox %% starts with the parsing macro. The latter's name derives from %% by prefixing something to its name. %% |\StripEsc| is a little helper for removing the backslash %% from a macro name. \providecommand*{\StripEsc}{\expandafter\@gobble\string} %% Name spaces: %% 2012/08/29 \newcommand*{\blog@x}{\StripEsc\blogx} \newcommand*{\blogTryOneArgCmd}[1]{% \csname \blog@x:\StripEsc#1\expandafter\endcsname \fdOutputCode \@gobble#1\@empty\@nil} %% Here, `\@empty' is the dummy argument for ---this is what %% must be modified for with more than one parameter. %% At present (2011/11/05), that tail starting with `\@gobble' %% may stay at the end of `\fdOutputCode' for each interception per %% `\fdInputLine', until it expands to nothing in the `\write'. %% %% |\MakeBlogOneArgInterception{}{}{}| \ \ %% says that when is found in `\fdOutputCode', %% should be executed, and `' should be replaced %% by in `\fdOutputCode' where is the argument for %% found in `\fdOutputCode'. Let be without %% delimiting braces if `' is `{}' %% (otherwise `' is the same as `'). %% Then use `#2' for referring to inside and . %% (Sorry, I cannot afford replacing `#2' by a more natural %% placeholder right now.) \begingroup \catcode`\|\z@ |MakeOther|\% %% \z@ 2011/11/22 |@ifdefinable|MakeBlogOneArgInterception{% |gdef|MakeBlogOneArgInterception#1#2#3{% %% First we add to `\blogOneArgInterceptions', %% unless it is already there: %% 2011/11/07 |TestListMacroForToken|blogOneArgInterceptions#1% |ifin@ |PackageWarning{blogexec}{Redeclaring |string#1.}% |else |ToListMacroAdd|blogOneArgInterceptions#1% |fi %% Now the parsing macro is defined, together with the actions %% depending on the result: %% %% TODO csnames/namemod.sty 2011/11/22 |@namedef{|blog@x:|StripEsc#1}##1#1##2##3|@nil{% %% #3 will be empty if and only if does \emph{not} occur %% in `\fdOutputCode'. A backslash made ``other" will not occur %% in `\fdOutputCode', therefore the following %% `\ifx' becomes true if and only if #3 is empty, i.e., %% does \emph{not} occur in `\fdOutputCode': |ifx\##3\% %% In this case we just do nothing. |else %% Otherwise, we apply and : #2% |def|fdOutputCode{##1#3##3}% |fi}% }% }% |endgroup %% %% was single `%' 2011/11/20 %% === &\EXECUTE === %% |\EXECUTE{}| runs and is removed from the %% output line: \MakeBlogOneArgInterception\EXECUTE{#2}{} %% You can \strong{store settings} for processing a source %% file in this file by `\EXECUTE{}' %% (e.g., shorthand macros only useful in this single file). %% You even can switch off the interception functionality %% after running the other settings %% by `\EXECUTE{\BlogCopyLines}'. %% %% `\EXECUTE{}' may be a great relief thinking of pure %% expansion with 'blog.sty'. You may be happy enough with it %% and \emph{restrict} the interception functionality to `\EXECUTE' %% by |\BlogInterceptExecute|. Its definition may be a %% redefinition of the preliminary macro in 'blog.sty'. %% (TODO: option for stopping here, avoid 'dowith'.) \def\blog@icl@exec{% \let\BlogProcessLine\BlogAllowIntercepting \def\BlogInterceptions{\blogTryOneArgCmd\EXECUTE}} \def\BlogInterceptExecute{\@ifstar@intercept@hash\blog@icl@exec} %% %% === &\begin\ and &\end === %% At present (2011/11/06), only |\begin{}| will run %% box 2012/08/28 %% settings. Macros `\' and `\end' will expand %% in the `.html' as with 'blog.sty' alone, not touched here. %% Settings to be \emph{run} must be stored in a macro %% `\blogx.b:'. If this has not been done, only `\relax' %% (from `\csname') will be ``run." \MakeBlogOneArgInterception\begin{% %% Indeed, we have a ``modified selection" from \LaTeX's original `\begin': \@ifundefined{#2}% {\def\@tempa{\@latex@error{Environment #2 undefined}\@eha}}% {\def\@tempa{\def\@currenvir{#2}% % \edef\@currenvline{\on@line}% %% not in source \csname \blog@x.b:#2\endcsname}}% %% \StripEsc->: 2012/08/28 \begingroup \@tempa}{% \csname #2\endcsname} %% % %% TODO single token!? %% rm. 2011/12/15 %% \[|\MakeBlogBeginRun{}{}|\] resembles %% \[`\newenvironment*{}{}{}'\] except that %% it does not have `{}': \newcommand*{\MakeBlogBeginRun}{\@makeblogbeginrun\newcommand} %% v0.2 allows redefinition by %% \[|\ChangeBlogBeginRun{}{}|\] \newcommand*{\@makeblogbeginrun}[2]{% \expandafter #1\expandafter *% \csname \blog@x.b:#2\endcsname} %% \StripEsc->: 2012/08/28 \newcommand*{\ChangeBlogBeginRun}{\@makeblogbeginrun\renewcommand} %% Moreover, v0.2 allows copying that action by %% \[|\CopyBlogBeginRunTo{}{}|\] \newcommand*{\CopyBlogBeginRunTo}[2]{% \withcsname \let \blog@x.b:#2\expandafter\endcsname \csname \blog@x.b:#1\endcsname} %% |\end{}|: \MakeBlogOneArgInterception\end{\@checkend{#2}\endgroup}{\end{#2}} % \expandafter\show\csname blogx:end\endcsname %% \[|\BlogInterceptEnvironments|\] restricts interception functionality %% to `\EXECUTE', `\begin', and `\end': \def\blog@icl@envs{% \BlogInterceptExecute \ToListMacroAdd\BlogInterceptions{% \blogTryOneArgCmd\begin\blogTryOneArgCmd\end}} \def\BlogInterceptEnvironments{\@ifstar@intercept@hash\blog@icl@envs} %% TODO: \ 1.~imitate \LaTeX's toggling with `\emph' %% (redefine it in italic environments) %% \ 2.~code indenting (cf.~\ctanpkgref{inputtrc}) %% %% === Skipping Source Code === %% The |{noblog}| environment ``suppresses" \TeX~source %% code in the sense that it does not produce \HTML~code---while %% 'blog.sty''s `{commentlines}' produces an \HTML~comment. \newenvironment*{noblog}{}{} %% 2012/03/04 from ... \MakeBlogBeginRun{noblog}{% \BlogInterceptEnvironments %% 2012/06/22 \let\WriteResult\@gobble} %% %% === A Comfortable Table Environment === %% As an application of |\MakeBlogBeginRun| for 'blog.sty''s %% |{stdallrulestable}|, we provide \lq`|'\rq\ as an active character %% invoking 'blog.sty''s `\endcell' (move to next cell) %% was \cr 2011/11/10 %% and an active character \lq`&'\rq\ for `\figurespace', %% i.e., a Unicode symbol for aligning figures. %% Indeed, we are \emph{not} going back to \LaTeX\ and Plain \TeX\ %% by using `&' for moving to the next cell, I consider the present %% choice more intuitive. \MakeBlogBeginRun{stdallrulestable}{% \MakeActiveDef\|{\endcell}\MakeActiveDef\&{\figurespace}} %% I hope nobody will confuse `&' and `8'. A little drawback may be %% that you now can't use `&' for inserting \acro{HTML} entities. %% However, recall that these settings are restricted to the %% `{stdrulestable}' environment, and that you can use %% `\MakeBlogBeginRun{stdallrulestable}' again for your own choice %% of shorthands. %% (TODO: `\MakeActiveLet') %% %% %% == Intercepting Two-Parameter Macros == %% Here especially I have a macro %% |\labelsection{