summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/usebib/usebib.dtx
blob: 4909210f1f64c824dc3ece2b6d3b0b7e93186734 (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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
% \iffalse meta-comment
%
% Copyright (C) 2012 by Enrico Gregorio 
% <Enrico dot Gregorio at univr dot it>
% -------------------------------------------------------
% 
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any
% later version. The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is Enrico Gregorio.
%
% This work consists of the files
%   usebib.dtx 
%   usebib.ins
% and the derived file usebib.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{usebib.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2008/04/05]
%<package>\ProvidesPackage{usebib}
%<*package>
    [2012/04/13 v1.0a Reusing bib files]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\providecommand{\BibTeX}{\textsc{Bib}\!\TeX}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{usebib.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{128}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0a}{2012/04/13}{Corrected macro names in the doc}
% \changes{v1.0}{2012/03/17}{Initial version}
%
% \GetFileInfo{usebib.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment,\!,\@empty,\@gobble,\@gobbletwo}
% \DoNotIndex{\@ifpackageloaded,\@ifpackagewith,\@ifundefined,\@namedef}
% \DoNotIndex{\@nil,\@onlypreamble,\@tempa,\@tempb,\@tempswafalse,\def}
% \DoNotIndex{\@tempswatrue,\^,\-,\active,\begingroup,\catcode,\@car,\@cdr}
% \DoNotIndex{\edef,\else,\endgroup,\endinput,\expandafter,\fi,\if}
% \DoNotIndex{\if@tempswa,\ifcase,\ifnum,\ifx,\lccode,\let,\lowercase}
% \DoNotIndex{\MessageBreak,\next,\number,\numexpr,\or,\PackageError}
% \DoNotIndex{\PackageWarning,\PackageWarningNoLine,\strip@prefix,\@@end}
% \DoNotIndex{\relax,\space,\string,\DeclareOption,\ProcessOptions}
% \DoNotIndex{\meaning,\ifdefined,\csname,\chardef,\endcsname,\protect}
% \DoNotIndex{\input,\RequirePackage,\global,\ifcsname,\makeatother}
% \DoNotIndex{\@makeother,\the,\toks@}
%
% \title{The \textsf{usebib} package\thanks{This document
%   corresponds to \textsf{newunicodechar}~\fileversion, dated \filedate.}}
% \author{Enrico Gregorio \\ \texttt{Enrico dot Gregorio at univr dot it}}
%
% \maketitle
%
% \section{Introduction}
%
% With \textsf{biblatex} it's possible to use any element of a
% bibliographic item in a document. With packages such as
% \textsf{natbib} or simply with the native \BibTeX{} support one
% can't refer directly to the title of a cited article or book without
% directly typing it in.
%
% This package allows this by reading in a special environment a
% |.bib| file. It should be considered no more than a devious usage of
% a |.bib| file, to be honest. But it works.
%
% \section{Usage}
%
% The package \emph{must} be loaded after \textsf{hyperref}, but it
% doesn't require it. It depends only on \textsf{url} and
% \textsf{keyval}, which should be present on every \TeX{}
% distribution.
%
% \subsection{Preamble commands}
% 
% \DescribeMacro{\bibinput}
% The main command is |\bibinput|, which accepts the name of a |.bib|
% file (\emph{without} the extension) and may be repeated any number
% of times to read all the necessary files.\footnote{Making it
% dependent on the \texttt{\string\bibliography} command would be too
% difficult.}  The command should appear only in the preamble.
%
% \DescribeMacro{\newbibfield}
% With the macro |\newbibfield|, to be issued \emph{before}
% |\bibinput|, it's possible to declare new known fields, for example
%\begin{verbatim}
% \newbibfield{annotation}
%\end{verbatim}
% and say in the document |\usebibentry{xyz}{annotation}|.  It's also
% possible to say |\newbibfield{author}|, but as author names are
% input in a very peculiar way, the result would be at least
% questionable in the vast majority of cases. This command should
% appear before |\bibinput|.
%
% \DescribeMacro{\newbibignore}
% The entry types |@preamble| and |@string| are ignored by default. If
% some other type should also, it's possible to say
% \begin{flushleft}
% |\newbibignore{|\meta{type}|}|
% \end{flushleft}
% so that, for example, |\newbibignore{misc}| will ignore all |@misc|
% entry types. This command should appear before |\bibinput|.
% 
% \subsection{Document commands}
%
% \DescribeMacro{\usebibentry}
% The main document command is |\usebibentry| which requires two
% arguments, the bibliography key and the field name:
% \begin{flushleft}
% |\usebibentry{|\meta{key}|}{|\meta{field}|}|
% \end{flushleft}
% The \meta{key} is what's used in the argument to |\cite| (or
% variations thereof) and \meta{field} can be |title|, |year|, |note|
% or |isbn|, but it's possible to augment the list of known
% fields. So, in order to get in the document the referenced item's
% title one can say
%\begin{verbatim}
% In the book ``\usebibentry{newton1687}{title}''~\cite{newton1687},
% published in~\usebibentry{newton1687}{year}, Newton
% describes the Law of Universal Gravitation
%\end{verbatim}
% to get the text
% \begin{quote}
% In the book ``Philosophiae Naturalis Principia Mathematica''~[3],
% published in 1687, Newton describes the Law of Universal Gravitation
% \end{quote}
% assuming that in the |.bib| file that has been read with |\bibinput|
% there's an entry such as
%\begin{verbatim}
% @book{newton1687,
%  author={Newton, Isaac},
%  title={Philosophiae Naturalis Principia Mathematica},
%  publisher={Royal Society},
%  address={London},
%  year={1687},
%  url={http://royalsociety.org},
% }
%\end{verbatim}
% Unknown keys and missing values trigger errors: so
% |\usebibentry{newton1687}{isbn}| would result in the error
%\begin{verbatim}
% Undefined key `newton1687' or empty value for `isbn'
%\end{verbatim}
% Unsupported fields will be ignored and print nothing.
%
% \DescribeMacro{\usebibentryurl}
% If the |.bib| entry has a |url| field, its value can be obtained
% with
% \begin{flushleft}
% |\usebibentryurl{|\meta{key}|}|
% \end{flushleft}
% \begin{trivlist}\footnotesize\item
% When \textsf{hyperref} is not loaded, this is equivalent to calling
% \verb+\url|+\meta{url}\verb+|+. In case the URL contains the
% character \verb+|+, this call will produce wrong results and
% one can specify a different delimiter
% \begin{flushleft}
% |\usebibentry[!]{|\meta{key}|}|
% \end{flushleft}
% where, of course, the optional argument is a character not appearing
% in the URL. This optional argument is not needed when
% \textsf{hyperref} is loaded and, if present, it's ignored.
% \end{trivlist}
%
% \section{Limitations}
%
% The field delimiters in the |.bib| files \emph{must} be braces, as
% must also the entry delimiters. \BibTeX{} allows double quotes in
% for delimiting fields and parentheses for the entry. So, while
%\begin{verbatim}
% @book(newton1687,
%  author="Newton, Isaac",
%  title="Philosophiae Naturalis Principia Mathematica",
%  publisher="Royal Society",
%  address="London",
%  year=1687,
%  url="http://royalsociety.org",
% )
%\end{verbatim}
% would be accepted by \BibTeX{}, it won't be by
% \textsf{usebib}. Supporting this is out of question, since we parse
% entries as a key-value list. Strictly speaking, double quotes won't
% give errors, as long as no comma is in the fields, but will be part
% of the replacement text anyways. Numeric field values can, of
% course, be input without field delimiters.
%
% Another limitation is in the fact that field names should always be
% lowercase; supporting mixed case for these is beyond the limits of a
% small package like this. Sorry.
%
% Note also that all the bibliographic data are loaded in memory, so
% large |.bib| files could exceed \TeX{} capacity.
%
% Don't ever try typing |\usebibentry{foo}{url}|: you've been
% warned. There's |\usebibentryurl{foo}| for this.
%
% Finally, the package requires $\varepsilon$-\TeX, which shouldn't be
% a problem, nowadays.
%
% \StopEventually{}
%
% \section{Implementation}
%
% After the usual presentation, we check first of all that the
% typesetting engine is sufficiently recent to include
% $\varepsilon$-\TeX{} extensions.
%    \begin{macrocode}
\@ifundefined{eTeXversion}
  {\PackageError{usebib}{LaTeX engine too old, aborting}
   {Please upgrade your TeX system}\@@end}{}
%    \end{macrocode}
% We start by loading the required packages.
%    \begin{macrocode}
\RequirePackage{url}
\RequirePackage{keyval}
%    \end{macrocode}
% 
% When we read a |.bib| file the |@| character is made active. Its
% action is to read what follows up to the next open brace, using it
% as the value of the |currenttype| key. This is necessary for
% ignoring the entry types |@preamble| and |@string| which would mess
% up everything.
%
% Now we define the known fields as keys for \textsf{keyval} and the
% two auxiliary keys. The |\define@reuse@key| macro is just syntactic
% sugar.
%    \begin{macrocode}
\define@key{usebib}{currenttype}{\def\@tempa{#1}}
\define@key{usebib}{currententry}{\def\reuse@current{#1}}
\def\define@reuse@key#1{%
  \define@key{usebib}{#1}{\global\@namedef{reuse@\reuse@current @#1}{##1}}}
\define@reuse@key{title}
\define@reuse@key{isbn}
\define@reuse@key{url}
\define@reuse@key{year}
\define@reuse@key{note}
%    \end{macrocode}
%
% \begin{macro}{\reuse@find}
% The first macro to be used when looking at an entry, later we'll
% define the active |@| to be this macro: it takes as argument the
% entry's type and does, for instance,
% |\setkeys{usebib}{currenttype=BOOK}|, but inside a |\lowercase| so
% that the type will be normalized. Then it checks whether
% |\reuse@type@book| is defined, which it isn't, so |\reuse@extract|
% will be expanded; since we later define |\reuse@type@preamble| and
% |\reuse@type@string|, such entries will be ignored because of
% |\@gobble|. The expansion of |\reuse@extract| is done in a group
% where |@| has category code~12 and also the percent character,
% because it can be in some URL (and has not a special meaning in
% \BibTeX{} entries).
%    \begin{macrocode}
\def\reuse@find#1#{%
  \lowercase{\setkeys{usebib}{currenttype=#1}}%
  \ifcsname reuse@type@\@tempa\endcsname
    \expandafter\@gobble
  \else
    \begingroup\@makeother\%\makeatother
    \expandafter\reuse@extract
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\reuse@extract}
% The entire entry is the argument to |\reuse@extract|; since it has a
% fixed form, we feed the citation key as the value of |currententry|
% and then read all the fields as key-value pairs. The effect of
% |currententry=xyz| is to define |\reuse@current| to |xyz|; so a
% subsequent |year=2012| will do the equivalent of 
%\begin{verbatim}
% \gdef\reuse@xyz@year{2012}
%\end{verbatim}
% and similarly for the other known fields. The group opened by
% |\reuse@find| is then closed.
%    \begin{macrocode}
\def\reuse@extract#1{\setkeys{usebib}{currententry=#1}\endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\reuse@type@preamble}
% \begin{macro}{\reuse@type@preamble}
% \begin{macro}{\newbibignore}
% Here we define the two entry types to ignore and the user level
% command to augment the list of ignored fields.
%    \begin{macrocode}
\let\reuse@type@preamble\@empty
\let\reuse@type@string\@empty
\def\newbibignore#1{\expandafter\let\csname reuse@type@#1\endcsname\@empty}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\reuse@error}
% A macro for issuing an error message.
%    \begin{macrocode}
\def\reuse@error#1#2{%
  \PackageError{usebib}
    {Undefined key `#1' or empty value for `#2'}
    {The key you used is wrong or the value to `#2' has not been set}}
%    \end{macrocode}
% \end{macro}
%
% Next we define the other four user level macros.
% \begin{macro}{\newbibfield}
% |\newbibfield{type}| defines a new key.
%    \begin{macrocode}
\newcommand\newbibfield[1]{\define@reuse@key{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\usebibentry}
% \begin{macro}{\usebibentryurl}
% \begin{macro}{\reuse@usebibentryurl}
% Both |\usebibentry| and |\usebibentryurl| check whether the
% corresponding inner macro is defined. The latter then expands a
% special inner version that's defined in different ways depending
% whether \textsf{hyperref} has been loaded or not. If it is, a simple
% |\scantokens| hands the job to the |\url| macro, which is cleverly
% defined for accepting special characters; otherwise we need to be
% sure that the URL is properly delimited.
%    \begin{macrocode}
\def\usebibentry#1#2{\@ifundefined{reuse@#1@#2}
  {\reuse@error{#1}{#2}}
  {\@nameuse{reuse@#1@#2}}}
\newcommand{\usebibentryurl}[2][|]{\@ifundefined{reuse@#2@url}
  {\reuse@error{#2}{url}}
  {\reuse@usebibentryurl{#1}{#2}}}
\@ifpackageloaded{hyperref}{\@tempswatrue}{\@tempswafalse}
\if@tempswa
  \def\reuse@usebibentryurl#1#2{%
    \scantokens{\url{\csname reuse@#2@url\endcsname}\endinput}}
\else
  \def\reuse@usebibentryurl#1#2{%
    \toks@=\expandafter\expandafter\expandafter
      {\csname reuse@#2@url\endcsname}%
    \scantokens\expandafter{%
      \expandafter\url\expandafter#1\the\toks@#1\endinput}}
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\bibinput}
% The macro that starts the reading of a |.bib| file. We start a group
% where end-of-line characters are treated like spaces and where the
% error messages of \textsf{keyval} and \textsf{xkeyval} about
% undefined keys are disabled. Then we define the active |@| to be
% |\reuse@find| and input the |.bib| file, closing the group at the
% end.
%    \begin{macrocode}
\newcommand{\bibinput}[1]{%
  \begingroup
  \catcode`\^^M=10
  \let\KV@err=\@gobble
  \let\KV@errx=\@gobble
  \let\XKV@err=\@gobble
  \begingroup\lccode`\~=`\@
    \lowercase{\endgroup\let~}\reuse@find
  \catcode`\@=\active \input{#1.bib}\endgroup}
%    \end{macrocode}
% \end{macro}
% \Finale
\endinput