summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/usebib.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/usebib.opm')
-rw-r--r--macros/luatex/optex/usebib.opm334
1 files changed, 334 insertions, 0 deletions
diff --git a/macros/luatex/optex/usebib.opm b/macros/luatex/optex/usebib.opm
new file mode 100644
index 0000000000..4ff38c8736
--- /dev/null
+++ b/macros/luatex/optex/usebib.opm
@@ -0,0 +1,334 @@
+% opmac-bib
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Petr Olsak, version Feb. 2018 (beta)
+
+% This is module for OPmac macros, see http://petr.olsak.net/opmac.html
+% The command:
+% \usebib/<sorttype> (<style>) (bibfiles>
+% for direct reading .bib files by OPmac macros (without bibTeX) is implemented here.
+% The implementation depends on librarian.tex package by Paul Isambert.
+% Use:
+% \input opmac \input opmac-bib
+% or simply:
+% \input opmac-bib
+% before using the command \usebib.
+% For more information see the end of this file.
+
+\ifx\MakeReference\udefined \else \endinput \fi
+\ifx\OPmacversion\undefined \input opmac \fi
+\ifx\printbib\undefined
+ \errmessage{Please, upgrade OPmac to version Apr. 2014 or newer}
+ \endinput\fi
+
+% we needn't \errmessage when bad TeX engnine is detected during \input librarian:
+
+\def\tmp{}
+\let\errmessageori=\errmessage
+\def\errmessage#1{\def\tmp{error}}
+\let\newwriteori=\newwrite % we need not to create \jobname.lbr:
+\def\newwrite#1{\csname lb@restoreat\endcsname \endinput}
+\catcode`\_=12
+\input librarian
+\catcode`\_=11
+\let\errmessage=\errmessageori
+\let\newwrite=\newwriteori
+\ifx\tmp\empty\else
+ \def\usebib/#1 (#2) #3 {%
+ \opwarning{eTeX and (pdfTeX or XeTeX or LuaTeX) not detected}%
+ \immediate\write16{\space\space
+ But librarian package needs it. \noexpand\usebib ignored.}%
+ }
+ \endinput \fi
+
+% The \usebib command:
+
+\def\usebib/#1 (#2) #3 {%
+ \ifx\citelist\empty
+ \opwarning{No cited items. \noexpand\usebib ignored}%
+ \else
+ \bgroup \par
+ \ifx\bibpart\undefined \def\bibpart{none}\fi
+ \catcode`<=12
+ \ifx\savedttchar\undefined\else \catcode\savedttchar=12 \fi
+ \def\opmacbibstyle{#2}%
+ \input bib-#2.opm
+ \bibtexhook
+ \let\citeI=\relax \xdef\citelist{\citelist\citelistB}%
+ \global\let\addcitelist=\writeXcite
+ \def\tmp##1[*]##2\relax{\def\tmp{##2}}\expandafter\tmp\citelist[*]\relax
+ \ifx\tmp\empty\else % there was \nocite[*] used.
+ \setbox0=\vbox{\def\citelist{}\adef@{\readbibentry}%
+ \input #3.bib
+ \expandafter}\expandafter\def\expandafter\citelist\expandafter{\citelist}%
+ \fi
+ \def\citeI[##1]{\csname lb@cite\endcsname{##1}{\bibpart}{}{}}\citelist
+ \BibFile{#3}%
+ \if s#1\def\warntwobytes{}\def\warnthreebytes{}% \scantokens is used during sorting
+ \SortList{\bibpart}\fi
+ \ReadList{\bibpart}%
+ \egroup
+ \fi
+}
+\def\readbibentry#1#{\readbibentryA}
+\def\readbibentryA#1{\readbibentryB#1,,\relax!.}
+\def\readbibentryB#1#2,#3\relax!.{\addto\citelist{\citeI[#1#2]}}
+
+% Corrections in librarian macros:
+
+\tmpnum=\catcode`\@ \catcode`\@=11
+\def\lb@checkmissingentries#1,{% we needn't \errmessage here, only \opmacwarning
+ \def\lb@temp{#1}%
+ \unless\ifx\lb@temp\lb@eoe
+ \lb@ifcs{#1}{fields}%
+ {}%
+ {\opwarning{\string\usebib: entry [#1] isn't found in .bib file(s)}}%
+ \expandafter\lb@checkmissingentries
+ \fi
+}
+\def\lb@readentry#1#2#3,{% space before key have to be ingnored
+ \def\lb@temp{#2#3}% we need case sensitive keys
+ \def\lb@next{\expandafter\lb@gotoat\lb@gobbletoeoe}%
+ \lb@ifcs\lb@temp{requested}%
+ {\let\lb@entrykey\lb@temp
+ \lb@ifcs\lb@entrykey{fields}{}%
+ {\lb@defcs\lb@entrykey{fields}{}%
+ \lowercase{\lb@addfield{entrytype}{#1}}%
+ \let\lb@next\lb@analyzeentry}}{}%
+ \lb@next
+}
+\let\lb@compareA=\lb@compare
+\let\lb@preparesortA=\lb@preparesort
+\def\lb@compare#1\lb@eoe#2\lb@eoe{% SpecialSort:
+ \ifx\lb@sorttype\lb@namestring
+ \ifx\sortfield\undefined \lb@compareA#1\lb@eoe#2\lb@eoe
+ \else
+ \expandafter\RetrieveFieldInFor\expandafter{\sortfield}\lb@entrykey\lb@temp
+ \ifx\lb@temp\empty \toks1={#1\lb@eoe}\else \toks1=\expandafter{\lb@temp\lb@eoe}\fi
+ \expandafter\RetrieveFieldInFor\expandafter{\sortfield}\lb@currententry\lb@temp
+ \ifx\lb@temp\empty \toks2={#2\lb@eoe}\else \toks2=\expandafter{\lb@temp\lb@eoe}\fi
+ \edef\lb@temp{\noexpand\lb@compareA\space\the\toks1 \space\the\toks2}\lb@temp
+ \fi
+ \else \lb@compareA#1\lb@eoe#2\lb@eoe \fi
+}
+\def\lb@preparesort#1#2\lb@eoe{%
+ \if#1-%
+ \def\lb@sorttype{#2}%
+ \else
+ \def\lb@sorttype{#1#2}%
+ \fi
+ \lb@preparesortA#1#2\lb@eoe
+}
+\def\SpecialSort#1{\def\sortfield{#1}}
+\def\WriteImmediateInfo#1{} % the existence of .lbr file bocks new reading of .bib
+\catcode`\@=\tmpnum
+
+% Main action per every entry:
+
+\def\MakeReference{\par \ifnum\bibnum>0 \bibskip \fi
+ \advance\bibnum by1
+ \isdefined{bim:\the\bibnum}\iftrue
+ \edef\tmpb{\csname bim:\the\bibnum\endcsname}%
+ \bibmark=\expandafter{\tmpb}%
+ \else \bibmark={}\fi
+ \noindent \edef\tmpb{\EntryKey}%
+ \printbib \dest[cite:\the\bibnum]%
+ \bgroup
+ \RetrieveFieldIn{entrytype}\entrytype
+ \csname print:BEGIN\endcsname
+ \isdefined{print:\entrytype}\iftrue
+ \csname print:\entrytype\endcsname
+ \else
+ \ifx\entrytype\empty \else
+ \opwarning{Entrytype @\entrytype\space from [\EntryKey] undefined}%
+ \csname print:misc\endcsname
+ \fi\fi
+ \csname print:END\endcsname
+ \ifx\wref\wrefrelax\else \immediate\wref\Xbib{{\EntryKey}{\the\bibnum}{\the\bibmark}}\fi
+ \egroup \par
+}
+
+% The \bprinta, \bprintb, \bprintc, \bprintv commands used in the style files:
+
+\def\bprinta {\bprintb*}
+\def\bprintb #1[#2#3]{%
+ \def\bibfieldname{#2#3}%
+ \if!#2\relax
+ \def\bibfieldname{#3}%
+ \RetrieveFieldIn{#3}\bibfield
+ \ifx\bibfield\empty\else
+ \RetrieveFieldIn{#3number}\namecount
+ \def\bibfield{\csname Read#3\expandafter\endcsname\csname #3name\endcsname}%
+ \fi
+ \else
+ \RetrieveFieldIn{#2#3}\bibfield
+ \fi
+ \if^#1^%
+ \ifx\bibfield\empty \expandafter\expandafter\expandafter \doemptyfield
+ \else \expandafter\expandafter\expandafter \dofullfield \fi
+ \else \expandafter \bprintaA
+ \fi
+}
+\def\dofullfield#1#2{\def\dofield##1{#1}\expandafter\dofield\expandafter{\bibfield}}
+\def\doemptyfield#1#2{\def\dofield##1{#2}\expandafter\dofield\expandafter{\bibfield}}
+\let\Readauthor=\ReadAuthor \let\Readeditor=\ReadEditor
+\def\bprintaA #1#2{\ifx\bibfield\empty #2\else\bprintaB #1**\eee\fi}
+\def\bprintaB #1*#2*#3\eee{\if^#3^#1\else\expandafter\bprintaC\expandafter{\bibfield}{#1}{#2}\fi}
+\def\bprintaC #1#2#3{#2#1#3}
+\def\bprintc#1#2{\bprintcA#1#2**\relax}
+\def\bprintcA#1#2*#3*#4\relax{\ifx#1\empty \else \if^#4^#2\else#2#1#3\fi\fi}
+\def\bprintv [#1]#2#3{\def\tmpa{#2}\def\tmpb{#3}\bprintvA #1,,}
+\def\bprintvA #1,{%
+ \if^#1^\tmpb\else
+ \RetrieveFieldIn{#1}\tmp
+ \ifx \tmp\empty
+ \else \tmpa \def\tmpb{}\def\tmpa{}%
+ \fi
+ \expandafter \bprintvA
+ \fi
+}
+
+% Various macros + multilinguas:
+
+\def\bibwarning{\opwarning{Missing field \string"\bibfieldname\string" in [\EntryKey]}}
+
+\def\slet#1#2{\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname}
+\def\mtdef#1#2#3#4{\sdef{_mt:#1:en}{#2} \sdef{_mt:#1:cs}{#3}
+ \if$#4$\slet{_mt:#1:sk}{_mt:#1:cs}
+ \else \sdef{_mt:#1:sk}{#4}
+ \fi
+}
+
+\endinput
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The following command is implemented here:
+
+ \usebib/<sorttype> (<style>) <bibfiles>
+
+where <sorttype> is one letter 'c' (references ordered by citation order in
+the text) or 's' (references ordered by key in the style file),
+<style> is the part of the name `opmac-bib-<style>.tex' of the style file
+and <bibfiles> are one or more .bib file names without suffix separated by
+comma without space. Example:
+
+ \usebib/s (simple) mybase,yourbase
+
+This command reads the <bibfiles> directly and creates the list of
+bibliographics references (only those declared by by \cite[] or \nocite[]
+in the text). The formatting of such references is defined in the style
+file. The usage is mentioned in OPmac documentation too.
+
+The principle "first entry wins" is used. Suppose
+
+ \usebib/s (simple) local,global
+
+If an entry with the same label is declared in local.bib and in
+global.bib too then the first wins. So, you can set an exceptions in your
+local.bib file for your document, for example.
+
+
+Notes for style writers:
+------------------------
+
+The opmac-bib-<style>.tex file must define the commands:
+
+\authorname ... formatting of one name in the authors list. The macro can
+ use the following data: \NameCount (the number of the currently
+ processed author name in the list), 0\namecount (the total number of the
+ authors in the list), \Lastname, \Firstname, \Von, \Junior (the parts of
+ the name). See the documentation of the librarian package for more info.
+
+\editorname ... the same as \authorname, but for editors list.
+
+print:<entrytype> (defined by \sdef) for formatting the entry of <entrytype>.
+ The <entrytype> have to be lowercase. This command can use the command:
+
+\bprinta [<fieldname>] {<if defined>} {<if not defined>}. The part <if defined>
+ is executed if <fieldname> is declared in .bib file for the entry which is
+ currently processed. Else the part <if not defined> is processed.
+ The part <if defined> can include the * parameter which is replaced
+ by the value of the <fieldname>. The part <if not defined> can include
+ the \bibwarning command if the <fieldname> is mandatory.
+\bprintb [<fieldname>] {<if defined>} {<if not defined>}. The same as
+ \bprinta, but the ##1 parameter is used instead *. Differences: ##1
+ parameter can be used more than once and can be enclosed in nested
+ braces. The * parameter can be used at most once and cannot be enclosed
+ in braces. Warning: if the \bprintb commands are nested (\bprintb in
+ \bprintb), then you need to write ####1 parameter for internal \bprintb.
+ But if \bprinta commands are nested then the * parameter is not dubbled.
+\pbprintc \macro {<if non-empty>}. The <if non-empty> part is executed if
+ \macro is non-empty. The * parameter can be used, it is replaced by
+ the \macro.
+\bprintv [<field1>,<field2>,...] {<if defined>} {<if not defined>}.
+ The part <if defined> is executed if <field1> or <filed2> or ...
+ is defined, else the second part <if not defined> is executed.
+ There is one filed name or the list field names separated by commas.
+ The parts cannot include any parameter.
+
+There are two special fieldnames: !author and !editor. The processed list of
+authors or editors (by repeatedly calling \authorname or \editorname) are
+used here insted of raw data.
+
+You can define print:BEGIN and/or print:END which is executed at the begin or
+end of each <entrytype>. The formatting does not solve the numbering and
+paragraph indentation of the entry. This is processed by \printbib macro
+used in OPmac (and may be redefined by the author or document designer).
+
+You can declare \bimark={something} in the print:END macro. This bibmark is
+saved to the .ref file (created by OPmac) and used in the next TeX run as \cite
+marks when \nonumcitations is set.
+
+The whole style file is read in the group during \usebib command is executed
+before typesetting the reference list. Each definition or setting is local
+here.
+
+If you are using non-standard fieldnames in .bib database and bib. style,
+you has to declare them by \CreateField {<fieldname>}.
+
+You can declare \SortingOrder in the manner documented by librarian package.
+
+If your style adds some words or abbreviations you can make them
+multilingual by saying \mtext{<label>} instead such word and
+\mtdef{<label>} {<English>} {<Czech>} {<Slovak>} declaration.
+The right part is printed by current value of the \language regiter.
+You can add more languages by re-defining the \mtdef command
+and by \sdef{lan:<language number>}{<language mark>}. See the opmac.tex
+for inspiration.
+
+If you are using \nonumcitations, then the \bibmark toks register have to be
+prepared in the style file (in print:BEGIN, print:END, in \authorname etc.)
+This value will be used in the \cite[] places in the document.
+
+The example of the style file is in opmac-bib-simple.tex.
+
+User or author of the bib. style can create the hidden field which has a
+precedence while sorting names. Example:
+
+ \CreateField {sortedby}
+ \SpecialSort {sortedby}
+
+Suppose that the .bib file includes:
+
+ ...
+ author = "Jan Chadima",
+ sortedby = "Hzzadima Jan",
+ ...
+
+Now, this author is sorted between H and I, because the Ch digraph in this
+name has to be sorted by this rule.
+
+If you need (for example) to place the autocitations before other citations,
+then you can mark your entries in .bib file by sortedby = "@", because this
+character is sorted before A.
+
+
+History:
+--------
+
+Apr. 2014: released
+Jan. 2016: "first entry wins" implemented
+Apr. 2016: \readentry -> \readbibentry, \usebib->\MakeReference
+Feb. 2018: \input librarian does not create \jobname.lbr
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end of the opmac-bib.tex