Skip to content

Commit

Permalink
Doc examples: compile through the makefile.
Browse files Browse the repository at this point in the history
Previously, the compilation of individual examples was triggered by compilation
of the documentation.  This was cumbersome, and required shell escape mode.

Changes:
* The compilation is triggered through the Makefile in the examples folder.
  All targets are listed explicitly, and the number of compilations needed to
  produce an example is specified.
* The resulting files are preprocessed where needed (no more `\sed`ding and
  inputting `.mmz` files during compilation).
* In the document source, \ExampleName is abolished and \tcbinputexample has
  simpler argument structure.
* Centralized extraction of excerpts.
  • Loading branch information
sasozivanovic committed Oct 23, 2024
1 parent b82a3e9 commit e879ea4
Show file tree
Hide file tree
Showing 12 changed files with 395 additions and 533 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ include Makefile.runtimes

VERSION-MAN = of Memoize v$(VERSION)

.PHONY: all-runtimes link-all-runtimes unlink-all-runtimes test
.PHONY: all-runtimes link-all-runtimes unlink-all-runtimes test examples

all-runtimes: runtimes
$(MAKE) -f Makefile.advice runtimes
Expand All @@ -161,3 +161,6 @@ unlink-all-runtimes: unlink-runtimes

test:
cd testing && ./MakeTests.py

examples:
$(MAKE) -C doc/examples
2 changes: 1 addition & 1 deletion advice.edtx
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@
% did not set it, or has reset it by writing |args| without a value), it is
% assumed that the handled command was defined by |xparse| and |\AdviceArgs|
% will be retrieved by |\GetDocumentCommandArgSpec|.
% \begin{listingregion}{_advice-CollectArgumentsRaw.tex}
% \begin{listingregion}{_advice-CollectArgumentsRaw}
\def\advice@CollectArgumentsRaw{%
\AdviceIfArgs{}{%
\expandafter\GetDocumentCommandArgSpec\expandafter{\AdviceName}%
Expand Down
2 changes: 2 additions & 0 deletions doc/examples/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
!ins.end
!memoize.cfg
!*.gitignore
!extract-excerpts.pl
!get-filename-from-mmz.tex
136 changes: 112 additions & 24 deletions doc/examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,36 +1,124 @@
SHELL := /bin/bash
N = 1
.PHONY: clean all excerpts
.SECONDARY:
.DEFAULT_GOAL := all

.PRECIOUS: %.c1

%.ins: ins.begin ins.mid ins.end
sed 's|example|$*|g;' $< > $@
cat ins.begin > $@
for n in {1..$N} ; do sed "s|example|$*|g; s/c1/c$$n/g;" ins.mid >> $@ ; done
cat ins.end >> $@
clean:
find . \( \( -type f -not \( \
-name '*.dtx' -or -name 'ins.*' -or -name .gitignore -or \
-name Makefile -or -name memoize.cfg -or -name extract-excerpts.pl -or \
-name get-filename-from-mmz.tex
\) \) -or \( -type d -name '*.memo.dir' \) \) -print -delete

%.c1: %.dtx %.ins
tex -interaction batchmode $*.ins
sed -i 's/~//g;' $*.c? $*.c?.attachment
echo $@
N = 0

%.pdf: %.tex.c1
cp $*.tex.c1 $*.tex
%.pdf: %.tex
touch $*.mmz ; memoize-clean.py --all --yes $*.mmz
rm -f $*.mmz
latexmk -C $*
for n in {1..$N}; do cp $*.tex.c$$n $*.tex ; pdflatex -interaction batchmode $* ; cp $*.pdf $*.c$$n.pdf ; if [[ -a $*.mmz ]] ; then cp $*.mmz $*.mmz.c$$n ; fi ; done

%.sty: %.sty.c1
cp $*.sty.c$N $@
if [[ $(N) > 0 ]] ; then \
for ((n=1;$$n<=$(N);n++)) ; do \
cp $*.tex.c$$n $*.tex ; \
pdflatex -interaction batchmode $* ; \
cp $*.pdf $*.c$$n.pdf ; \
if [[ -a $*.mmz ]] ; then cp $*.mmz $*.mmz.c$$n ; fi ; \
done ; \
else \
pdflatex -interaction batchmode $* ; \
fi

%.excerpt: $(SOURCE)
if [[ -z '$(SOURCE)' ]] ; then echo Empty SOURCE! ; false ; fi
perl -e '$$f=q{$*}; while(<>) {$$r &&= !/^ *% *\\\Qend{listingregion}/; print if $$r; $$r ||= /^ *% *\\\Qbegin{listingregion}{$$f}/; }' ${SOURCE} > $@
%:: %.dtx
sed 's|example|$*|g;' ins.begin > $*.ins
for ((n=1;$$n<=$(N);n++)) ; \
do sed "s|example|$*|g; s/c1/c$$n/g;" ins.mid >> $*.ins ; \
done
cat ins.end >> $*.ins
tex -interaction batchmode $*.ins
shopt -s nullglob ; sed -i 's/~//g;' $* $*.attachment $*.c? $*.c?.attachment

%.listing.attachment: %.listing
sed 's/~//g;' $< > $@

.PHONY: clean
clean:
find . -type f -not \( -name '*.dtx' -or -name 'ins.*' -or -name .gitignore -or -name Makefile \) -delete
EMPTY :::=
SPACE :::= $(EMPTY) $(EMPTY)
SED_CMD :::= \\\\\([a-zA-Z]\\+\)
SED_CMD_ :::= \\\\[a-zA-Z]\\+
SED_MARG :::= {\([^}]*\)}
SED_MARG_ :::= {[^}]*}

# returns the one and only mandatory argument of the first occurrence of \\$(1) in file $(2)
FIRST_ARG = `grep $(1) $(2) | head -1 | sed 's/$(SED_CMD_) *$(SED_MARG)/\1/'`

# returns the one and only mandatory argument of the second occurrence of \\$(1) in file $(2)
SECOND_ARG = `grep $(1) $(2) | head -2 | tail -1 | sed 's/$(SED_CMD_) *$(SED_MARG)/\1/'`

# returns the one and only mandatory argument of the last occurrence of \\$(1) in file $(2)
LAST_ARG = `grep $(1) $(2) | tail -1 | sed 's/$(SED_CMD_) *$(SED_MARG)/\1/'`

# GET_FILENAME_FROM_MMZ = etex -interaction batchmode '\input{get-filename-from-mmz}\get{$(1)}{$(2)}{$(3)}{$(4)}{$(5)}'
GET_FILENAME_FROM_MMZ = etex '\input{get-filename-from-mmz}\get{$(1)}{$(2)}{$(3)}{$(4)}{$(5)}'

excerpts: memoize.excerpts advice.excerpts collargs.excerpts

%.excerpts: ../../%.edtx
perl extract-excerpts.pl $< && touch $@

TARGETS = memoize-example.cfg disable-bad.tex disable-good.tex disable-nomemoize.tex disable-nommz.tex disable-auto-cmd.tex disable-auto-env.tex book.tex chapters/chapter1.tex memoize-region.cfg titlepage.pdf test.pdf manual.pdf mmztikz.pdf automemoize-environment.pdf automemoize-command.pdf recompile.pdf disable.pdf readonly.pdf meaning-to-context.pdf clean-house.pdf dirty-house.pdf beamer.pdf overlay.pdf verbatim-manual.pdf verbatim-auto.pdf capture.pdf no-linebreaking.pdf sectionbox.tex ref.pdf vref.tex fontsize.pdf skak.pdf redefinitions.pdf progressbar.pdf poormansbox.sty poormansbox.pdf poormansbox-memoizable.sty poormansbox-memoizable.pdf memoize-internal.pdf label.pdf label+.pdf per-overlay-v1.sty salt.pdf record-files.tex record-extern-pages.tex pgfmathparse.pdf pgfmathparse-embellished.pdf countdown.pdf countdown.sty poormansbox-driver.pdf poormansbox-driver.sty _auto-ref.tex chained-advice.tex om-collector-NewDocumentCommand.tex om-collector-newcommand.tex collargs-makebox.tex collargs-minipage.tex collargs-verbatim.tex plainTeX.tex ConTeXt.tex _collargs-verbatim.tex _collargs-ignore-other-tags.tex collargs-processor.tex collargs-expandable-processor.tex collargs-nodelimiters.tex collargs-return-plain.tex collargs-return-no.tex collargs-transition-ok.tex collargs-transition-cs.tex collargs-transition-comment.tex \
titlepage.mmz.c1 titlepage.mmz.c2 titlepage.cmemo titlepage.ccmemo poormansbox-memoizable.cmemo label.ccmemo label+.ccmemo ref.cmemo beamer.cmemo beamer.ccmemo poormansbox-driver.ccmemo pgfmathparse.ccmemo

all: excerpts $(TARGETS)

chained-advice.tex _collargs-ignore-other-tags.tex countdown.sty poormansbox-driver.pdf fontsize.pdf label+.pdf meaning-to-context.pdf memoize-internal.pdf no-linebreaking.pdf progressbar.pdf readonly.pdf titlepage.pdf : N = 2
label.pdf recompile.pdf : N = 3
overlay.pdf : N = 4
label+.tex redefinitions.pdf : N = 6
ref.pdf : N = 7

poormansbox.pdf: poormansbox.sty
poormansbox-memoizable.pdf: poormansbox-memoizable.sty
countdown.pdf: countdown.sty
poormansbox-driver.pdf: poormansbox-driver.sty

titlepage.mmz.c1: titlepage.pdf
sed -i 's/\\mmzNewExtern/~\0~/' $@

titlepage.mmz.c2: titlepage.pdf
sed -i 's/\\mmzUsedExtern/~\0~/' $@

titlepage.cmemo: titlepage.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCMemo,$(basename $<).mmz.c1,mymemo,$@)

titlepage.ccmemo: titlepage.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCCMemo,$(basename $<).mmz.c1,mymemo,$@)
sed 's/\\quitvmode \\mmzIncludeExtern/\\quitvmode\n\\mmzIncludeExtern/; s/\\\mmzStepPgfPictureId/\n\0/' `tail -1 titlepage.ccmemo` > $@.listing

poormansbox-memoizable.cmemo: poormansbox-memoizable.pdf
$(call GET_FILENAME_FROM_MMZ,GetLast,mmzNewCMemo,$(basename $<).mmz,mymemo,$@)
sed 's/]{/]\n {/;' `tail -1 $@` > $@.listing

label.ccmemo: label.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCCMemo,$(basename $<).mmz.c1,mymemo,$@)
sed 's/\\quitvmode \\mmzIncludeExtern/\\quitvmode\n\\mmzIncludeExtern/; s/$(SED_MARG)\\mmzIncludeExtern/{\1}\n\\mmzIncludeExtern/; s/\\mmzLabel *$(SED_MARG)$(SED_MARG)/~\\mmzLabel{\1}{\2}~ /g; s/\\\mmzStepPgfPictureId/\n\0/; ' `tail -1 $@` > $@.listing

label+.ccmemo: label+.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCCMemo,$(basename $<).mmz.c1,mymemo,$@)
sed 's/\\mmzLabel *$(SED_MARG)$(SED_MARG)/~\0~/; s/$(SED_MARG)\\mmzIncludeExtern/\1 \\mmzIncludeExtern/; s/\($(SED_MARG_)$(SED_MARG_)$(SED_MARG_)\)\($(SED_MARG_)$(SED_MARG_)$(SED_MARG_)$(SED_MARG_)\)/\1 \2/;' `tail -1 $@` > $@.listing

ref.cmemo: ref.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCMemo,$(basename $<).mmz.c1,mymemo,$@)
sed 's/\\global.*/~\0~/' `tail -1 $@` > $@.listing

beamer.cmemo: beamer.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCMemo,$(basename $<).mmz,mymemo,$@)
sed 's/\\mmzSetBeamerOverlays $(SED_MARG)$(SED_MARG)/~\0~/' `tail -1 $@` > $@.listing

beamer.ccmemo: beamer.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCCMemo,$(basename $<).mmz,mymemo,$@)
sed 's/overlay=[0-9]*/~\0~/; s/pauses=[0-9]*/~\0~/; s/}\\mmzIncludeExtern/}\n\\mmzIncludeExtern/; s/\\\mmzStepPgfPictureId/\n\0/; ' `tail -1 $@` > $@.listing

poormansbox-driver.ccmemo: poormansbox-driver.pdf
$(call GET_FILENAME_FROM_MMZ,GetSecond,mmzNewCCMemo,$(basename $<).mmz.c1,mymemo,$@)
sed 's/\\csuse *{poormansbox@outer}/~\0~/; s/{\\mmzIncludeExtern.*}}/~\0~/' `tail -1 $@` > $@.listing

pgfmathparse.ccmemo: pgfmathparse.pdf
$(call GET_FILENAME_FROM_MMZ,GetFirst,mmzNewCCMemo,$(basename $<).mmz,mymemo,$@)
28 changes: 28 additions & 0 deletions doc/examples/extract-excerpts.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
while (<>) {
if ($in_listing) {
if (/^ *% *\\end\{listingregion\}/) {
# print the collected lines, automatically deindented
$indent = -1;
for my $line (@lines) {
$line =~ /^ */;
$current_indent = length($&);
$indent = -1 ? $current_indent : min($indent, $current_indent);
}
for $line (@lines) {
print LISTING substr($line, $indent);
}
# close the excerpt file
close LISTING;
$in_listing = 0;
} else {
# append to the list
push(@lines, $_);
}
} elsif (/^ *% *\\begin\{listingregion\}\{([^}]*)\}/) {
# upon encountering " % \begin{listingregion}{<filename>}",
# open the excerpt file, initialize the excerpt list
open LISTING, ">$1.excerpt";
$in_listing = 1;
@lines = ();
}
}
42 changes: 42 additions & 0 deletions doc/examples/get-filename-from-mmz.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
% execute with etex

\def\mmzPrefix#1{}
\def\mmzNewCMemo#1{}
\def\mmzNewCCMemo#1{}
\def\mmzNewExtern#1#2#3#4{}%
\def\mmzUsedCMemo#1{}
\def\mmzUsedCCMemo#1{}
\def\mmzUsedExtern#1{}

\def\GetFirst#1{%
\def\filename{#1}%
\endinput
}
\def\GetSecond#1{%
\def\GetSecond##1{%
\def\filename{##1}%
\endinput
}%
}
\def\GetLast#1{%
\def\filename{#1}%
}

% #1 = GetFirst | GetSecond | GetLast
% #2 = mmzNewCMemo | mmzNewCCMemo | ... (mmzNewExtern is not supported)
% #3 = from <filename.mmz>
% #4 = store into this cs (in TeX output)
% #5 = into thi filename (plus .tex for TeX output)
\def\get#1#2#3#4#5{%
\expandafter\edef\csname#2\endcsname{%
\unexpanded\expandafter{\csname#1\endcsname}%
}%
\input{#3}%
\immediate\openout0{#5}%
\immediate\immediate\write0{%
\noexpand\def\unexpanded\expandafter{\csname#4\endcsname}{\filename}}%
\immediate\immediate\write0{\noexpand\endinput}%
\immediate\immediate\write0{\filename}%
\immediate\closeout0
\csname bye\endcsname
}
3 changes: 3 additions & 0 deletions doc/examples/ins.begin
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
\nopostamble
\askforoverwritefalse
\generate{%
\file{example}{\from{example.dtx}{t}}%
\file{example.listing}{\from{example.dtx}{lst,t}}%
\file{example.attachment}{\from{example.dtx}{att,t}}%
File renamed without changes.
File renamed without changes.
60 changes: 7 additions & 53 deletions doc/memoize-doc.sty
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,6 @@
\tcbincludegraphics[reset,capture=hbox,graphics options={clip,#4},#1]{#2}#3%
}%
}%
\def\ExampleName#1{\edef\examplename{#1}\ignorespaces}
\def\makeexample#1{\pdfsystem{make -C \exampledir\space#1}\ignorespaces}
% \def\makeexample#1{\pdfsystem{make -B -C \exampledir\space#1}}
\def\examplepath{\exampledir\examplename}
\RequirePackage{intopdf}
\RequirePackage{fontawesome}
Expand Down Expand Up @@ -235,14 +232,10 @@
fill=white, draw=gray, thick,
ellipse, inner xsep=-0.5mm, inner ysep=0, shift={(-2mm,-2mm)}, rotate=45,
]{%
\pdfsystem{make -f examples/Makefile \attachmentpath}%
\expandafter\myattachandlink\expandafter[\attachmentname]{\attachmentpath}[application/x-tex]{Click here to open the code.}{\rotatebox{-45}{\faPaperclip}}
};
}
},
excerpt/.code 2 args={%
\makeexample{#2.excerpt SOURCE=#1}%
},
}
\NewDocumentCommand\attachexample{O{\examplename.tex} O{\examplepath.tex.c1.attachment}}{%
{\textsuperscript{\kern-0.25em \expandafter\myattachandlink\expandafter[#1]{#2}[application/x-tex]{Click here to open the code.}{\rotatebox{-45}{\faPaperclip}}\kern-0.25em \relax}}}
Expand All @@ -265,8 +258,12 @@
\AtEndDocument{\immediate\closeout\attachments}

\NewTCBInputListing{\tcbinputexample}{
>{\edef\ProcessedArgument} D(){\examplename} O{.tex} O{.c1} +m }
>{\edef\ProcessedArgument} m O{.tex} D(){} +m }
{%
/utils/exec={%
\edef\examplename{#1}%
\edef\examplepdfpath{\exampledir#1#3.pdf}%
},%
/mmz/context={dtxmd5sum=\csuse{pdf@filemdfivesum}{\exampledir#1#2.dtx}},
example title={#1#2},
% enlarge left by=\leftmargin,% this takes care of using this box in lists
Expand All @@ -276,7 +273,6 @@
attachment={\exampledir#1#2#3},
},
listing file=\exampledir#1#2#3.listing,
/utils/exec={\edef\examplepdfpath{\exampledir#1#3.pdf}},%
attachment=\exampledir#1#2#3.attachment,
attachment name=#1#2,%
#4,
Expand All @@ -289,10 +285,10 @@
listing and compile/.style={
listing and comment,
comment={%
\input\examplepath.tex.c#1
\input\examplepath.tex#1%
}
},
listing and compile/.default=1,
listing and compile/.default=,
}

\pgfkeys{
Expand Down Expand Up @@ -423,52 +419,10 @@
\usepackage{xstring}
\usepackage{placeins}

\NewDocumentCommand\makeexcerpt{ m O{.tex} D(){../../memoize.edtx} }{%
\ExampleName{#1}%
\makeexample{#1#2.excerpt SOURCE=#3}%
\ignorespaces
}

\newcommand\sed[2]{%
\begingroup
\def\cmd##1{\noexpand\\##1}%
\def\0{\bslash0}%
\def\1{\bslash1}%
\def\2{\bslash2}%
\def\3{\bslash3}%
\def\4{\bslash4}%
\def\5{\bslash5}%
\def\6{\bslash6}%
\def\7{\bslash7}%
\def\8{\bslash8}%
\def\9{\bslash9}%
\def~{\noexpand~}%
\def\n{\string\n}%
\def\({\bslash(}%
\def\){\bslash)}%
\let\lbrace\sedlbrace
\let\rbrace\sedrbrace
\edef\nobrace{[^\sedlbrace\sedrbrace]}
\edef\marg{{[^\sedrbrace]*}}%
\def\repeat##1{\bslash\sedlbrace##1\bslash\sedrbrace}%
\pdfsystem{sed -i "#1" #2}%
\endgroup
}
\begingroup
\catcode`\(=1
\catcode`\)=2
\catcode`\{=12
\catcode`\}=12
\gdef\sedlbrace({)%
\gdef\sedrbrace(})%
\endgroup

\usepackage{pifont}
\newcommand\yes{{\small\ding{51}}} % pifont
\newcommand\no{{\small\ding{55}}} % pifont

%\newcommand\oarg[1]{{\ttfamily[}\meta{#1}{\ttfamily]}}

\definecolor{Option}{rgb}{0.118,0.546,0.222}
\definecolor{Definition}{rgb}{0.784,0.06,0.176}
\definecolor{ExampleFrame}{rgb}{0.628,0.705,0.942}
Expand Down
Loading

0 comments on commit e879ea4

Please sign in to comment.