diff --git a/HISTORY.md b/HISTORY.md index ff661a16..ef1331c8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ Work in progress ---------------- - added extension modules - - packages: graphicx, hyperref, listings, tikz + - packages: biblatex, graphicx, hyperref, listings, tikz - document classes: article, book, report, scrartcl, scrbook - added file list-of-macros.md - yalafi diff --git a/list-of-macros.md b/list-of-macros.md index 4604e6e2..d73e8f4d 100644 --- a/list-of-macros.md +++ b/list-of-macros.md @@ -14,6 +14,7 @@ Please note that not everything has to be declared. [LaTeX builtins](#latex-builtins), [amsmath](#package-amsmath), [amsthm](#package-amsthm), +[biblatex](#package-biblatex), [graphicx](#package-graphicx), [hyperref](#package-hyperref), [listings](#package-listings), @@ -147,6 +148,21 @@ multiline(\*) proof +## Package biblatex + +[yalafi/packages/biblatex.py](yalafi/packages/biblatex.py), +[tests/test\_packages/test\_biblatex.py](tests/test_packages/test_biblatex.py) + +**Macros** + +\\cite, +\\Cite, +\\footcite, +\\footcitetext, +\\parencite, +\\Parencite + + ## Package graphicx [yalafi/packages/graphicx.py](yalafi/packages/graphicx.py), diff --git a/tests/test_packages/test_biblatex.py b/tests/test_packages/test_biblatex.py new file mode 100644 index 00000000..b16e1d1d --- /dev/null +++ b/tests/test_packages/test_biblatex.py @@ -0,0 +1,39 @@ + + +import pytest +from yalafi import parameters, parser, utils + +preamble = '\\usepackage{biblatex}\n' + +def get_plain(latex): + parms = parameters.Parameters() + p = parser.Parser(parms) + plain, nums = utils.get_txt_pos(p.parse(preamble + latex)) + return plain + + +data_test_macros_latex = [ + + (r'A\cite*{x}B', 'A[0]B'), + (r'A\cite[p. 15]{x}B', 'A[0, p. 15]B'), + (r'A\cite[][p. 15]{x}B', 'A[0, p. 15]B'), + (r'A\cite*[p. 15]{x}B', 'A[0, p. 15]B'), + (r'A\cite[]{x}B', 'A[0]B'), + (r'A\cite[][]{x}B', 'A[0]B'), + (r'A\cite[ ]{x}B', 'A[0, ]B'), + (r'A\cite[ ][ ]{x}B', 'A[ 0, ]B'), + (r'A\cite[See][]{x}B', 'A[See 0]B'), + (r'A\cite[See][p. 15]{x}B', 'A[See 0, p. 15]B'), + (r'A\Cite{x}B', 'A[0]B'), + (r'A\footcite{x} B', 'A B\n\n\n[0].\n'), + (r'A\footcitetext{x} B', 'A B\n\n\n[0].\n'), + (r'A\parencite{x}B', 'A[0]B'), + (r'A\Parencite{x}B', 'A[0]B'), + +] + +@pytest.mark.parametrize('latex,plain_expected', data_test_macros_latex) +def test_macros_latex(latex, plain_expected): + plain = get_plain(latex) + assert plain == plain_expected + diff --git a/yalafi/packages/__init__.py b/yalafi/packages/__init__.py index 0f3f3a7e..51891b56 100644 --- a/yalafi/packages/__init__.py +++ b/yalafi/packages/__init__.py @@ -5,6 +5,7 @@ '*': [ 'amsmath', 'amsthm', + 'biblatex', 'graphicx', 'hyperref', 'listings', diff --git a/yalafi/packages/biblatex.py b/yalafi/packages/biblatex.py new file mode 100644 index 00000000..7a79fbe4 --- /dev/null +++ b/yalafi/packages/biblatex.py @@ -0,0 +1,74 @@ + +# +# YaLafi module for LaTeX package biblatex +# +# very simple approximation +# - citation text is fixed --> variable cite_text +# - we always add [] brackets (even for \cite and \footcite) +# + +from yalafi import defs +from yalafi.defs import Macro, ModParm + +require_packages = [] + +cite_text = '0' + +def modify_parameters(parms): + + macros_latex = '' + + macros_python = [ + + Macro(parms, '\\cite', args='*OOA', repl=h_cite), + Macro(parms, '\\Cite', args='*OOA', repl=h_cite), + Macro(parms, '\\footcite', args='*OOA', repl=h_footcite), + Macro(parms, '\\footcitetext', args='*OOA', repl=h_footcite), + Macro(parms, '\\parencite', args='*OOA', repl=h_cite), + Macro(parms, '\\Parencite', args='*OOA', repl=h_cite), + + ] + + environments = [] + + return ModParm(macros_latex=macros_latex, macros_python=macros_python, + environments=environments) + + +def h_cite(parser, buf, mac, args, pos): + opt1 = args[1] + opt2 = args[2] + if len(opt1) == 1 and type(opt1[0]) is defs.VoidToken: + # only [] given + opt1 = [] + if opt2: + pre = opt1 + if len(opt2) == 1 and type(opt2[0]) is defs.VoidToken: + # only [] given + opt2 = [] + post = opt2 + else: + pre = [] + post = opt1 + + out = [defs.TextToken(pos, '[', pos_fix=True)] + if pre: + out += pre + out.append(defs.SpaceToken(out[-1].pos, ' ', pos_fix=True)) + out.append(defs.TextToken(out[-1].pos, cite_text, pos_fix=True)) + if post: + out += [defs.TextToken(out[-1].pos, ',', pos_fix=True), + defs.SpaceToken(out[-1].pos, ' ', pos_fix=True)] + out += post + out += [defs.TextToken(out[-1].pos, ']', pos_fix=True), + defs.ActionToken(out[-1].pos)] + return out + +def h_footcite(parser, buf, mac, args, pos): + out = [defs.MacroToken(pos, '\\footnote'), + defs.SpecialToken(pos, '{')] + out += h_cite(parser, buf, mac, args, pos) + out += [defs.TextToken(out[-1].pos, '.', pos_fix=True), + defs.SpecialToken(out[-1].pos, '}'), defs.ActionToken(out[-1].pos)] + return out +