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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
%% This is part of OpTeX project, see http://petr.olsak.net/optex
\_codedecl \cite {Cite, Biblioraphy <2020-03-09>} % loaded in format
\_doc -----------------------------
Registers used by `\cite`, `\bib` macros are declared here
\_cod -----------------------------
\_newcount\_bibnum % the bibitem counter
\_newtoks\_bibmark % the bibmark used if \nonumcitations
\_newcount\_lastcitenum \_lastcitenum=0 % for \shortcitations
\_public \bibnum \bibmark ;
\_doc -----------------------------
`\cite [<label>,<label>,...,<label>]` manages <labes> using `\_citeA`
and prints prints `[<bib-marks>]` using `\_printsavedcites`.
`\nocite [<label>,<label>,...,<label>]` only manages <labels> but prints nothing.
`\rcite [<label>,<label>,...,<label>]` behaves like `\cite` but prints
<bib-marks> without brackets.
`\ecite [<label>]{<text>}` behaves like `\rcite [<label>]` but prints
<text> instead <bib-mark>. The <text> is hyperlinked like <bib-marks>
when `\cite` or `\rcite` is used.
The emptpty internal macro `\_savedcites` will include the <bib-marks> list to
be printed. This list is set by `\_citeA` inside group and it is used by
`\_printsavedcites` in the same group. Each `\cite`/`\rcite`/`\ecite` macro
starts from empty list of <bib-marks> because new group is opened.
\_cod -----------------------------
\_def\_cite[#1]{{\_citeA#1,,,[\_printsavedcites]}}
\_def\_nocite[#1]{{\_citeA#1,,,}}
\_def\_rcite[#1]{{\_citeA#1,,,\_printsavedcites}}
\_def\_ecite[#1]{\_bgroup\_citeA#1,,,\_ea\_eciteB\_savedcites;}
\_def\_eciteB#1,#2;#3{\_if?#1\_relax #3\_else \_ilink[cite:#1]{#3}\_fi\_egroup}
\_def\_savedcites{}
\_public \cite \nocite \rcite \ecite ;
\_doc -----------------------------
<bib-marks> may be numbers or a special text related to cited bib-entry.
It depends on `\nonumcitations` and on used bib-style. The mapping from
<label> to <bib-makr> is done when `\bib` or `\usebib` is processed.
These macros store the information to
`\_Xbib{<label>}{<number>}{<nonumber>}` where <number> and <nonumber> are
two variants of <bib-mark> (numbered or text-like). This information is
read from `.ref` file and it is saved to macros
\_bib:<label> and \_bibm:<number>. First one includes number and second
one includes <nonumber>. The `\_lastbibnum` macro includes last number of
bib-entry used in the document. A designer can use it to set apropriate
indentation when printing the list of all bib-entries.
\_cod -----------------------------
\_def\_Xbib#1#2#3{\_sdef{_bib:#1}{\_bibnn{#2}&}%
\_if^#3^\_else\_sdef{_bim:#2}{#3}\_fi\_def\_lastbibnum{#2}}
\_doc -----------------------------
`\_citeA <label>,` processes one label from list of labels given in the
parameter of `\cite`, `\nocite`, `\rcite` or `\ecite` macros. It adds the
<label> to global list `\_citelist` which will be used by `\usebib` (it
must to know what <labels> are used in the document in order to pick-up
only relevant bib-entries from the database. Because we want to save
space and not to save the same <label> to `\_citelist` twice, we
distinguish four cases:
\begitems
* <label> was not declared by `\_Xbib` and it is first such <label> in the
document: Then `\_bib:<label>` is undefined and we save label using
`\_addcitlist`, write warning on the terminal and define
`\_bib:<label>` as empty.
* <label> was not declared by `\_Xbib` but it was used previously in the
document: Then `\_bib:<label>` is empty and we do nothing (only data to
`\_savedcites` are saved).
* <label> was declared by `\_Xbib` and it is first such <label> in the
document: Then `\_bin:<label>` includes `\_bibnn{<number>}&` and we
test this case by `\if &\_bibnn{<number>}&` when `\_bibnn{<number>}`
expands to empty. The <label> is saved by `\_addcitelist` and
`\_bib:<label>` is re-defined directly as <number>.
* <label> was declared by `\_Xbib` and it was used previously in the
document. Then we do nothing (only data to `\_savedcites` are saved.
\enditems
The `\_citeA` macro runs repeatedly over whole list of <labels>.
\_cod -----------------------------
\_def\_citeA #1#2,{\_if#1,\_else
\_if *#1\_addcitelist{*}\_ea\_skiptorelax \_fi
\_ifcsname _bib:#1#2\_endcsname \_else
\_addcitelist{#1#2}%
\_opwarning{The cite [#1#2] unknown. Try to TeX me again}\_openref
\_addto\_savedcites{?,}\_def\_sortcitesA{}\_lastcitenum=0
\_ea\_gdef \_csname _bib:#1#2\_endcsname {}%
\_ea\_skiptorelax \_fi
\_ea\_ifx \_csname _bib:#1#2\_endcsname \_empty
\_addto\_savedcites{?,}\_def\_sortcitesA{}\_lastcitenum=0
\_ea\_skiptorelax \_fi
\_def\_bibnn##1{}%
\_if &\_csname _bib:#1#2\_endcsname
\_def\_bibnn##1##2{##1}%
\_addcitelist{#1#2}%
\_sxdef{_bib:#1#2}{\_csname _bib:#1#2\_endcsname}%
\_fi
\_edef\_savedcites{\_savedcites \_csname _bib:#1#2\_endcsname,}%
\_relax
\_ea\_citeA\_fi
}
\_def\_addcitelist#1{\_global\_addto\_citelist{\_citeI[#1]}}
\_def\_citelist{}
\_doc -----------------------------
The <bib-marks> (in numeric or text form) are saved in `\_savedcites`
macro separated by commas.
The `\_printsavedcites` prints them by normal order or sorted if
`\sortcitations` is specified or condensed if `\shordcitations` is
specified.
`\sortcitations` appends the dummy number 300000 and we suppose that normal
numbers of bib-entries are less than this constant.
This constant is removed after sorting algorithm.
The macros for <bib-marks> printing folows (sorry, without detail
documentation). They are documented in `opmac-d.pdf` (but only in Czech).
\_cod -----------------------------
\_def\_printsavedcites{\_sortcitesA
\_chardef\_tmpb=0 \_ea\_citeB\_savedcites,%
\_ifnum\_tmpb>0 \_printdashcite{\_the\_tmpb}\_fi
}
\_def\_sortcitesA{}
\_def\_sortcitations{%
\_def\_sortcitesA{\_edef\_savedcites{300000,\_ea}\_ea\_sortcitesB\_savedcites,%
\_def\_tmpa####1300000,{\_def\_savedcites{####1}}\_ea\_tmpa\_savedcites}%
}
\_def\_sortcitesB #1,{\_if $#1$%
\_else
\_mathchardef\_tmpa=#1
\_edef\_savedcites{\_ea}\_ea\_sortcitesC \_savedcites\_end
\_ea\_sortcitesB
\_fi
}
\_def\_sortcitesC#1,{\_ifnum\_tmpa<#1\_edef\_tmpa{\_the\_tmpa,#1}\_ea\_sortcitesD
\_else\_edef\_savedcites{\_savedcites#1,}\_ea\_sortcitesC\_fi}
\_def\_sortcitesD#1\_end{\_edef\_savedcites{\_savedcites\_tmpa,#1}}
\_def\_citeB#1,{\_if$#1$\_else
\_if?#1\_relax??%
\_else
\_ifnum\_lastcitenum=0 % only comma separated list
\_printcite{#1}%
\_else
\_ifx\_citesep\_empty % first cite item
\_lastcitenum=#1\_relax
\_printcite{#1}%
\_else % next cite item
\_advance\_lastcitenum by1
\_ifnum\_lastcitenum=#1\_relax % cosecutive cite item
\_mathchardef\_tmpb=\_lastcitenum
\_else % there is a gap between cite items
\_lastcitenum=#1\_relax
\_ifnum\_tmpb=0 % previous items were printed
\_printcite{#1}%
\_else
\_printdashcite{\_the\_tmpb}\_printcite{#1}\_chardef\_tmpb=0
\_fi\_fi\_fi\_fi\_fi
\_ea\_citeB\_fi
}
\_def\_shortcitations{\_lastcitenum=1 }
\_def\_printcite#1{\_citesep\_ilink[cite:#1]{\_citelinkA{#1}}\_def\_citesep{,\_hskip.2em\_relax}}
\_def\_printdashcite#1{\_ifmmode-\_else\_hbox{--}\_fi\_ilink[cite:#1]{\_citelinkA{#1}}}
\_def\_citesep{}
\_def\_nonumcitations{\_lastcitenum=0\_def\_sortcitesA{}\_def\_etalchar##1{$^{##1}$}%
\_def\_citelinkA##1{\_isdefined{_bim:##1}\_iftrue \_csname _bim:##1\_endcsname
\_else ##1\_opwarning{\_noexpand\_nonumcitations + empty bibmark. Maybe bad BibTeX style}\_fi}
}
\_def\_citelinkA{}
\_public \nonumcitations \sortcitations \shortcitations ;
\_doc -----------------------------
The `\bib [<label>] {<optional bib-mark>}` prints one bib-entry
without reading any database. The bib-enty follows after this command.
This command counts the used `\bib`s from one by `\bibnum` counter and
saves `\_Xbib{<label>}{\_the\_bibnum}{\_the\_bibmark}` into `.ref` file
immediately using `\_wbib`. This is the core of creation of mapping from
<labels> to <bib-marks>.
\_cod -----------------------------
\_def\_bib[#1]{\_def\_tmp{\_isnextchar={\_bibA[#1]}{\_bibmark={}\_bibB[#1]}}%
\_ea\_tmp\_romannumeral-`\.} % ignore optional space
\_def\_bibA[#1]=#2{\_bibmark={#2}\_bibB[#1]}
\_def\_bibB[#1]{\_par \_bibskip
\_advance\_bibnum by1
\_noindent \_def\_tmpb{#1}\_wbib{#1}{\_the\_bibnum}{\_the\_bibmark}%
\_printlabel{#1}%
\_printbib \_ignorespaces
}
\_def\_wbib#1#2#3{\_dest[cite:\_the\_bibnum]%
\_ifx\_wref\_wrefrelax\_else \_immediate\_wref\_Xbib{{#1}{#2}{#3}}\_fi}
\_public \bib ;
\_doc -----------------------------
The `\_printbib` prints the bib-entry itself. You can re-define it if you
want different design. The `\_pritbib` starts in horizontal mode after
`\noindent` and after the eventual hyperlink destination is inserted.
By default, the `\_printbib` sets the indentation
by `\hangindent` and prints numeric <bib-marks> by
`\llap{[\the\bibnum]}` If `\nonumcitations` then the `\_citelinkA` is not
empty and <bib-marks> (`\the\bibnum` nor `\the\bibmark`) are not printed.
The text of bib-entry follows. User can create this text manualy
using `\bib` command or it is generated automaticaly from a `.bib` database
by `\usebib` command.
The vertical space between bib-entries is controlled by `\_bibskip` macro.
\_cod -----------------------------
\_def \_printbib {\_hangindent=\_iindent
\_ifx\_citelinkA\_empty \_hskip\_iindent \_llap{[\_the\_bibnum] }\_fi
}
\_def \_bibskip {\_ifnum\_bibnum>0 \_smallskip \_fi}
\_doc -----------------------------
The `\usebib` command is implemted in `usebib.opm` file which is loaded
when the `\usebib` command is firstly used.
The `usebib.opm` file loads the `librarian.tex` for scaning the `.bib`
files. This macro is external created by Paul Isambert. This is only one
such situation where \OpTeX/ macros depends on an external macro.
\_cod -----------------------------
\_def\_usebib{\_par \_opinput {usebib.opm} \_usebib}
\_def\usebib{\_usebib}
\_doc -----------------------------
The macros above works if all `\cite` (or similar) commands are used
before the `\usebib` command is used because `\usebib` prints only such
bib-entries their <labels> are saved in the `\_citelist`. But if some
`\cite` is used after `\usebib`, then `\usebib` sets `\_addcitelist` to
`\_writeXcite`, so such `\cite` saves the information to the
`.ref`file in the format `\_Xcite{<label>}`. Such information are copied
to `\_citelistB` during reading `.ref` file and `\usebib` concats two
lists of <labels> from `\_citelist` and `\_citelistB` and
uses this concatenated list.
\_cod -----------------------------
\_def\_Xcite#1{\_addto\_citelistB{\_citeI[#1]}}
\_def\_writeXcite#1{\_openref\_immediate\_wref\_Xcite{{#1}}}
\_def\_citelistB{}
\_endcode % -------------------------------------
See end of the `usebib.opm` file for documentation about creating style
files `bib-<style>.opm`.
See end of the `bib-iso690.opm` file for large documentation about `.bib` files
structure and about usage of `iso690` bib-style.
|