summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/ref-file.opm
blob: 01363ef9a9731635726415db290a1380ca26470b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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.