summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/cite-bib.opm
blob: c756a619bd0e8f98c7ccf7784714cf9f6eef0557 (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
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
253
254
255
256
257
258
%% 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.
   The \`\bibnum` counts the bibliography items from one.
   The \`\bibmark` is used when `\nonumcitations` is set.
   \_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 `[<bib-marks>]` using `\_printsavedcites`.
   \nl
   \`\nocite` `[<label>,<label>,...,<label>]` only manages <labels> but prints nothing.
   \nl
   \`\rcite` `[<label>,<label>,...,<label>]` behaves like `\cite` but prints
    <bib-marks> without brackets. 
   \nl
   \`\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 empty 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-mark> 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 appropriate
   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>}&`. This is true 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.\nl 
   The `\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 \`\shortcitations` sets simply `\_lastcitenum=1`.
   The macros for <bib-marks> printing follows (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 manually 
   using `\bib` command or it is generated automatically 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 implemented in `usebib.opm` file which is loaded
   when the `\usebib` command is firstly used. 
   The `usebib.opm` file loads the `librarian.tex` for scanning the `.bib`
   files. See the section~\ref[usebib], where the file `usebib.opm` is
   documented.
   \_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.