summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/ref-file.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/base/ref-file.opm')
-rw-r--r--macros/luatex/optex/base/ref-file.opm137
1 files changed, 137 insertions, 0 deletions
diff --git a/macros/luatex/optex/base/ref-file.opm b/macros/luatex/optex/base/ref-file.opm
new file mode 100644
index 0000000000..52ace30b8d
--- /dev/null
+++ b/macros/luatex/optex/base/ref-file.opm
@@ -0,0 +1,137 @@
+%% This is part of OpTeX project, see http://petr.olsak.net/optex
+
+\_codedecl \openref {File for references <2020-02-14>} % preloaded in format
+
+ \_doc --------------------------
+ The \`\_inputref` macro is used in `\everyjob`. It reads `\jobname.ref` file
+ if it exists. After the file is read then it is removed and opened to write
+ a new contents to this file.
+ \_cod --------------------------
+
+\_newwrite\_reffile
+
+\_def\_inputref {%
+ \_isfile{\_jobname.ref}\_iftrue
+ \_input {\_jobname.ref}
+ \_gfnotenum=0 \_lfnotenum=0 \_mnotenum=0
+ \_openrefA{\_string\_inputref}%
+ \_fi
+}
+
+ \_doc --------------------------
+ If the file does not exists then it is not created by default. It means that if you
+ process a document without any forward references then no `\jobname.ref`
+ file is created because it is unusable. The \^`\_wref` macro is dummy in
+ such case.
+ \_cod --------------------------
+
+\_def\_wrefrelax#1#2{}
+\_let\_wref=\_wrefrelax
+
+ \_doc ---------------------
+ If a macro needs to ceate and to use `.ref` file then such macro must use
+ \`\openref`. When the file is created (using internal \`\_openrefA`) then
+ the \`\_wref` `\<macro>{<data>}` is redefined in order to
+ save the line `\<macro><data>` to the `.ref` file using asynchronous
+ `\write` primitive. Finally, the `\_openref` destroys itself, because we
+ need not to open the file again.
+ \_cod ---------------------
+
+\_def\_openref {%
+ \_ifx \_wref\_wrefrelax \_openrefA{\_string\openref}\_fi
+ \_gdef\_openref{}%
+}
+\_def\_openrefA #1{%
+ \_immediate\_openout\_reffile="\_jobname.ref"\_relax
+ \_gdef\_wref ##1##2{\_write\_reffile{\_string##1##2}}%
+ \_immediate\_write\_reffile {\_pcent\_pcent\_space OPTeX <\_optexversion> - REF file (#1)}%
+ \_immediate\_wref \Xrefversion{{\_REFversion}}%
+}
+\def\openref{\_openref}
+
+ \_doc ----------------------
+ We are using convention that the macros used in `.ref` file are named
+ `\_X<foo>`. If there is a new version of \OpTeX/ with different collection
+ of such macros then we don't want to read the `.ref` files produced by an
+ old version of \OpTeX/ or by OPmac. So first line of `.ref` file is in
+ the form
+ \begtt \catcode`\<=13
+ \Xrefversion{<version>}
+ \endtt
+ We can check the version compatibility by this macro.
+ Because OPmac does not understand `\_Xrefversion` we use
+ \`\Xrefversion` (with different number of `<version>` form OPmac) here.
+ The result: OPmac skips the `.ref` files produced by \OpTeX/ and vice
+ versa.
+ \_cod ----------------------
+
+\_def\_REFversion{3} % actual version of .ref files in OpTeX
+\_def\_Xrefversion#1{\_ifnum #1=\_REFversion\_relax \_else \_endinput \_fi}
+\_public \Xrefversion ; % we want to ignore .ref files generated by OPmac
+
+ \_doc -----------------------
+ You cannot define your special `.ref` macros before `.ref` file is read
+ because it is read in `\everyjob`. But you can define such macros using
+ \`\refdecl``{<definitions of your ref macros>}`.
+ This command sends to `.ref` file your `<definitions of your ref macros>`
+ immediately. Next lines in `.ref` file should include our macros. Example
+ from CTUstyle2:
+ \begtt
+ \refdecl{%
+ \def\totlist{} \def\toflist{}^^J
+ \def\Xtab#1#2#3{\addto\totlist{\totline{#1}{#2}{#3}}}^^J
+ \def\Xfig#1#2#3{\addto\toflist{\tofline{#1}{#2}{#3}}}
+ }
+ \endtt
+ We must read `<definition of your ref macros>` when catcode of `#` is 12
+ because we needn't to duplicate each `#` in the `.ref` file.
+ \_cod \_fin -----------------
+
+\_def\_refdecl{\_bgroup \_catcode`\#=12 \_refdeclA}
+\_def\_refdeclA #1{\egroup\_openref
+ \_immediate\_write\_reffile {\_pcent\_space \_string \refdecl:}%
+ \_immediate\_write\_reffile {\_detokenize{#1}}%
+}
+\_public \refdecl ;
+
+\_endcode % ================================================
+
+
+The `.ref` file has the name `\jobname.ref` and
+it saves information about references, TOC lines, etc.
+All data needed in next \TeX/ run are saved here.
+\OpTeX/ reads this file at the beginning of the document
+(using `\everyjob`) if such file exists.
+The `.ref` file looks like:
+
+\begtt \catcode`\<=13
+\Xrefversion{<ref-version>}
+\_Xpage{<gpageno>}{<pageno>}
+\_Xtoc{<level>}{<type>}{<text>}{<title>}
+\_Xlabel{<label>}{<text>}
+\_Xlabel{<label>}{<text>}
+...
+\_Xpage{<gpageno>}{<pageno>}
+\_Xlabel{<label>}{<text>}
+...
+\endtt
+%
+where <gpageno> is internal page number globally numbered from one and
+`<pageno>` is a page number (`\the\pageno`) used in pagination (they may be differ).
+Each page begins with `\_Xpage`.
+The `<label>` is a label used by user in `\label[<label>]` and `<text>` is a
+text which should be referenced (the number of section or table, for
+example `2.3.14`). The `<title>` is a title of the chapter (`<level>`=1,
+`<type>`=`chap`), section (`<level>`=2, `<type>`=`sec`), subsection
+(`<level>`=3, `<type>`=`secc`). The `\_Xpage` is written at begining of each
+page, the `\_Xtoc` is written when chapter or section or subsection title
+exists on the page and `\_Xlabel` when labeled object prefixed by
+`\label[<label>]` exists on the page.
+
+The `.ref` file is read when the processing of the document starts using
+`\everyjob`. It is read, removed and opened to writing immediately.
+But the `.ref` file should be missing. If none forward references are needed
+in the document then `.ref` file is not created. For example, you only want
+to test a simple plain \TeX/ macro, you create `test.tex` file, you do
+`optex test` and you don't need to see empty `test.ref` file in your directory.
+