From 36846a866c020aa9369708b527a1297fcd5215f9 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Thu, 9 Jul 2020 03:02:09 +0000 Subject: CTAN sync 202007090302 --- macros/latex/contrib/media9/ChangeLog | 6 + macros/latex/contrib/media9/doc/media9.pdf | Bin 3727330 -> 3735778 bytes macros/latex/contrib/media9/media9.sty | 4 +- macros/latex/contrib/media9/pdfbase.sty | 10 +- macros/luatex/latex/ekdosis/Makefile | 109 + macros/luatex/latex/ekdosis/README.md | 130 + macros/luatex/latex/ekdosis/ekdosis.dtx | 5388 ++++++++++++++++++++ macros/luatex/latex/ekdosis/ekdosis.ins | 62 + macros/luatex/latex/ekdosis/ekdosis.pdf | Bin 0 -> 362094 bytes .../latex/ekdosis/samples/Caesar_BG-6-13-1-tei.xml | 225 + .../latex/ekdosis/samples/Caesar_BG-6-13-1.pdf | Bin 0 -> 17989 bytes .../latex/ekdosis/samples/Caesar_BG-6-13-1.tex | 118 + macros/xetex/latex/nanicolle/README.md | 18 +- macros/xetex/latex/nanicolle/nanicolle-doc-en.pdf | Bin 0 -> 262772 bytes macros/xetex/latex/nanicolle/nanicolle-doc-en.tex | 296 ++ macros/xetex/latex/nanicolle/nanicolle-doc-zh.pdf | Bin 0 -> 389748 bytes macros/xetex/latex/nanicolle/nanicolle-doc-zh.tex | 355 ++ macros/xetex/latex/nanicolle/nanicolle-ex-en.pdf | Bin 0 -> 156442 bytes macros/xetex/latex/nanicolle/nanicolle-ex-en.tex | 9 + macros/xetex/latex/nanicolle/nanicolle-ex-zh.pdf | Bin 0 -> 172449 bytes macros/xetex/latex/nanicolle/nanicolle-ex-zh.tex | 10 + macros/xetex/latex/nanicolle/nanicolle-example.pdf | Bin 174330 -> 0 bytes macros/xetex/latex/nanicolle/nanicolle-example.tex | 9 - macros/xetex/latex/nanicolle/nanicolle.cls | 216 +- macros/xetex/latex/nanicolle/nanicolle.pdf | Bin 387379 -> 0 bytes macros/xetex/latex/nanicolle/nanicolle.tex | 322 -- 26 files changed, 6865 insertions(+), 422 deletions(-) create mode 100644 macros/luatex/latex/ekdosis/Makefile create mode 100644 macros/luatex/latex/ekdosis/README.md create mode 100644 macros/luatex/latex/ekdosis/ekdosis.dtx create mode 100644 macros/luatex/latex/ekdosis/ekdosis.ins create mode 100644 macros/luatex/latex/ekdosis/ekdosis.pdf create mode 100644 macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1-tei.xml create mode 100644 macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.pdf create mode 100644 macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.tex create mode 100644 macros/xetex/latex/nanicolle/nanicolle-doc-en.pdf create mode 100644 macros/xetex/latex/nanicolle/nanicolle-doc-en.tex create mode 100644 macros/xetex/latex/nanicolle/nanicolle-doc-zh.pdf create mode 100644 macros/xetex/latex/nanicolle/nanicolle-doc-zh.tex create mode 100644 macros/xetex/latex/nanicolle/nanicolle-ex-en.pdf create mode 100644 macros/xetex/latex/nanicolle/nanicolle-ex-en.tex create mode 100644 macros/xetex/latex/nanicolle/nanicolle-ex-zh.pdf create mode 100644 macros/xetex/latex/nanicolle/nanicolle-ex-zh.tex delete mode 100644 macros/xetex/latex/nanicolle/nanicolle-example.pdf delete mode 100644 macros/xetex/latex/nanicolle/nanicolle-example.tex delete mode 100644 macros/xetex/latex/nanicolle/nanicolle.pdf delete mode 100644 macros/xetex/latex/nanicolle/nanicolle.tex (limited to 'macros') diff --git a/macros/latex/contrib/media9/ChangeLog b/macros/latex/contrib/media9/ChangeLog index 66d442ad26..953a714fc0 100644 --- a/macros/latex/contrib/media9/ChangeLog +++ b/macros/latex/contrib/media9/ChangeLog @@ -1,3 +1,9 @@ +2020-05-06 + * v1.12 : media9.sty + * v0.43 : pdfbase.sty + * fix : pdfbase.sty: \pbs_pdfxform:nnnnn (dvips version) missing `newpath' + operator added + 2020-05-06 * v1.11 : media9.sty * v0.42 : pdfbase.sty diff --git a/macros/latex/contrib/media9/doc/media9.pdf b/macros/latex/contrib/media9/doc/media9.pdf index 705a7870f2..5b378b6781 100644 Binary files a/macros/latex/contrib/media9/doc/media9.pdf and b/macros/latex/contrib/media9/doc/media9.pdf differ diff --git a/macros/latex/contrib/media9/media9.sty b/macros/latex/contrib/media9/media9.sty index 259bec096f..610ff93c53 100644 --- a/macros/latex/contrib/media9/media9.sty +++ b/macros/latex/contrib/media9/media9.sty @@ -37,8 +37,8 @@ \RequirePackage{xparse} \RequirePackage{atbegshi} -\def\g@mix@date@tl{2020/05/06} -\def\g@mix@version@tl{1.11} +\def\g@mix@date@tl{2020/07/08} +\def\g@mix@version@tl{1.12} \ProvidesExplPackage{media9}{\g@mix@date@tl}{\g@mix@version@tl} {acrobat-9/X compatible media} diff --git a/macros/latex/contrib/media9/pdfbase.sty b/macros/latex/contrib/media9/pdfbase.sty index cde66c506c..9da881bd6d 100644 --- a/macros/latex/contrib/media9/pdfbase.sty +++ b/macros/latex/contrib/media9/pdfbase.sty @@ -159,8 +159,8 @@ \RequirePackage{expl3} \RequirePackage{l3keys2e} -\def\g@pbs@date@tl{2020/05/06} -\def\g@pbs@version@tl{0.42} +\def\g@pbs@date@tl{2020/07/08} +\def\g@pbs@version@tl{0.43} \ProvidesExplPackage{pdfbase}{\g@pbs@date@tl}{\g@pbs@version@tl} {driver independent access to low-level PDF features} @@ -1133,13 +1133,13 @@ %clipbox (i. e. page area) available for distilling; outlying parts %get clipped { - clippath~pathbbox~pop~pop~ - pbs@ury~sub~exch~pbs@llx~sub~exch~translate~ + clippath~pathbbox~newpath~pop~pop~translate~ + pbs@llx~neg~pbs@ury~neg~translate }?pdfmark~ %move origin (0,0) to the current position gsave~pbs@curx~pbs@cury~translate~ %distillation-bbox left and top coords - clippath~pathbbox~pop~pop~/pbs@bbox@top~exch~def~ + clippath~pathbbox~newpath~pop~pop~/pbs@bbox@top~exch~def~ /pbs@bbox@left~exch~def~ %distill graphics to XObject mark~ diff --git a/macros/luatex/latex/ekdosis/Makefile b/macros/luatex/latex/ekdosis/Makefile new file mode 100644 index 0000000000..b57cb54116 --- /dev/null +++ b/macros/luatex/latex/ekdosis/Makefile @@ -0,0 +1,109 @@ +NAME = ekdosis +SHELL = bash +CMP = lualatex-dev +PWD = $(shell pwd) +VERS = $(shell ltxfileinfo -v $(NAME).dtx|sed -e 's/^v//') +LOCAL = $(shell kpsewhich --var-value TEXMFLOCAL) +UTREE = $(shell kpsewhich --var-value TEXMFHOME) +HOMEDIR := $$HOME + +exts := md html ins dtx el +texsamples := $(basename $(wildcard $(PWD)/samples/*.tex)) +texsamplesout := $(notdir $(basename $(wildcard $(PWD)/samples/*.tex))) +findopts := $(foreach ext,$(exts),-or -iname "*.$(ext)") + +define dosamples + $(CMP) --output-dir=$(PWD)/TMP --shell-escape $1 >/dev/null + $(CMP) --output-dir=$(PWD)/TMP --shell-escape $1 >/dev/null + $(CMP) --output-dir=$(PWD)/TMP --shell-escape $1 >/dev/null + $(CMP) --output-dir=$(PWD)/TMP --shell-escape $1 >/dev/null +endef + +all: sty $(NAME).pdf + +sty: clean + $(CMP) $(NAME).ins >/dev/null + +$(NAME).pdf: $(NAME).dtx + @ echo "Make the sample files first..." + if [ ! -d $(PWD)/TMP ]; then mkdir $(PWD)/TMP; fi + $(foreach file,$(texsamples), $(call dosamples, $(file))) + mv TMP/*.pdf samples/ + mv $(texsamplesout)-tei.xml samples/ + @ echo "Build the documentation of $(NAME)..." + $(CMP) --shell-escape -recorder -interaction=batchmode $(NAME).dtx >/dev/null + biber $(NAME) >/dev/null + if [ -f $(NAME).glo ]; then makeindex -q -s gglo.ist -o $(NAME).gls $(NAME).glo; fi + if [ -f $(NAME).idx ]; then makeindex -q -s gind.ist -o $(NAME).ind $(NAME).idx; fi + $(CMP) --shell-escape --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null + $(CMP) --shell-escape --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null + $(CMP) --shell-escape --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null + $(CMP) --shell-escape --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null + $(CMP) --shell-escape --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null + +samples: clean sty + if [ ! -d $(PWD)/TMP ]; then mkdir $(PWD)/TMP; fi + $(foreach file,$(texsamples), $(call dosamples, $(file))) + mv TMP/*{\.pdf,-tei\.xml} samples/ + +clean: + rm -rf auto + rm -f $(NAME).bib $(PWD)/TMP/*.bib + rm -rf .backup + find -iname "*~" -or -iname "*.pdf" | xargs rm -rf + find ./* -type f -iname "Makefile" $(findopts) > ls-R + find ./* -type f -iname "*.tex" | grep '/samples/' >> ls-R + rsync -aPr --files-from=ls-R . .backup + rm -rf * + cp -p -r .backup/* . + rm -rf .backup + pandoc -s README.md -o about.html + +auctex: + if [ ! -d "$(HOMEDIR)/.emacs.d/auctex/auto" ]; then \ + mkdir -p $(HOMEDIR)/.emacs.d/auctex/auto; \ + fi + cp $(NAME)*.el $(HOMEDIR)/.emacs.d/auctex/auto + +distclean: clean uninst + +uninst: + rm -rf $(UTREE)/{tex,source,doc}/lualatex/$(NAME) + rm -rf $(HOMEDIR)/.emacs.d/auctex/auto/$(NAME).{el,elc} + +inst: uninst auctex all + mkdir -p $(UTREE)/{tex,source,doc}/lualatex/$(NAME) + cp $(NAME).dtx $(UTREE)/source/lualatex/$(NAME) + cp $(NAME).sty $(UTREE)/tex/lualatex/$(NAME) + cp $(NAME).lua $(UTREE)/tex/lualatex/$(NAME) + cp $(NAME).pdf $(UTREE)/doc/lualatex/$(NAME) + cp -r samples/ $(UTREE)/doc/lualatex/$(NAME) + +local: uninst auctex + $(CMP) $(NAME).ins + mkdir -p $(UTREE)/{tex,source,doc}/lualatex/$(NAME) + cp $(NAME).sty $(UTREE)/tex/lualatex/$(NAME) + cp $(NAME).lua $(UTREE)/tex/lualatex/$(NAME) + +zip: all + ln -sf . $(NAME) + zip -Drq $(PWD)/$(NAME)-$(VERS).zip $(NAME)/{samples,README.md,$(NAME).{pdf,sty,lua,el}} + rm $(NAME) + +package: distclean all + mkdir $(NAME)/ + cp Makefile README.md $(NAME).{ins,dtx,pdf} $(NAME)/ + cp -r samples/ $(NAME)/ + mkdir -p tex/lualatex/$(NAME)/ + cp *.lua *.sty tex/lualatex/$(NAME)/ + mkdir -p doc/lualatex/$(NAME)/ + cp README.md *.el *.pdf doc/lualatex/$(NAME)/ + cp -r samples/ doc/lualatex/$(NAME)/ + mkdir -p source/lualatex/$(NAME)/ + cp Makefile *.ins *.dtx source/lualatex/$(NAME)/ + zip -r $(NAME).tds.zip tex doc source + rm -rf tex/ source/ doc/ + tar czf $(NAME)-$(VERS).tar.gz $(NAME).tds.zip $(NAME)/ + rm -rf $(NAME)/ + +.PHONY: all clean distclean inst local uninst install uninstall zip package samples diff --git a/macros/luatex/latex/ekdosis/README.md b/macros/luatex/latex/ekdosis/README.md new file mode 100644 index 0000000000..4baa1e9727 --- /dev/null +++ b/macros/luatex/latex/ekdosis/README.md @@ -0,0 +1,130 @@ +--- +author: +- Robert Alessi +title: 'The ekdosis package – README file' +--- + +Overview +======== +`ekdosis` is a LuaLaTeX package designed for multilingual critical +editions. It can be used to typeset texts and different layers of +critical notes in any direction accepted by LuaTeX. Texts can be +arranged in running paragraphs or on facing pages, in any number of +columns which in turn can be synchronized or not. In addition to +printed texts, `ekdosis` can convert `.tex` source files so as to +produce `TEI xml` compliant critical editions. Database-driven +encoding under LaTeX then allows extraction of texts entered segment +by segment according to various criteria: main edited text, variant +readings, translations or annotated borrowings between texts. It is +published under the terms of the GNU General Public License (GPL) +version 3. + +Notice to the Gentle Reader +=========================== +The current state of this documentation covers the basics of +`ekdosis`, namely what should be enough to start a new document and +see how it works. v1.0 with a full documentation should be out by the +end of July. Until then, there is a web page that can be accessed, +, with a mailing list that one can +subscribe to and a section entitled “Literature” where one will find +some slides and a paper submitted to a journal. + +License and Disclamer +===================== +ekdosis – Typesetting TEI xml Compliant Critical Editions + +Copyright ⓒ 2020 Robert Alessi + +Please send error reports and suggestions for improvements to Robert +Alessi: + +- email: + +- website: + +- comments, feature requests, bug reports: + + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . + +This release of icite consists of the following source files: + +- `ekdosis.dtx` + +- `ekdosis.ins` + +- `ekdosis.el` + +- `Makefile` + +License Applicable to the Documentation +--------------------------------------- +Copyright ⓒ 2020 Robert Alessi + +The documentation file `ekdosis.pdf` that is generated from the +`ekdosis.dtx` source file is licensed under the GNU Free Documentation +License, as follows:--- + +Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; with + no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled + “GNU Free Documentation License”. + +Installation +============ +1. Run `'latex ekdosis.ins'` to produce the `ekdosis.sty` and + `ekdosis.lua` files. + +2. To finish the installation you have to move the `ekdosis.sty` and + `ekdosis.lua` files into a directory where LaTeX can find it. See + the FAQ on `texfaq.org` at for + more on this. + +Development, Git Repository +=========================== + +Browse the Code +--------------- +You can browse icite repository on the web: + + +From this page, you can download all the releases of `ekdosis`. For +instructions on how to install `ekdosis`, please see above. + +Comments, Feature Requests, Bug Reports +--------------------------------------- + + + +Download the Repository +----------------------- +`ekdosis` development is facilitated by git, a distributed version +control system. You will need to install git (most GNU/Linux +distributions package it in their repositories). + +Use this command to download the repository + + git clone http://git.robertalessi.net/ekdosis + +A new directory named icite will have been created, containing +`ekdosis`. + +Git Hosting +----------- +Make an account on and navigate (while logged in) +to . Click *Fork* and you will +have in your account your own repository of `ekdosis` where you will +be able to make whatever changes you like to. diff --git a/macros/luatex/latex/ekdosis/ekdosis.dtx b/macros/luatex/latex/ekdosis/ekdosis.dtx new file mode 100644 index 0000000000..f2700aa972 --- /dev/null +++ b/macros/luatex/latex/ekdosis/ekdosis.dtx @@ -0,0 +1,5388 @@ +% \iffalse meta-comment +% +% ekdosis -- Typesetting TEI xml compliant critical editions +% Copyright (C) 2020 Robert Alessi +% +% Please send error reports and suggestions for improvements to Robert +% Alessi +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see +% . +% +%<*internal> +\iffalse +% +%<*luapre> +--[[ +This file is part of the `ekdosis' package + +ekdosis -- Typesetting TEI xml compliant critical editions +Copyright (C) 2020 Robert Alessi + +Please send error reports and suggestions for improvements to Robert +Alessi + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +. +--]] + +% +%<*internal> +\fi +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{ekdosis.dtx} +% +%\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%\ProvidesPackage{ekdosis} +%<*package> + [2020/07/08 v0.99a Typesetting TEI xml compliant critical editions] +% +%<*driver> +\begin{filecontents}[overwrite]{\jobname.bib} +@Article{Alessi2020, + author = {Alessi, Robert}, + title = {ekdosis: Using Lua\LaTeX{} for Producing \texttt{TEI + xml} Compliant Critical Editions and Highlighting + Parallel Writings}, + journaltitle = {Journal of Data Mining and Digital Humanities}, + date = 2020, + pubstate = {submitted}, + issuetitle = {Collecting, Preserving, and Disseminating Endangered + Cultural Heritage for New Understandings through + Multilingual Approaches}, + eprinttype = {hal}, + eprint = {hal-02779803} +} + +@Book{Caesar-BG-v2, + author = {{Caesar}}, + title = {Gallic War}, + origtitle = {Guerre des Gaules}, + date = 1987, + origdate = 1926, + editor = {Constans, L.-A.}, + volume = 2, + pagination = {none}, + series = {Collection des Universités de France}, + publisher = {Les Belles Lettres}, + location = {Paris} +} + +@Book{CaesarTr, + author = {{Caesar}}, + title = {Gallic War}, + date = 1869, + editor = {McDevitte, W. A., and Bohn, W. S.}, + edition = 1, + series = {Harper's New Classical Library}, + publisher = {Harper \& Brothers}, + location = {New York}} + +@Online{DLL-TC, + author = {{Digital Latin Library}}, + title = {Textual Criticism}, + url = + {https://digitallatin.org/library-digital-latin-texts/textual-criticism}, + urldate = {2020-05-24} +} + +@Online{Mastronarde.Tarrant2017, + author = {Mastronarde, Donald J. and Tarrant, Richard J.}, + title = {Review: Guidelines for Encoding Critical Editions + for the Library of Digital Latin Texts}, + date = {2017-12-04}, + url = + {https://classicalstudies.org/scs-blog/donald-j-mastronarde/review-guidelines-encoding-critical-editions-library-digital-latin}, + organization = {Society for Classical Studies} +} +\end{filecontents} +\begin{filecontents}[overwrite]{\jobname-cfg.tex} +\footnotelayout{m} +\DeclareApparatus{default}[ + delim=\hskip0.75em, + ehook=.] +\DeclareWitness{M}{M}{\emph{Marcianus Gr.} 269}[ + settlement=Venice, + institution=Marciana Library, + msName=\emph{Marcianus Gr.}, + idno=269, + origDate=s. X] +\DeclareHand{M1}{M}{M\textsuperscript{1}}[Emendatio scribae ipsius] +\DeclareHand{M2}{M}{M\textsuperscript{2}}[Manus posterior] +% Peter and John Story: +\DeclareWitness{pjA}{A}{Manuscript A Call No 123} +\DeclareWitness{pjB}{B}{Manuscript B Call No 456} +% Caesar's Gallic War: +\DeclareWitness{cA}{A}{\emph{Bongarsianus} 81}[ + msName=\emph{Bongarsianus}, + settlement=Amsterdam, + idno=81, + institution=University Library, + origDate=s. IX--X] +\DeclareHand{cA1}{cA}{A\textsuperscript{1}}[\emph{Emendationes + scribae ipsius}] +\DeclareWitness{cM}{M}{\emph{Parisinus Lat.} 5056}[ + origDate={s. XII}] +\DeclareWitness{cB}{B}{\emph{Parisinus Lat.} 5763}[ + origDate={s. IX--X}] +\DeclareWitness{cR}{R}{\emph{Vaticanus Lat.} 3864}[ + origDate={s. X}] +\DeclareWitness{cS}{S}{\emph{Laurentianus} R 33}[ + origDate={s. X}] +\DeclareWitness{cL}{L}{\emph{Londinensis} Br. Mus. 10084}[ + origDate={s. XI}] +\DeclareWitness{cN}{N}{\emph{Neapolitanus} IV, c. 11}[ + origDate={s. XII}] +\DeclareWitness{cT}{T}{\emph{Parisinus Lat.} 5764}[ + origDate={s. XI}] +\DeclareWitness{cf}{\emph{f}}{\emph{Vindobonensis} 95}[ + origDate={s. XII}] +\DeclareWitness{cU}{U}{\emph{Vaticanus Lat.} 3324}[ + origDate={s. XI}] +\DeclareWitness{cl}{\emph{l}}{\emph{Laurentianus} Riccard. 541}[ + origDate={s. XI--XII}] +\DeclareShorthand{ca}{α}{cA,cM,cB,cR,cS,cL,cN} +\DeclareShorthand{cb}{β}{cT,cf,cU,cl} +\end{filecontents} +\documentclass{ltxdoc} + %\usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry} +\usepackage[letterpaper,margin=1.25in,left=50mm,nohead]{geometry} +\usepackage{dox} +\doxitem{Option}{option}{options} +\usepackage{microtype} +\usepackage[no-math]{fontspec} +\usepackage[latin.classic,greek.ancient,american]{babel} +\babelfont{rm}[ + SlantedFont={Old Standard}, + SlantedFeatures={FakeSlant=0.25}, + BoldSlantedFont={Old Standard}, + BoldSlantedFeatures={FakeBold=1.5,FakeSlant=0.25}]{Old Standard} +\babelfont{sf}{NewComputerModern Sans} +\babelfont{tt}{NewComputerModern Mono} +\babelfont[greek]{rm}[ + Script=Greek, RawFeature={+ss05;+ss06}, + SlantedFont={Old Standard}, + SlantedFeatures={FakeSlant=0.25}, + BoldSlantedFont={Old Standard}, + BoldSlantedFeatures={FakeBold=1.5,FakeSlant=0.25}]{Old Standard} +\babelfont[greek]{sf}[Script=Greek]{NewComputerModern Sans} +\babelfont[greek]{tt}[Script=Greek]{NewComputerModern Mono} +\babeltags{ancientgreek = greek} +\def\sg#1{\textancientgreek{#1}} +\usepackage[Old Standard]{mathfont} +\usepackage{arabluatex} +\usepackage[parnotes=roman,teiexport=tidy]{ekdosis} +\input{ekdosis-cfg} +\usepackage{xltabular} +\usepackage[prevent-all]{widows-and-orphans} +\usepackage[shortcuts,nospacearound]{extdash} +\usepackage[american]{isodate} +\usepackage{nextpage} +\usepackage{spacingtricks} +\usepackage{csquotes} +\usepackage{relsize} +\usepackage{enumitem} +\setlist{nosep} +\setlist[itemize]{label=\textendash} +\setlist[enumerate,1]{label=(\alph*)} +\newlist{remarks}{enumerate}{10} +\setlist[remarks]{ + label*=\textsc{Rem.} \arabic*, + left=0.25in, + before=\smaller} +\usepackage{manfnt} +\usepackage{lettrine} +\newcommand\danger{\lettrine[loversize=-.5]{\textdbend}{\hskip6pt}} +\usepackage{metalogox} +\usepackage{hologo} +\usepackage{xcolor} +\newbool{nocolordoc} +\definecolor{ekdcolor}{RGB}{243,241,235} +\definecolor{cinnamon}{rgb}{0.82, 0.41, 0.12} +\ifbool{nocolordoc}{ + \colorlet{ekdcolor}{white} + \colorlet{cinnamon}{black}}{} +\definecolor{gainsboro}{RGB}{222,222,222} +\PassOptionsToPackage{bookmarks=true}{hyperref} +\usepackage{xurl} +\usepackage[numbered]{hypdoc} +\usepackage[loadlang=en]{metastr} +\hypersetup{ + colorlinks, + allcolors=cinnamon, + linktocpage=true, + pdftype={Text} +} +\usepackage{uri} +\labelformat{section}{sect.~#1} +\labelformat{subsection}{sect.~#1} +\labelformat{subsubsection}{sect.~#1} +\labelformat{figure}{fig.~#1} +\newcounter{dummy} +\newcommand{\dummy}{\refstepcounter{dummy}} +\usepackage[nospace,american]{varioref} +\usepackage[style=oxnotes-inote,dashed]{biblatex} +\DeclareSourcemap{ + \maps[datatype=bibtex]{ + \map{ + \step[fieldsource=issuetitle] + \step[fieldset=journalsubtitle,origfieldval] + } + } +} +\ifbool{nocolordoc} +{ + \usepackage{fontawesome} + \def\oasymbol{\faUnlock} + \usepackage{biblatex-ext-oa} +} +{\usepackage[symbolpackage=l3draw]{biblatex-ext-oa}} +\DeclareDelimFormat[bib,biblist]{nametitledelim}{\addcomma\space} +\DeclareDelimFormat[bib,biblist]{innametitledelim}{\addcomma\space} +\renewcommand*\newunitpunct{\addcomma\space} +\newcommand*{\halurl}[1]{http://hal.archives-ouvertes.fr/#1} +\DeclareFieldFormat{eprint:hal}{% + \ifhyperref + {\href{\halurl{#1}}{hal:~\nolinkurl{#1}}} + {hal:~\nolinkurl{#1}}} +\DeclareFieldAlias{eprint:HAL}{eprint:hal} +\DeclareOpenAccessEprintUrl[always]{hal}{% + http://hal.archives-ouvertes.fr/\thefield{eprint}} +\DeclareOpenAccessEprintAlias{HAL}{hal} +\addbibresource{ekdosis.bib} +\metaset{titletext}{% + \metapick[#1]{title}% + \metacompose[#1]{subtitle}{\metaget[sep]{subtitle}}{}{}} +\metaset[print]{titletext}{% + \metatitleline[print]{title}% + \metatitleline[print]{subtitle}% + \metatitleline[print]{author}% + \metatitleline[print]{contactemail}% + \metatitlelinetwo[print]{date}[print]{draft}} +\metaset[skip]{subtitle}{\vspace{1ex}} +\metaset[skip]{author}{\vspace{2ex}} +\metaset[skip]{date}{\vspace{1ex}} +\metaset[style]{title}{\LARGE} +\metaset[style]{author}{\large} +\metaset[sep]{draft}{ -- } +\metasetlang{en-US} +\metaset{title}{ἔκδοσις} +\metaset{date}{\filedate} +\metaset{draft}{\fileversion} +\metaset{subject}{TEI xml compliant critical editions} +\metaset{subtitle}{Typesetting TEI xml Compliant Critical Editions} +\metaset[print]{subtitle}{Typesetting \texttt{TEI xml} Compliant + Critical Editions} +\metaset{author}{Robert Alessi} +\metaset{keywords}{LaTeX, Lua, TEI xml, multilingual critical + editions, alignment, segmentation} +\metaset{contactemail}{alessi@roberalessi.net} +\metaset[print]{contactemail}{\mailto[ekdosis]{alessi@robertalessi.net}} +\metaset{contacturl}{http://www.roberalessi.net} +\metaset{partof}{The ekdosis Package} +\metaset[print]{partof}{The \textsf{ekdosis} Package} +\metaset{copyrightowner}{\metapick[#1]{author}} +\metaset{copyrightdate}{2020} +\metaset{licensemessage}{Permission is granted to copy, distribute + and/or modify this document under the terms of the GNU Free + Documentation License, Version 1.3 or any later version published by + the Free Software Foundation; with no Invariant Sections, no + Front-Cover Texts, and no Back-Cover Texts. A copy of the license + is included in the section entitled ``GNU Free Documentation + License''.} +\metaset{licenseurl}{https://www.gnu.org/licenses/fdl-1.3.html} +\metaset[print]{licenseurl}{% + \url{https://www.gnu.org/licenses/fdl-1.3.html}} +\metaset[cmd]{licenselogo}{\includegraphics[scale=0.75]{#1}} +\metawritepdfinfo +\metawritepdfaux +\metawritepdfpreamble +\metawritepdfcontact +\metawritepdfrights +\usepackage{multicol} +\setlength\IndexMin{100pt} +\usepackage{tocloft} +\newlistof{listing}{lol}{List of listings} +\renewcommand\cfttocprehook{\begin{multicols}{2}} +\renewcommand\cfttocposthook{\end{multicols}} +\renewcommand\cfttoctitlefont{\Large\bfseries} +\renewcommand\cftlolprehook{\begin{multicols}{2}} +\renewcommand\cftlolposthook{\end{multicols}} +\renewcommand\cftloltitlefont{\Large\bfseries} +\usepackage{units} +\newcommand*\tred[1]{\textcolor{red}{#1}} +\usepackage{fbox} +\usepackage{tikz} +\usetikzlibrary{tikzmark} +\NewDocumentCommand{\pointto}{m}{% + \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,0.5ex) to + ([shift={(0.5em,0pt)}]pic cs:#1);% + \tikz[remember picture] \draw[color=gray, overlay] + ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} +\NewDocumentCommand{\pointtol}{m}{% + \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,0.5ex) to + [bend left] ([shift={(0.5em,0pt)}]pic cs:#1);% + \tikz[remember picture] \draw[color=gray, overlay] + ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} +\NewDocumentCommand{\pointtor}{m}{% + \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,0.5ex) to + [bend right] ([shift={(0.5em,0pt)}]pic cs:#1);% + \tikz[remember picture] \draw[color=gray, overlay] + ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} +\NewDocumentCommand{\pointtoer}{m}{% + \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,0.5ex) to + [bend right] ([shift={(0em,0pt)}]pic cs:#1);% + \tikz[remember picture] \draw[color=gray, overlay] + ([shift={(-0.5em,0.5ex)}]pic cs:#1) ellipse [x radius=45pt, y + radius=6pt];} +\usepackage[breakable, skins, xparse]{tcolorbox} +\tcbset{colback=white, boxrule=0.4pt, colframe=cinnamon, + breakable} +\usepackage[newfloat]{minted} +\labelformat{listing}{listing~#1} +\ifbool{nocolordoc}{\usemintedstyle{bw}}{} +\setminted{bgcolor=ekdcolor,linenos, fontsize=\small} +\newminted[ekdlua]{lua}{bgcolor={}, linenos, fontsize=\relsize{-0.5}, + xleftmargin=12pt, breaklines, numberblanklines=false, numbersep=3pt, + firstnumber=last} +\renewcommand{\theFancyVerbLine}{\rmfamily\smaller\arabic{FancyVerbLine}} +\usepackage[contents]{colordoc} +\newcommand{\pkg}[1]{\textsf{#1}\index{#1=#1 (package)}} +\newcommand{\env}[1]{\texttt{#1}\index{#1=#1 (environment)}} +\backgroundcolor{c}{ekdcolor} +\usepackage{caption} +\captionsetup[listing]{position=above,skip=-1ex} +\usepackage{needspace} +\NewDocumentCommand{\captof}{O{listing} m O{}}{% + \bgroup + \needspace{5\baselineskip}% + \vskip 1ex plus 2pt minus 2pt% + \captionof{#1}{#2}% + #3% + \egroup} +% \usepackage{etoc} +% \etocsettocdepth{paragraph} +% \newcommand{\ekdtableofcontents}{% +% \begingroup +% \etocsetstyle{section}{}{} +% {\etocsavedsectiontocline{% +% \numberline{\etocnumber}\etocname}{\etocpage}}{} +% \etocsetstyle{subsection}{}{} +% {\etocsavedsubsectiontocline{% +% \numberline{\etocnumber}\etocname}{\etocpage}}{}% +% \etocsetstyle{subsubsection}{}{} +% {\etocsavedsubsubsectiontocline{% +% \numberline{\etocnumber}\etocname}{\etocpage}}{}% +% \etocsetstyle{paragraph}{}{\leftskip2cm\rightskip 2.2em \parfillskip +% 0pt plus 1fil\relax \nobreak} +% {\noindent\etocname{} \etocpage{} }{\par}% +% \etocmulticolstyle[2]{\section*{Contents}} +% \pdfbookmark[1]{Contents}{toc} +% \tableofcontents +% \endgroup} +\EnableCrossrefs +\CodelineIndex +\RecordChanges + %\OnlyDescription +\begin{document} + \DocInput{\jobname.dtx} + \PrintChanges + \PrintIndex +\end{document} +% +% \fi +% +% \CheckSum{1522} +% +% \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 \~} +% +% \GetFileInfo{\jobname.dtx} +% \DoNotIndex{\newcommand,\newenvironment,\begin,\begingroup} +% \DoNotIndex{\bgroup,\def,\edef,\egroup,\else,\expandafter,\endgroup} +% \DoNotIndex{\fi,\ifdefined,\luadirect,\luastring,\luastringN} +% \DoNotIndex{\luastringO,\NewDocumentCommand,\space,\unexpanded} +% +% \pdfbookmark[1]{\metaterm{title}}{title} +% \begin{tcolorbox}[ +% colframe=black, +% enhanced, +% drop lifted shadow, +% colback=white, +% boxrule=.25mm, +% halign=center, +% center +% ] +% \metapick[print]{titletext} +% \end{tcolorbox} +% +% \begin{tcolorbox}[title=Notice to the Gentle Reader] +% The current state of this documentation covers the basics of +% \pkg{ekdosis}, namely what should be enough to start a new +% document and see how it works. v1.0 with a full documentation +% should be out by the end of July. Until then, there is a web page +% that can be accessed,\footnote{% +% \url{http://www.robertalessi.net/ekdosis}} with a mailing list +% that one can subscribe to and a section entitled +% \enquote{Literature} where one will find some slides and a paper +% submitted to a journal. +% \end{tcolorbox} +% +% \tableofcontents +% \listoflistings +% +% \changes{v0.99a}{2020/07/08}{First public release (documentation in +% progress)} +% +% \begin{abstract} +% \pkg{ekdosis} is a Lua\LaTeX{} package designed for +% multilingual critical editions. It can be used to typeset texts +% and different layers of critical notes in any direction accepted +% by Lua\TeX. Texts can be arranged in running paragraphs or on +% facing pages, in any number of columns which in turn can be +% synchronized or not. In addition to printed texts, +% \pkg{ekdosis} can convert \texttt{.tex} source files so as to +% produce \texttt{TEI xml} compliant critical +% editions. Database-driven encoding under \LaTeX{} then allows +% extraction of texts entered segment by segment according to +% various criteria: main edited text, variant readings, translations +% or annotated borrowings between texts. It is published under the +% terms of the GNU General Public License (GPL) version 3. +% \end{abstract} +% +% \section*{License and Disclaimer} +% \addcontentsline{toc}{section}{License and disclamer} +% \subsection*{License Applicable to this Document} +% \pdfbookmark[2]{Licence applicable to this document}{copyright-doc} +% \leavevmode\marginpar{\hfill\texttt{fdl1.3}} +% \metapick[print]{rightstext} (See below \vref{sec:fdl}.) +% +% \subsection*{License Applicable to the Software} +% \pdfbookmark[2]{Licence applicable to the software}{copyright-soft} +% \label{sec:license-software} +% +% \pkg{ekdosis} --- \metapick[print]{subtitle} +% \metapick[print]{copyrightstatement} +% +% Please send error reports and suggestions for improvements to Robert +% Alessi: +% \begin{itemize} +% \item email: \mailto[ekdosis package]{alessi@roberalessi.net} +% \item website: \url{http://www.robertalessi.net/ekdosis} +% \item development: \url{http://git.robertalessi.net/ekdosis} +% \item comments, feature requests, bug reports: +% \url{https://gitlab.com/ralessi/eksodis/issues} +% \end{itemize} +% +% \leavevmode\marginpar{\hfill\texttt{gpl3+}} +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see +% \href{http://www.gnu.org/licenses}% +% {\texttt{}}. +% +% This release of \pkg{ekdosis} consists of the following +% source files: +% \begin{itemize} +% \item |ekdosis.ins| +% \item |ekdosis.dtx| +% \item |ekdosis.el| +% \item |Makefile| +% \end{itemize} +% +% \section{Introduction} +% \label{sec:introduction} +% \begin{comment} +% \begin{keyfigure}{l={fig:grid-typesetting},c={Grid Typesetting +% (which never came into existence)}, t={Each square in the grid +% has a side length of \unit[10]{pt}. Therefore, the distance +% between the last line of the text and the first line of the +% apparatus is here approximately \unit[25]{pt}.}} +% \centering +% \begin{tikzpicture} +% \draw[gainsboro,thin] (0.5,0.5) grid [step=10pt] (10,5); % +% \path node [align=justify, text width=8cm] at (5.5,3) {% +% I saw my friend Peter at the station yesterday. We were both +% in a great mood. \enquote{How nice to find you here!} he +% said. I chuckled to myself, recalling the last time we +% met.\par +% \rule{3cm}{0.01cm}\par\footnotesize% +% \textbf{1}~saw A] met B\hskip1em Peter A] John B \hskip1em +% \textbf{2}~great A] good B\hskip1em \textbf{2--3}~How +% nice... said A] \emph{om.} B\hskip1em \textbf{4} \emph{post} +% met \emph{add.} there B.}; \node at (0,3) {\scriptsize +% $\approx$ \unit[25]{pt}}; \draw [->] (0,2.875) -- (0,2.025); +% \end{tikzpicture} +% \end{keyfigure} +% \end{comment} +% +% The reader will find here, by way of introduction, a summarized +% version of the first part of an article that the author submitted +% some weeks ago to the +% \mkbibemph{\citefield{Alessi2020}{journaltitle}} as a contribution +% to a Digital Humanities workshop held at Stanford University +% (\printdate{2019-04-15}).\footcite{Alessi2020} +% +% The name of this package, \pkg{ekdosis}, derives from a Greek +% action noun\---\sg{ἔκδοσις}\---the meaning of which is: +% \enquote{publishing a book}, and also in concrete sense: \enquote{a +% publication, treatise}. For us moderns, this term refers to a long +% tradition of scholarly work consisting in establishing from +% manuscript evidence the texts of Greek and Latin classics that were +% handled down through the Middle Ages to the time of the first +% printed editions. Of course, this definition is extendible to other +% languages as well. The basic premise is that critical editions +% exhibit reconstructed texts from manuscript evidence either under +% the title of the edited text (direct tradition) or from explicit +% citations or parallel passages or translations in other languages +% (indirect tradition). +% +% Whether in print or digital, critical editions come with an +% apparatus criticus in which is mentioned all the evidence that was +% used to build the edited text. Arguably, it is precisely on this +% common point that the two kind of editions part ways for reading a +% traditional, well written apparatus criticus is only meant for +% experienced readers. Getting oneself familiarized with its many +% conventional rules is not unrelated to learning a language, equipped +% with technical terms, grammar rules and style embellishments, which +% came into existence out of over three centuries of scholarly +% attainments. Nevertheless, whereas this language is immediately +% accessible to human mind's ability to use language and interpret +% conventional symbols, it is quite inaccessible to a computer unless +% every item of information has been encoded in the rather dumb format +% that is suited to machines. +% +% On the other hand, editions in print have their own limitations. For +% example, every detail that editors of classical texts decide to +% discard to save space, regardless to its relevance to the purpose of +% the edition, is lost permanently as in the case of dialectal +% coloring of ancient books. Furthermore, passages collected as +% indirect tradition are only available as references in the +% \emph{apparatus testium} and cannot be referred to the original +% text. As a result, the reader is refrained from bestowing attention +% upon major parallel passages to understand better difficult passages. +% +% To conclude on these issues, print publications and digital editions +% are often contrasted as they belonged to two different +% worlds.\footnote{For a good illustration of this point, see +% \cite[\mkbibquote{Content, not Display}]{DLL-TC}.} It is commonly +% said that the content of editions in print is the result of the +% binding of the book itself as an object, whereas digital editions, +% in which format and presentation are by definition separated from +% content, are free from limitations coming from such bindings. To sum +% up from the foregoing considerations, this statement is likely to be +% qualified: as already seen above, the apparatus criticus must be +% looked at as a brilliant production of mind refined by centuries of +% scholarly tradition\---and surely tradition must go on\---arguably +% not as compact paragraphs that require special and painful training +% to be \enquote*{decoded}. On the other hand, what editions in print +% do not provide are what \citename{Mastronarde.Tarrant2017}{author} +% have called \enquote{actionable texts for use in digital +% research},\footcite{Mastronarde.Tarrant2017} namely database-driven +% texts allowing the reader to select annotations and display or +% arrange translations, parallel passages or borrowings in a variety +% of ways. +% +% \pkg{ekdosis} can be seen as an attempt at combining the two +% approaches. +% +% \subsection{Requirements} +% \label{sec:requirements} +% Please refer to \vref{ref:ekdrequirements}. +% +% \subsection{Features} +% \label{sec:features} +% A list of the main features of \pkg{ekdosis} follows:--- +% \begin{enumerate} +% \item \label{it:multicol-feature}\emph{Multilingual critical +% editions\/}: \pkg{ekdosis} can be used to typeset any number of +% texts in any direction accepted by \hologo{LuaTeX}. Running +% paragraphs of text can be arranged in any number of columns, +% either on single or facing pages, which in turn can be +% synchronized or not. \pkg{ekdosis} is also suitable for complex +% layouts as in the case of Arabic poetry or images where three-way +% alignment is required, or diagrams, \emph{\&c}. +% \item \emph{Apparatus criticus\/}: Edited texts can receive multiple +% layers of apparatus, e.g.\ apparatus criticus (to record variant +% readings), apparatus fontium (to collect references to texts quoted +% or cited in the edited text), apparatus testium (to collect +% testimonia or parallel passages), or any kind of short notes to be +% printed on the same page as the edited text, \emph{\&c}. +% \item \texttt{TEI xml} output: \pkg{ekdosis} can be instructed +% to output both PDF and \texttt{TEI xml} files at the same time. +% \item \emph{Database-driven encoding} under \LaTeX{} of texts +% entered segment by segment allows for alignment of parallel texts +% from multilingual corpora. +% \end{enumerate} +% +% Before going into detail, the following simple example will give the +% reader a general idea of the method of encoding with +% \pkg{ekdosis} authoritative texts composed of lemmata, in a way +% that is very close to \texttt{TEI xml} encoding:--- +% +% \captof{The \enquote{Peter/John} basic example}[\label{lst:pj1}] +% \iffalse +%<*example> +% \fi +\begin{minted}{latex} +\begin{ekdosis} + I + \app{ + \lem{saw} + \rdg{met} + } + my friend \app{\lem{Peter}\rdg{John}} at the station yesterday. +\end{ekdosis} +\end{minted} +% \iffalse +% +% \fi +% +% \needspace{4\baselineskip}PDF output:--- +% \medskip +% \begin{alignment}[tcols=1,texts=specimen,apparatus=specimen] +% \begin{specimen} +% I +% \app{ +% \lem{saw} +% \rdg{met} +% } +% my friend +% \app{ +% \lem{Peter} +% \rdg{John} +% } +% at the station yesterday. +% \end{specimen} +% \end{alignment} +% +% \texttt{TEI xml} output:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{xml} +

I + + saw + met +my friend + + Peter + John +at the station yesterday.

+\end{minted} +% \iffalse +% +% \fi +% +% As can be seen from \vref{lst:pj1}, the edition text is inserted in +% the \env{ekdosis} environment (l.~1 to 8). Then two +% \cs{app}\marg{apparatus entry} commands (ll.~3 and 7) contain the +% lemma (\cs{lem}\marg{lemma}), namely the reading that is accepted by +% the editor, and at least one variant reading +% (\cs{rdg}\marg{reading}, ll.~5 and 7). As the listing shows, the +% editor is free to lay out the code in a legible manner to the eye: +% the first lemma above spans several lines whereas the second one is +% written in sequence without spaces. +% +% In the PDF ouput, the edition text is printed in the upper part of +% the page, above the line, and naturally shows the accepted +% readings. The margins are used for numeration. In the apparatus +% criticus, below the line, reference to the text is made by +% specifying the number of the line and if several entries refer to +% the same line, numbers are not repeated. Instead, entries are +% separated from one another by a broad horizontal space. Finally, a +% square bracket is used inside entries to distinguish the lemma from +% the variant readings. +% +% Furthermore, as said above, if a \texttt{TEI xml} output be +% required, \pkg{ekdosis} compiles an additional |.xml| file an +% excerpt of which is provided above. +% +% \section{The Basics of \pkg{ekdosis}} +% \label{sec:ekdosis-basics} +% +%\subsection{Loading the Package\---General Options} +%\label{sec:load-general-options} +% +% \pkg{ekdosis} is loaded in the preamble like so:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\usepackage{ekdosis} +\end{minted} +% \iffalse +% +% \fi +% +% \pkg{ekdosis} may be loaded with four optional \enquote*{named +% arguments} either of which is set using the syntax +% \meta{key}$=$\meta{value}. The description of the optional arguments +% follows. +% +% \danger The reader is invited to refer to the relevant sections of +% this documentation for more information on how to use them. +% +% \DescribeOption{layout}\label{ref:layout-opt} +% |layout|$=$\verb+float|footins+\hfill\tcboxverb{Default: float}\\ +% By default, layers of critical notes are inserted as a floating +% environment to be printed at the bottom of pages. |layout=footins| +% can be set to insert critical notes in the default footnote block +% which can be considered to be a special kind of float that is +% printed at the bottom of pages. In this case, the apparatus criticus +% will be inserted between regular numbered footnotes, but will carry +% no footnote mark of its own. +% +% \DescribeOption{divs}\label{ref:divs-opt} +% |divs|$=$\verb+ekdosis|latex+\hfill\tcboxverb{Default: ekdosis}\\ +% In many occasions, \LaTeX{} standard textual divisions do not meet +% the specific requirements of classical and literary texts, the +% divisions of which may depend on many different received +% traditions. \pkg{ekdosis} provides a flexible mechanism in which +% format and presentation have been carefully separated from +% content. It is designed to build un-numbered \texttt{TEI} divisions +% allowed to nest recursively. However, if |divs| be set to |latex|, +% \LaTeX{} standard textual divisions can be used and will be +% translated into \texttt{TEI} numbered |
| elements. +% +% \danger It must be noted that the two styles are mutually exclusive. +% \vskip\baselineskip +% +% \DescribeOption{parnotes}\label{ref:parnotes-opt} +% |parnotes|$=$\verb+true|false|roman+% +% \hfill\tcboxverb{Default: not set}\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. Apparatus criticus typeset by \pkg{ekdosis} may +% contain notes and footnotes. The latter can be laid out as +% paragraphed notes below the block of critical notes by means of the +% \pkg{parnotes} package. Additionally, |parnotes=roman| prints these +% footnotes numbered with Roman numerals. +% +% \DescribeOption{teiexport}\label{ref:teiexport-option} +% |teiexport|$=$\verb+true|false|tidy+% +% \hfill\tcboxverb{Default: not set}\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. If |teiexport| be set to |true|, \pkg{ekdosis} is +% instructed to output both PDF and \texttt{TEI xml} files at the same +% time. By default, the \texttt{TEI} file will receive the same +% basename as the |.tex| source file, suffixed with |-tei.xml|. The +% raw |.xml| file that is produced by \pkg{ekdosis} can be further +% processed by the \textsf{tidy} console application.\footnote{See +% \url{http://www.html-tidy.org}.} To make this happen, \textsf{tidy} +% must be installed and the |.tex| source file must be compiled with +% the |--shell-escape| facility so that spawning programs from +% \LaTeX{} can be allowed.\footnote{See +% \url{https://texfaq.org/FAQ-spawnprog} for more information on how +% to do this.} +% +% As an example, the following line loads \pkg{ekdosis} and instructs +% it to output a \texttt{TEI xml} file (in addition to the PDF one) +% and to use \pkg{parnotes} to format with Roman numerals the footnotes +% that are inserted in the apparatus criticus:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\usepackage[teiexport, parnotes=roman]{ekdosis} +\end{minted} +% \iffalse +% +% \fi +% +% \subsection{Witnesses, Hands, Shorthands \& Scholars } +% \label{sec:declarations} +% Any reference that is to be used in the apparatus criticus must be +% \enquote{declared} in the preamble beforehand, namely: manuscript +% sigla (either for single manuscripts or manuscript families, primary +% or later hands, \emph{\&c.}) or abbreviated last names of scholars. +% To that effect, \pkg{ekdosis} provides the following preamble-only +% commands:--- +% \begin{comment} +% \begin{xltabular}[c]{0.4\linewidth}{lXr} +% \caption*{\textbf{Conspectus Siglorum}}\\ +% \SigLine{M}\\ +% \end{xltabular} +% \end{comment} +% +% \paragraph{Witnesses} +% \DescribeMacro{\DeclareWitness} \cs{DeclareWitness}\marg{unique +% id}\marg{rendition}\marg{description}\oarg{options}\\ +% This command requires three mandatory arguments enclosed between +% curly braces used to specify consecutively: +% \begin{enumerate} +% \item The unique identifier of the witness to be used both in the +% |.tex| source file and as an |xml:id| in the \texttt{TEI xml} +% output if any. +% \item The rendition to be used in the printed apparatus criticus, +% which also will be found within the || element of the +% \texttt{TEI} header where the description of the witness occurs, +% within a || element. +% \item A basic description of the manuscript to be found in a typical +% printed Conspectus Siglorum, namely: the name of the manuscript +% followed by its call number. +% \end{enumerate} +% Finally, the optional argument of \cs{DeclareWitness} accepts a +% comma-separated list of the following \enquote{name=value} arguments +% that are used to collect items of information to be found within +% the || element in the \texttt{TEI} +% header:---\footnote{See +% \url{https://tei-c.org/release/doc/tei-p5-doc/en/html/MS.html\#msid} +% for detailed information on these elements.}\\ +% \DescribeOption{settlement} |settlement|$=$\meta{name}: The name of +% a city or administrative unit.\\ +% \DescribeOption{institution} |institution|$=$\meta{name}: The name +% of an institution such as a university or library.\\ +% \DescribeOption{repository} |repository|$=$\meta{name}: The name of +% the repository within which the witness is stored.\\ +% \DescribeOption{collection} |collection|$=$\meta{name}: The name of +% a collection of manuscripts.\\ +% \DescribeOption{idno} |idno|$=$\meta{call \#}: Any form of call +% number.\\ +% \DescribeOption{msName} |msName|$=$\meta{name}: The name commonly +% used for the witness.\\ +% \DescribeOption{origDate} |origDate|$=$\meta{date}: Any form of date +% used to identify the date of origin for the witness. +% +% To take here one example, a witness such as the \emph{Marcianus +% Graecus}~269, referred to as manuscript \enquote*{M} in the +% editions, which contains sixty treatises from Hippocrates, could be +% declared as follows:--- \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\DeclareWitness{M}{M}{\emph{Marcianus Gr.} 269}[ + settlement=Venice, + institution=Marciana Library, + msName=\emph{Marcianus Gr.}, + idno=269, + origDate=s. X] +\end{minted} +% \iffalse +% +% \fi +% +% \paragraph{Hands} +% \DescribeMacro{\DeclareHand} \cs{DeclareHand}\marg{unique +% id}\marg{base ms.}\marg{rendition}\oarg{note}\\ +% This command requires three mandatory arguments enclosed between +% curly braces and one optional argument between square brackets used +% to specify consecutively:--- +% \begin{enumerate} +% \item The unique identifier of the hand to be used both in the +% |.tex| source file and as an |xml:id| in the \texttt{TEI xml} output +% if any. +% \item The unique idendifier of the witness the hand is related +% to. Of course, this witness must have been declared beforehand. +% \item The rendition to be used in the printed apparatus criticus, +% which also will be found within the || element of the +% \texttt{TEI} header where the description of the hand occurs, within +% a || element. +% \item Some further information about the hand. +% \end{enumerate} +% +% To continue the preceding example, here is how additions and +% corrections found in the \emph{Marcianus Gr.}~269 could be declared +% after this witness has been declared itself:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\DeclareHand{M1}{M}{M\textsuperscript{1}}[Emendatio scribae ipsius] +\DeclareHand{M2}{M}{M\textsuperscript{2}}[Manus posterior] +\end{minted} +% \iffalse +% +% \fi +% +% As can be seen, values such as |M|, |M1| and |M2| in the |.tex| +% source file will be printed as \getsiglum{M}, \getsiglum{M1} and +% \getsiglum{M2} respectively. Not only the code gains legibility, but +% also flexibility for simply changing any declared rendition will +% update corresponding sigla thoughout the entire edition. +% +% As a final example, here is how \pkg{ekdosis} would encode +% information as declared above for the \emph{Marcianus Gr.}~269 +% should a \texttt{TEI} output be required:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{xml} + + + + M + Marcianus Gr.269 + + + Venice + Marciana Library + 269 + + Marcianus Gr. + + + + + + M + 1 +

Emendatio scribae ipius

+
+ + M + 2 +

Manus posterior

+
+
+
+ + + s. X + + +
+
+
+\end{minted} +% \iffalse +% +% \fi +% +% \paragraph{Shorthands} +% \DescribeMacro{\DeclareShorthand} \cs{DeclareShorthand}\marg{unique +% id}\marg{rendition}\marg{csv list of witnesses}\\ +% This command provides a convenient way to declare \emph{families} of +% witnesses. It takes three mandatory arguments used to specify +% consecutively:--- +% \begin{enumerate} +% \item The unique identifier of the family to be used in the |.tex| +% source file. +% \item The rendition to be used in the printed apparatus criticus. +% \item A comma-separated list of previously declared witnesses. +% \end{enumerate} +% +% As an example, the manuscripts of Caesar's \emph{Gallic War} are +% divided into two families: α, which includes mss.\ A, M, B, R, S, L +% and N, and β, which includes mss.\ T, f, U and l. Therefore, +% provided that all these witnesses have been already declared, here +% is how the two families α and β could be +% declared:---\footnote{These witnesses are used in the example +% provided below in \vref{lst:caesar-bg}.} +% \label{ref:caesar-bg-sigla} +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\DeclareShorthand{a}{α}{A,M,B,R,S,L,N} +\DeclareShorthand{b}{β}{T,f,U,l} +\end{minted} +% \iffalse +% +% \fi +% +% Then, symbols |a| and |b| can be used in the |.tex| source file in +% place of manuscripts that belong to either family. +% +% \paragraph{Scholars} +% \DescribeMacro{\DeclareScholar} \cs{DeclareScholar}\marg{unique +% label}\marg{rendition}\\ +% The \emph{Conspectus Siglorum} that is placed ahead of the edition +% text is traditionally divided into two parts: a)~\emph{Codices}, +% which provides the list of sigla used in the apparatus, +% b)~\emph{Editiones uel Studia}, which provides references to +% scholars whose published or unpublished works contain conjectures +% used in the apparatus criticus. \cs{DeclareScholar} takes two +% mandatory arguments used to specify consecutively:--- +% \begin{enumerate} +% \item A unique label used in the |.tex| source file to refer to the +% work where the conjecture is found. +% \item The rendition to be used in the printed apparatus criticus. +% \end{enumerate} +% +% As \pkg{ekdosis} can include and use \texttt{TEI xml} compliant +% lists of references, it is avisable to use Bib\hologo{(La)TeX} +% labels in the first argument of \cs{DeclareScholar}. Likewise, +% shorthands fields from the bibliographical database can be recalled +% from within the second argument of \cs{DeclareScholar}:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\DeclareScholar{Wil}{Wilamowitz} +% or for example: +\DeclareScholar{Wil}{\citename{Wil}{shorteditor}} +\end{minted} +% \iffalse +% +% \fi +% \label{sec:declarations-end} +% +% \subsection{Editing a Single Text With No Translation} +% \label{sec:single-text-editing} +% \DescribeEnv{ekdosis} +% Running paragraphs of one single text to be edited should be +% inserted in the \env{ekdosis} environment, like so:---\footnote{See +% above \vref{lst:pj1}.} +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\begin{ekdosis} + Edition text goes here. +\end{ekdosis} +\end{minted} +% \iffalse +% +% \fi +% +% \paragraph{Apparatus Entries} +% \DescribeMacro{\app} \cs{app}|[type=|\meta{type}|]|\marg{apparatus +% entries}\\ +% This command takes one mandatory argument and accepts one optional +% argument. Once references to be used as witnesses in the apparatus +% criticus have been declared in the preamble as described in +% \ref{sec:declarations} +% \vpagerefrange{sec:declarations}{sec:declarations-end}, the \cs{app} +% command is used for inserting entries in the apparatus criticus, +% either lemmata, readings or notes, like so:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +I saw my friend \app{\lem{Peter}\rdg{John}} yesterday. +or: +I saw my friend + \app{ + \lem{Peter} + \rdg{John} + } +yesterday. +\end{minted} +% \iffalse +% +% \fi +% \cs{app} accepts one further optional argument:---\\ +% \DescribeOption{type} |type|$=$\meta{type}\hfill% +% \tcboxverb{Default: default}\\ +% By default, \pkg{ekdosis} sets one layer of notes\--- the |default| +% layer\---in the apparatus criticus. This layer is fit to receive +% notes related to variant readings from witnesses and sources used by +% the editor to establish the edition text. Additional layers can be +% defined to receive other kinds of notes, such as references to texts +% quoted or cited in the text of the edition (\emph{apparatus +% fontium}), references to testimonia, or quotations of the edited +% text by other authors (\emph{apparatus testium}), explanatory notes, +% and so forth.\footnote{See below, \vref{ref:type-app}.} Once +% additional layers have been defined and assigned to new +% \enquote*{types}, such as \enquote*{testium} and the like, these +% types can be used as values appended to the |type| \enquote*{named +% option}. +% +% \paragraph{Base text and variants} As can be seen in the example +% above, there are two kinds of individual readings: the \emph{lemma}, +% which contains the base text accepted by the editor, and the +% \emph{reading}, which contains deviant readings rejected by the +% editor. +% +% \paragraph{Lemmata} \DescribeMacro{\lem} +% \cs{lem}\oarg{options}\marg{lemma text}\\ +% As \meta{lemma text} is a word or a phrase judged by the editor to +% be authentic or authoritative, \cs{lem} prints it by default both in +% the edition text and as the first part of a new entry in the +% apparatus criticus, preceded by the line number where it occurs or a +% broad space if the entry refers to the same line as the preceding +% entry. \label{ref:lem-opts-b}The optional argument of \cs{lem} +% accepts the following +% comma-separated list of \enquote{name$=$value} arguments:---\\ +% \DescribeOption{wit} |wit|$=$\meta{csv list of witnesses}\\ +% While a single witness may be recorded as in |wit=A|, +% comma-separated lists of multiple witnesses must obviously be +% enclosed in curly braces, like so: +% |wit={A,B,C}|. \label{ref:mss-sep-families}It must be noted +% that witnesses can be grouped by using spaces as separators, like +% so: \verb*|wit={A,B,C, D,E,F}|.\\ +% \DescribeOption{alt} |alt|$=$\meta{alternate lemma}\\ +% While the mandatory argument of \cs{lem}, \meta{lemma text}, is +% always used to print the edition text in the upper part of the page, +% \meta{alternate lemma}, if specified, supersedes what is printed in +% the related entry of the apparatus criticus. This mechanism is useful +% in more than one respect. For instance, it can be used to insert +% abbreviated lemmata in the apparatus criticus, or to introduce an +% alternate way of writing entries with Latin technical terms in the +% apparatus criticus as will be demonstrated below in the example +% provided by \vref{lst:pj2}.\\ +% \DescribeOption{sep} |sep|$=$\meta{separator}\\ +% |sep| allows to change the symbol used to separate the lemma text +% from deviant readings, which is by default the closing square +% bracket (|]|)\\ +% \DescribeOption{nosep} |nosep|$=$\verb+true|false+\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. Obviously, |nosep| removes the separator mentioned +% above.\\ +% \DescribeOption{nolem} |nolem|$=$\verb+true|false+\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. |nolem| completely removes the lemma text from the +% related +% entry in the apparatus criticus.\\ +% \DescribeOption{type} |type|$=$\meta{value}\\ +% This named argument has no effect on the apparatus criticus of the +% edition in print, but it is used in the \texttt{TEI xml} ouput to +% classify the variation recorded in the entry according to some +% convenient typology. Categories such as lexical, morphological, +% orthographical and the like may apply. +% +% Finally, four named arguments can be used to insert words at the +% following specific places in the lemma text:\\ +% \noindent +% \fparbox*{\centered{\textbf{1} \tikzmark{pre}\tred{pre} Peter +% \tikzmark{post}\tred{post} \tikzmark{prewit}\tred{prewit} +% \getsiglum{pjA} +% \tikzmark{postwit}\tred{postwit}] John \getsiglum{pjB}}}\\ +% \DescribeOption{pre} |pre|$=$\meta{words}\pointtol{pre}\\ +% |pre| inserts \meta{words} \emph{before} the lemma text.\\ +% \DescribeOption{post} |post|$=$\meta{words}\pointto{post}\\ +% |post| inserts \meta{words} \emph{after} the lemma text.\\ +% \DescribeOption{prewit} |prewit|$=$\meta{words}\pointto{prewit}\\ +% |prewit| inserts \meta{words} \emph{before} the list of witnesses.\\ +% \DescribeOption{postwit} |postwit|$=$\meta{words}\pointtor{postwit}\\ +% |postwit| inserts \meta{words} \emph{after} the list of witnesses. +% \label{ref:lem-opts-e} +% +% \paragraph{Readings} \DescribeMacro{\rdg} +% \cs{rdg}\oarg{options}\marg{variant reading}\\ +% As \meta{reading} is a word or a phrase judged by the editor to be +% unsatisfactory or corrupted, \cs{rdg} prints it by default in the +% last part of the corresponding entry in the apparatus criticus, +% after the symbol that is used to separate words of the base text +% (the lemma text) from words rejected by the editor. The optional +% argument of \cs{rdg} accepts a comma-separated list of +% \enquote{name$=$value} arguments that is almost identical to +% \cs{app}. Therefore, emphasis will be placed here only on the +% differences. The reader is invited to refer to the description +% provided above \vpagerefrange{ref:lem-opts-b}{ref:lem-opts-e} for +% more detailed information:---\\ +% \DescribeOption{wit} |wit|$=$\meta{csv list of witnesses}\\ +% \DescribeOption{alt} |alt|$=$\meta{alternate reading}\\ +% \DescribeOption{nordg} |nordg|$=$\verb+true|false+\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. |nordg| completely removes the variant reading from +% the related entry in the apparatus criticus.\\ +% \DescribeOption{type} |type|$=$\meta{value}\\ +% \DescribeOption{pre} |pre|$=$\meta{words}\\ +% \DescribeOption{post} |post|$=$\meta{words}\\ +% \DescribeOption{prewit} |prewit|$=$\meta{words}\\ +% \DescribeOption{postwit} |postwit|$=$\meta{words}\\ +% +% \paragraph{Notes} +% \DescribeMacro{\note}\DescribeMacro{\note*} +% \cs{note}\oarg{options}\marg{text} or +% \cs{note*}\oarg{options}\marg{text}\\ +% It may happen that editorial notes be needed to record short +% comments of general nature \emph{between} lemmata and +% readings. \cs{note} inserts inline comments while \cs{note*} places +% comments below the entire apparatus block. Furthermore, if +% \pkg{ekdosis} has been loaded with the |parnotes| option as +% described above \vpageref{ref:parnotes-opt}, \cs{note*} will use the +% \pkg{parnotes} package to lay out the notes as an additional +% paragraph below the apparatus criticus. The optional argument of +% \cs{note}/\cs{note*} accepts the following comma-separated list of +% \enquote{name$=$value} +% arguments:---\\ +% \DescribeOption{pre} |pre|$=$\meta{words}\\ +% |pre| inserts \meta{words} immediately before the note.\\ +% \DescribeOption{post} |post|$=$\meta{words}\\ +% |post| inserts \meta{words} immediately after the note.\\ +% +% \danger Under no circumstances is it permitted to insert the command +% \cs{note} or \cs{note*} inside the argument of \cs{lem} or +% \cs{rdg}. \cs{note}/\cs{note*} must go \emph{between} these +% commands. As a general rule, within \cs{app}|{}| elements, notes +% are inserted immediately \emph{after} the lemma or the variant +% reading they are related to. +% +% \Vref{lst:pj2} provides an illustration of some of the possibilities +% afforded by the commands just described:--- +% +% \captof{The \enquote{Peter/John} full example}[\label{lst:pj2}] +% \iffalse +%<*example> +% \fi +\begin{minted}{latex} +\begin{ekdosis} + I + \app{ + \lem[wit=A]{saw} + \rdg[wit=B]{met}} + my friend + \app{ + \lem{Peter} + \rdg{John} + } + at the station yesterday. We were both in a + \app{ + \lem[wit=A]{great} + \rdg[wit=B]{good}} + mood. + \app{ + \lem[wit=A, alt={How nice... said}]{\enquote{How nice to find + you here!} he said.} + \note*{There are no quotation marks in the mss.} + \rdg[wit=B, alt=\emph{om.}]{}} + I chuckled to myself, recalling the last time we + \app{ + \lem[wit=A,nolem]{met} + \rdg[wit=B, alt={\emph{post} met \emph{add.} there}]{met + there} + \note*{Ms. \getsiglum{B} provides other additions of this kind.}}. +\end{ekdosis} +\end{minted} +% \iffalse +% +% \fi +% \resetlinenumber +% \begin{alignment}[tcols=1,texts=specimen,apparatus=specimen] +% \begin{specimen} +% I \app{\lem[wit=pjA]{saw}\rdg[wit=pjB]{met}} my friend +% \app{ +% \lem{Peter} +% \rdg{John} +% } +% at the station yesterday. We were both in a +% \app{ +% \lem[wit=pjA]{great} +% \rdg[wit=pjB]{good}} +% mood. +% \app{ +% \lem[wit=pjA, alt={\textooquote How nice... said}]{\enquote{How +% nice to find you here!} he said.} +% \note*{There are no quotation marks in the mss.} +% \rdg[wit=pjB, alt=\emph{om.}]{}} +% I chuckled to myself, recalling the last time we +% \app{ +% \lem[wit=pjA,nolem]{met} +% \rdg[wit=pjB, alt={\emph{post} met \emph{add.} there}]{met +% there} +% \note*{Ms. \getsiglum{pjB} provides other additions of this kind.}}. +% \end{specimen} +% \end{alignment} +% +% \begin{remarks} +% \item Close examination of lines~17--8 from \vref{lst:pj2} shows how +% |alt| has been used to insert an abbridged lemma text in the +% apparatus criticus in print while keeping safe what is to be found +% in the \texttt{TEI xml} output. +% \item The same technique has been used at line~24 to insert +% alternate words, including Latin technical terms, in place of the +% variant reading. Hence the use of |nolem| at line~23 to remove the +% lemma text from the apparatus criticus in print. +% \item \cs{note*} has been used to insert short annotations in two +% places (ll.~19 and 26). +% \item For an example of the use of |nordg|, see below +% \vref{lst:caesar-bg}, l.~11. +% \end{remarks} +% +% The corresponding \texttt{TEI xml} output produced by \pkg{ekdosis} +% from the \LaTeX{} source file follows:--- +% +% \captof{The \enquote{Peter/John} full example: \texttt{TEI xml} +% output}[\label{lst:pj2-tei}] +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{xml} +

I + + saw + met +my friend + + Peter + John +at the station yesterday. We were both in a + + great + good +mood. + + + How nice to find you here! he said. + There are no quotation marks in the mss. + +I chuckled to myself, recalling the last time we + + met + met there + Ms. + Bprovides other additions of + this kind. +.

+\end{minted} +% \iffalse +% +% \fi +% +% \section{Alignment of Parallel Texts} +% \label{sec:alignment-basic} +% As already said above,\footnote{See point +% \vref{it:multicol-feature}.} \pkg{ekdosis} can arrange sundry texts +% in parallel columns\---synchronized or not\---either on the same +% page or on facing pages. Depending on what is needed, any text can +% be equipped with an apparatus criticus. The most common example is +% that of an edition of a classical text with an apparatus criticus +% accompanied by a translation into a modern language on the facing +% page. One can also imagine an edition of two classical texts or two +% different recensions of the same text, each of which provides +% variants recorded in separate apparatus crititus, laid out on the +% left-hand pages, with one or more translations on the corresponding +% right-hand pages, and so forth. +% +% \paragraph{The \env{alignment} Environment} +% \DescribeEnv{alignment} \cs{begin}|{alignment}|\oarg{options}\dots +% \cs{end}|{alignment}|\label{ref:alignment-syntax}\\ +% This environment can be used as it is provided to typeset a standard +% critical edition, namely an edition text, equipped with an apparatus +% criticus and laid out on the left-hand pages, accompanied by a +% translation into a modern language on the facing pages. +% +% \DescribeEnv{edition}\DescribeEnv{translation} Within +% \env{alignment}, two environments are available by default: +% \cs{begin}|{edition}|\allowbreak\dots +% \cs{end}|{ed|\allowbreak|ition}| and \cs{begin}|{translation}|\dots +% \cs{end}|{translation}|. Obviously, the former is used to typeset +% the edition text with an apparatus criticus on the left, while the +% latter is used to typeset the translation on the right, like so:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\begin{alignment} + \begin{edition} + First § of the edition text. + \end{edition} + \begin{translation} + First § of the translation. + \end{translation} + \begin{edition} + Second § of the edition text. + \end{edition} + \begin{translation} + Second § of the translation. + \end{translation} +\end{alignment} +\end{minted} +% \iffalse +% +% \fi +% +% \DescribeEnv{edition*}\DescribeEnv{translation*} Furthermore, +% so-called \enquote{starred} versions of these environments can be +% used at any point to synchronize texts, that is to print them in +% such a way that the tops of all paragraphs are vertically +% aligned. To that effect, it must be noted that merely applying this +% command on a single environment\---for instance the leftmost +% one\---will have all other associated paragraphs printed aligned. +% +% \danger While the whole edition text and the whole translation can +% be inserted in a single \env{edition}/\env{translation} environment +% respectively, it is recommended to enter both texts paragraph by +% paragraph as shown in the example above. Not only this method of +% encoding allows not to lose sight of paragraphs that are meant to be +% read together, but it is also the only way to align paragraphs in +% print, and it is much more suitable to mark up correspondence +% between spans of texts as will be demonstrated below in +% \vref{ref:segmentation}. +% +% As an illustration, a short extract of Caesar's \emph{Gallic War}, +% VI, XIII.1 follows.\footnote{Latin text: \cite{Caesar-BG-v2}; +% English translation: \cite{CaesarTr}.} See the list of sigla for +% manuscripts and manuscript families above +% \vpageref{ref:caesar-bg-sigla}. As this document is not set for +% duplex printing, both texts have been put together on the same +% page. However, the reader will find the full |.tex| source file +% in \vref{sec:caesar-gw-tex} and \texttt{TEI xml} output in +% \vref{sec:caesar-gw-tei}. The corresponding PDF output is available +% in \href{samples/Caesar_BG-6-13-1.pdf}{a separate file}:--- +% +% \captof{Caesar's \emph{Gallic War}, VI, 13.1}[\label{lst:caesar-bg}] +% \iffalse +%<*example> +% \fi +\begin{minted}{latex} +\begin{alignment} + \begin{edition} + \ekddiv{head=XIII, depth=2, n=6.13, type=section} + In omni Gallia eorum hominum qui \app{ + \lem[wit=a]{aliquo} + \rdg[wit=b, alt=in al-]{in aliquo}} + sunt numero atque honore genera sunt duo. Nam plebes paene + seruorum habetur loco, quae \app{ + \lem[wit={A,M}, alt={nihil audet (aut et \getsiglum{A1}) + per se}]{nihil audet per se} + \rdg[wit=A1,nordg]{nihil aut et per se} + \rdg[wit={R,S,L,N}]{nihil habet per se} + \rdg[wit=b]{per se nihil audet}}, \app{ + \lem[wit=a]{nullo} + \rdg[wit=b]{nulli}} adhibetur \app{ + \lem{consilio} + \rdg[wit={T, U}, alt=conc-]{concilio}}. + \end{edition} + \begin{translation} + \ekddiv{head=XIII, depth=2, n=6.13, type=section} + Throughout all Gaul there are two orders of those men who are of + any rank and dignity: for the commonality is held almost in the + condition of slaves, and dares to undertake nothing of itself, + and is admitted to no deliberation. + \end{translation} +\end{alignment} +\end{minted} +% \iffalse +% +% \fi +% +% \resetlinenumber +% \ekdfmtdiv{2}{}{.} +% \begin{alignment}[lcols=2, +% texts=edition[xml:lang="la"]; +% translation[xml:lang="en"]] +% \AtBeginEnvironment{edition}{\selectlanguage{latin}} +% \AtBeginEnvironment{translation}{\selectlanguage{american}} +% \begin{edition} +% \ekddiv{head=XIII, depth=2, n=6.13, type=section} +% In omni Gallia eorum hominum qui \app{ +% \lem[wit=ca]{aliquo} +% \rdg[wit=cb, alt=in al-]{in aliquo}} +% sunt numero atque honore genera sunt duo. Nam plebes paene +% seruorum habetur loco, quae \app{ +% \lem[wit={cA,cM}, alt={nihil audet (aut et \getsiglum{cA1}) +% per se}]{nihil audet per se} +% \rdg[wit=cA1,nordg]{nihil aut et per se} +% \rdg[wit={cR,cS,cL,cN}]{nihil habet per se} +% \rdg[wit=cb]{per se nihil audet}}, \app{ +% \lem[wit=ca]{nullo} +% \rdg[wit=cb]{nulli}} adhibetur \app{ +% \lem{consilio} +% \rdg[wit={cT, cU}, alt=conc-]{concilio}}. +% \end{edition} +% \begin{translation} +% \ekddiv{head=XIII, depth=2, n=6.13, type=section} +% Throughout all Gaul there are two orders of those men who are of +% any rank and dignity: for the commonality is held almost in the +% condition of slaves, and dares to undertake nothing of itself, +% and is admitted to no deliberation. +% \end{translation} +% \end{alignment} +% +% \begin{remarks} +% \item As can be seen from the apparatus entry related to l.~4 above, +% a subvariant has been inserted in the lemma part: \enquote{(aut et +% \getsiglum{cA1})}. This was done by using |alt| in +% \vref{lst:caesar-bg}, ll.~9--10. But as this variant is already +% recorded\---and printed\---in the lemma part, it was necessary to +% remove the entire otherwise redundant variant from the apparatus +% criticus in print. Hence the use of |nordg| at l.~11. +% \item For examples of abbreviations, see ll.~6 and 17. +% \item Line~17 shows how mss.\ T and U (which belong to two distinct +% subfamilies) have been separated from one another: % +% \verb*+wit={T, U}+. See above \vpageref{ref:mss-sep-families} for +% more information on this technique. +% \end{remarks} +% +% Finally, the corresponding \texttt{TEI xml} output follows:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{xml} +
+
+ XIII +

In omni Gallia eorum hominum qui + + aliquo + in aliquo + sunt numero atque honore genera sunt duo. Nam + plebes paene seruorum habetur loco, quae + + nihil audet per se + nihil aut et per se + nihil habet per se + per se nihil audet + , + + nullo + nulli + adhibetur + + consilio + concilio + .

+
+
+
+
+ XIII +

Throughout all Gaul there are two orders of those men + who are of any rank and dignity: for the commonality is + held almost in the condition of slaves, and dares to + undertake nothing of itself, and is admitted to no + deliberation.

+
+
+\end{minted} +% \iffalse +% +% \fi +% +% \subsection{Alignment of Several Texts} +% \label{sec:multiple-alignment} +% As described above \vpageref{ref:alignment-syntax}, the +% \env{alignment} environment may receive an optional argument in which +% the following \enquote{name$=$value} arguments are accepted:---\\ +% \DescribeOption{tcols} +% |tcols|$=$\meta{number}\hfill\tcboxverb{Default: 2}\\ +% |tcols| stores the \underLine{t}otal number of +% \underLine{col}umn\underLine{s} of text to be aligned.\\ +% \DescribeOption{lcols} +% |lcols|$=$\meta{number}\hfill\tcboxverb{Default: 1}\\ +% |lcols| stores the number of \underLine{col}umn\underLine{s} to be +% printed on the \underLine{l}eft-hand page, \emph{out of the total +% number} of columns specified with |tcols|. As can be seen from the +% preceding two default values, \env{alignment} initially sets two +% columns of text on facing pages. Of course, for this setting to work +% properly, one must ensure that the \env{alignment} environment is +% started on a +% left page.\\ +% \DescribeOption{texts} +% |texts|$=$\meta{\underLine{semicolon}-separated +% values}\hfill\tcboxverb{Default: edition;translation}\\ +% Depending on the total number of columns that has been specified +% with |tcols| above, |texts| is then used to define the names of the +% environments that shall receive edition texts, translations, +% \emph{\&c.} Some very important points need to be emphasized in this +% respect:--- +% \begin{enumerate} +% \item Only unaccented letters of the alphabet (whatever the case) +% are allowed to compose the names of \LaTeX{} environments. +% \item These names must be separated from one another by +% \emph{semicolons}, as shown in red in the listing below at the end +% of lines~1 and 2. +% \begin{enumerate} +% \item[\dbend] The colon at the end of line~3 closes the whole +% value of |text| and acts as a higher level separator. +% \end{enumerate} +% \item Each name may be followed by a \enquote*{suboptional} argument +% between square brackets which will then be used to insert +% \texttt{TEI xml} attributes in the corresponding |
| +% element. For example, +% \iffalse +%<*example> +% \fi +\begin{minted}[escapeinside=++]{latex} +texts=latin[xml:lang="la"]+\textcolor{red}{;}+ + english[xml:lang="en"]+\textcolor{red}{;}+ + french[xml:lang="fr"]+\textcolor{red}{,}+ +\end{minted} +% \iffalse +% +% \fi +% will be converted into \texttt{TEI xml} as follows:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{xml} +
+... +
+
+... +
+
+... +
+\end{minted} +% \iffalse +% +% \fi +% \begin{enumerate} +% \item[\dbend] As can be seen, \pkg{ekdosis} takes care of +% computing and inserting the |xml:id| attributes which are +% therefore not accepted in the \enquote*{suboptional} arguments +% of |texts|. +% \end{enumerate} +% \item The names of the environments must be specified in exactly the +% same order as they are supposed to appear in the print edition, +% from left to right. +% \end{enumerate} +% \DescribeOption{apparatus} +% |apparatus|$=$\meta{\underLine{semicolon}-separated +% values}\hfill\tcboxverb{Default: edition}\\ +% Then, the |apparatus| option, just as |texts|, takes a +% \underLine{semicolon}-separated list of previously defined +% environments that shall receive at least one layer of apparatus +% criticus.\\ +% \DescribeOption{paired} |paired|$=$\verb+true|false+% +% \hfill\tcboxverb{Default: true (initially not set)}\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. By default, \pkg{ekdosis} follows the \LaTeX{} page +% numbering scheme when multiple texts are arranged on facing +% pages. The |paired| option leaves every right-hand page number +% unchanged, so that both facing pages hold the same page number.\\ +% \DescribeOption{lineation} |lineation|$=$\verb+page|document+ +% \hfill\tcboxverb{Default: document}\\ +% This option applies to edition texts initially set to receive an +% apparatus criticus. By default, lines are continuously numbered +% throughout the document. |lineation=page| sets the numbering to +% start afresh at the top of each page.\\ +% \DescribeOption{flush} |flush|$=$\verb+true|false+ +% \hfill\tcboxverb{Default: false}\\ +% This named argument does not need a value as it defaults to |true| +% if it is used. This option applies on rare occasions only, when two +% or more distinct \env{alignment} environments are started on the same +% page. Should this happen, any subsequent \env{alignment} environment +% must be set with the |flush| option so that every one of them +% carry its own apparatus criticus. +% +% As an example, the alignment of the Latin edition text of Caesar's +% \emph{Gallic War}, printed on left-hand pages, along with two +% translations into English and French, printed on right-hand pages, +% can be set as follows:--- +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\begin{alignment}[tcols=3, + lcols=1, + texts=latin[xml:lang="la"]; + english[xml:lang="en"]; + french[xml:lang="fr"], + apparatus=latin, + lineation=page] + \begin{latin} + Gallia est omnis divisa in partes tres quarum unam incolunt + Belgae, [...] + \end{latin} + \begin{english} + All Gaul is divided into three parts, one of which the Belgae + inhabit, [...] + \end{english} + \begin{french} + L'ensemble de la Gaule est divisé en trois parties: l'une est + habitée par les Belges, [...] + \end{french} +\end{alignment} +\end{minted} +% \iffalse +% +% \fi +% +% \DescribeMacro{\SetEkdosisAlignment} +% \cs{SetEkdosisAlignment}\marg{alignment settings}\\ +% If the same alignment settings are to be shared by several +% \env{alignment} environments, common settings can be collected in +% the argument of \cs{SetEkdosisEnvironment}, like +% so:---\\ +% \iffalse +%<*example> +% \fi +\begin{minted}[linenos=false]{latex} +\SetEkdosisAlignment{ + tcols=3, + lcols=1, + texts=latin[xml:lang="la"]; + english[xml:lang="en"]; + french[xml:lang="fr"], + apparatus=latin, + lineation=page +} +\begin{alignment} + ... +\end{alignment} +\end{minted} +% \iffalse +% +% \fi +% +% \cs{SetEkdosisAlignment} can be used either in the preamble or at +% any point of the document to set or to modify alignment settings. +% +% \section{To Be Continued...} +% v1.0 of \pkg{ekdosis}, which should be available by the end of July +% 2020, will include a full documentation. At the time of writing, the +% author is working on this part of the package. +% +% \begin{comment} +% \section{Multiple-Layer Apparatus Criticus} +% \end{comment} +% \label{sec:multilayer-apparatus} +% +% \label{ref:type-app} +% \begin{comment} +% \section{Correspondence and Alignment} +% \end{comment} +% \label{sec:correspondance-alignment} +% +% \label{ref:segmentation} +% +% \section{GNU Free Documentation License} +% \label{sec:fdl} +% \textbf{Version 1.3, 3 November 2008} +% +% \begin{center} +% Version 1.3, 3 November 2008 +% +% Copyright \copyright{} 2000, 2001, 2002, 2007, 2008 Free +% Software Foundation, Inc. +% +% \bigskip +% +% \url{https://fsf.org/} +% +% \bigskip +% +% Everyone is permitted to copy and distribute verbatim copies +% of this license document, but changing it is not allowed. +% \end{center} +% +% \needspace{3\baselineskip} +% \begin{center} +% {\bf\large Preamble} +% \end{center} +% +% The purpose of this License is to make a manual, textbook, or other +% functional and useful document \enquote{free} in the sense of +% freedom: to assure everyone the effective freedom to copy and +% redistribute it, with or without modifying it, either commercially +% or noncommercially. Secondarily, this License preserves for the +% author and publisher a way to get credit for their work, while not +% being considered responsible for modifications made by others. +% +% This License is a kind of \enquote{copyleft}, which means that +% derivative works of the document must themselves be free in the same +% sense. It complements the GNU General Public License, which is a +% copyleft license designed for free software. +% +% We have designed this License in order to use it for manuals for +% free software, because free software needs free documentation: a +% free program should come with manuals providing the same freedoms +% that the software does. But this License is not limited to software +% manuals; it can be used for any textual work, regardless of subject +% matter or whether it is published as a printed book. We recommend +% this License principally for works whose purpose is instruction or +% reference. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 1. APPLICABILITY AND DEFINITIONS\par} +% \end{center} +% +% This License applies to any manual or other work, in any medium, +% that contains a notice placed by the copyright holder saying it can +% be distributed under the terms of this License. Such a notice +% grants a world-wide, royalty-free license, unlimited in duration, to +% use that work under the conditions stated herein. The +% \enquote{\textbf{Document}}, below, refers to any such manual or +% work. Any member of the public is a licensee, and is addressed as +% \enquote{\textbf{you}}. You accept the license if you copy, modify +% or distribute the work in a way requiring permission under copyright +% law. +% +% A \enquote{\textbf{Modified Version}} of the Document means any work +% containing the Document or a portion of it, either copied verbatim, +% or with modifications and/or translated into another language. +% +% A \enquote{\textbf{Secondary Section}} is a named appendix or a +% front-matter section of the Document that deals exclusively with the +% relationship of the publishers or authors of the Document to the +% Document's overall subject (or to related matters) and contains +% nothing that could fall directly within that overall subject. +% (Thus, if the Document is in part a textbook of mathematics, a +% Secondary Section may not explain any mathematics.) The +% relationship could be a matter of historical connection with the +% subject or with related matters, or of legal, commercial, +% philosophical, ethical or political position regarding them. +% +% The \enquote{\textbf{Invariant Sections}} are certain Secondary +% Sections whose titles are designated, as being those of Invariant +% Sections, in the notice that says that the Document is released +% under this License. If a section does not fit the above definition +% of Secondary then it is not allowed to be designated as Invariant. +% The Document may contain zero Invariant Sections. If the Document +% does not identify any Invariant Sections then there are none. +% +% The \enquote{\textbf{Cover Texts}} are certain short passages of +% text that are listed, as Front-Cover Texts or Back-Cover Texts, in +% the notice that says that the Document is released under this +% License. A Front-Cover Text may be at most 5 words, and a +% Back-Cover Text may be at most 25 words. +% +% A \enquote{\textbf{Transparent}} copy of the Document means a +% machine-readable copy, represented in a format whose specification +% is available to the general public, that is suitable for revising +% the document straightforwardly with generic text editors or (for +% images composed of pixels) generic paint programs or (for drawings) +% some widely available drawing editor, and that is suitable for input +% to text formatters or for automatic translation to a variety of +% formats suitable for input to text formatters. A copy made in an +% otherwise Transparent file format whose markup, or absence of +% markup, has been arranged to thwart or discourage subsequent +% modification by readers is not Transparent. An image format is not +% Transparent if used for any substantial amount of text. A copy that +% is not \enquote{Transparent} is called \enquote{\textbf{Opaque}}. +% +% Examples of suitable formats for Transparent copies include plain +% ASCII without markup, Texinfo input format, LaTeX input format, SGML +% or XML using a publicly available DTD, and standard-conforming +% simple HTML, PostScript or PDF designed for human modification. +% Examples of transparent image formats include PNG, XCF and JPG. +% Opaque formats include proprietary formats that can be read and +% edited only by proprietary word processors, SGML or XML for which +% the DTD and/or processing tools are not generally available, and the +% machine-generated HTML, PostScript or PDF produced by some word +% processors for output purposes only. +% +% The \enquote{\textbf{Title Page}} means, for a printed book, the +% title page itself, plus such following pages as are needed to hold, +% legibly, the material this License requires to appear in the title +% page. For works in formats which do not have any title page as +% such, \enquote{Title Page} means the text near the most prominent +% appearance of the work's title, preceding the beginning of the body +% of the text. +% +% The \enquote{\textbf{publisher}} means any person or entity that +% distributes copies of the Document to the public. +% +% A section \enquote{\textbf{Entitled XYZ}} means a named subunit of +% the Document whose title either is precisely XYZ or contains XYZ in +% parentheses following text that translates XYZ in another language. +% (Here XYZ stands for a specific section name mentioned below, such +% as \enquote{\textbf{Acknowledgements}}, +% \enquote{\textbf{Dedications}}, \enquote{\textbf{Endorsements}}, or +% \enquote{\textbf{History}}.) To \enquote{\textbf{Preserve the +% Title}} of such a section when you modify the Document means that it +% remains a section \enquote{Entitled XYZ} according to this +% definition. +% +% The Document may include Warranty Disclaimers next to the notice +% which states that this License applies to the Document. These +% Warranty Disclaimers are considered to be included by reference in +% this License, but only as regards disclaiming warranties: any other +% implication that these Warranty Disclaimers may have is void and has +% no effect on the meaning of this License. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 2. VERBATIM COPYING\par} +% \end{center} +% +% You may copy and distribute the Document in any medium, either +% commercially or noncommercially, provided that this License, the +% copyright notices, and the license notice saying this License +% applies to the Document are reproduced in all copies, and that you +% add no other conditions whatsoever to those of this License. You +% may not use technical measures to obstruct or control the reading or +% further copying of the copies you make or distribute. However, you +% may accept compensation in exchange for copies. If you distribute a +% large enough number of copies you must also follow the conditions in +% section~3. +% +% You may also lend copies, under the same conditions stated above, +% and you may publicly display copies. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 3. COPYING IN QUANTITY\par} +% \end{center} +% +% If you publish printed copies (or copies in media that commonly have +% printed covers) of the Document, numbering more than 100, and the +% Document's license notice requires Cover Texts, you must enclose the +% copies in covers that carry, clearly and legibly, all these Cover +% Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +% the back cover. Both covers must also clearly and legibly identify +% you as the publisher of these copies. The front cover must present +% the full title with all words of the title equally prominent and +% visible. You may add other material on the covers in addition. +% Copying with changes limited to the covers, as long as they preserve +% the title of the Document and satisfy these conditions, can be +% treated as verbatim copying in other respects. +% +% If the required texts for either cover are too voluminous to fit +% legibly, you should put the first ones listed (as many as fit +% reasonably) on the actual cover, and continue the rest onto adjacent +% pages. +% +% If you publish or distribute Opaque copies of the Document numbering +% more than 100, you must either include a machine-readable +% Transparent copy along with each Opaque copy, or state in or with +% each Opaque copy a computer-network location from which the general +% network-using public has access to download using public-standard +% network protocols a complete Transparent copy of the Document, free +% of added material. If you use the latter option, you must take +% reasonably prudent steps, when you begin distribution of Opaque +% copies in quantity, to ensure that this Transparent copy will remain +% thus accessible at the stated location until at least one year after +% the last time you distribute an Opaque copy (directly or through +% your agents or retailers) of that edition to the public. +% +% It is requested, but not required, that you contact the authors of +% the Document well before redistributing any large number of copies, +% to give them a chance to provide you with an updated version of the +% Document. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 4. MODIFICATIONS\par} +% \end{center} +% +% You may copy and distribute a Modified Version of the Document under +% the conditions of sections 2 and 3 above, provided that you release +% the Modified Version under precisely this License, with the Modified +% Version filling the role of the Document, thus licensing +% distribution and modification of the Modified Version to whoever +% possesses a copy of it. In addition, you must do these things in +% the Modified Version: +% +% \begin{itemize} +% \item[A.] Use in the Title Page (and on the covers, if any) a title +% distinct from that of the Document, and from those of previous +% versions (which should, if there were any, be listed in the +% History section of the Document). You may use the same title as a +% previous version if the original publisher of that version gives +% permission. +% +% \item[B.] List on the Title Page, as authors, one or more persons +% or entities responsible for authorship of the modifications in +% the Modified Version, together with at least five of the +% principal authors of the Document (all of its principal authors, +% if it has fewer than five), unless they release you from this +% requirement. +% +% \item[C.] State on the Title page the name of the publisher of the +% Modified Version, as the publisher. +% +% \item[D.] Preserve all the copyright notices of the Document. +% +% \item[E.] Add an appropriate copyright notice for your +% modifications adjacent to the other copyright notices. +% +% \item[F.] Include, immediately after the copyright notices, a +% license notice giving the public permission to use the Modified +% Version under the terms of this License, in the form shown in the +% Addendum below. +% +% \item[G.] Preserve in that license notice the full lists of +% Invariant Sections and required Cover Texts given in the +% Document's license notice. +% +% \item[H.] Include an unaltered copy of this License. +% +% \item[I.] Preserve the section Entitled \enquote{History}, +% Preserve its Title, and add to it an item stating at least the +% title, year, new authors, and publisher of the Modified Version +% as given on the Title Page. If there is no section Entitled +% \enquote{History} in the Document, create one stating the title, +% year, authors, and publisher of the Document as given on its +% Title Page, then add an item describing the Modified Version as +% stated in the previous sentence. +% +% \item[J.] Preserve the network location, if any, given in the +% Document for public access to a Transparent copy of the Document, +% and likewise the network locations given in the Document for +% previous versions it was based on. These may be placed in the +% \enquote{History} section. You may omit a network location for a +% work that was published at least four years before the Document +% itself, or if the original publisher of the version it refers to +% gives permission. +% +% \item[K.] For any section Entitled \enquote{Acknowledgements} or +% \enquote{Dedications}, Preserve the Title of the section, and +% preserve in the section all the substance and tone of each of the +% contributor acknowledgements and/or dedications given therein. +% +% \item[L.] Preserve all the Invariant Sections of the Document, +% unaltered in their text and in their titles. Section numbers or +% the equivalent are not considered part of the section titles. +% +% \item[M.] Delete any section Entitled \enquote{Endorsements}. +% Such a section may not be included in the Modified Version. +% +% \item[N.] Do not retitle any existing section to be Entitled +% \enquote{Endorsements} or to conflict in title with any Invariant +% Section. +% +% \item[O.] Preserve any Warranty Disclaimers. +% \end{itemize} +% +% If the Modified Version includes new front-matter sections or +% appendices that qualify as Secondary Sections and contain no +% material copied from the Document, you may at your option designate +% some or all of these sections as invariant. To do this, add their +% titles to the list of Invariant Sections in the Modified Version's +% license notice. These titles must be distinct from any other +% section titles. +% +% You may add a section Entitled \enquote{Endorsements}, provided it +% contains nothing but endorsements of your Modified Version by +% various parties---for example, statements of peer review or that the +% text has been approved by an organization as the authoritative +% definition of a standard. +% +% You may add a passage of up to five words as a Front-Cover Text, and +% a passage of up to 25 words as a Back-Cover Text, to the end of the +% list of Cover Texts in the Modified Version. Only one passage of +% Front-Cover Text and one of Back-Cover Text may be added by (or +% through arrangements made by) any one entity. If the Document +% already includes a cover text for the same cover, previously added +% by you or by arrangement made by the same entity you are acting on +% behalf of, you may not add another; but you may replace the old one, +% on explicit permission from the previous publisher that added the +% old one. +% +% The author(s) and publisher(s) of the Document do not by this +% License give permission to use their names for publicity for or to +% assert or imply endorsement of any Modified Version. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 5. COMBINING DOCUMENTS\par} +% \end{center} +% +% You may combine the Document with other documents released under +% this License, under the terms defined in section~4 above for +% modified versions, provided that you include in the combination all +% of the Invariant Sections of all of the original documents, +% unmodified, and list them all as Invariant Sections of your combined +% work in its license notice, and that you preserve all their Warranty +% Disclaimers. +% +% The combined work need only contain one copy of this License, and +% multiple identical Invariant Sections may be replaced with a single +% copy. If there are multiple Invariant Sections with the same name +% but different contents, make the title of each such section unique +% by adding at the end of it, in parentheses, the name of the original +% author or publisher of that section if known, or else a unique +% number. Make the same adjustment to the section titles in the list +% of Invariant Sections in the license notice of the combined work. +% +% In the combination, you must combine any sections Entitled +% \enquote{History} in the various original documents, forming one +% section Entitled \enquote{History}; likewise combine any sections +% Entitled \enquote{Acknowledgements}, and any sections Entitled +% \enquote{Dedications}. You must delete all sections Entitled +% \enquote{Endorsements}. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 6. COLLECTIONS OF DOCUMENTS\par} +% \end{center} +% +% You may make a collection consisting of the Document and other +% documents released under this License, and replace the individual +% copies of this License in the various documents with a single copy +% that is included in the collection, provided that you follow the +% rules of this License for verbatim copying of each of the documents +% in all other respects. +% +% You may extract a single document from such a collection, and +% distribute it individually under this License, provided you insert a +% copy of this License into the extracted document, and follow this +% License in all other respects regarding verbatim copying of that +% document. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 7. AGGREGATION WITH INDEPENDENT WORKS\par} +% \end{center} +% +% A compilation of the Document or its derivatives with other separate +% and independent documents or works, in or on a volume of a storage +% or distribution medium, is called an \enquote{aggregate} if the +% copyright resulting from the compilation is not used to limit the +% legal rights of the compilation's users beyond what the individual +% works permit. When the Document is included in an aggregate, this +% License does not apply to the other works in the aggregate which are +% not themselves derivative works of the Document. +% +% If the Cover Text requirement of section~3 is applicable to these +% copies of the Document, then if the Document is less than one half +% of the entire aggregate, the Document's Cover Texts may be placed on +% covers that bracket the Document within the aggregate, or the +% electronic equivalent of covers if the Document is in electronic +% form. Otherwise they must appear on printed covers that bracket the +% whole aggregate. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 8. TRANSLATION\par} +% \end{center} +% +% Translation is considered a kind of modification, so you may +% distribute translations of the Document under the terms of +% section~4. Replacing Invariant Sections with translations requires +% special permission from their copyright holders, but you may include +% translations of some or all Invariant Sections in addition to the +% original versions of these Invariant Sections. You may include a +% translation of this License, and all the license notices in the +% Document, and any Warranty Disclaimers, provided that you also +% include the original English version of this License and the +% original versions of those notices and disclaimers. In case of a +% disagreement between the translation and the original version of +% this License or a notice or disclaimer, the original version will +% prevail. +% +% If a section in the Document is Entitled \enquote{Acknowledgements}, +% \enquote{Dedications}, or \enquote{History}, the requirement +% (section~4) to Preserve its Title (section~1) will typically require +% changing the actual title. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 9. TERMINATION\par} +% \end{center} +% +% You may not copy, modify, sublicense, or distribute the Document +% except as expressly provided under this License. Any attempt +% otherwise to copy, modify, sublicense, or distribute it is void, and +% will automatically terminate your rights under this License. +% +% However, if you cease all violation of this License, then your +% license from a particular copyright holder is reinstated (a) +% provisionally, unless and until the copyright holder explicitly and +% finally terminates your license, and (b) permanently, if the +% copyright holder fails to notify you of the violation by some +% reasonable means prior to 60 days after the cessation. +% +% Moreover, your license from a particular copyright holder is +% reinstated permanently if the copyright holder notifies you of the +% violation by some reasonable means, this is the first time you have +% received notice of violation of this License (for any work) from +% that copyright holder, and you cure the violation prior to 30 days +% after your receipt of the notice. +% +% Termination of your rights under this section does not terminate the +% licenses of parties who have received copies or rights from you +% under this License. If your rights have been terminated and not +% permanently reinstated, receipt of a copy of some or all of the same +% material does not give you any rights to use it. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 10. FUTURE REVISIONS OF THIS LICENSE\par} +% \end{center} +% +% The Free Software Foundation may publish new, revised versions of +% the GNU Free Documentation License from time to time. Such new +% versions will be similar in spirit to the present version, but may +% differ in detail to address new problems or concerns. See +% \url{https://www.gnu.org/licenses/}. +% +% Each version of the License is given a distinguishing version +% number. If the Document specifies that a particular numbered +% version of this License \enquote{or any later version} applies to +% it, you have the option of following the terms and conditions either +% of that specified version or of any later version that has been +% published (not as a draft) by the Free Software Foundation. If the +% Document does not specify a version number of this License, you may +% choose any version ever published (not as a draft) by the Free +% Software Foundation. If the Document specifies that a proxy can +% decide which future versions of this License can be used, that +% proxy's public statement of acceptance of a version permanently +% authorizes you to choose that version for the Document. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf 11. RELICENSING\par} +% \end{center} +% +% \enquote{Massive Multiauthor Collaboration Site} (or \enquote{MMC +% Site}) means any World Wide Web server that publishes copyrightable +% works and also provides prominent facilities for anybody to edit +% those works. A public wiki that anybody can edit is an example of +% such a server. A \enquote{Massive Multiauthor Collaboration} (or +% \enquote{MMC}) contained in the site means any set of copyrightable +% works thus published on the MMC site. +% +% \enquote{CC-BY-SA} means the Creative Commons Attribution-Share +% Alike 3.0 license published by Creative Commons Corporation, a +% not-for-profit corporation with a principal place of business in San +% Francisco, California, as well as future copyleft versions of that +% license published by that same organization. +% +% \enquote{Incorporate} means to publish or republish a Document, in +% whole or in part, as part of another Document. +% +% An MMC is \enquote{eligible for relicensing} if it is licensed under +% this License, and if all works that were first published under this +% License somewhere other than this MMC, and subsequently incorporated +% in whole or in part into the MMC, (1) had no cover texts or +% invariant sections, and (2) were thus incorporated prior to November +% 1, 2008. +% +% The operator of an MMC Site may republish an MMC contained in the +% site under CC-BY-SA on the same site at any time before August 1, +% 2009, provided the MMC is eligible for relicensing. +% +% \needspace{3\baselineskip} +% \begin{center} +% {\large\bf ADDENDUM: How to use this License for your documents\par} +% \end{center} +% +% To use this License in a document you have written, include a copy +% of the License in the document and put the following copyright and +% license notices just after the title page: +% +% \bigskip +% \begin{quote} +% Copyright \copyright{} YEAR YOUR NAME. Permission is granted to +% copy, distribute and/or modify this document under the terms of +% the GNU Free Documentation License, Version 1.3 or any later +% version published by the Free Software Foundation; with no +% Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +% A copy of the license is included in the section entitled +% \enquote{GNU Free Documentation License}. +% \end{quote} +% \bigskip +% +% If you have Invariant Sections, Front-Cover Texts and Back-Cover +% Texts, replace the \enquote{with \dots\ Texts.}\ line with this: +% +% \bigskip +% \begin{quote} +% with the Invariant Sections being LIST THEIR TITLES, with the +% Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. +% \end{quote} +% \bigskip +% +% If you have Invariant Sections without Cover Texts, or some other +% combination of the three, merge those two alternatives to suit the +% situation. +% +% If your document contains nontrivial examples of program code, we +% recommend releasing these examples in parallel under your choice of +% free software license, such as the GNU General Public License, +% to permit their use in free software. +% +% \printbibliography[heading=bibintoc] +% +% \StopEventually{} +% +% \section{Implementation} +% \label{sec:implementation} +% +% \iffalse +%<*package> +% \fi +% +% \pkg{ekdosis} relies on Lua functions and tables. Read the +% |.lua| files that accompany \pkg{ekdosis} for more +% information. +% \begin{macrocode} +\RequirePackage{iftex} +% \end{macrocode} +% Of course, \pkg{ekdosis} requires {\LuaLaTeX}. Issue an error +% if the document is processed with another engine. +% \begin{macrocode} +\RequireLuaTeX +% \end{macrocode} +% Set global options:--- +% \begin{macrocode} +\RequirePackage{expkv-opt} +\RequirePackage{expkv-def} +\newif\if@pkg@float +\newif\if@pkg@footins +\newif\if@pkg@ekddivs +\newif\if@parnotesroman +\newif\if@pkg@parnotes +\newif\iftei@export +\ekvdefinekeys{ekdosis}{ + choice layout = {float = {\@pkg@floattrue}, + footins = {\@pkg@footinstrue}}, + initial layout = float, + unknown-choice layout = \PackageError{ekdosis}{unknown + layout=#1}{`layout' must be either `float' or `footins'.}, + choice divs = {ekdosis = {\@pkg@ekddivstrue}, + latex = {\@pkg@ekddivsfalse + \AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}}}}, + initial divs = ekdosis, + unknown-choice divs = \PackageError{ekdosis}{unknown divs=#1}{`divs' + must be either `ekdosis' or `latex'.}, + choice parnotes = {false = {}, + true = {\@pkg@parnotestrue}, + roman = {\@pkg@parnotestrue\@parnotesromantrue}}, + default parnotes = true, + unknown-choice parnotes = \PackageError{ekdosis}{unknown + parnotes=#1}{`parnotes' must be either `true', or `false' or + `roman'.}, + choice teiexport = {false = {}, + true = {\tei@exporttrue + \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% + \AtEndDocument{\luadirect{ekdosis.closeteistream()}}}, + tidy = {\tei@exporttrue + \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% + \AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}}}}, + default teiexport = true, + unknown-choice teiexport = \PackageError{ekdosis}{unknown + teiexport=#1}{`teiexport' must be either `true', `false' or + `tidy'.} +} +\ekvoProcessLocalOptions{ekdosis} +% \end{macrocode} +% \paragraph{Required Packages} \label{ref:ekdrequirements} In +% addition to \pkg{iftex}, \pkg{expkv-opt} and \pkg{expkv-def}, a list +% of the packages that are required by \pkg{ekdosis} follows:--- +% \begin{macrocode} +% \RequirePackage{iftex} % already loaded above +% \RequirePackage{expkv-opt} % already loaded above +% \RequirePackage{expkv-def} % already loaded above +\RequirePackage{luacode} +\RequirePackage{paracol} +\RequirePackage{xparse} +\RequirePackage{etoolbox} +\RequirePackage{lineno} +\RequirePackage{keyfloat} +\RequirePackage{refcount} +\RequirePackage[user,abspage]{zref} +\RequirePackage{ltxcmds} +\if@pkg@parnotes + \RequirePackage{parnotes} +\fi +% \end{macrocode} +% \paragraph{Lua} Here begins the real work: load |ekdosis.lua|:--- +% \begin{macrocode} +\luadirect{dofile(kpse.find_file("ekdosis.lua"))} +% \end{macrocode} +% \begin{macrocode} +\AtEndDocument{ + \luadirect{ekdosis.closestream()} +} +% \end{macrocode} +% Use |\normalfont| for line numbers:--- +% \begin{macrocode} +\renewcommand\linenumberfont{\normalfont\footnotesize} +% \end{macrocode} +% \begin{macro}{\SetEkdosisHooks} \cs{SetEkdosisHooks} is used to set +% hooks meant to be shared by all declared apparatuses, such as the +% font size, the format of numerals, \emph{\&c.} This command can be +% used in the preamble or at any point of the document. +% \begin{macrocode} +\ekvdefinekeys{ekd@hooks}{ + store appfontsize = \ekd@appfontsize, + store refnumstyle = \ekd@refnumstyle, + store postrefnum = \ekd@postrefnum, + initial appfontsize = \footnotesize, + initial refnumstyle = \bfseries, + initial postrefnum = ~ +} +\NewDocumentCommand{\SetEkdosisHooks}{m}{\ekvset{ekd@hooks}{#1}} +% \end{macrocode} +% \end{macro} +% Build and process the list of witnesses and hands:--- +% \begin{macrocode} +\ekvdefinekeys{ekd@witness}{ + store settlement = \settlement@value, + store institution = \institution@value, + store repository = \repository@value, + store collection = \collection@value, + store idno = \idno@value, + store msName = \msName@value, + store origDate = \origDate@value +} +% \end{macrocode} +% \begin{macro}{\DeclareWitness} \cs{DeclareWitness} is a +% preamble-only command. It takes three mandatory arguments and one +% optional argument. It is meant to collect data related to +% witnesses to be used in the edition text. Data are stored in |Lua| +% tables and are used to encode the || part of the |TEI| +% header as well as the Conspectus Siglorum in the edition in print. +% \begin{macrocode} +\NewDocumentCommand{\DeclareWitness}{m m m O{}}{% + \bgroup + \ekvset{ekd@witness}{#4} + \luadirect{ekdosis.newwitness( + \luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringO{\settlement@value}, + \luastringO{\institution@value}, + \luastringO{\repository@value}, + \luastringO{\collection@value}, + \luastringO{\idno@value}, + \luastringO{\msName@value}, + \luastringO{\origDate@value})} + \egroup + } +\@onlypreamble\DeclareWitness +% \end{macrocode} +% \end{macro} +% \begin{macro}{\DeclareHand} As \cs{DeclareWitness}, \cs{DeclareHand} +% is a preamble-only command meant to collect data and store them in +% |Lua| tables. It takes three mandatory arguments and one optional +% argument. The second argument is used to connect the hand to a +% declared witness it is related to. Then the table in which this +% witness is recorded can be fed with new data. +% \begin{macrocode} +\NewDocumentCommand{\DeclareHand}{m m m +O{}}{ + \luadirect{ekdosis.newhand(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringN{#4})} +} +\@onlypreamble\DeclareHand +% \end{macrocode} +% \end{macro} +% \begin{macro}{\DeclareScholar} There is also a table in which are +% collected data related to scholars' names to be used in the +% apparatus criticus. \cs{DeclareScholar} is a preamble-only command +% and takes two mandatory arguments: a unique id and a shorthand to +% be used in the apparatus criticus which can be extracted from a +% bibliographic database. +% \begin{macrocode} +\NewDocumentCommand{\DeclareScholar}{m m}{ + \luadirect{ekdosis.newscholar(\luastringN{#1}, + \luastringN{#2})} +} +\@onlypreamble\DeclareScholar +% \end{macrocode} +% \end{macro} +% \begin{macro}{\DeclareShorthand} \cs{DeclareShorthand} is a +% preamble-only command that can be used to record manuscript +% families or any kind of shorthand to be used to refer to +% previously declared ids, for example the shorthand |codd| can be +% used to point to all declared witnesses. This command takes three +% mandatory arguments: a unique id, its rendition in print and a +% csv-list of previously declared ids. +% \begin{macrocode} +\NewDocumentCommand{\DeclareShorthand}{m m m}{ + \luadirect{ekdosis.newshorthand(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +\@onlypreamble\DeclareShorthand +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\NewDocumentCommand{\getsiglum}{m}{% + \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% +} +\NewDocumentCommand{\SigLine}{m}{% + \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} +} +% \end{macrocode} +% \paragraph{\TeX\ to \texttt{TEI xml}} +% The following three commands can be used to instruct \pkg{ekdosis} +% how to convert unknown or unusual \hologo{(La)TeX} commands into +% \texttt{TEI xml} equivalents. +% \begin{macro}{\TeXtoTEI} +% \cs{TeXtoTEI}\marg{csname}\marg{TEI element}\oarg{TEI attribute(s)} +% takes two mandatory arguments and one optional argument, namely: the +% control sequence name to be converted, the \texttt{TEI} element it +% is to be converted into and any additional \texttt{xml} attributes +% to be appended to the opening \texttt{TEI} element:--- +% \begin{macrocode} +\NewDocumentCommand{\TeXtoTEI}{m m O{}}{% + \luadirect{ekdosis.newcmdtotag(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EnvtoTEI} +% \begin{macro}{\EnvtoTEI*} +% \cs{EnvtoTEI}\meta{*}\marg{env name}\marg{TEI element}\oarg{TEI +% attribute(s)} instructs how to convert \LaTeX{} environments into +% \texttt{TEI xml} equivalents. It takes two mandatory arguments and +% one optional argument, namely the name of the \LaTeX{} environment +% to be converted, the \texttt{TEI} element it is to be converted into +% and any additional attributes to be appended to the \texttt{TEI} +% opening element. \cs{EnvtoTEI*} is restricted to \texttt{TEI} +% elements that must never appear within |

| elements, such as +% |

|, || and the like. +% \begin{macrocode} +\NewDocumentCommand{\EnvtoTEI}{s m m O{}}{% + \IfBooleanTF{#1}{% + \luadirect{ekdosis.newenvtotag(\luastringN{#2}, + \luastringN{#3}, + \luastringN{#4}, + "yes")} + }{% + \luadirect{ekdosis.newenvtotag(\luastringN{#2}, + \luastringN{#3}, + \luastringN{#4})} + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\TeXtoTEIPatt} +% Finally, the more flexible\---and more delicate to +% handle\---\cs{TeXtoTEIPatt}\marg{\TeX\ +% pattern}\allowbreak\marg{\texttt{TEI} pattern} uses pattern matching +% to instruct \pkg{ekdosis} how to convert \hologo{(La)TeX} commands +% into \texttt{TEI} equivalents. +% \begin{macrocode} +\NewDocumentCommand{\TeXtoTEIPatt}{m m}{% + \luadirect{ekdosis.newpatttotag(\luastringN{#1}, \luastringN{#2})} +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\SetTEIFilename} \cs{SetTEIFilename}\marg{basename} is +% a preamble-only command. It is used to set the base name of the +% |TEI xml| output file, to which the suffix |.xml| is appended. By +% default, the base name is |\jobname-tei|:--- +% \begin{macrocode} +\NewDocumentCommand{\SetTEIFileName}{m}{ + \luadirect{ekdosis.setteifilename(\luastringN{#1})} +} +\@onlypreamble\SetTEIFileName +% \end{macrocode} +% \end{macro} +% \begin{macro}{\SetxmlBibResource} This is a preamble-only command. +% If a base name for a \texttt{TEI xml} compliant bibliographical +% database file is provided with +% \cs{SetxmlBibResource}\marg{basename}, \pkg{ekdosis} will use +% insert formatted data in the back matter section of its own +% \texttt{TEI xml} output file, as || elements within a +% || section. +% \begin{macrocode} +\NewDocumentCommand{\SetxmlBibResource}{m}{ + \luadirect{ekdosis.setxmlbibresource(\luastringN{#1})} +} +\@onlypreamble\SetxmlBibResource +% \end{macrocode} +% \end{macro} +% +%\paragraph{Multi-layer apparatuses} +% \pkg{ekdosis} must know is an entry is to be processed in a single- +% or multiple-layer context:--- +% \begin{macrocode} +\newif\ifekd@mapps +% \end{macrocode} +% Now the key-value options can be defined:--- +% \begin{macrocode} +\ekvdefinekeys{ekd@newapp}{ + choice direction = {LR = \def\direction@val{LR}, + RL = \def\direction@val{RL}}, + unknown-choice direction = \PackageError{ekdosis}{unknown + direction=#1}{`direction' must be either `LR' or `RL'.}, + store rule = \rule@val, + store delim = \delim@val, + store sep = \sep@val, + store bhook = \bhook@val, + store ehook = \ehook@val, + initial direction = LR, + initial ehook = {\csname ekd@end@apparatus\endcsname} +} +% \end{macrocode} +% \begin{macro}{\DeclareApparatus} +% \cs{DeclareApparatus}\marg{apparatus name}\oarg{options} is a +% preamble-only command. As a mandatory argument, it takes the name of +% the new layer of notes to be inserted in the apparatus block. Then, +% the following six key-value options can be used to lay out the +% layer: \verb+direction=LR|RL+, |rule|, |delim| (the delimiter between +% entries), |sep| (the separator between lemma part and readings or +% notes), |bhook| (\LaTeX{} code inserted as the layer begins), +% |ehook| (\LaTeX{} code inserted as the layer ends):--- +% \begin{macrocode} +\NewDocumentCommand{\DeclareApparatus}{m O{}}{ + \newbool{subsq@unit@#1} + \booltrue{subsq@unit@#1} + \unless\ifekd@mapps\global\ekd@mappstrue\fi + \bgroup + \ekvset{ekd@newapp}{#2} + \luadirect{ekdosis.newapparatus( + \luastringN{#1}, + \luastring{\direction@val}, + \luastringO{\rule@val}, + \luastringO{\delim@val}, + \luastringO{\sep@val}, + \luastringO{\bhook@val}, + \luastringO{\ehook@val} + )} + \egroup +} +\@onlypreamble\DeclareApparatus +% \end{macrocode} +% \end{macro} +% Apparatus-related settings and functions. Some booleans to check if +% an apparatus should be inserted and what is the current environment. +% \begin{macrocode} +\newbool{do@app} +\newif\ifekd@state +\newif\ifekd@isinapp +\newif\ifekd@isinlem +% \end{macrocode} +% The next boolean is shared with \pkg{arabluatex}. \cs{LRnum} is used +% internally to ensure that numerals referring to line spans are +% displayed in the right order. +% \begin{macrocode} +\providebool{al@rlmode} +\@ifpackageloaded{arabluatex}{}{% + \def\setRL{\booltrue{al@rlmode}\pardir TRT\textdir TRT} + \def\setLR{\boolfalse{al@rlmode}\pardir TLT \textdir TLT} +} +\protected\def\LRnum#1{\bgroup\textdir TLT#1\egroup} +% \end{macrocode} +% Set counter referring to line numbers and make it global. +% \begin{macrocode} +\newcounter{ekd@lab} +\globalcounter{ekd@lab} +% \end{macrocode} +% This command inserts words in the apparatus criticus without +% checking if both |ekd@isinapp| and |ekd@state| are set to |true|. +% \begin{macrocode} +\NewDocumentCommand{\unconditional@appin}{o m}{% + \IfNoValueTF{#1} + {\luadirect{ekdosis.appin(\luastringO{#2})}} + {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% +} +% \end{macrocode} +% \begin{macro}{\blfootnote} \cs{blfootnote}\marg{footnote} is used +% internally to insert the apparatus in the footnote block should the +% global optional argument |layout| be set to |footins|. Therefore, it +% is not documented. +% \begin{macrocode} + % \def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext} +\def\blfootnote{\gdef\@thefnmark{}\@blfootnotetext} +\long\def\@blfootnotetext#1{\insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark + }% + \color@begingroup + \@makeblfntext{% + \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% + \color@endgroup}}% +\newcommand\@makeblfntext[1]{% + \parindent 1em% + \noindent + \hb@xt@0em{\hss\@makefnmark}#1} +% \end{macrocode} +% \end{macro} +% \paragraph{Single-layer apparatus} The following commands are for +% general settings. All of them can be used in the preamble or at any +% point of the document:--- +% \begin{macro}{\SetLTRapp} +% \begin{macro}{\SetRTLapp} +% \cs{SetLTRapp} and \cs{SetRTLapp} are two argument-less commands to +% set the direction of single-layer apparatus criticus, either LTR or +% RTL:--- +% \begin{macrocode} +\newif\ifrtl@app +\NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue} +\NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\SetSeparator} +% \cs{SetSeparator}\marg{separator} allows to change the separator +% between lemma texts and variant readings, which is by default +% a closing square bracket followed by a space (\verb*+] +):--- +% \begin{macrocode} +\edef\ekdsep{] } +\NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\SetEndApparatus} +% \cs{SetEndApparatus}\marg{characters} can be used to append +% characters at the end of the apparatus block\---such as a full stop, +% as it is customary in some editions. By default, nothing is +% appended:--- +% \begin{macrocode} +\edef\ekd@end@apparatus{} +\NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\SetUnitDelimiter} +% \cs{SetUnitDelimiter}\marg{delimiter} can be used to set the +% delimiter between entries in the apparatus criticus. By default, +% there is no delimiter except a simple space. \cs{SetUnitDelimiter} +% can be used to insert a broad space (with |\hskip| for instance, as +% in the OCT series) or the divider-sign (‖, as in the Budé series):--- +% \begin{macrocode} +\def\ekd@unit@delim{} +\NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\footnoteruletrue} +% \begin{macro}{\footnoterulefalse} +% As \pkg{ekdosis} takes care of drawing a rule separating the main +% text from the apparatus block as well as layers of notes from each +% other inside this block, it may not be desirable to have +% the standard \LaTeX{} \enquote{footnoterule} printed on every page +% of the edition text. \cs{footnoterulefalse} removes it while +% \cs{footnoteruletrue} leaves it untouched. The latter is set by +% default. +% \begin{macrocode} +\def\ekd@default@rule{\rule{2truein}{0.5pt}} +\newif\iffootnoterule +\footnoteruletrue +\let\dflt@footnoterule\footnoterule +\let\dflt@pcol@footnoterule\pcol@footnoterule +\renewcommand\footnoterule{% + \iffootnoterule + \dflt@footnoterule% + \fi +} +\renewcommand\pcol@footnoterule{% + \iffootnoterule + \dflt@pcol@footnoterule% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\SetDefaultRule} +% By default, \pkg{ekdosis} draws separating rules the definition of +% which is |\rule{2truein}{0.5pt}|. This can be changed in the +% preamble or at any point of the document with +% \cs{SetDefaultRule}\marg{\allowbreak{}rule definition}. Leaving this +% argument empty as in \cs{SetDefaultRule}|{}| removes the rule. +% \begin{macrocode} +\NewDocumentCommand{\SetDefaultRule}{m}{% + \def\@tempa{#1} + \ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}% + \else% + \def\ekd@default@rule{#1}% + \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\NLS} +% \cs{NLS} is adapted from a snippet written by Heiko Oberdiek. It is +% used by \pkg{ekdosis} internally to prevent page breaks between +% separating rules and subsequent notes. Therefore, it is not +% documented. +% \begin{macrocode} +\newcommand*{\NLS}{% + \par% + \nobreak% + \vspace{-\parskip}% + \noindent% + \ignorespaces} +% \end{macrocode} +% \end{macro} +% This boolean is used to test if a given entry is to be preceded by a +% numeral referring to the line of the edition text. +% \begin{macrocode} +\newif\ifsubsq@unit +\subsq@unittrue +% \end{macrocode} +% \cs{add@@apparatus} inserts the apparatus block on a given page +% either in the footnote floating block or in a float of its own, +% depending on the value set in the |layout| global option. +% \begin{macrocode} +\def\add@@apparatus{% + \if@pkg@parnotes\parnotes\else\fi% + \if@pkg@footins% + \bgroup% + \ifrtl@app\setRL\else\setLR\fi% + \blfootnote{% + \if@pkg@parnotes% + \if@parnotesroman% + \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% + \parnoteclear\else\fi% + \footnotesize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% + \if@pkg@parnotes\parnotes\parnotereset\else\fi% + }% + \egroup% + \fi% + \if@pkg@float% + \keyparbox[!b]{}{\ifrtl@app\setRL\else\setLR\fi% + \if@pkg@parnotes% + \if@parnotesroman% + \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% + \parnoteclear\else\fi% + \ekd@appfontsize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% + \if@pkg@parnotes\parnotes\parnotereset\else\fi% + }% + \fi% +} +% \end{macrocode} +% Before inserting any new entry, \cs{add@apparatus} is called +% \cs{test@apparatus} to decide whether a new apparatus block must be +% created on a given page. +% \begin{macrocode} +\def\add@apparatus{% + \test@apparatus% + \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}% +} +% \end{macrocode} +% \cs{append@app} inserts a bare (sub)entry in the apparatus... +% \begin{macrocode} +\NewDocumentCommand{\append@app}{o +m}{% + \ifekd@isinapp% + \ifekd@state% + \IfNoValueTF{#1}% + {\luadirect{ekdosis.appin(\luastringO{#2})}}% + {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% + \fi% + \fi} +% \end{macrocode} +% while \cs{append@ln@app} inserts a (sub)entry possibly preceded by a +% line number. +% \begin{macrocode} +\NewDocumentCommand{\append@ln@app}{o +m}{% + \IfNoValueTF{#1} + {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}} + {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}, + \luastringO{#1}))}}} +% \end{macrocode} +% \begin{macro}{\EkdosisDefaultApparatus} +% By default, \pkg{ekdosis} defines one layer of critical notes which +% is called |default|. This name can be changed at any point of the +% document with \cs{EkdosisDefaultApparatus}\marg{name}. +% \begin{macrocode} +\ekvdefinekeys{appnote}{ + store type = \ekdan@type, + initial type = default + } +\NewDocumentCommand{\EkdosisDefaultApparatus}{m}{% + \ekvset{appnote}{type=#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\app} +% \cs{app}|[type=|\meta{type}|]|\marg{apparatus entries} takes one +% mandatory argument and accepts one optional argument. |type=| refers +% to the layer the note must go into and \meta{apparatus entries} +% contains command used to insert the entries, either \cs{lem}, +% \cs{rdg} or \cs{note}\meta{*}:--- +% \begin{macrocode} +\NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{% + \begingroup + \ekvset{appnote}{#1}% + \ekd@isinapptrue% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{ekdosis.storeabspg( + \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% + \ifekd@state\add@apparatus\fi% + \luadirect{tex.sprint(ekdosis.removesp(\luastringN{#2}))}% + \ekd@isinappfalse% + \endgroup} +% \end{macrocode} +% \end{macro} +% \cs{current@ref@arg} is used outside \cs{app} by \cs{note}. It takes +% two mandatory arguments: the beginning line label and the ending +% line label\---which are manually inserted---and returns the formatted +% reference to be inserted in the apparatus criticus. +% \begin{macrocode} +\def\current@ref@arg#1#2{{%\textdir TLT% + \unexpanded\expandafter{\ekd@refnumstyle}% + \ifnum% + \getpagerefnumber{#1} + = + \getpagerefnumber{#2} + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{#2} + % + \ifekd@mapps% + \ifbool{subsq@unit@\ekdan@type}{% + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi% + }% + {\LRnum{\getrefnumber{#1}}}% issue the no + \else + \ifsubsq@unit% + % + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi + % + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi + \fi + % + \else + \LRnum{\getrefnumber{#1}}--% + \LRnum{\getrefnumber{#2}}% issue the nos + \fi% + \else + \LRnum{\getrefnumber{#1}}--% + \LRnum{\getpagerefnumber{#2}}.% + \LRnum{\getrefnumber{#2}}% issue pg and ln nos + \fi% + }\unexpanded\expandafter{\ekd@postrefnum}% +} +% \end{macrocode} +% \cs{current@ref} is pretty much the same as \cs{current@reg@arg}, +% but takes no argument. It is used by commands such as \cs{lem} when +% references to page and line numbers can be returned by \textsf{Lua}. +% \begin{macrocode} +\def\current@ref{{%\textdir TLT% + \unexpanded\expandafter{\ekd@refnumstyle}% + \ifnum% + \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} + % + \ifekd@mapps% + \ifbool{subsq@unit@\ekdan@type}{% + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi% + }{\LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}}% issue the no + \else + \ifsubsq@unit% + % + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi + % + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi + \fi + % + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue the nos + \fi% + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% + \LRnum{\getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}.% + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue pg and ln nos + \fi% + }\unexpanded\expandafter{\ekd@postrefnum}% +} +% \end{macrocode} +% Define keys to be used by the optional arguments of \cs{lem} and +% \cs{rdg}:--- +% \begin{macrocode} +\ekvdefinekeys{lem}{ + code wit = \def\ekdlr@wit{#1}, + code alt = \def\ekdlr@alt{#1}, + code pre = \def\ekdlr@pre{#1}, + code post = \def\ekdlr@post{#1}, + code prewit = \def\ekdlr@prewit{#1}, + code postwit = \def\ekdlr@postwit{#1}, + store type = \ekdlr@type, + store sep = \ekdl@sep, + bool nolem = \ifekdl@nolem, + bool nosep = \ifekdl@nosep, + initial sep = \ekdsep +} +\ekvdefinekeys{rdg}{ + code wit = \def\ekdlr@wit{#1}, + code alt = \def\ekdlr@alt{#1}, + code pre = \def\ekdlr@pre{#1}, + code post = \def\ekdlr@post{#1}, + code prewit = \def\ekdlr@prewit{#1}, + code postwit = \def\ekdlr@postwit{#1}, + store type = \ekdlr@type, + bool nordg = \ifekdr@nordg +} +% \end{macrocode} +% \begin{macro}{\lem} +% \cs{lem}\oarg{options}\marg{lemma text} inserts \meta{lemma text} +% both in the edition text and in the apparatus criticus by default, +% preceded by the reference to the line number or a space if it is the +% same number as the one of the previous entry. This command accepts +% the optional key-value arguments just defined above. +% \begin{macrocode} +\NewDocumentCommand{\lem}{O{} m}{% + \ekd@isinlemtrue% + \luadirect{ekdosis.dolnlab(\luastringN{#2})}% + \bgroup% + \ekvset{lem}{#1}% + \ifekd@mapps% + \ifnum% + \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} + = 1 + \boolfalse{subsq@unit@\ekdan@type}% + \fi% + \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% + \def\ekd@munit@delim{% + \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% + \fi% + \ifekdl@nolem\edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref}%\hskip .25em}% + \else% + \ifbool{al@rlmode}{% + \edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref%\hskip .25em + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \else + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded{#2}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi + }% + }% + {% + \edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref%\hskip .25em + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdlr@alt}}% + {\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \else + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi + }% + }% + \fi% + \ifekd@mapps% + \append@ln@app[\ekdan@type]{\lem@app}% + \else% + \append@ln@app{\lem@app}% + \fi% + \egroup% + \ekd@isinlemfalse% + \subsq@unittrue% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\rdg} +% \cs{rdg}\oarg{options}\marg{variant reading} inserts \meta{variant +% reading} in the second part of the entry, after the lemma text and +% the separator, in the apparatus criticus. This command accepts the +% optional key-value arguments defined above. +% \begin{macrocode} +\NewDocumentCommand{\rdg}{O{} m}{% + \bgroup% + \ekvset{rdg}{#1}% + % \ifekdr@nordg\append@app{}\else% do we need \append@app{} here? If + % % so, keep in mind \ifekd@mapps, + % like so: + \ifekdr@nordg% + \ifekd@mapps% + \append@app[\ekdan@type]{}% + \else% + \append@app{}% + \fi% + \else% + \ifbool{al@rlmode}{% + \edef\rdg@app{% + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \else + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded{#2}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + }% + }% + {% + \edef\rdg@app{% + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdlr@alt}}% + {\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \else + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + }% + }% + \ifekd@mapps% + \append@app[\ekdan@type]{\rdg@app}% + \else% + \append@app{\rdg@app}% + \fi% + \fi% + \egroup% +} +% \end{macrocode} +% \end{macro} +% Define keys to be used by the optional argument of \cs{note} when +% this command is found outside \cs{app}:--- +% \begin{macrocode} +\ekvdefinekeys{note}{ + store type = \ekdan@type, + store lem = \ekdn@lem, + code labelb = \def\ekdn@labelb{#1}, + code labele = \def\ekdn@labele{#1}, + store sep = \ekdn@sep, + initial type = default, + initial sep = \ekdsep +} +% \end{macrocode} +% \cs{note@noapp} is used internally when a \cs{note} command is found +% outside \cs{app}. This command is mostly used to insert short +% comments or references to texts quoted or cited in the edition text +% to go into additional layers of the apparatus criticus, e.g.\ the +% \emph{apparatus testium}. It accepts the optional key-value +% arguments just defined above. It must be noted that |labelb| must be +% specified; otherwise \pkg{ekdosis} will issue an error message. +% \begin{macrocode} +\NewDocumentCommand{\note@noapp}{O{} +m}{% + \bgroup% + \ekvset{note}{#1}% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{ekdosis.storeabspg( + \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% + \ifekd@state\add@apparatus\fi% + \ifekd@mapps% + \ifnum% + \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} + = 1 + \boolfalse{subsq@unit@\ekdan@type}% + \fi% + \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% + \def\ekd@munit@delim{% + \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% + \fi% + \ifdefined\ekdn@labelb% + \luadirect{tex.sprint(ekdosis.setnotelab(\luastringO{\ekdn@labelb}))}% + \ifdefined\ekdn@labele\else\def\ekdn@labele{\ekdn@labelb}\fi% + \else\PackageError{ekdosis}{missing labelb}{`labelb' must be + set.}\fi% + \ifbool{al@rlmode}% + {\edef\note@contents{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em + \ifdefined\ekdn@lem% + {\textdir TRT\unexpanded\expandafter{\ekdn@lem}}% + \unexpanded\expandafter{\ekdn@sep}\else\fi% + {\textdir TRT\unexpanded{#2}}}}% + {\edef\note@contents{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em + \ifdefined\ekdn@lem + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdn@lem}}% + {\unexpanded\expandafter{\ekdn@lem}}% + \unexpanded\expandafter{\ekdn@sep}\else\fi% + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}}}% + \ifekd@mapps% + \unconditional@appin[\ekdan@type]{\note@contents}% + \else% + \unconditional@appin{\note@contents}% + \fi% + \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}% + \egroup% + \subsq@unittrue% +} +% \end{macrocode} +% Define keys to be used by the optional argument of \cs{note} when +% this command is found inside \cs{app}:--- +% \begin{macrocode} +\ekvdefinekeys{ekd@note}{ + store pre = \pre@value, + store post = \post@value +} +% \end{macrocode} +% The following three commands, \cs{note@app}, \cs{ekd@note} and +% \cs{ekd@note@star} are used internally when a \cs{note} command is +% found inside \cs{app}. These commands are used to insert short +% comments after the lemma text or after any variant reading in the +% apparatus criticus. \cs{note@app} and subsequently \cs{ekd@note} and +% \cs{ekd@note@star} accept the optional key-value arguments just +% defined above. +% \begin{macrocode} +\NewDocumentCommand{\ekd@note}{O{} m}{% + \bgroup% + \ekvset{ekd@note}{#1}% + \edef\note@contents{% + \ekvifdefinedNoVal{note}{pre}{}{% + \unexpanded\expandafter{\pre@value}}% + \unexpanded{#2}% + \ekvifdefinedNoVal{note}{post}{}{% + \unexpanded\expandafter{\post@value}}% + }% + \append@app{\note@contents}% + \egroup% +} +\NewDocumentCommand{\ekd@note@star}{O{} m}{% + \if@pkg@parnotes + \bgroup% + \ekvset{ekd@note}{#1}% + \edef\note@contents{% + \ekvifdefinedNoVal{note}{pre}{}{% + \unexpanded\expandafter{\pre@value}}% + \unskip\noexpand\parnote{#2}% + \ekvifdefinedNoVal{note}{post}{}{% + \unexpanded\expandafter{\post@value}}% + }% + \append@app{\note@contents}% + \egroup% + \else + \append@app{\unskip\footnote{#2}}% + \fi% +} +\NewDocumentCommand{\note@app}{s O{} +m}{% + \ifbool{al@rlmode}{% + \IfBooleanTF{#1}{\ekd@note@star[#2]{% + {\textdir TRT#3}}} + {\ekd@note[#2]{{\textdir TRT#3}}}% + }{% + \IfBooleanTF{#1}{\ekd@note@star[#2]{#3}} + {\ekd@note[#2]{#3}}% + }% +} +% \end{macrocode} +% \begin{macro}{\note} +% Finally, \cs{note} is a simple command designed to check whether +% \cs{note} itself is called inside or outside \cs{app}. Then, unless +% it is found inside \cs{lem}, it calls \cs{note@app} in the former +% case and \cs{note@noapp} in the latter case:--- +% \begin{macrocode} +\NewDocumentCommand{\note}{s O{} +m}{% + \ifekd@state% + \ifekd@isinapp% + \ifekd@isinlem% + \note@noapp[#2]{#3}% + \else% + \IfBooleanTF{#1}{\note@app*[#2]{#3}}{\note@app[#2]{#3}}% + \fi% + \else% + \note@noapp[#2]{#3}% + \fi% + \fi% +} +% \end{macrocode} +% \end{macro} +% \cs{apparatus} is used internally by \pkg{ekdosis} to print the +% apparatus at the bottom of pages. Therefore, it is not documented, +% but this may change in the future for it will be possible to have +% apparatuses printed at other places. +% \begin{macrocode} +\NewDocumentCommand{\apparatus}{}{% + \luadirect{tex.sprint(ekdosis.appout())}} +% \end{macrocode} +% The following two commands call \textsf{Lua} functions to check +% whether an apparatus should be printed on a given page and to store +% the current column id. +% \begin{macrocode} +\NewDocumentCommand{\test@apparatus}{}{% + \luadirect{tex.sprint(ekdosis.testapparatus())}} +\NewDocumentCommand{\ekd@storecol}{}{% + \luadirect{ekdosis.storecurcol(\luastring{\thecolumn})}% +} +% \end{macrocode} +% Start and stop |ekdosis|: +% \begin{macrocode} +\NewDocumentCommand{\EkdosisOn}{}{% + \ekd@statetrue} +\NewDocumentCommand{\EkdosisOff}{}{% + \ekd@statefalse% +} +% \end{macrocode} +% Neutralize unwanted commands provided by \pkg{lineno} within the +% \env{ekdosis} environment:--- +% \begin{macrocode} +\def\ekd@setlineno{% + \let\setpagewiselinenumbers\relax% + \let\pagewiselinenumbers\relax% + \let\endpagewiselinenumbers\relax% + \let\runningpagewiselinenumbers\relax% + \let\realpagewiselinenumbers\relax% +} +% \end{macrocode} +% \begin{environment}{ekdosis} +% Finally comes the \env{ekdosis} environment meant to receive the +% edition text equipped with an apparatus criticus. This environment +% collects its contents and delivers it to \textsf{Lua} functions if a +% \texttt{TEI xml} output file be desired. +% \begin{macrocode} +\NewDocumentEnvironment{ekdosis}{+b}{% + \ekd@setlineno% + \runninglinenumbers + \EkdosisOn#1}{% + \EkdosisOff + \endrunninglinenumbers% + \iftei@export + \luadirect{ekdosis.exporttei(\luastringN{\par #1\par })}\fi} +% \end{macrocode} +% \end{environment} +% \paragraph{Alignment} What follows isto arrange texts in parallel +% columns either on single pages or on facing pages. +% +% Define keys to be used by the \env{alignment} environment:--- +% \begin{macrocode} +\newif\ifekd@pagelineation +\ekvdefinekeys{ekd@align}{ + store tcols = \tcols@num, + store lcols = \lcols@num, + store texts = \texts@value, + store apparatus = \apparatus@value, + bool paired = \ifekd@paired, + choice lineation = {page = \ekd@pagelineationtrue, + document = \ekd@pagelineationfalse}, + unknown-choice lineation = \PackageError{ekdosis}{unknown + lineation=#1}{`lineation' must be either `page' or `document'.}, + choice segmentation = {auto = \def\segmentation@val{auto}, + noauto = \def\segmentation@val{noauto}}, + unknown-choice segmentation = \PackageError{ekdosis}{unknown + segmentation=#1}{`segmentation' must be either `auto' or + `noauto'.}, + bool flush = \ifekd@flushapp, + initial tcols = 2, + initial lcols = 1, + initial texts = edition;translation, + initial apparatus = edition, + default segmentation = auto +} +% \end{macrocode} +% \begin{macro}{\SetEkdosisAlignment} +% \cs{SetEkdosisAlignment}\marg{settings} can be used either in the +% preamble or at any point of the document to set or modify the +% keys-value settings just defined above. +% \begin{macrocode} +\NewDocumentCommand{\SetEkdosisAlignment}{m}{ + \ekvset{ekd@align}{#1} +} +% \end{macrocode} +% \end{macro} +% Patch \pkg{paracol} to insert a hook in \cs{pcol@nextpage}. This +% hook is used to reset line numbers on new pages. +% \begin{macrocode} +\patchcmd{\pcol@nextpage}{% + \endgroup}{% + \ifekd@pagelineation\resetlinenumber\fi + \endgroup}{}{} +% \end{macrocode} +% \cs{EkdosisColStart} and \cs{EkdosisColStop} initialize columns +% meant to receive edition texts. These commands are used internally +% by \pkg{ekdosis}. +% \begin{macrocode} +\NewDocumentCommand{\EkdosisColStart}{}{% + \ekd@setlineno% + \runninglinenumbers + \ekd@storecol% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{% + ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, + "pg_i")}% + \ifekd@pagelineation + \luadirect{tex.sprint(ekdosis.checkresetlineno())} + \fi +} +\NewDocumentCommand{\EkdosisColStop}{}{% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{% + ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, + "pg_ii")}% + \endrunninglinenumbers% +} +% \end{macrocode} +% \begin{environment}{alignment} +% \cs{begin}|{alignment}|\oarg{options}\dots\cs{end}|{alignment}| can +% be used as it is provided to typeset a standard critical edition +% text on the left-hand pages accompanied with a translation on the +% right-hand pages. To that effect, it provides by default two new +% environments, \env{edition} and \env{translation}, to be used to +% typeset both texts. (Either whole texts or texts entered by +% paragraphs alternately.) The optional argument of \env{aligment} +% accepts the exact same key-value options as \cs{SetEkdosisAlignment} +% described above. One may contrast these options with those accepted +% by \cs{SetEkdosisAlignment} as \enquote{local settings}. +% \begin{macrocode} +\NewDocumentEnvironment{alignment}{O{}} +{% + \ekvset{ekd@align}{#1}% + \luadirect{ekdosis.mkenvdata( + \luastring{\texts@value}, + "texts" + )} + \ifekd@flushapp + \luadirect{ekdosis.newalignment("set")} + \fi + \luadirect{ekdosis.mkenvdata( + \luastring{\apparatus@value}, "apparatus" + )} + \setrunninglinenumbers + \luadirect{tex.sprint(ekdosis.mkenv())} + \ifekd@paired + \begin{paracol}[\lcols@num]{\tcols@num} + \else + \begin{paracol}[\lcols@num]*{\tcols@num} + \fi + } + {\end{paracol} + \iftei@export\luadirect{ekdosis.export_coldata_totei()}\fi + \ifekd@flushapp + \luadirect{ekdosis.newalignment("reset")} + \fi + \luadirect{ekdosis.flushenvdata()} + \luadirect{ekdosis.flushcolnums()} + } +% \end{macrocode} +% \end{environment} +% \paragraph{Divisions of the Body} +% \pkg{ekdosis} can convert \cs{book}, \cs{part}, \cs{chapter}, +% \cs{section}, \cs{subsec{\allowbreak}tion} and \cs{subsubsection} +% into corresponding \texttt{TEI} \enquote*{numbered} +% || elements, where $1\leq n\leq 6$. +% \begin{macro}{\MkBodyDivs} +% \cs{MkBodyDivs} is used to let \pkg{ekdosis} know which sectional +% commands are actually being used in an edition text. This command +% takes six mandatory arguments. For example, if \cs{section} and +% \cs{subsection} are the only sectional commands being used, +% |\MkBodyDivs{section}{subsection}{}{}{}{}| will have \cs{section} +% and \cs{subsection} converted into || and || +% respectively. +% \begin{macrocode} +\NewDocumentCommand{\MkBodyDivs}{mmmmmm}{ + \luadirect{ekdosis.mkdivdepths( + \luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringN{#4}, + \luastringN{#5}, + \luastringN{#6} + ) + } +} +% \end{macrocode} +% \end{macro} +% Divisions specific to \pkg{ekdosis}. Define keys to be used by +% \cs{ekddiv}:--- +% \begin{macrocode} +\ekvdefinekeys{ekd@div}{ + code type = \def\type@value{#1}, + code n = \def\n@value{#1}, + code head = \def\head@value{#1}, + code barehead = \def\barehead@value{#1}, + store depth = \depth@value, + choice toc = {book = \def\toc@value{book}, + part = \def\toc@value{part}, + chapter = \def\toc@value{chapter}, + section = \def\toc@value{section}, + subsection = \def\toc@value{subsection}, + subsubsection = \def\toc@value{subsubsection}, + paragraph = \def\toc@value{paragraph}, + subparagraph = \def\toc@value{subparagraph}}, + unknown-choice toc = \PackageError{ekdosis}{unknown toc=#1}{`toc' + must be either `book', `part', `chapter', `section', `subsection', + \MessageBreak `subsubsection', `paragraph' or `subparagraph'.}, + initial depth = 1 +} +% \end{macrocode} +% \begin{macro}{\ekdfmtdiv} +% \cs{ekdfmtdiv}\marg{n}\marg{code before}\marg{code after} is +% used to lay out the heading of the title. It takes three mandatory +% arguments: \emph{n}, namely the number referring to the particular +% depth of the division, and then some \LaTeX{} formatting commands +% to go before and after the heading itself:--- +% \begin{macrocode} +\NewDocumentCommand{\ekdfmtdiv}{m m m}{ + \luadirect{ekdosis.fmtdiv(\luastring{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +% \end{macrocode} +% \end{macro} +% \cs{ekd@getfmtdiv} gets the formatting commands that have been +% stored by \cs{ekdfmtdiv}. +% \begin{macrocode} +\NewDocumentCommand{\ekd@getfmtdiv}{m m}{% + \luadirect{tex.sprint(ekdosis.getfmtdiv(\luastringO{#1}, + \luastringN{#2}))}% +} +% \end{macrocode} +% \begin{macro}{\ekddiv} +% \cs{ekddiv}\marg{key-value arguments} is the standard command +% provided by \pkg{ekdosis} to meet the requirements of classical and +% literary texts the divisions of which depend on many different +% received traditions. It takes one optional argument in which the +% key-value arguments defined above are accepted, and converts the +% divisions into \texttt{TEI} \enquote*{un-numbered} |
| +% elements. +% \begin{macrocode} +\NewDocumentCommand{\ekddiv}{m}{ + \begingroup + \ekvset{ekd@div}{#1}% + \ifdefined\head@value + \bgroup + \ekd@getfmtdiv{\depth@value}{b}% + \head@value + \ekd@getfmtdiv{\depth@value}{e}% + \egroup + \ifdefined\toc@value + \ltx@ifpackageloaded{hyperref}{\phantomsection}{}% + \ifdefined\barehead@value + \addcontentsline{toc}{\toc@value}{\barehead@value}% + \else + \addcontentsline{toc}{\toc@value}{\head@value}% + \fi + \fi + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% A very basic and provisional implementation of poetry lines +% follows:--- +% \begin{macrocode} +\newlength{\ekdverseindentlength} +\setlength{\ekdverseindentlength}{\parindent} +\newenvironment*{ekdverse}[1][\ekdverseindentlength]{ + \begin{list}{}{% + \setlength{\leftmargin}{#1} + \setlength{\itemsep}{0pt} + \setlength{\topsep}{0pt} + \setlength{\partopsep}{0pt} + } + \item[] + }{\end{list}} +% \end{macrocode} +% +% \iffalse +% +% \fi +% +% \Finale +% \iffalse +%<*lua> +% \fi +% \begin{comment} +% \begin{ekdlua} +-- `' +-- This table will hold the functions: +ekdosis = {} + +-- lpeg equivalent for string.gsub() +local function gsub(s, patt, repl) + patt = lpeg.P(patt) + patt = lpeg.Cs((patt / repl + 1)^0) + return lpeg.match(patt, s) +end + +-- some basic patterns: +local letters = lpeg.R("az", "AZ") +local ascii = lpeg.R("az", "AZ", "@@") +local dblbkslash = lpeg.Cs("\\") +local bsqbrackets = lpeg.Cs{ "[" * ((1 - lpeg.S"[]") + lpeg.V(1))^0 * "]" } +local bcbraces = lpeg.Cs{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" } +local spce = lpeg.Cs(" ") +local spcenc = lpeg.P(" ") +local cmdstar = lpeg.Cs(spce * lpeg.P("*")) +local bsqbracketsii = lpeg.Cs(bsqbrackets^-2) +local bcbracesii = lpeg.Cs(bcbraces^-2) +local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1) +local rawcmd = lpeg.Cs(dblbkslash * ascii^1) +local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) +local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) +local app = lpeg.Cs("app") +local lemrdg = lpeg.Cs(lpeg.Cs("lem") + lpeg.Cs("rdg")) +local note = lpeg.Cs("note") +local lnbrk = lpeg.Cs("\\\\") +local poemline = lpeg.Cs(lnbrk * bsqbrackets^-1) +local endpoem = lpeg.Cs(lnbrk * lpeg.S("*!") * bsqbrackets^-1) +local sections = lpeg.Cs(lpeg.P("book") + lpeg.P("part") + lpeg.P("chapter") + + lpeg.P("section") + lpeg.P("subsection") + + lpeg.P("subsubsection")) +local par = lpeg.P(lpeg.P("\\par") * spce^1) +local parb = lpeg.P(lpeg.Cs("\\p@rb") * spce^1) +local para = lpeg.P(lpeg.Cs("\\p@ra") * spce^1) + +-- Bind to local variables +local next = next + +-- General +xmlids = {} + +local function xmlidfound(element) + for i = 1,#xmlids do + if xmlids[i].xmlid == element then + return true + end + end + return false +end + +-- Witnesses +listWit = {} +idsRend = {} +shorthands = {} + +local function isfound(table, value) + for i = 1,#table do + if table[i] == value then + return true + end + end + return false +end + +local function isintable(table, value) + for i = 1,#table do + if table[i].a == value then + return true + end + end + return false +end + +local function get_a_index(id, table) + local idfound = nil + for i = 1,#table + do + if table[i].a == id then + idfound = i + break + end + end + return idfound +end + +local function getindex(id, table) + local idfound = nil + for i = 1,#table + do + if table[i].xmlid == id then + idfound = i + break + end + end + return idfound +end + +function ekdosis.newwitness(id, + siglum, + description, + Settlement, + Institution, + Repository, + Collection, + Idno, + MsName, + OrigDate) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(listWit, {xmlid = id, + abbr = siglum, + detailsDesc = description, + msIdentifier = { + settlement = Settlement, + institution = Institution, + repository = Repository, + collection = Collection, + idno = Idno, + msName = MsName} + }) + local indexwit = getindex(id, listWit) + if OrigDate ~= "" then + listWit[indexwit].history = {} + listWit[indexwit].history.origin = {origDate = OrigDate} + end + end + return true +end + +function ekdosis.newhand(id, witid, siglum, description) + if xmlidfound(id) or not xmlidfound(witid) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + local indexwit = getindex(witid, listWit) + -- listWit[indexwit].handDesc = {xmlid = id, abbr = siglum, handNote = description} + if listWit[indexwit].handDesc == nil + then + listWit[indexwit].handDesc = {} + else + end + table.insert(listWit[indexwit].handDesc, + {xmlid = id, abbr = siglum, detailsDesc = description}) + end + return true +end + +function ekdosis.newshorthand(id, rend, xmlids) + if isintable(shorthands, id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a shorthand. " + .. + "Please pick another shorthand.}}") + else + table.insert(shorthands, { a = id, b = rend, c = xmlids }) + table.sort(shorthands, function(a ,b) return(#a.a > #b.a) end) + table.insert(idsRend, {xmlid = id, abbr = rend}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + +local xmlbibresource = nil + +function ekdosis.setxmlbibresource(str) + xmlbibresource = str..".xml" + return true +end + +function ekdosis.newscholar(id, siglum) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + +function ekdosis.getsiglum(str, opt) + str = str.."," + str = string.gsub(str, "%s-(%,)", "%1") + ctrl = str + if opt == "tei" then + for i = 1,#shorthands do + str = string.gsub(str, shorthands[i].a, shorthands[i].c) + end + for i = 1,#idsRend do + str = string.gsub(str, "(%f[%w])"..idsRend[i].xmlid.."(%,)", + "%1#"..idsRend[i].xmlid.."%2") + ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") + end + str = string.gsub(str, "%,(%s-)([%#])", " %2") + str = string.gsub(str, "%,$", "") + else + for i = 1,#idsRend do + str = string.gsub(str, idsRend[i].xmlid.."%,", idsRend[i].abbr) + ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") + end + end + -- if string.find(ctrl, "[A-Za-z0-9]") + if string.find(ctrl, "%S") + then + return "" + else + return str + end +end + +-- begin totei functions + +local cmdtotags = { + {a="textsuperscript", b="hi", c=" rend=\"sup\""}, + {a="textsubscript", b="hi", c=" rend=\"sub\""}, + {a="LRfootnote", b="note", c=" place=\"bottom\""}, + {a="RLfootnote", b="note", c=" place=\"bottom\""}, + {a="enquote *", b="quote", c=""}, + {a="footnote", b="note", c=" place=\"bottom\""}, + {a="enquote", b="quote", c=""}, + {a="txtrans", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, + {a="textbf", b="hi", c=" rend=\"bold\""}, + {a="textit", b="hi", c=" rend=\"italic\""}, + {a="textsc", b="hi", c=" rend=\"smallcaps\""}, + {a="textsf", b="hi", c=" rend=\"sf\""}, + {a="arbup", b="hi", c=" rend=\"sup\""}, + {a="txarb", b="s", c=" xml:lang=\"arb\""}, + {a="arb", b="foreign", + c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} +} + +local texpatttotags = { + {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 %2"}, + {a="\\icite%s?%[(.-)%]{(.-)}", b="%1"}, + {a="\\icite%s?{(.-)}", b=""}, + {a="\\linelabel%s?{(.-)}", b=""}, + {a="\\label%s?{(.-)}", b=""}, + {a="\\v?pageref%s?{(.-)}", b=""}, + {a="\\v?ref%s?{(.-)}", b=""} +} + +local envtotags = { + {a="flushright", b="p", c=" rend=\"align(right)\""}, + {a="flushleft", b="p", c=" rend=\"align(left)\""}, + {a="quotation", b="quote", c=""}, + {a="ekdverse", b="lg", c=""}, + {a="txarabtr", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, + {a="txarab", b="p", c=" xml:lang=\"arb\""}, + {a="center", b="p", c=" rend=\"align(center)\""}, + {a="verse", b="lg", c=""}, + {a="arab", b="p", + c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} +} + +local close_p = { + "p", + "lg" +} + +local forbid_xmlid = true + +function ekdosis.newcmdtotag(cmd, tag, attr) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + if isintable(cmdtotags, cmd) + then + local index = get_a_index(cmd, cmdtotags) + table.remove(cmdtotags, index) + table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) + table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) + else + table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) + table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) + end + return true +end + +function ekdosis.newpatttotag(pat, repl) + pat = string.gsub(pat, "([%[%]])", "%%%1") + pat = string.gsub(pat, "%#[1-9]", "(.-)") + repl = string.gsub(repl, "%#([1-9])", "%%%1") + table.insert(texpatttotags, { a = pat, b = repl }) + table.sort(texpatttotags, function(a ,b) return(#a.a > #b.a) end) + return true +end + +function ekdosis.newenvtotag(env, tag, attr, closep) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + if isintable(envtotags, env) + then + local index = get_a_index(env, envtotags) + table.remove(envtotags, index) + table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) + table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) + else + table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) + table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) + end + return true +end + +-- Get values of attributes +local function get_attr_value(str, attr) + str = str.."," + local attrval = string.match(str, "%f[%w]"..attr.."%s?%=%s?%b{}") + or string.match(str, "%f[%w]"..attr.."%s?%=%s?.-%,") + or "" + attrval = string.gsub(attrval, attr.."%s?%=%s?(%b{})", function(bbraces) + bbraces = string.sub(bbraces, 2, -2) + return string.format("%s", bbraces) + end) + attrval = string.gsub(attrval, attr.."%s?%=%s?(.-)%s?%,", "%1") + return attrval +end + +local function xml_entities(str) + str = string.gsub(str, "%<", "<") + str = string.gsub(str, "%>", ">") + return str +end + +local function note_totei(str) + str = gsub(str, + dblbkslash * + note * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + teitype = get_attr_value(opt, "type") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + right = get_attr_value(opt, "labelb") + left = get_attr_value(opt, "labele") + if left ~= "" + then + return string.format( + "<%s%s target=\"#range(right(%s),left(%s))\">%s", + cmd, teitype, right, left, arg, cmd, right) + elseif left == "" + then + return string.format( + "<%s%s target=\"#right(%s)\">%s", + cmd, teitype, right, arg, cmd, right) + end + end) + return str +end + +local function app_totei(str) + str = gsub(str, + dblbkslash * + app * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + opt = get_attr_value(opt, "type") + if opt ~= "" then opt = " type=\""..opt.."\"" else end + return app_totei(string.format("<%s%s>%s", + cmd, opt, arg, cmd)) + end) + return str +end + +local function lem_rdg_totei(str) + str = gsub(str, + spcenc^-1 * + dblbkslash * + lemrdg * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + -- opt = get_attr_value(opt, "wit") + -- + teiwit = get_attr_value(opt, "wit") + if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end + teitype = get_attr_value(opt, "type") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + -- + if opt == "" + then + return lem_rdg_totei(string.format("<%s>%s", + cmd, arg, cmd)) + else + -- opt = ekdosis.getsiglum(opt, "tei") + return lem_rdg_totei(string.format("<%s%s%s>%s", + cmd, teiwit, teitype, arg, cmd)) + end + end) + str = gsub(str, spcenc^-0 * dblbkslash * lemrdg * spcenc^-1 * bcbraces * spcenc^-1, + function(bkslash, cmd, arg) + arg = string.sub(arg, 2, -2) + return lem_rdg_totei(string.format("<%s>%s", cmd, arg, cmd)) + end) + return str +end + +local function relocate_notes(str) + str = string.gsub(str, "(%.-)(%.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2") + return str +end + +local function linestotei(str) +-- str = "\n"..str + str = string.gsub(str, "^%s?(.-)%s?$", "\n%1\n") +-- str = gsub(str, endpoem, "\n") + str = gsub(str, poemline * spcenc^-1 * lpeg.P(">"), "\n") + str = gsub(str, poemline * spcenc^-1, "\n") +-- str = str.."\n" + return str +end + +-- better use lpeg: look into this later +local function versetotei(str) + str = string.gsub(str, "(\\begin%s?%{ekdverse%})(%b[])(.-)(\\end%s?%{ekdverse%})", function(benv, opt, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s%s", benv, opt, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{ekdverse%})(.-)(\\end%s?%{ekdverse%})", function(benv, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s", benv, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{verse%})(%b[])(.-)(\\end%s?%{verse%})", function(benv, opt, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s%s", benv, opt, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{verse%})(.-)(\\end%s?%{verse%})", function(benv, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s", benv, arg, eenv) + end) + return str +end + +local function envtotei(str) + for i = 1,#envtotags + do + if envtotags[i].b ~= "" + then + if isfound(close_p, envtotags[i].b) or envtotags[i].d == "yes" + then + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "\\p@rb <"..envtotags[i].b..envtotags[i].c..">") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "\\p@ra ") + else + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "<"..envtotags[i].b..envtotags[i].c..">") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "") + end + else + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "") + end + end + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii + * bcbracesii * spcenc^-1, + "<%1>") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii + * bcbracesii, + "") + return str +end + +local function texpatttotei(str) + for i = 1,#texpatttotags do + str = string.gsub(str, texpatttotags[i].a, texpatttotags[i].b) + end + return str +end + +local function cmdtotei(str) + for i = 1,#cmdtotags + do + str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * bsqbrackets * -bcbraces, "\\%1%2{}") + str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * -(bsqbrackets + bcbraces), "\\%1[]{}") + str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b{})", "%1[]%2") + str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b[])(%b{})", + function(cmd, arg, body) + body = string.sub(body, 2, -2) + arg = string.sub(arg, 2, -2) + arg = string.gsub(arg, "(%b{})", function(braces) + braces = string.sub(braces, 2, -2) + return string.format("\"%s\"", braces) + end) + body = cmdtotei(body) + -- return string.format("<"..cmdtotags[i].b..cmdtotags[i].c.." %s>%s", arg, body) + if cmdtotags[i].b ~= "" + then + return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s", body) + else + return "" + end + end) + end + -- temporarily: + str = string.gsub(str, "\\(getsiglum)%s?(%b{})", + function(cmd, body) + body = string.sub(body, 2, -2) + teisiglum = ekdosis.getsiglum(body, "tei") + printsiglum = ekdosis.getsiglum(body) + -- body = cmdtotei(body) + return string.format("%s", + teisiglum, printsiglum) + end) + str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})", + function(cmd, opt, body) + body = string.sub(body, 2, -2) + body = cmdtotei(body) + return string.format("<%s>%s", cmd, body, cmd) + end) + str = string.gsub(str, "\\(%a+)%s?%*?(%b{})", + function(cmd, body) + body = string.sub(body, 2, -2) + body = cmdtotei(body) + return string.format("<%s>%s", cmd, body, cmd) + end) + str = string.gsub(str, "(%s)(%>)", "%2") + return str +end + +local function partotei(str) + str = gsub(str, lpeg.P(lpeg.P("\\par") * spcenc^1)^1, "\\par ") + str = gsub(str, ((para + parb) * par^-1)^2, "\\p@r ") + str = string.gsub(str, "\\p@ra%s+", "

") + str = string.gsub(str, "\\p@rb%s+", "

") + str = string.gsub(str, "\\p@r%s+", "") + str = string.gsub(str, "%s?\\par%s?", "

", 1) + str = string.gsub(str, "(%)(%s-)(%<%/?div%d?)", "%3") + str = string.gsub(str, "%s?\\par%s?", "

") + str = string.gsub(str, "

%s?

", "") + str = string.gsub(str, "(%)%s?(%)$", "%2") + str = string.gsub(str, "(%)%s?$", "") + str = string.gsub(str, "(

)%s?()", "%2%1") + return str +end + +local function self_close_tags(str) + str = gsub(str, lpeg.P("<" * -lpeg.S("/")) + * lpeg.Cs(letters^1) + * lpeg.Cs((1 - lpeg.S"<>")^0) + * lpeg.P(">") + * lpeg.P(""), function(ftag, arg, ltag) + if ftag == ltag + then + return string.format("<%s%s/>", ftag, arg) + else + end + end) + return str +end + +local divdepth = { + book = 1, + part = 2, + chapter = 3, + section = 4, + subsection = 5, + subsubsection = 6 +} + +function ekdosis.mkdivdepths(...) + divdepth = {} + local num = 1 + for _, y in ipairs{...} + do + if y == "book" or "part" or "chapter" + or "section" or "subsection" or "subsubsection" + then + divdepth[y] = num + num = num + 1 + else + end + end + return true +end + +-- LaTeX side: format the divisions +local fmtdiv = {} + +function ekdosis.fmtdiv(n, fmtb, fmte) + if isintable(fmtdiv, n) + then + local index = get_a_index(n, fmtdiv) + table.remove(fmtdiv, index) + else + end + table.insert(fmtdiv, { a = n, formatb = fmtb, formate = fmte} ) + return true +end + +function ekdosis.getfmtdiv(n, pos) + local index = get_a_index(n, fmtdiv) + if index ~= nil + then + if pos == "b" + then + return fmtdiv[index].formatb + elseif pos == "e" + then + return fmtdiv[index].formate + end + else + return "" + end +end + +local ekddivs = true + +function ekdosis.setekddivsfalse() + ekddivs = false +end + +local function ekddivs_totei(str) + str = gsub(str, dblbkslash * lpeg.Cs("ekddiv") * spce^-1 * bcbraces, + function(bkslash, cmd, space, arg) + if ekddivs + then + arg = string.sub(arg, 2, -2) + teitype = get_attr_value(arg, "type") + tein = get_attr_value(arg, "n") + teihead = get_attr_value(arg, "head") + teidepth = get_attr_value(arg, "depth") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + if tein ~= "" then tein = " n=\""..tein.."\"" else end + if teidepth ~= "" + then + teidepth = " depth=\""..teidepth.."\"" + else + teidepth = " depth=\"1\"" + end + return string.format("\\p@rb %s\\p@ra ", + teitype, tein, teidepth, teihead) + else + return "" + end + end) + return str +end + +local function section_totei(str) + str = gsub(str, dblbkslash * sections * spce^-1 * bcbraces, "%1%2%3[]%4") + str = gsub(str, dblbkslash * sections * spce^-1 * bsqbrackets * bcbraces, + function(bkslash, secname, space, opt, arg) + if ekddivs + then + return "" + else + ctr = divdepth[secname] + arg = string.sub(arg, 2, -2) + return string.format("\\p@rb %s\\p@ra ", + ctr, secname, arg) + end + end) + return str +end + +local used_ndivs = {} + +local function close_ekddivs_at_end(str) + local isdiv = false + if string.find(str, "

$") + then + isdiv = true + str = string.gsub(str, "(.*)(
)$", "%1") + else + end + -- collect used depth numbers + for i in string.gmatch(str, "
") + do + i = string.match(i, "depth=\"%d\"") + i = string.match(i, "%d") + if isintable(used_ndivs, i) + then + else + table.insert(used_ndivs, {a = i} ) + end + end + if next(used_ndivs) ~= nil + then + table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end) + else + end + local firstdiv = string.match(str, "
") or "" + firstdiv = string.match(firstdiv, "depth%=\"%d\"") or "" + firstdiv = string.match(firstdiv, "%d") or "" + local lastdiv = string.match(string.reverse(str), ">.-\"%d\"%=htped.- vid<") or "" + lastdiv = string.match(lastdiv, "\"%d\"%=htped") or "" + lastdiv = string.match(lastdiv, "%d") or "" + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if isintable(used_ndivs, firstdiv) + then + while lastdivindex >= firstdivindex + do + closedivs = closedivs.."
" + lastdivindex = lastdivindex - 1 + end + end + if isdiv + then + return str..closedivs.."
" + else + return str..closedivs + end +end + +local function close_ndivs_at_end(str) + local isdiv = false + if string.find(str, "
$") + then + isdiv = true + str = string.gsub(str, "(.*)(
)$", "%1") + else + end + -- collect used div numbers + for i in string.gmatch(str, " #b.a) end) + else + end + local firstdiv = string.match(str, "= firstdivindex + do + closedivs = closedivs.."" + lastdivindex = lastdivindex - 1 + end + end + if isdiv + then + return str..closedivs.."" + else + return str..closedivs + end +end + +local function close_ekddivs_in_between(str) + local maxdepth = 1 + for i in string.gmatch(str, "", "%1") + do + if tonumber(i) > tonumber(maxdepth) + then + maxdepth = i + else + end + end + for ndivi = 1, maxdepth + do + str = string.gsub(str, "(
)(.-)(
)", + function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) + local firstdiv = ndivi + local lastdiv = ndivii + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if firstdivindex >= lastdivindex + then + while firstdivindex >= lastdivindex + do + closedivs = closedivs.."
" + firstdivindex = firstdivindex - 1 + end + end + return string.format("%s%s%s%s%s%s%s%s", + bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) + end) + end + str = string.gsub(str, "()", "%1%3") + used_ndivs = {} + return str +end + +local function close_ndivs_in_between(str) + for ndivi = 1, 6 + do + str = string.gsub(str, "()(.-)()", + function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) + local firstdiv = ndivi + local lastdiv = ndivii + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if firstdivindex >= lastdivindex + then + while firstdivindex >= lastdivindex + do + closedivs = closedivs.."" + firstdivindex = firstdivindex - 1 + end + end + return string.format("%s%s%s%s%s%s%s%s", + bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) + + end) + end + used_ndivs = {} + return str +end + +local function textotei(str) + str = xml_entities(str) + str = texpatttotei(str) + str = note_totei(str) + str = app_totei(str) + str = lem_rdg_totei(str) + str = relocate_notes(str) + str = versetotei(str) + str = envtotei(str) + str = ekddivs_totei(str) + str = section_totei(str) + str = cmdtotei(str) + str = self_close_tags(str) + str = partotei(str) + if ekddivs + then + str = close_ekddivs_at_end(str) + str = close_ekddivs_in_between(str) + else + str = close_ndivs_at_end(str) + str = close_ndivs_in_between(str) + end + return str +end + +local teifilename = tex.jobname.."-tei" + +function ekdosis.setteifilename(str) + teifilename = str + return true +end + +function ekdosis.openteistream() + local f = io.open(teifilename.."_tmp.xml", "a+") + f:write('', "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("<!-- Title -->", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + f:write("", "\n") + for i = 1,#listWit do + f:write('", "\n") + f:write('', textotei(listWit[i].abbr), "", "\n") + f:write(textotei(listWit[i].detailsDesc), "\n") + f:write("", "\n") + if listWit[i].msIdentifier.settlement == "" + and listWit[i].msIdentifier.institution == "" + and listWit[i].msIdentifier.repository == "" + and listWit[i].msIdentifier.collection == "" + and listWit[i].msIdentifier.idno == "" + and listWit[i].msIdentifier.msName == "" + then + f:write("", "\n") + else + f:write("", "\n") + if listWit[i].msIdentifier.settlement ~= "" then + f:write("", textotei(listWit[i].msIdentifier.settlement), "", "\n") + else end + if listWit[i].msIdentifier.institution ~= "" then + f:write("", textotei(listWit[i].msIdentifier.institution), "", "\n") + else end + if listWit[i].msIdentifier.repository ~= "" then + f:write("", textotei(listWit[i].msIdentifier.repository), "", "\n") + else end + if listWit[i].msIdentifier.collection ~= "" then + f:write("", textotei(listWit[i].msIdentifier.collection), "", "\n") + else end + if listWit[i].msIdentifier.idno ~= "" then + f:write("", textotei(listWit[i].msIdentifier.idno), "", "\n") + else end + if listWit[i].msIdentifier.msName ~= "" then + f:write("", textotei(listWit[i].msIdentifier.msName), "", "\n") + else end + f:write("", "\n") + end + if listWit[i].handDesc ~= nil then + f:write("", "\n") + f:write("", "\n") + local j = 1 + while listWit[i].handDesc[j] + do + f:write("", "\n") + f:write('', textotei(listWit[i].handDesc[j].abbr), "", "\n") + f:write("

", textotei(listWit[i].handDesc[j].detailsDesc), "

", "\n") + f:write("
", "\n") + j = j + 1 + end + f:write("
", "\n") + f:write("
", "\n") + else end + if listWit[i].history ~= nil then + f:write("", "\n") + f:write("", "\n") + f:write("", textotei(listWit[i].history.origin.origDate), "", "\n") + f:write("", "\n") + f:write("", "\n") + end + f:write("
", "\n") + f:write("
", "\n") + end + f:write("
", "\n") + f:write("
", "\n") + f:write("
", "\n") + f:write("", "\n") + f:write('', "\n") + f:write("", "\n") + f:write("
", "\n") + f:write("", "\n") + f:write("", "\n") + f:close() + return true +end + +local tidy = nil + +local function cleanup_tei() + local f = assert(io.open(teifilename.."_tmp.xml", "r")) + t = f:read("*a") + t = string.gsub(t, "%%s?%", "") + t = string.gsub(t, "^\n", "") + f:close() + local fw = assert(io.open(teifilename.."_tmp.xml", "w")) + fw:write(t) + fw:close() + return true +end + +function ekdosis.closeteistream(opt) + local f = io.open(teifilename.."_tmp.xml", "a+") + f:write("\n", "", "\n") + if xmlbibresource ~= nil then + bibf = assert(io.open(xmlbibresource, "r")) + t = bibf:read("*a") + t = string.gsub(t, "%s+corresp%=%b\"\"", "") + t = string.gsub(t, "\n\n", "\n") + f:write("", "\n") + f:write("", "\n") + for i in string.gmatch(t, ".-") + do + f:write(i, "\n") + end + f:write("", "\n") + f:write("", "\n") + bibf:close() + else + end + f:write("", "\n") + f:write("
", "\n") + f:close() + cleanup_tei() + os.remove(teifilename..".xml") + os.rename(teifilename.."_tmp.xml", teifilename..".xml") + if opt == "tidy" then + os.execute("tidy -qmi -xml --output-xml yes "..teifilename..".xml") + else + end + return true +end + +function ekdosis.exporttei(str) + local f = io.open(teifilename.."_tmp.xml", "a+") + -- f:write("\n

") + str = textotei(str) + f:write(str) + f:close() + return true +end +-- end totei functions + +-- begin basic TeX Conspectus siglorum +function ekdosis.basic_cs(msid) + local indexwit = getindex(msid, listWit) + siglum = listWit[indexwit].abbr + -- if listWit[indexwit].detailsDesc == "" + -- then + -- name = listWit[indexwit].msIdentifier.msName + -- else + -- name = listWit[indexwit].msIdentifier.msName + -- .."\\thinspace\\newline\\bgroup\\footnotesize{}".. + -- listWit[indexwit].detailsDesc + -- .."\\egroup{}" + -- end + name = listWit[indexwit].detailsDesc + if listWit[indexwit].history ~= nil + and + listWit[indexwit].history.origin ~= nil + then + date = listWit[indexwit].history.origin.origDate + else + date = "" + end + return siglum.."&"..name.."&"..date +end +-- end basic TeX Conspectus siglorum + +function ekdosis.removesp(str) + str = gsub(str, cmd * cmdargs * spcenc^-1, "%1%2") + return str +end + +function ekdosis.closestream() + os.remove(tex.jobname..".ekd") + os.rename(tex.jobname.."_tmp.ekd", tex.jobname..".ekd") + return true +end + +local cur_abs_pg = 0 +local pg_i = nil +local pg_ii = nil +local prevcol = nil +local curcol = "x" + +local check_resetlineno = {} + +function ekdosis.update_abspg(n) -- not used + cur_abs_pg = n + return true +end + +function ekdosis.storeabspg(n, pg) + if pg == "pg_i" then + pg_i = n + elseif pg == "pg_ii" then + pg_ii = n + table.insert(check_resetlineno, curcol.."-"..pg_ii) + end + cur_abs_pg = n + return true +end + +function ekdosis.checkresetlineno() + if isfound(check_resetlineno, curcol.."-"..pg_i) + then + return "" + else + return "\\resetlinenumber" + end +end + +-- +-- Build environments to be aligned +-- + +local cur_alignment = "-" +local cur_alignment_patt = "%-" +local cur_alignment_cnt = 1 + +local newalignment = false +function ekdosis.newalignment(str) + if str == "set" + then + newalignment = true + cur_alignment = "-"..cur_alignment_cnt.."-" + cur_alignment_patt = "%-"..cur_alignment_cnt.."%-" + cur_alignment_cnt = cur_alignment_cnt + 1 + elseif str == "reset" + then + newalignment = false + cur_alignment = "-" + cur_alignment_patt = "-" + end + return true +end + +local aligned_texts = {} +local texts_w_apparatus = {} +local coldata_totei = {} + +local function sanitize_envdata(str) -- look for a better way to achieve this + str = string.gsub(str, "(%a+)%s+(%b[])", "%1%2") + str = string.gsub(str, "(%a+)(%b[])%s+", "%1%2") + str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") + str = gsub(str, lpeg.Cs(letters^1) + * spcenc^-1 + * -bsqbrackets + * lpeg.Cs(";"), "%1[]%2") + str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") + return str +end + +function ekdosis.mkenvdata(str, opt) + if not string.find(str, "%;", -1) then str = str .. ";" else end + -- str = str ..";" + -- str = string.gsub(str, "%s+", "") + local fieldstart = 1 + local col = 0 + if opt == "texts" then + str = sanitize_envdata(str) + repeat + local _s, nexti = string.find(str, "%b[]%s-%;", fieldstart) + local namediv = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%1") + local attr = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%2") + attr = string.sub(attr, 2, -2) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + table.insert(aligned_texts, { text = namediv, + attribute = attr, + column = col }) + table.insert(coldata_totei, { environment = namediv, + data = {} }) + col = col + 1 + fieldstart = nexti + 1 + until fieldstart > string.len(str) + return aligned_texts + elseif opt == "apparatus" then + repeat + local nexti = string.find(str, "%;", fieldstart) + table.insert(texts_w_apparatus, string.sub(str, fieldstart, nexti-1)) + fieldstart = nexti +1 + until fieldstart > string.len(str) + return texts_w_apparatus + end +end + +-- Reminder: the following two variables are already set above +-- local prevcol = nil +-- local curcol = "x" + +function ekdosis.storecurcol(n) + curcol = n + return true +end + +function ekdosis.flushcolnums() + prevcol = nil + curcol = "x" + return true +end + +function ekdosis.flushenvdata() + aligned_texts = {} + texts_w_apparatus = {} + coldata_totei = {} + return true +end + +function ekdosis.storecoldata(nthcol, chunk) + local tindex = tonumber(nthcol) + 1 + table.insert(coldata_totei[tindex].data, chunk) + return true +end + +local environment_div = {} + +function ekdosis.newscholar(id, siglum) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + + +local function build_envdiv(str) + if not environment_div[str] + then + environment_div[str] = 1 + else + environment_div[str] = environment_div[str] + 1 + end + local div = "div-"..str.."_"..environment_div[str] + if xmlidfound(div) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..div.. + "\" already exists as a xml:id. " + .. + "ekdosis has generated some random id.}}") + return "div-"..math.random(1000,9999) + else + table.insert(xmlids, {xmlid = div}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + return div + end +end + +function ekdosis.mkenv() + local environments = {} + for i = 1,#aligned_texts + do + if isfound(texts_w_apparatus, aligned_texts[i].text) + then + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" + .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" + .."\\par" + .."\\EkdosisColStart" + .."\\EkdosisOn#1" + .."}{\\EkdosisOff" + .."\\EkdosisColStop" + .."\\end{nthcolumn}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" + .."{\\begin{nthcolumn*}{".. aligned_texts[i].column.."}[]" + .."\\par" + .."\\EkdosisColStart" + .."\\EkdosisOn#1" + .."}{\\EkdosisOff" + .."\\EkdosisColStop" + .."\\end{nthcolumn*}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + else + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" + .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" + .."\\par" + .."#1" + .."}{\\end{nthcolumn}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" + .."{\\begin{nthcolumn*}{"..aligned_texts[i].column.."}[]" + .."\\par" + .."#1" + .."}{" + .."\\end{nthcolumn*}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + end + forbid_xmlid = false + if aligned_texts[i].attribute ~= "" + then + ekdosis.newenvtotag(aligned_texts[i].text, "div", + "xml:id=\"" + ..build_envdiv(aligned_texts[i].text) + .."\" " + ..aligned_texts[i].attribute) + else + ekdosis.newenvtotag(aligned_texts[i].text, "div", + "xml:id=\"" + ..build_envdiv(aligned_texts[i].text) + .."\"") + end + forbid_xmlid = true + end + str = table.concat(environments) + return str +end + +function ekdosis.export_coldata_totei() + for i = 1,#coldata_totei + do + ekdosis.exporttei("\\begin{".. coldata_totei[i].environment .."}" + .. table.concat(coldata_totei[i].data) + .. "\\end{".. coldata_totei[i].environment .."}") + end +end + +-- handle multiple layers in apparatuses +-- +local apparatuses = {} +local bagunits = {} + +function ekdosis.newapparatus(teitype, + appdir, + apprule, + appdelim, + appsep, + appbhook, + appehook) + if isintable(apparatuses, teitype) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..teitype.. + "\" already exists.}}") + else + table.insert(apparatuses, {a = teitype, + direction = appdir, + rule = apprule, + delim = appdelim, + sep = appsep, + bhook = appbhook, + ehook = appehook}) + end + bagunits[teitype] = 1 + return true +end + +function ekdosis.getappdelim(str) + for i = 1,#apparatuses + do + if apparatuses[i].a == str then + delimfound = apparatuses[i].delim + break + end + end + return delimfound +end + +function ekdosis.get_bagunits(teitype) + return bagunits[teitype] +end + +function ekdosis.increment_bagunits(teitype) + bagunits[teitype] = (bagunits[teitype] or 0) + 1 +end + +local function reset_bagunits() + for i = 1,#apparatuses + do + bagunits[apparatuses[i].a] = 1 + end +end + +function ekdosis.appin(str, teitype) + local f = io.open(tex.jobname.."_tmp.ekd", "a+") + if next(apparatuses) == nil + then + f:write("<", cur_abs_pg, cur_alignment, curcol, "-0>", str, "\n") + else + for i = 1,#apparatuses + do + if apparatuses[i].a == teitype then + appno = i + break + end + end + f:write("<", cur_abs_pg, cur_alignment, curcol, "-", + appno, ">", str, "\n") + end + f:close() + return true +end + +function ekdosis.appout() + local file = io.open(tex.jobname..".ekd", "r") + if file ~= nil then io.close(file) + f = assert(io.open(tex.jobname..".ekd", "r")) + t = f:read("*a") + local output = {} + if next(apparatuses) == nil then + -- table.insert(output, "BEGIN") + table.insert(output, "\\noindent\\csname ekd@default@rule\\endcsname\\NLS{}") +-- table.insert(output, "\\noindent ") + for i in string.gmatch(t, + "<"..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-0>.-") + do + table.insert(output, i) + end + -- table.insert(output, "END") + else + local n = 1 + while apparatuses[n] + do + if string.match(t, "<"..cur_abs_pg.. + cur_alignment_patt + ..curcol.."%-"..n..">.-") + then + -- table.insert(output, "BEGIN") + table.insert(output, "\\bgroup{}") + if apparatuses[n].direction == "LR" + then + table.insert(output, "\\pardir TLT\\textdir TLT{}") + elseif apparatuses[n].direction == "RL" + then + table.insert(output, "\\pardir TRT\\textdir TRT{}") + end + if apparatuses[n].rule == "none" + then + if n > 1 + then + table.insert(output, "\\NLS{}") + else + table.insert(output, "\\noindent ") + end + elseif apparatuses[n].rule ~= "" + then + if n > 1 + then + table.insert(output, "\\NLS{}" .. apparatuses[n].rule .. "\\NLS{}") + else +-- table.insert(output, "\\noindent ") + table.insert(output, apparatuses[n].rule .. "\\NLS{}") + end + else + if n > 1 + then + table.insert(output, "\\NLS\\csname ekd@default@rule\\endcsname\\NLS{}") + else +-- table.insert(output, "\\noindent ") + table.insert(output, "\\csname ekd@default@rule\\endcsname\\NLS{}") + end + end + if apparatuses[n].sep ~= "" + then + table.insert(output, "\\edef\\ekdsep{" .. apparatuses[n].sep .. "}") + else + end + if apparatuses[n].bhook ~= "" + then + table.insert(output, apparatuses[n].bhook) + else + table.insert(output, "\\relax") + end + for i in string.gmatch(t, + "<"..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-"..n..">.-") + do + table.insert(output, i) + end + if apparatuses[n].ehook ~= "" + then + table.insert(output, apparatuses[n].ehook) + else + end + table.insert(output, "\\egroup{}") + -- table.insert(output, "END") + end + n = n + 1 + end + end + f:close() + str = table.concat(output) + str = string.gsub(str, "", "") + str = string.gsub(str, "<"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", " ") + return str + else + end +end + +function ekdosis.appin_out(str, nl) + local f = io.open(tex.jobname.."_tmp.ekd", "a+") + if nl == "yes" then + f:write(str, "\n") + else + f:write(str) + end + f:close() + return true +end + +local curcol_curabspg = {} + +function ekdosis.testapparatus() + if isfound(curcol_curabspg, curcol.."-"..cur_abs_pg) + then + if newalignment + then + if next(apparatuses) ~= nil then + reset_bagunits() + end + newalignment = false + return "\\booltrue{do@app}" + else + return "\\boolfalse{do@app}" + end + else + table.insert(curcol_curabspg, curcol.."-"..cur_abs_pg) + if next(apparatuses) ~= nil then + reset_bagunits() + end + return "\\booltrue{do@app}" + end +end + +local lnlabs = {} +local lnlab_salt = 0 +local current_lnlab = nil +local prev_lnlab = nil +local current_notelab = nil +local prev_notelab = nil +local current_lemma = nil +local salt = 0 + +local function mdvisintable(table, value) + for _, v in pairs(table) do + if v == value then return true end + end + return false +end + +function ekdosis.dolnlab(str) + prev_lnlab = current_lnlab + current_lemma = str + i = md5.sumhexa(str) + if not mdvisintable(lnlabs, i) then + table.insert(lnlabs, i) + else + i = i..salt + table.insert(lnlabs, i) + salt = salt + 1 + end + current_lnlab = i + return true +end + +function ekdosis.getlnlab() + return current_lnlab +end + +function ekdosis.getprevlnlab() + return prev_lnlab +end + +function ekdosis.setnotelab(str) + current_notelab = str + return "\\linelabel{" .. current_notelab .. "}" +end + +function ekdosis.getnotelab() + return current_notelab +end + +function ekdosis.setprevnotelab(str) + prev_notelab = str + return true +end + +function ekdosis.getprevnotelab() + return prev_notelab +end + +local function remove_note(str) + str = gsub(str, dblbkslash * lpeg.P("note") * cmdargs, "") + return str +end + +function ekdosis.mdvappend(str, teitype) + if teitype == nil + then + return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" + .. + current_lemma + .. + "\\linelabel{" .. current_lnlab .. "-e}" + .. + "\\csname append@app\\endcsname{" + .. remove_note(str) .. "}" + else + return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" + .. + current_lemma + .. + "\\linelabel{" .. current_lnlab .. "-e}" + .. + "\\csname append@app\\endcsname" .. "[" .. teitype .. "]{" + .. remove_note(str) .. "}" + end +end + +% \end{ekdlua} +% \end{comment} +% \iffalse +% +% \fi +% +% \section{Sample: C. J. Caesar, \emph{Gallic War}, +% VI, XIII.1} +% \label{sec:caesar-gw-6-1-13} +% \subsection{\texttt{.tex} Source File} +% \label{sec:caesar-gw-tex} +% \inputminted[linenos=false]{latex}{samples/Caesar_BG-6-13-1.tex} +% \subsection{\texttt{TEI xml} Output} +% \label{sec:caesar-gw-tei} +% \inputminted[linenos=false]{xml}{samples/Caesar_BG-6-13-1-tei.xml} +% +\endinput diff --git a/macros/luatex/latex/ekdosis/ekdosis.ins b/macros/luatex/latex/ekdosis/ekdosis.ins new file mode 100644 index 0000000000..6427d37969 --- /dev/null +++ b/macros/luatex/latex/ekdosis/ekdosis.ins @@ -0,0 +1,62 @@ +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +-------:| ----------------------------------------------------------------- +ekdosis:| Typesetting TEI xml compliant critical editions + Author:| Robert Alessi + E-mail:| alessi@robertalessi.net +License:| Released under the GNU General Public License v3 or later + See:| http://www.gnu.org/licenses/ + +This file is part of the `ekdosis' package + +ekdosis -- Typesetting TEI xml compliant critical editions +Copyright (C) 2020 Robert Alessi + +Please send error reports and suggestions for improvements to Robert +Alessi + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +. + +This work consists of the files ekdosis.dtx, ekdosis.el, this file and +a Makefile. +Running "make" generates the derived files README, ekdosis.pdf and +ekdosis.sty. +Running "make inst" installs the files in the user's TeX tree. +\endpreamble + +\usedir{tex/lualatex/ekdosis} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} +\nopreamble\nopostamble +\usedir{tex/lualatex/ekdosis} +\bgroup +\catcode9=12 +\generate{ + \file{\jobname.lua}{ + \from{\jobname.dtx}{luapre} + \from{\jobname.dtx}{lua} + } +} +\egroup +% \usedir{doc/lualatex/ekdosis} +% \generate{ +% \file{ekdosis-ex01.tex}{ +% \from{\jobname.dtx}{example01} +% } +% } +\endbatchfile diff --git a/macros/luatex/latex/ekdosis/ekdosis.pdf b/macros/luatex/latex/ekdosis/ekdosis.pdf new file mode 100644 index 0000000000..ef69e146fa Binary files /dev/null and b/macros/luatex/latex/ekdosis/ekdosis.pdf differ diff --git a/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1-tei.xml b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1-tei.xml new file mode 100644 index 0000000000..b9e4f9a23a --- /dev/null +++ b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1-tei.xml @@ -0,0 +1,225 @@ + + + + + + + <!-- Title --> + + + + + + + + + + + + + + + + + + + A + Bongarsianus81 + + + Amsterdam + University Library + 81 + + Bongarsianus + + + + + + A + 1 +

+ Emendationes scribae ipsius +

+ + + + + + s. IX--X + + + + + M + Parisinus Lat.5056 + + + + + s. XII + + + + + B + Parisinus Lat.5763 + + + + + s. IX--X + + + + + R + Vaticanus Lat.3864 + + + + + s. X + + + + + S + LaurentianusR 33 + + + + + s. X + + + + + L + LondinensisBr. Mus. 10084 + + + + + s. XI + + + + + N + NeapolitanusIV, c. 11 + + + + + s. XII + + + + + T + Parisinus Lat.5764 + + + + + s. XI + + + + + + f + + Vindobonensis95 + + + + + s. XII + + + + + U + Vaticanus Lat.3324 + + + + + s. XI + + + + + + l + + LaurentianusRiccard. 541 + + + + + s. XI--XII + + + + + + + + + + + + +
+
+ XIII +

In omni Gallia eorum hominum qui + + aliquo + in aliquo + sunt numero atque honore genera sunt duo. Nam + plebes paene seruorum habetur loco, quae + + nihil audet per se + nihil aut et per se + nihil habet per se + per se nihil audet + , + + nullo + nulli + adhibetur + + consilio + concilio + .

+
+
+
+
+ XIII +

Throughout all Gaul there are two orders of those men + who are of any rank and dignity: for the commonality is + held almost in the condition of slaves, and dares to + undertake nothing of itself, and is admitted to no + deliberation.

+
+
+
+
+ XIII +

Partout en Gaule il y a deux classes d'hommes qui + comptent et qui sont considérés. Quant aux gens du + peuple, ils ne sont guère traités autrement que des + esclaves, ne pouvant se permettre aucune initiative, + n'étant consultés sur rien.

+
+
+ +
+ diff --git a/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.pdf b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.pdf new file mode 100644 index 0000000000..4f80ccc137 Binary files /dev/null and b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.pdf differ diff --git a/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.tex b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.tex new file mode 100644 index 0000000000..8002aec9e2 --- /dev/null +++ b/macros/luatex/latex/ekdosis/samples/Caesar_BG-6-13-1.tex @@ -0,0 +1,118 @@ +\documentclass[12pt]{article} +\usepackage{fontspec} +\usepackage[latin.classic,french,english]{babel} +\babelfont{rm}{Old Standard} +\babelfont{sf}{NewComputerModern Sans} +\babelfont{tt}{NewComputerModern Mono} + +\usepackage{nextpage} +\usepackage{xltabular} + +\usepackage[teiexport=tidy]{ekdosis} +\DeclareApparatus{default}[ + delim=\hskip0.75em, + ehook=.] + +\ekdfmtdiv{2}{}{.} + +\SetEkdosisAlignment{ + tcols=3, + lcols=1, + texts=latin[xml:lang="la"]; + english[xml:lang="en"]; + french[xml:lang="fr"], + apparatus=latin, + segmentation=auto} + +\AtBeginEnvironment{latin}{\selectlanguage{latin}} +\AtBeginEnvironment{english}{\sloppy\selectlanguage{english}} +\AtBeginEnvironment{french}{\sloppy\selectlanguage{french}} + +\DeclareWitness{A}{A}{\emph{Bongarsianus} 81}[ + msName=\emph{Bongarsianus}, + settlement=Amsterdam, + idno=81, + institution=University Library, + origDate=s. IX--X] +\DeclareHand{A1}{A}{A\textsuperscript{1}}[\emph{Emendationes + scribae ipsius}] +\DeclareWitness{M}{M}{\emph{Parisinus Lat.} 5056}[ + origDate={s. XII}] +\DeclareWitness{B}{B}{\emph{Parisinus Lat.} 5763}[ + origDate={s. IX--X}] +\DeclareWitness{R}{R}{\emph{Vaticanus Lat.} 3864}[ + origDate={s. X}] +\DeclareWitness{S}{S}{\emph{Laurentianus} R 33}[ + origDate={s. X}] +\DeclareWitness{L}{L}{\emph{Londinensis} Br. Mus. 10084}[ + origDate={s. XI}] +\DeclareWitness{N}{N}{\emph{Neapolitanus} IV, c. 11}[ + origDate={s. XII}] +\DeclareWitness{T}{T}{\emph{Parisinus Lat.} 5764}[ + origDate={s. XI}] +\DeclareWitness{f}{\emph{f}}{\emph{Vindobonensis} 95}[ + origDate={s. XII}] +\DeclareWitness{U}{U}{\emph{Vaticanus Lat.} 3324}[ + origDate={s. XI}] +\DeclareWitness{l}{\emph{l}}{\emph{Laurentianus} Riccard. 541}[ + origDate={s. XI--XII}] +\DeclareShorthand{a}{α}{A,M,B,R,S,L,N} +\DeclareShorthand{b}{β}{T,f,U,l} + +\begin{document} + +\begin{xltabular}[c]{0.75\linewidth}{lXl} + \caption*{\textbf{Conspectus siglorum}\label{tab:conspectus-siglorum}}\\ + \multicolumn{3}{c}{\emph{Familia} \getsiglum{a}}\\ + \SigLine{A}\\ + & \getsiglum{A1} \emph{Emendationes scribae ipsius} & \\ + \SigLine{M}\\ + \SigLine{B}\\ + \SigLine{R}\\ + \SigLine{S}\\ + \SigLine{L}\\ + \SigLine{N}\\ + \multicolumn{3}{c}{\emph{Familia} \getsiglum{b}}\\ + \SigLine{T}\\ + \SigLine{f}\\ + \SigLine{U}\\ + \SigLine{l}\\ +\end{xltabular} + +\cleartoevenpage + +\begin{alignment} + \begin{latin} + \ekddiv{head=XIII, depth=2, n=6.13, type=section} + In omni Gallia eorum hominum qui \app{ + \lem[wit=a]{aliquo} + \rdg[wit=b, alt=in al-]{in aliquo}} + sunt numero atque honore genera sunt duo. Nam plebes paene + seruorum habetur loco, quae \app{ + \lem[wit={A,M}, alt={nihil audet (aut et \getsiglum{A1}) + per se}]{nihil audet per se} + \rdg[wit=A1,nordg]{nihil aut et per se} + \rdg[wit={R,S,L,N}]{nihil habet per se} + \rdg[wit=b]{per se nihil audet}}, \app{ + \lem[wit=a]{nullo} + \rdg[wit=b]{nulli}} adhibetur \app{ + \lem{consilio} + \rdg[wit={T, U}, alt=conc-]{concilio}}. + \end{latin} + \begin{english} + \ekddiv{head=XIII, depth=2, n=6.13, type=section} + Throughout all Gaul there are two orders of those men who are of + any rank and dignity: for the commonality is held almost in the + condition of slaves, and dares to undertake nothing of itself, + and is admitted to no deliberation. + \end{english} + \begin{french} + \ekddiv{head=XIII, depth=2, n=6.13, type=section} + Partout en Gaule il y a deux classes d'hommes qui comptent et qui + sont considérés. Quant aux gens du peuple, ils ne sont guère + traités autrement que des esclaves, ne pouvant se permettre aucune + initiative, n'étant consultés sur rien. + \end{french} +\end{alignment} + +\end{document} diff --git a/macros/xetex/latex/nanicolle/README.md b/macros/xetex/latex/nanicolle/README.md index 4829ea97bc..5e3e77c459 100644 --- a/macros/xetex/latex/nanicolle/README.md +++ b/macros/xetex/latex/nanicolle/README.md @@ -1,21 +1,23 @@ nanicolle ======= -`nanicolle` is a LaTeX package providing class `nanicolle.cls` for typesetting labels of collection and of identification in Chinese for plant herbarium specimens. +`nanicolle` is a LaTeX package providing class `nanicolle.cls` for typesetting +collection labels and identification labels in Chinese style or in western style +for herbarium specimens. Documents using class `nanicolle` can only be compiled with XeLaTeX by far. Contributing ------------ -This package is developed and maintained by Yuchang Yang < yang.yc.allium@gmail.com >. +This package is authored and maintained by Yuchang Yang < yang.yc.allium@gmail.com >. Discussions and questions are welcome. Copyright and Licence --------------------- - Copyright (C) 2016--2019 Yuchang Yang < yang.yc.allium@gmail.com > + Copyright (C) 2016--2020 Yuchang Yang < yang.yc.allium@gmail.com > ---------------------------------------------------------------------- This work may be distributed and/or modified under the @@ -31,7 +33,9 @@ Copyright and Licence The Current Maintainer of this work is Yuchang Yang. This work consists of: - - the class file: [nanicolle.cls]; - - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; - - the manual files: [nanicolle.tex, nanicolle.pdf, README.md]; - - the example files: [nanicolle-example.tex, nanicolle-example.pdf]. + - the class file: [nanicolle.cls]; + - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; + - the manual files: [nanicolle-doc-zh.tex, nanicolle-doc-zh.pdf, + nanicolle-doc-en.tex, nanicolle-doc-en.pdf, README.md]; + - the example files: [nanicolle-ex-zh.tex, nanicolle-ex-zh.pdf, + nanicolle-ex-en.tex, nanicolle-ex-en.pdf]. diff --git a/macros/xetex/latex/nanicolle/nanicolle-doc-en.pdf b/macros/xetex/latex/nanicolle/nanicolle-doc-en.pdf new file mode 100644 index 0000000000..9b4cebd264 Binary files /dev/null and b/macros/xetex/latex/nanicolle/nanicolle-doc-en.pdf differ diff --git a/macros/xetex/latex/nanicolle/nanicolle-doc-en.tex b/macros/xetex/latex/nanicolle/nanicolle-doc-en.tex new file mode 100644 index 0000000000..ffa64b9815 --- /dev/null +++ b/macros/xetex/latex/nanicolle/nanicolle-doc-en.tex @@ -0,0 +1,296 @@ +%% nanicolle-doc-en.tex +%% Copyright 2016--2020 Yuchang Yang < yang.yc.allium@gmail.com > +% +% 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.3c 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 Yuchang Yang. +% +% This work consists of: +% - the class file: [nanicolle.cls]; +% - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; +% - the manual files: [nanicolle-doc-zh.tex, nanicolle-doc-zh.pdf, +% nanicolle-doc-en.tex, nanicolle-doc-en.pdf, README.md]; +% - the example files: [nanicolle-ex-zh.tex, nanicolle-ex-zh.pdf, +% nanicolle-ex-en.tex, nanicolle-ex-en.pdf]. +%% + +% arara: xelatex +% arara: xelatex + +\documentclass[a4paper]{article} + +\usepackage[top=32mm,bottom=32mm,textwidth=39em]{geometry} +\usepackage{marvosym} +\usepackage{metalogo} +\usepackage{rulerbox} +\usepackage{array} + \newcolumntype{+}{>{\global\let\currentrowstyle\relax}} + \newcolumntype{^}{>{\currentrowstyle}} + \newcommand{\rowstyle}[1]{\gdef\currentrowstyle{#1}#1\ignorespaces} +\usepackage{enumitem} + \setlist[description]{font=\color{mikudark}\bfseries,leftmargin=2em} +\usepackage{multicol} + \setlength\columnsep{3em} + \setlength\columnseprule{0.4pt} +\usepackage{adjustbox} +\usepackage{nth} +\usepackage{tikz} +\usepackage{color} + \definecolor{mikudark}{RGB}{19, 149, 139} +\newbox\mynmy +\sbox\mynmy{% + \smash{\raisebox{-5mm}{\begin{tikzpicture}[x=7mm,y=7mm] + \draw (0,1.2) + .. controls (0.3,0.9) and (0.2,0.4) .. (0.1,0.3) + .. controls (-0.5,-0.2) and (-0.3,1) .. (0.1,0.3) + .. controls (0.1005,0.299) .. (0.11,0.31) + .. controls (0.6,0.9) and (1.4,1.1) .. (1.5,1) + .. controls (1.6,0.9) and (1.5,0.7) .. (1.4,0.6) + .. controls (1.39,0.58) .. (2.8,1.3); + \draw (-0.42,0.38) .. controls (-0.22,0.39) .. (-0.1,0.35); + \end{tikzpicture}}}} + +\makeatletter +\let\url\texttt +\let\pkgname\textsf +\let\uppercase\relax +\def\zh#1{{\fontspec{SimSun}#1}} +\def\@fnsymbol#1{\ifcase#1\or*\or\Letter\fi} +\def\qtimes{\ensuremath{\times}} +\def\tab{\penalty-\@ne\kern1pt\ensuremath{\rightarrow}\kern1pt\relax} +\def\uspace{\textvisiblespace\allowbreak} +\def\@lan{\ensuremath{\langle}} +\def\@ran{\ensuremath{\rangle}} +\def\param#1{\textrm{\@lan\textit{#1}\@ran}} +\def\stopurl{\rlap{\char00}} % WHY URL IS TO GRAB EVERYTHING IT SEES? +\long\def\cmd#1{{\ttfamily\color{mikudark}#1}} +\long\def\pbox#1{\leavevmode\parbox{.86\linewidth}{\cmd{#1}}\kern-.03\linewidth} +\long\edef\[#1\]{$$\noexpand\pbox{\noexpand\raggedright#1\par}$$} +\catcode`\$=\active +\def$#1${\cmd{#1}} +\newcount\itemcnt + \def\clearcnt{\itemcnt\z@} + \def\@black#1{{\color{black}\rmfamily#1}} + \def\@theitem{\global\advance\itemcnt\@ne\@black{\romannumeral\the\itemcnt. }} + \def\@blackperiod{\@black{. }\penalty-\tw@\@gobble} + \def\@blackcolon{\@black{; }\penalty-\tw@} + \def\ritem#1{\mbox{\@theitem#1}\@ifnextchar*\@blackperiod\@blackcolon} +\makeatother + +\title{\pkgname{nanicolle} for herbarium specimen labels% + \footnote{Github repository: \url{https://github.com/Mikumikunisiteageru/nanicolle}\stopurl.}} +\author{\zh{杨宇昌} (Yuchang \textsc{Yang})% + \footnote{Email address: \url{yang.yc.allium@gmail.com}\stopurl.}% + \qquad \box\mynmy\kern-1cm} +\date{July \nth{8}, 2020\qquad ver.~2.02} +\frenchspacing + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} + +\maketitle + +\parskip=1ex\relax + +Herbarium specimens are plant material well preserved as samples of plant populations. The plant material itself is insufficient to reflect all important information of the population, so it is required to prepare a fully recorded \emph{collection label} along with the material. Plant taxonomists may study a herbarium specimen and determine which species the population belongs to, and such comments are presented on \emph{identification labels} and then pasted on the specimen sheet. + +\pkgname{nanicolle} is a \LaTeX\ document class for typesetting collection and identification labels for herbarium specimens, in Chinese style or in western style using English. Labels mentioned hereinafter are by default in western style, which uses a really different layout from the Chinese version (see the Chinese manual for details). Collection and identification labels can be typeset by macros $\string\collect$ and $\string\identify$ (NB: both lower case!) respectively. The output file can be printed on A4 papers (\ensuremath{297\times210} mm). + +Documents in this class can only be compiled with \XeLaTeX{}. + +\pkgname{nanicolle} is distributed under the terms of \LaTeX{} Project Public License (LPPL) 1.3c\footnote{Details of the license are available on \url{http://www.latex-project.org/lppl.txt}\stopurl.}. It depends on package collection \pkgname{C\TeX{}} as well as packages including + \pkgname{calc}, + \pkgname{color}, + \pkgname{geometry}, + \pkgname{graphicx}, + \pkgname{listofitems}, + \pkgname{multicol}\footnote{Since applying \pkgname{nanicolle} document class leads to indirect use of \pkgname{multicol} package, if one wishes to employ \pkgname{nanicolle} for commercial use, he/she may be subject to moral obligation of \pkgname{multicol} (see the notice in its source file for details).}, + \pkgname{xstring}, +etc. + +\vfill\tableofcontents\vfill\null + +\clearpage + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Structure of documents in \pkgname{nanicolle} class}\label{usage} + +A document in the \pkgname{nanicolle} class should be a plain text file with the extension \texttt{.tex}. The document generally should consist of the five following parts: +\begin{enumerate} + \item Document class loader, i.e. $\string\documentclass[\param{option list}]\{nanicolle\}$. $\param{option}$s seperated by comma $,$ in the $\param{option list}$ control the behavior of the document. For example, $nomap$ suppresses the map on collection labels, and $autoduplicate$ repeats the collection labels according to their $\param{duplicate count}$s (vide infra). When no $\param{option}$ is specified, one can simply write $\string\documentclass\{nanicolle\}$ instead. + \item Optional $\string\heading\{\param{heading}\}$ and $\string\subheading\{\param{subheading}\}$ in the preamble to customize content of the headings on each collection label. Both the length of $\param{heading}$ and $\param{subheading}$ should not exceed the line width. One can make a one-line heading by skipping the $\string\subheading$. If both $\string\heading$ and $\string\subheading$ are skipped, no heading will occur on the collection labels. + \item $\string\begin\{document\}$, as the name implies. + \item Lines starting with either $\string\collect$ or $\string\identify$ to typeset collection or identification labels respectively. Syntaxes of these macros will be declared in Section~\ref{collect} and Section~\ref{identify}. + \item $\string\end\{document\}$. +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The macro $\textbackslash collect$ for collection labels}\label{collect} + +The syntax of the macro $\string\collect$ is +\[% + \hangindent=2em\relax + \string\collect + \tab\param{record number}\tab\param{collectors}\tab\param{collecting number}% + \tab\param{collecting date}\tab\param{family}\tab\param{vernacular name}% + \tab\param{scientific name}\tab\param{photo number}\tab\param{duplicate count}% + \tab\param{location}\tab\param{longitude}\tab\param{latitude}% + \tab\param{altitude}\tab\param{habitat}\tab\param{life form}% + \tab\param{height}\tab\param{diameter at breast height}\tab\param{note}% +\] +where $\tab$ denotes a horizontal tab (U+0009, the character that the tab key inputs). Each $\string\collect$ macro followed by its parameters must exclusively occupy a single line without comment sign, and the line should begin immediately with the macro. +Parameters can be left empty (some cannot), but even so the tabs seperating them should never be omitted. +The requirements of each parameter of $\string\collect$ are listed as follows. + +\begin{enumerate} + \item $\param{record number}$: Only for the convenience of data organizing, not printed on collection label. + \item $\param{collectors}$: Names of the persons or the team who collected the specimen. When there were more than one collectors, all their names should be listed here. When a team was involved, it is strongly suggested to list its members' names in parentheses after the team name. $\param{collectors}$ \textsl{cannot} be empty. + \item $\param{collecting number}$: Serial number indexing the specimen collection of the first component of $\param{collectors}$. Traditionally it is suggested to apply sequences of increasing integers starting from 1 to $\param{collecting number}$. + \item $\param{collecting date}$: Date when the specimen was collected, better expressed in arabic numerals following the formula $\param{year}.\param{month}.\param{date}$. Parameter $\param{collecting date}$ \textsl{cannot} be empty. + \item $\param{family}$: Preliminary scientific name (in Latin) of the family. + \item $\param{vernacular name}$: Preliminary vernacular name of the species, in local language. Not printed on collection label. + \item $\param{scientific name}$: Preliminary scientific name (in Latin) of the species, better with no author citation especially when uncertain. Unless empty, $\param{scientific name}$ follows the fomula $\param{generic part}\param{specific part}\param{infraspecific part}$. \par + In the formula above, there are two possible patterns for the $\param{generic part}$: + \[\clearcnt + \ritem{\param{genus name}}% + \ritem{\qtimes\param{genus name}}*\] + $\param{specific part}$ has nine possible patterns: + \[\clearcnt + \ritem{\uspace sp.}% + \ritem{\uspace sp.\uspace nov.}% + \ritem{\uspace\param{species epithet}}% + \ritem{\uspace\qtimes\param{species epithet}}% + \ritem{\uspace aff.\uspace\param{species epithet}}% + \ritem{\uspace aff.\uspace\qtimes\param{species epithet}}% + \ritem{\uspace cf.\uspace\param{species epithet}}% + \ritem{\uspace cf.\uspace\qtimes\param{species epithet}}% + \ritem{\uspace '\param{cultispecies name}'}*\] + where $\uspace$ denotes a normal space (U+0020). + $\param{infraspecific part}$ can be not empty when and only when $\param{specific part}$ fits its pattern iii or iv, at this time having four possible patterns: + \[\clearcnt + \ritem{\uspace subsp.\uspace\param{subspecific epithet}}% + \ritem{\uspace var.\uspace\param{varietal epithet}}% + \ritem{\uspace f.\uspace\param{form epithet}}% + \ritem{\uspace '\param{cultivar name}'}*\] + Control sequences like $\string\textit$ manually designating font style are unavailable in $\param{scientific name}$. + \item $\param{photo number}$: Only for the convenience of data organizing, not printed on collection label. + \item $\param{duplicate count}$: Count of specimen duplicates with the same $\param{collecting number}$, expressed in arabic numerals; not printed on collection label. When $autoduplicate$ is loaded as an $\param{option}$ of the document class, each $\string\collect$ macro automatically makes $\param{duplicate count}$ duplicate collection labels. + \item $\param{location}$: Location where the specimen was collected, expressed in natural way, providing as much detailed information as possible, including country, province, city, town, etc., and the specific locality (probably with respect to some landmarks), so that other researchers can locate the population. $\param{location}$ \textsl{cannot} be empty. + \item $\param{longitude}$: Longitude value of the $\param{location}$, a decimal floating number in degree (without unit), positive for east, negative for west. Sexagesimal expression (in degree, minute, and second) are not acceptable. + \item $\param{latitude}$: Latitude value of the $\param{location}$, a decimal floating number in degree (without unit), positive for north, negative for south. Sexagesimal expression (in degree, minute, and second) are not acceptable. + \item $\param{altitude}$: Altitude value of the $\param{location}$, in meter (without unit), positive or possibly negative. + \item $\param{habitat}$: Living habitat of the population in the wild, e.g. $slopes$, $forest margins$, $streamsides$; or $cultivated$ for those in garden or arboretum. + \item $\param{life form}$: Life form of typical individuals in the population, e.g. $tree$, $shrub$, $vine$. + \item $\param{height}$: Height of typical individuals in the population, in meter (without unit). + \item $\param{diameter at breast height}$: Diameter at breast height (DBH) of typical individuals in the population, in centimeter (without unit), only applying to trees or large shrubs. + \item $\param{note}$: Other valuable information that is no longer observable on herbarium specimens, in aspects of morphology (e.g. color \& smell of different parts, texture of the bark), ecology (e.g. richness, pollinator species), or ethnobotany (e.g. local usages). Different from other parameters of $\string\collect$, $\param{note}$ is a complete sentence (unless empty), so that the leading letter of the first word should be capitalized, and a punctuation (usually period) is required at the end. +\end{enumerate} + +\def\degree{\kern0.1ex\ensuremath{^\circ}} +By default, when preparing a collection label, \pkgname{nanicolle} typesets a map below the main body of the label, illustrating the position of the coordinates, given that the $\param{longitude}$ lies between 73\degree E and 136\degree E, and the $\param{latitude}$ lies between 17\degree N and 54\degree N. One can load a $nomap$ $\param{option}$ into the document class (Section~\ref{usage}) to suppress the typesetting of maps. It is also possible to redefine the geographic range of the maps. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The macro $\textbackslash identify$ for identification labels}\label{identify} + +The syntax of the macro $\string\identify$ is +\[% + \hangindent=2em\relax + \string\identify + \tab\param{record number}\tab\param{scientific name}\tab\param{vernacular name}% + \tab\param{identifier}\tab\param{identifier code}% + \tab\param{identifying date}\tab\param{comment}% +\] +Just as $\string\collect$, each $\string\identify$ macro with its parameters must exclusively occupy a single line. +Parameters can be left empty unless specialized, but the tabs seperating them cannot be omitted. +The requirements of each parameter of $\string\identify$ are listed as follows. + +\begin{enumerate} + \item $\param{record number}$: Only for the convenience of data organizing, not printed on identification label. + \item $\param{scientific name}$: Scientific name with author citation of the species that the identification yielded, following the formula $\param{generic part}\param{specific part}\param{infraspecific part}\uspace\param{author citation}$. As that of $\string\collect$, macros for manually manipulating font style are unavailable here either. $\param{scientific name}$ \textsl{cannot} be empty. + \item $\param{vernacular name}$: Common name associated with $\param{scientific name}$ of the species. + \item $\param{identifier}$: Full name of the identifier. + \item $\param{identifier code}$: Standard form (taxonomic) of the name of the identifier. $\param{identifier}$ and $\param{identifier code}$ \textsl{cannot} be both empty, while it is suggested to leave either of them empty in a record. + \item $\param{identifying date}$: Date when the specimen was identified, following the same restriction as $\param{collecting date}$ for $\string\collect$. $\param{identifying date}$ \textsl{cannot} be empty. + \item $\param{comment}$: Comment about the identification worth mention. Different from other parameters of $\string\identify$, $\param{comment}$ is a complete sentence (unless empty), so that the leading letter of the first word should be capitalized, and a punctuation (usually period) is required at the end. +\end{enumerate} + +The $\string\identify$ macro has no $\param{duplication count}$ parameter, so identification label will not be automatically repeated. When repeating is wanted, one has to repeat the lines with $\string\identify$ manually. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Other issues} + +\subsection{Store original data in a spreadsheet software} + +Using tabs $\tab$ as delimiters between parameters is not the convention of \LaTeX{}. This special rule for delimiters was designed to make \pkgname{nanicolle} able to read the plain text lines from a spreadsheet software\footnote{Microsoft Office Excel is an instance of spreadsheet software.}. When some rows of cells are pasted from a spreadsheet software to plain text environment, it is automatically converted to TSV (Tab-Separated Values) format --- rows/lines are separated by end-of-line character(s), and cells within a row/line are separated by tab. This mechanism allows users to establish a database for collection or identification records in a spreadsheet software (as Table~\ref{table}). When one wants to print labels according to certain records, he/she can simply copy the involved rows from the database, paste them in a \LaTeX{} source file, and then call \pkgname{nanicolle} to deal with them. Databases can also contain extra information after the parameters required, which will be ignored by $\string\collect$ or $\string\identify$ and will not affect the output. + +\begin{table}[htbp] + \centering + \begin{tabular}{|+c|*{4}{^c|}} + \hline + \rowstyle{\bfseries} macro & record number & collectors & collecting number & \ensuremath{\cdots} \\\hline + \string\collect & 1 & Foo, Bar & 3141 & \ensuremath{\cdots} \\\hline + \string\collect & 2 & Foo, Bar & 3142 & \ensuremath{\cdots} \\\hline + \string\collect & 3 & Foo, Bar & 3143 & \ensuremath{\cdots} \\\hline + \end{tabular} + \caption{A sample of database for collection records in a spreadsheet database}\label{table} +\end{table} + +\subsection{Set the printer correctly} + +Before the PDF file from \pkgname{nanicolle} is sent to a printer, it is necessary to do some settings. When printing an A4-sized PDF file on to an A4-sized paper with a home printer, the file is usually shrunk a little bit smaller to fit into the printable range. If so, since \pkgname{nanicolle} uses a four-column landscape layout, the outer columns would be some broader than the inner ones. To avoid unbalance, one can select to print ``at actual size'', ``at absolute size'', or make the scale ``100\%''. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Change history} + +\pkgname{nanicolle} was originally designed for making Chinese collection labels and identification labels, with its first version completed on 2016/8/3 (ver. 1.01). Later on 2017/10/22 (ver. 1.07), the typesetting of western style collection labels was carried out for an international plant expedition, and that was the first version with maps. The macro for collection labels in western style had been temporarily hidden since 2019.4.28 (ver. 2.00), until rewritten and republished on 2020.7.8 (ver. 2.02). +For more details, please refer to the Chinese manual \texttt{nanicolle-zh.PDF}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{A full example using \pkgname{nanicolle}} + +The following is a full example file using document class \pkgname{nanicolle}. It can be found as \texttt{nanicolle-ex-en.tex} in the package. To display it more clearly, the $\uspace$ denotion for space is no longer used in this example. Actual lines correspond with line numbers in the left. An actual line may be so long that it is wrapped here, just as in text editors, but remember, these wrapped parts in fact belong to a single line, as there is no end-of-line character in between. + +\begingroup +\catcode`\^^I\active\let^^I\tab +\[% +\clearcnt +\def\zh#1{{\fontspec{FangSong}#1}} +\everypar={\hangindent=2em\relax\advance\itemcnt1\relax% +\leavevmode\llap{\number\itemcnt\quad}} +\string\documentclass[autoduplicate]\string{nanicolle\string}\par +\string\begin\string{document\string}\par +\string\collect 1997 Yuchang Yang (\zh{杨宇昌}) 5731 2018.5.8 Caprifoliaceae \zh{苦糖果} Lonicera fragrantissima subsp. standishii 7609 1 between Dongjiamen Village (\zh{董家门村}) and Dongnao (\zh{洞垴}), Guantao Town (\zh{管陶乡}), Wu'an City (\zh{武安市}), Hebei Province (\zh{河北省}), China 113.759512 36.951612 1356.0 meadow thickets on slopes shrub 3 Ripe fruit orange-red, tasting sweet with minimal bitter.\par +\string\collect 1545 Sino-Nepal Joint Plant Expedition (Haining Qin, Prabin Bhandari, Tirtha Raj Pandey, Bijay Raj Subedee, Yuchang Yang, Shuren Zhang) 601 2017.9.18 Fagaceae Quercus glauca - 2 Talkot, Bajhang District, Nepal 1700 forests tree 10 15 Fruiting. Associated with \string\textit\string{Rhododendron arboreum\string} and \string\textit\string{Lyonia ovalifolia\string}.\par +\string\identify 392 Allium atrosanguineum var. tibeticum (Regel) G. H. Zhu \string& Turland \zh{藏葱} (Z\string\`ang C\string\=ong) Yuchang Yang 2018.10.7 \par +\string\identify 176 Acer davidii subsp. grosseri (Pax) P. C. de Jong Yuchang Yang 2018.4.19 \par +\string\identify 230 Erysimum \qtimes cheiri (L.) Crantz Yuchang Yang 2018.5.17 \par +\string\identify 590 Koenigia alpina (All.) T. M. Schust. \string& Reveal Yuchang Yang 2019.4.13 \par +\string\end\string{document\string}\par +\] +\endgroup + +Locate to the path of the example file in a command line window, then type and execute \texttt{xelatex nanicolle-ex-en}. After the compilation, the output PDF file (see Figure~\ref{example}) \texttt{nanicolle-ex-en.PDF} can be found in the same path. + +\begin{figure}[htbp] + \centering + \fboxsep=-.2pt\relax + \hbox{}\hidewidth\rulerbox{\vbox{\kern-.2pt\hbox{\kern-.2pt\fbox{\includegraphics*[bb=0cm 0cm 14.85cm 21cm]{nanicolle-ex-en.pdf}}\kern-.2pt}\kern-.2pt}}\hidewidth\hbox{}\par + \caption{Left two columns in the sample PDF file \texttt{nanicolle-ex-en.pdf}}\label{example} +\end{figure} + +\end{document} diff --git a/macros/xetex/latex/nanicolle/nanicolle-doc-zh.pdf b/macros/xetex/latex/nanicolle/nanicolle-doc-zh.pdf new file mode 100644 index 0000000000..8756fabd90 Binary files /dev/null and b/macros/xetex/latex/nanicolle/nanicolle-doc-zh.pdf differ diff --git a/macros/xetex/latex/nanicolle/nanicolle-doc-zh.tex b/macros/xetex/latex/nanicolle/nanicolle-doc-zh.tex new file mode 100644 index 0000000000..1344ac3ff8 --- /dev/null +++ b/macros/xetex/latex/nanicolle/nanicolle-doc-zh.tex @@ -0,0 +1,355 @@ +%% nanicolle-doc-zh.tex +%% Copyright 2016--2020 Yuchang Yang < yang.yc.allium@gmail.com > +% +% 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.3c 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 Yuchang Yang. +% +% This work consists of: +% - the class file: [nanicolle.cls]; +% - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; +% - the manual files: [nanicolle-doc-zh.tex, nanicolle-doc-zh.pdf, +% nanicolle-doc-en.tex, nanicolle-doc-en.pdf, README.md]; +% - the example files: [nanicolle-ex-zh.tex, nanicolle-ex-zh.pdf, +% nanicolle-ex-en.tex, nanicolle-ex-en.pdf]. +%% + +% arara: xelatex +% arara: xelatex + +\documentclass[a4paper]{ctexart} + \CTEXsetup[format={\Large\bfseries}]{section} + +\usepackage[top=32mm,bottom=32mm,textwidth=39em]{geometry} +\usepackage{marvosym} +\usepackage{metalogo} +\usepackage{rulerbox} +\usepackage{tikz} +\usepackage{color} + \definecolor{mikudark}{RGB}{19, 149, 139} +\usepackage{array} + \newcolumntype{+}{>{\global\let\currentrowstyle\relax}} + \newcolumntype{^}{>{\currentrowstyle}} + \newcommand{\rowstyle}[1]{\gdef\currentrowstyle{#1}#1\ignorespaces} +\usepackage{enumitem} + \setlist[description]{font=\color{mikudark}\bfseries,leftmargin=2em} +\usepackage{multicol} + \setlength\columnsep{3em} + \setlength\columnseprule{0.4pt} +\usepackage{adjustbox} +\newbox\mynmy +\sbox\mynmy{% + \smash{\raisebox{-5mm}{\begin{tikzpicture}[x=7mm,y=7mm] + \draw (0,1.2) + .. controls (0.3,0.9) and (0.2,0.4) .. (0.1,0.3) + .. controls (-0.5,-0.2) and (-0.3,1) .. (0.1,0.3) + .. controls (0.1005,0.299) .. (0.11,0.31) + .. controls (0.6,0.9) and (1.4,1.1) .. (1.5,1) + .. controls (1.6,0.9) and (1.5,0.7) .. (1.4,0.6) + .. controls (1.39,0.58) .. (2.8,1.3); + \draw (-0.42,0.38) .. controls (-0.22,0.39) .. (-0.1,0.35); + \end{tikzpicture}}}} + +\makeatletter +\let\url\texttt +\let\emph\textbf +\let\pkgname\textsf +\let\uppercase\relax +\def\@fnsymbol#1{\ifcase#1\or*\or\Letter\fi} +\def\qtimes{\ensuremath{\times}} +\def\tab{\penalty-\@ne\kern1pt\raisebox{.2ex}{\ensuremath{\rightarrow}}\kern1pt\relax} +\def\uspace{\textvisiblespace\allowbreak} +\def\@lan{\raisebox{.2ex}{\ensuremath{\langle}}} +\def\@ran{\raisebox{.2ex}{\ensuremath{\rangle}}} +\def\param#1{\textrm{\@lan\textit{#1}\@ran}} +\def\stopurl{\rlap{\char00}} % WHY URL IS TO GRAB EVERYTHING IT SEES? +\long\def\cmd#1{{\ttfamily\color{mikudark}#1}} +\long\def\pbox#1{\leavevmode\parbox{.86\linewidth}{\cmd{#1}}\kern-.03\linewidth} +\long\edef\[#1\]{$$\noexpand\pbox{\noexpand\raggedright#1\par}$$} +\catcode`\$=\active +\def\check@nextchar{% + \if\@nextchar、\unskip\fi + \if\@nextchar,\unskip\fi + \if\@nextchar:\unskip\fi + \if\@nextchar;\unskip\fi + \if\@nextchar。\unskip\fi} +\def$#1${\CJKecglue\cmd{#1}\CJKecglue + \futurelet\@nextchar\check@nextchar} +\newcount\itemcnt + \def\clearcnt{\itemcnt\z@} + \def\@black#1{{\color{black}\rmfamily#1}} + \def\@theitem{\advance\itemcnt\@ne\@black{\romannumeral\the\itemcnt.\space}} + \def\@blackperiod{\@black{。}\@gobble} + \def\@blackcolon{\@black{;}\penalty-\@ne} + \def\ritem#1{\@theitem#1\@ifnextchar*\@blackperiod\@blackcolon} +\makeatother + +\title{植物标本标签文档类\pkgname{nanicolle}% + \footnote{本项目的Github仓库地址为\url{https://github.com/Mikumikunisiteageru/nanicolle}\stopurl 。}} +\author{杨宇昌% + \footnote{电子邮箱为\url{yang.yc.allium@gmail.com}\stopurl 。}% + \qquad\box\mynmy\kern-1cm} +\date{2020年7月8日\qquad ver.~2.02} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} + +\maketitle + +\parskip=1ex\relax + +植物标本是经处理能够长期保存的植物材料。它们是植物居群的样本,通过标本可以了解植物居群。由于植物材料本身并不能完整地反映居群的所有重要信息,标本采集者需要作出补充并记录成\emph{采集标签},与标本一同保存。植物分类学者可以研究判定标本对应居群所属的物种,其鉴定意见则以\emph{鉴定标签}的形式,附在标本上。 + +\LaTeX{}文档类\pkgname{nanicolle}可排版植物标本用的中式或西式的采集标签和鉴定标签。中式的两种标签分别由$\string\Collect$命令和$\string\Identify$命令产生。要排版西式的采集标签和鉴定标签,需改用小写的$\string\collect$和$\string\identify$命令,格式和前者大致相同,具体要求和用例见英文文档。本中文文档中所说的标签都默认是中式的。 +标签会安排在横向A4尺寸、分为四栏的页面上,可以用A4纸张打印。目前,\pkgname{nanicolle}文档类仅支持\XeLaTeX{}引擎编译。 + +\pkgname{nanicolle}按 The \LaTeX{} Project Public License (LPPL) 1.3c 许可证\footnote{LPPL 1.3c 许可证的详细内容见\url{http://www.latex-project.org/lppl.txt}\stopurl 。}授权发布。它依赖\pkgname{C\TeX{}}宏集和 + \pkgname{calc}、 + \pkgname{color}、 + \pkgname{geometry}、 + \pkgname{graphicx}、 + \pkgname{listofitems}、 + \pkgname{multicol}\footnote{由于指定 \pkgname{nanicolle} 文档类会间接地构成对 \pkgname{multicol} 宏包的使用,若要将 \pkgname{nanicolle} 用于商业用途,则需要向 \pkgname{multicol} 宏包的作者支付授权费用,详情见该宏包的授权许可证。}、 + \pkgname{xstring} +等宏包。 + +\parskip=0ex\relax + +% \vfill +\tableofcontents\vfill\null + +\clearpage + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\pkgname{nanicolle}类文档的结构}\label{usage} + +一份使用\pkgname{nanicolle}类的文档应是包含以下5部分、文件名以后缀 \texttt{.tex} 结尾的纯文本: +\begin{enumerate} + \item 载入\pkgname{nanicolle}文档类,即$\string\documentclass[\param{选项}]\{nanicolle\}$。 + 其中,$\param{选项}$控制文档的行为,例如$nomap$可禁用采集标签中的地图,$autoduplicate$则能按标本份数重复采集标签;选项超过一个时,其间要用$,$分隔。不需要加载选项时,可写$\string\documentclass\{nanicolle\}$。 + \item 在导言区使用$\string\heading$和$\string\subheading$命令定义定制内容。要在采集标签上方添加统一的标题,可写$\string\heading\{\param{标题}\}$;副标题如需要则可由$\string\subheading\{\param{副标题}\}$命令产生。二者长度均不得超过一行。若跳过此部分,则采集标签上方无标题。 + \item 正文开始,即$\string\begin\{document\}$。 + \item 在正文中使用$\string\Collect$和$\string\Identify$两种命令分别产生采集标签和鉴定标签,每个命令占一行。两种命令的格式分别参见第 \ref{collect} 和第 \ref{identify} 节。 + \item 正文结束,即$\string\end\{document\}$。 +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{用\hbox{}$\textbackslash Collect$命令生成采集标签}\label{collect} + +$\string\Collect$命令的格式为 +\[% + \hangindent=2em\relax + \string\Collect + \tab\param{记录号}\tab\param{采集人}\tab\param{采集号}% + \tab\param{采集日期}\tab\param{科名}\tab\param{中文名}% + \tab\param{学名}\tab\param{照片号}\tab\param{标本份数}% + \tab\param{产地}\tab\param{经度}\tab\param{纬度}% + \tab\param{海拔}\tab\param{生境}\tab\param{生活型}% + \tab\param{体高}\tab\param{胸径}\tab\param{附注}% +\] +当中$\tab$表示水平制表符(U+0009,可按键盘Tab键输入)。每行最多能有一个$\string\Collect$命令;每个$\string\Collect$命令须出现在一行开始处,其所有参数必须出现在同一行中;$\string\Collect$所在的行不能有注释符号。 +某些参数可以为空,但$\tab$都须保留。 +以下分别说明诸参数。 + +\begin{enumerate} + \item $\param{记录号}$:仅为数据组织方便而设,不在采集标签上出现。 + \item $\param{采集人}$:标本的采集者的姓名。如有多个采集者,应列举姓名,其间可以用顿号分隔;如果要填写采集团队名称,也应注明其成员。此参数不得为空。 + \item $\param{采集号}$:属于$\param{采集人}$中第一个采集者的记录标本采集的序列号码。建议为简单的整数,从1开始递增。 + \item $\param{采集日期}$:采集植物材料的日期,可使用$\param{年}.\param{月}.\param{日}$的阿拉伯数字表示。此参数不得为空。 + \item $\param{科名}$:临时鉴定的科的名称,建议使用中文表示。 + \item $\param{中文名}$:临时鉴定的植物中文名。 + \item $\param{学名}$:临时鉴定的植物学名,建议不带作者引证。当非空时,可用通式$\param{属级部分}\param{种级部分}\param{种下等级部分}$表示。 + 其中,$\param{属级部分}$有2类结构: + \[\clearcnt + \ritem{\param{属名}}% + \ritem{\qtimes\param{属名}}*\] + $\param{种级部分}$有9类结构: + \[\clearcnt + \ritem{\uspace sp.}% + \ritem{\uspace sp.\uspace nov.}% + \ritem{\uspace\param{种加词}}% + \ritem{\uspace\qtimes\param{种加词}}% + \ritem{\uspace aff.\uspace\param{种加词}}% + \ritem{\uspace aff.\uspace\qtimes\param{种加词}}% + \ritem{\uspace cf.\uspace\param{种加词}}% + \ritem{\uspace cf.\uspace\qtimes\param{种加词}}% + \ritem{\uspace '\param{栽培种名}'}*\] + 当中的$\uspace$表示一个空格(U+0020)。$\param{种下等级部分}$仅当$\param{种级部分}$为结构iii或结构iv时可以非空,此时它有4类结构: + \[\clearcnt + \ritem{\uspace subsp.\uspace\param{亚种加词}}% + \ritem{\uspace var.\uspace\param{变种加词}}% + \ritem{\uspace f.\uspace\param{变型加词}}% + \ritem{\uspace '\param{栽培品种名}'}*\] + 此参数中不能用$\string\textit$之类的控制序列手动控制字体样式。 + \item $\param{照片号}$:仅为数据组织方便而设,不在采集标签上出现。 + \item $\param{标本份数}$:标本的同号复份数目,用阿拉伯数字表示。不在采集标签上出现。当文档类的$\param{选项}$包含$autoduplicate$时,每个$\string\Collect$命令将输出$\param{标本份数}$张重复的采集标签。 + \item $\param{产地}$:植物材料的采集地的自然语言表述,要包含完整的省级、县级、乡级行政单元序列和小地点,小地点可参照地标表示,以便考证与回访。此参数不得为空。 + \item $\param{经度}$:植物材料采集地的经度坐标,用十进制的浮点数表示,以角度为单位,不带单位符号,正数为东经,负数为西经。不接受度分秒表示。 + \item $\param{纬度}$:植物材料采集地的纬度坐标,用十进制的浮点数表示,以角度为单位,不带单位符号,正数为北纬,负数为南纬。不接受度分秒表示。 + \item $\param{海拔}$:植物材料采集地的海拔高度,用阿拉伯数字表示,以米为单位,不带单位符号,可以为负数。 + \item $\param{生境}$:植物居群的野外生活环境,如$山地$、$林缘$、$溪边$等,但对于栽培的植物,应填写$栽培$而非具体的生活环境。 + \item $\param{生活型}$:植物居群的生活型,如$乔木$、$灌木$、$藤本$等。 + \item $\param{体高}$:植物居群中个体的典型高度,用阿拉伯数字表示,以米为单位,不带单位符号。 + \item $\param{胸径}$:植物居群中个体的典型胸径,用阿拉伯数字表示,以厘米为单位,不带单位符号。 + \item $\param{附注}$:包含其他在植物标本上无法观察的有价值的信息,如各部的颜色、气味,树皮的纹理,传粉者,植物在当地的俗名、用途、常见程度等。和以上各参数不同,$\param{附注}$是完整的句子,末尾要有标点。 +\end{enumerate} + +\pkgname{nanicolle}文档类默认在经纬度均非空且经度在东经73--136度间、纬度在北纬17--54度间时在采集标签下方输出地图,以标明该坐标的位置。要禁用这个功能,可以在载入文档类时使用$nomap$选项,见第 \ref{usage} 节。 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{用\hbox{}$\textbackslash Identify$命令生成鉴定标签}\label{identify} + +$\string\Identify$命令的格式为 +\[% + \hangindent=2em\relax + \string\Identify + \tab\param{记录号}\tab\param{学名}\tab\param{中文名}% + \tab\param{鉴定人}\tab\param{鉴定人标准形式}% + \tab\param{鉴定日期}\tab\param{批注}% +\] +和$\string\Collect$一样,每个$\string\Identify$命令及其所有参数需独占一行。以下就诸参数分别说明。 + +\begin{enumerate} + \item $\param{记录号}$:仅为数据组织方便而设,不在采集标签上出现。 + \item $\param{学名}$:正式鉴定的植物学名,须带有作者引证,可用通式$\param{属级部分}\param{种级部分}\param{种下等级部分}\param{作者引证}$表示。此参数不得为空。 + \item $\param{中文名}$:与$\param{学名}$相关联的中文种名。 + \item $\param{鉴定人}$:标本鉴定者的姓名。 + \item $\param{鉴定人标准形式}$:标本鉴定者的姓名在分类学上约定的标准形式。此参数与$\param{鉴定人}$不得同时为空。 + \item $\param{鉴定日期}$:鉴定标本的日期,格式同$\param{采集日期}$。此参数不得为空。 + \item $\param{批注}$:需另外表明的分类学意见。和以上各参数不同,$\param{批注}$是完整的句子,末尾要有标点。 +\end{enumerate} + +不同于$\string\Collect$命令,$\string\Identify$命令不带$\param{标本份数}$参数,故每个$\string\Identify$命令固定地输出一张鉴定标签。要输出重复的鉴定标签,只能手动复制命令所在的行。 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{其他问题} + +\subsection{用电子表格软件储存原始数据} + +$\string\Collect$与$\string\Identify$之所以不遵照\LaTeX{}惯例而用制表符$\tab$作为参数的定界符,其用意是使得原始数据可以储存电子表格(Spreadsheet)软件\footnote{Microsoft Office Excel 便是一种电子表格软件。}中。当纯文本粘贴到电子表格中时,换行符分隔各行,制表符分隔行内各列。当电子表格的内容粘贴为纯文本时,各行由换行符分隔,行内各列由制表符分隔(形成TSV格式)。事实上,这种规定允许储存于电子表格中的原始数据可以直接为\XeLaTeX{}引擎所读取。具体来说,可以建立一个形如表 \ref{table} 的电子表格来储存原始数据。 +\begin{table}[htbp] + \centering + \begin{tabular}{|+c|*{8}{^c|}} + \hline + \rowstyle{\bfseries} 命令 & 记录号 & 采集人 & 采集号 & 采集日期 & 科名 & 中文名 & 学名 & \ensuremath{\cdots} \\\hline + \string\Collect & 1 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline + \string\Collect & 2 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline + \string\Collect & 3 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline + \end{tabular} + \caption{储存采集标签原始数据的电子表格示例}\label{table} +\end{table} +这样,电子表格中的若干行被选中并复制到纯文本环境下后便自动转换成了$\string\Collect$或$\string\Identify$命令要求的格式。而电子表格中的原始数据库在这些命令所要求的参数外还能储存更丰富的信息,这些额外信息会被$\string\Collect$或$\string\Identify$命令忽略,不影响标签的内容。 + +\subsection{PDF文件的打印设置} + +编译得到的PDF文件最终要用打印机打印并裁剪,成为可实际使用的标签。打印机的可打印范围一般比纸面小,故打印机通常默认将文件略为缩小。而\pkgname{nanicolle}采用A4纸横向四列布局,按这样印出来的线条裁切,便会出现两侧的标签宽、中间的标签窄的情形。为避免这种问题,打印PDF文件时应选中“使用原始页面大小”选项。 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{完整实例} + +以下是\pkgname{nanicolle}类的一份文档实例,即包中的 \texttt{nanicolle-ex-zh.tex} 文件。实际的行和左侧的行号是对应的,每个$\string\Collect$或$\string\Identify$命令和其所有参数均在同一行中,折行只是便于展示。定位至文件所在目录并运行 \texttt{xelatex nanicolle-ex-zh},编译完后即可得到 \texttt{nanicolle-ex-zh.pdf}(图 \ref{example})。 +\begingroup +\catcode`\^^I\active\let^^I\tab +\catcode`\ \active\let \uspace +\[% +\clearcnt +\everypar={\hangindent=2em\relax\advance\itemcnt1\relax% +\leavevmode\llap{\number\itemcnt\quad}} +\xeCJKsetup{CJKecglue={}} +\linespread{1.23}\selectfont +\string\documentclass[autoduplicate]\string{nanicolle\string}\par +\string\begin\string{document\string}\par +\string\Collect 724 杨宇昌 5358 2017.5.29 报春花科 粉报春 Primula farinosa 5992 1 内蒙古自治区赤峰市阿鲁科尔沁旗新民乡西拉沐伦大峡谷园区 117.574461 43.136042 918.6 沼泽化草甸 直立草本 0.2 花粉红色,花梗与花萼常被白粉;与天山报春 \string\textit\string{Primula nutans\string} 混生。\par +\string\Identify 78 Allium chrysanthum Regel 野葱 杨宇昌 2017.12.7 \par +\string\Collect 1997 杨宇昌 5731 2018.5.8 忍冬科 苦糖果 Lonicera fragrantissima subsp. standishii 7609 2 河北省邯郸市武安市管陶乡董家门村西至洞垴途中 1356.0 山坡灌草丛 灌木 3 果实橙红色,味甜微苦。\par +\string\Identify 439 Maianthemum bifolium (L.) F. W. Schmidt 舞鹤草 杨宇昌 2018.12.9 \par +\string\Identify Idesia polycarpa var. vestita Diels 毛叶山桐子 杨宇昌 2016.5.20 \par +\string\Identify 128 Kandelia obovata Sheue, H. Y. Liu \string& J. W. H. Yong 秋茄树 杨宇昌 2018.3.5 \par +\string\Identify 585 Ulmus lamellosa C. Wang \string& S. L. Chang 脱皮榆 杨宇昌 2019.4.11 \par +\string\end\string{document\string}\par +\] +\endgroup\par + +\begin{figure}[htbp] + \centering + \fboxsep=-.2pt\relax + \hbox{}\hidewidth\rulerbox{\vbox{\kern-.2pt\hbox{\kern-.2pt\fbox{\includegraphics*[bb=0cm 0cm 14.85cm 21cm]{nanicolle-ex-zh.pdf}}\kern-.2pt}\kern-.2pt}}\hidewidth\hbox{}\par + \caption{样例PDF文件 \texttt{nanicolle-ex-zh.pdf} 的前2栏(左半页)}\label{example} +\end{figure} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{更新日志} +\begin{multicols}{2} +\begin{description}[style=nextline] + \parskip=0pt + \obeylines + \item[ver. 2.02 (2020.7.8)] + 修正负经纬度值不能解析的错误。 + 中式采集标签的参数取消长度限制。 + 恢复西式采集标签排版功能。 + 新增西式标签样例和英文文档。 + \item[ver. 2.01 (2019.9.27)] + 再改进采集标签中下划线表的实现。 + 支持在附注等参数中直接用\LaTeX{}命令如 $\string\textit$ 等控制字体样式。 + 合并解析拉丁学名的两处代码,允许在采集标签的学名后引证作者。 + \item[ver. 2.00 (2019.4.28)] + 全部代码重构,打包为文档类,重新命名为\pkgname{nanicolle}。 + 新增地图自定义与自动选择功能。 + 暂时删去西式采集标签排版功能。 + 删去标本条码标签排版功能。 + 删去某植物园的建筑地图。 + 正式发布于CTAN和Github上。 + \item[ver. 1.14 (2018.12.2)] + 新增 $\textbackslash ifinternal$ 开关,以快速控制条码、照片号、标题等。 + \item[ver. 1.13 (2018.9.15)] + 改进采集标签中下划线表的实现。 + 修正地图中的国界错误。 + \sout{采集标签中增加某植物园建筑地图。} + 缩减采集标签中的悬挂缩进量。 + 代码模块化。 + \item[ver. 1.12 (2018.5.15)] + 优化拉丁学名断行位置。 + 调整标本条码标签的段落样式。 + \item[ver. 1.11 (2018.3.28)] + 调整原始数据结构。 + 鉴定标签中增加命名人标准缩写。 + \item[ver. 1.10 (2018.2.9)] + 采集标签中增加东莞市镇街地图。 + \item[ver. 1.09 (2018.1.28)] + \sout{实现标本条码标签排版。} + \item[ver. 1.08 (2017.10.31)] + 采集标签中增加经度 \ensuremath{73\mbox{--}136\,^\circ\mathrm E}、纬度 \ensuremath{17\mbox{--}54\,^\circ\mathrm N}范围的地图。 + \item[ver. 1.07 (2017.10.22)] + 采集标签与鉴定标签中增加条码。 + 实现带有尼泊尔分区地图的西式采集标签排版,用于2017年中国—尼泊尔联合植物考察。 + \item[ver. 1.06 (2017.10.21)] + 采集标签中增加标题。 + \item[ver. 1.05 (2017.7.4)] + 页面布局由A4纸纵向双栏改为横向四栏,字号相应缩小,用途更广。 + 改进水平切割线的样式。 + \item[ver. 1.03 (2017.7.2)] + 参数改用制表符分隔,方便操作。 + % 此版本曾发布于Github上。 + \item[ver. 1.02 (2016.8.6)] + \sout{新造某生僻字。} + \item[ver. 1.01 (2016.8.3)] + 实现采集标签与鉴定标签排版功能。 +\end{description} +\end{multicols} + +\end{document} diff --git a/macros/xetex/latex/nanicolle/nanicolle-ex-en.pdf b/macros/xetex/latex/nanicolle/nanicolle-ex-en.pdf new file mode 100644 index 0000000000..7a1373c40e Binary files /dev/null and b/macros/xetex/latex/nanicolle/nanicolle-ex-en.pdf differ diff --git a/macros/xetex/latex/nanicolle/nanicolle-ex-en.tex b/macros/xetex/latex/nanicolle/nanicolle-ex-en.tex new file mode 100644 index 0000000000..7c3ec22d55 --- /dev/null +++ b/macros/xetex/latex/nanicolle/nanicolle-ex-en.tex @@ -0,0 +1,9 @@ +\documentclass[autoduplicate]{nanicolle} +\begin{document} +\collect 1997 Yuchang Yang (杨宇昌) 5731 2018.5.8 Caprifoliaceae 苦糖果 Lonicera fragrantissima subsp. standishii 7609 1 between Dongjiamen Village (董家门村) and Dongnao (洞垴), Guantao Town (管陶乡), Wu'an City (武安市), Hebei Province (河北省), China 113.759512 36.951612 1356.0 meadow thickets on slopes shrub 3 Ripe fruit orange-red, tasting sweet with minimal bitter. +\collect 1545 Sino-Nepal Joint Plant Expedition (Haining Qin, Prabin Bhandari, Tirtha Raj Pandey, Bijay Raj Subedee, Yuchang Yang, Shuren Zhang) 601 2017.9.18 Fagaceae Quercus glauca - 2 Talkot, Bajhang District, Nepal 1700 forests tree 10 15 Fruiting. Associated with \textit{Rhododendron arboreum} and \textit{Lyonia ovalifolia}. +\identify 392 Allium atrosanguineum var. tibeticum (Regel) G. H. Zhu & Turland 藏葱 (Z\`ang C\=ong) Yuchang Yang 2018.10.7 +\identify 176 Acer davidii subsp. grosseri (Pax) P. C. de Jong Yuchang Yang 2018.4.19 +\identify 230 Erysimum ×cheiri (L.) Crantz Yuchang Yang 2018.5.17 +\identify 590 Koenigia alpina (All.) T. M. Schust. & Reveal Yuchang Yang 2019.4.13 +\end{document} diff --git a/macros/xetex/latex/nanicolle/nanicolle-ex-zh.pdf b/macros/xetex/latex/nanicolle/nanicolle-ex-zh.pdf new file mode 100644 index 0000000000..8d4898c656 Binary files /dev/null and b/macros/xetex/latex/nanicolle/nanicolle-ex-zh.pdf differ diff --git a/macros/xetex/latex/nanicolle/nanicolle-ex-zh.tex b/macros/xetex/latex/nanicolle/nanicolle-ex-zh.tex new file mode 100644 index 0000000000..911b3e8fd4 --- /dev/null +++ b/macros/xetex/latex/nanicolle/nanicolle-ex-zh.tex @@ -0,0 +1,10 @@ +\documentclass[autoduplicate]{nanicolle} +\begin{document} +\Collect 724 杨宇昌 5358 2017.5.29 报春花科 粉报春 Primula farinosa 5992 1 内蒙古自治区赤峰市阿鲁科尔沁旗新民乡西拉沐伦大峡谷园区 117.574461 43.136042 918.6 沼泽化草甸 直立草本 0.2 花粉红色,花梗与花萼常被白粉;与天山报春 \textit{Primula nutans} 混生。 +\Identify 78 Allium chrysanthum Regel 野葱 杨宇昌 2017.12.7 +\Collect 1997 杨宇昌 5731 2018.5.8 忍冬科 苦糖果 Lonicera fragrantissima subsp. standishii 7609 2 河北省武安市管陶乡董家门村西至洞垴途中 1356.0 山坡灌草丛 灌木 3 果实橙红色,味甜微苦。 +\Identify 439 Maianthemum bifolium (L.) F. W. Schmidt 舞鹤草 杨宇昌 2018.12.9 +\Identify Idesia polycarpa var. vestita Diels 毛叶山桐子 杨宇昌 2016.5.20 +\Identify 128 Kandelia obovata Sheue, H. Y. Liu & J. W. H. Yong 秋茄树 杨宇昌 2018.3.5 +\Identify 585 Ulmus lamellosa C. Wang & S. L. Chang 脱皮榆 杨宇昌 2019.4.11 +\end{document} diff --git a/macros/xetex/latex/nanicolle/nanicolle-example.pdf b/macros/xetex/latex/nanicolle/nanicolle-example.pdf deleted file mode 100644 index 0c110b2d80..0000000000 Binary files a/macros/xetex/latex/nanicolle/nanicolle-example.pdf and /dev/null differ diff --git a/macros/xetex/latex/nanicolle/nanicolle-example.tex b/macros/xetex/latex/nanicolle/nanicolle-example.tex deleted file mode 100644 index 5d5620c570..0000000000 --- a/macros/xetex/latex/nanicolle/nanicolle-example.tex +++ /dev/null @@ -1,9 +0,0 @@ -\documentclass[autoduplicate]{nanicolle} -\begin{document} -\Collect 2912 杨宇昌 6159 2018.9.24 莎草科 褐穗莎草 Cyperus fuscus 7038 1 北京市怀柔区琉璃庙镇双文铺村白河湾湿地生态公园 116.678772 40.655164 214 河边荒草地 披散草本 0.2 须根甚浅,不过2--3 cm;花的鳞片两侧紫褐色,中间绿色。 -\Collect 1997 杨宇昌 5731 2018.5.8 忍冬科 苦糖果 Lonicera fragrantissima subsp. standishii 7609 2 河北省邯郸市武安市管陶乡董家门村西至洞垴途中 1356.0 山坡灌草丛 灌木 3 果实橙红色,味甜微苦。 -\Identify 392 Allium atrosanguineum var. tibeticum (Regel) G. H. Zhu & Turland 藏葱 杨宇昌 2018.10.7 -\Identify 176 Acer davidii subsp. grosseri (Pax) P. C. de Jong 葛萝槭 杨宇昌 2018.4.19 -\Identify 230 Erysimum ×cheiri (L.) Crantz 桂竹香 杨宇昌 2018.5.17 -\Identify 590 Koenigia alpina (All.) T. M. Schust. & Reveal 高山神血宁 杨宇昌 2019.4.13 -\end{document} diff --git a/macros/xetex/latex/nanicolle/nanicolle.cls b/macros/xetex/latex/nanicolle/nanicolle.cls index 76f4cddc7c..205cd992ab 100644 --- a/macros/xetex/latex/nanicolle/nanicolle.cls +++ b/macros/xetex/latex/nanicolle/nanicolle.cls @@ -1,5 +1,5 @@ %% nanicolle.cls -%% Copyright 2016--2019 Yuchang Yang < yang.yc.allium@gmail.com > +%% Copyright 2016--2020 Yuchang Yang < yang.yc.allium@gmail.com > % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -16,11 +16,13 @@ % This work consists of: % - the class file: [nanicolle.cls]; % - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; -% - the manual files: [nanicolle.tex, nanicolle.pdf, README.md]; -% - the example files: [nanicolle-example.tex, nanicolle-example.pdf]. +% - the manual files: [nanicolle-doc-zh.tex, nanicolle-doc-zh.pdf, +% nanicolle-doc-en.tex, nanicolle-doc-en.pdf, README.md]; +% - the example files: [nanicolle-ex-zh.tex, nanicolle-ex-zh.pdf, +% nanicolle-ex-en.tex, nanicolle-ex-en.pdf]. %% \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{nanicolle}[2019/09/27 v2.01 class nanicolle] +\ProvidesClass{nanicolle}[2020/07/08 v2.02 class nanicolle] % CATCODE PART I \makeatletter % CLASS OPTIONS @@ -62,7 +64,7 @@ \newif\if@drew@map@ \newif\if@barcodeprepared@ \newif\if@identifying@ - \@identifying@false + \@identifying@false % KERNING AND SPACING \def\!{\kern-.0889em\relax} \def\:{\kern+.0667em\relax} @@ -99,7 +101,6 @@ \newbox\pin@point \setbox\pin@point=\vb@xt@\z@{\vss\hb@xt@\z@{% \hss\includegraphics{point.pdf}\hss}\vss} -% 20190926 \newdimen\whiterule \newdimen\whitevsep \newdimen\whitehsep @@ -127,23 +128,23 @@ \kern-1em}\vskip-\ht\@tempboxa\box\@tempboxa\par} % UNIT EXPRESSIONS \def\degree{\ensuremath{^\circ}} -\def\gobble@char#1{\relax} -\def\plus@one@degree#1#2#3{% +\def\add@degree#1#2#3{% + \edef\@arg{#1}% \if\relax#1\relax\else \ifdim#1\@unit>\z@ - #1\:\ensuremath{^\circ}\!#2% + #1\:\degree\!#2% \else - \expandafter\gobble@char#1\:\degree\!#3% + \expandafter\@gobble\@arg\:\degree\!#3% \fi \fi} -\def\plus@one@long#1{\plus@one@degree{#1}EW} -\def\plus@one@lat#1{\plus@one@degree{#1}NS} -\def\plus@one@second#1#2{% +\def\add@long#1{\add@degree{#1}EW} +\def\add@lat#1{\add@degree{#1}NS} +\def\add@unit#1#2{% \if\relax#1\relax\else #1\,#2% \fi} -\def\plus@one@cm#1{\plus@one@second{#1}{cm}} -\def\plus@one@m#1{\plus@one@second{#1}{m}} +\def\add@cm#1{\add@unit{#1}{cm}} +\def\add@m#1{\add@unit{#1}{m}} % PARSING % LATIN PARSING \def\inter@taxon@skip{ \hskip .1667em minus .1667em\relax} @@ -168,10 +169,10 @@ \strsubs{ }{ \upd@shape}% \strsubs{subsp.}{\textup{subsp.}\word@cnt\tw@} \strsubs{var.}{\textup{var.}\word@cnt\tw@} - \strsubs{f.}{\handle@f} - \strsubs{sp.}{\upshape sp.\word@cnt\z@} \strsubs{cf.}{\textup{cf.}\word@cnt\tw@} \strsubs{aff.}{\textup{aff.}\word@cnt\tw@} + \strsubs{f.}{\handle@f} + \strsubs{sp.}{\upshape sp.\word@cnt\z@} \strsubs{et}{\penalty-\@ne et\penalty-\@ne} \strsubs{ex}{\penalty-\tw@ et\penalty-\tw@} \strsubs{(}{\penalty-\thr@@(}\strsubs{)}{)\penalty-\thr@@} @@ -217,8 +218,7 @@ \fi\fi \if\relax\Collector\relax\@param@enough@false\fi \if\relax\ColDate\relax\@param@enough@false\fi - \if\relax\Location\relax\@param@enough@false\fi - } + \if\relax\Location\relax\@param@enough@false\fi} \def\det@parse@params#1{% \readlist\temp@argin{#1} \@param@enough@true @@ -232,13 +232,13 @@ \def\temp@name{\Identifier\IdentifierStd} \if\relax\LatName\relax\@param@enough@false\fi \if\relax\temp@name\relax\@param@enough@false\fi - \if\relax\DateIdentification\relax\@param@enough@false\fi - } + \if\relax\DateIdentification\relax\@param@enough@false\fi} % FONT STYLE \def\headerstyle{\bfseries} \def\headingstyle{\scshape} \def\detlatinstyle{\sffamily\bfseries} \def\detchinesestyle{\bfseries} +\def\detcommonnamestyle{\mdseries} \def\identifierstyle{\itshape} % INDIVIDUALIZATION \def\@herbariumcode{} @@ -255,8 +255,7 @@ \expandafter\def\csname#1@longmin\endcsname{#3}% \expandafter\def\csname#1@longmax\endcsname{#4}% \expandafter\def\csname#1@latmin\endcsname{#5}% - \expandafter\def\csname#1@latmax\endcsname{#6}% -} + \expandafter\def\csname#1@latmax\endcsname{#6}} % MAP DEFINITIONS \mapdef{ChinaMainland}{ChinaMainland.pdf}{73}{136}{17}{54} % \mapdef{Dongguan}{Dongguan.pdf}{113.5}{114.26667}{22.63333}{23.16667} @@ -273,29 +272,26 @@ \centerline{\hss\rule{.25\paperwidth}{\NC@seprule}\hss}} % COMPONENTS OF COLLECTION LABELS \RequirePackage{color} +\long\def\length@test#1#2#3#4{% + \sbox\temp@box{#1}% + \ifdim\wd\temp@box>#2\linewidth\relax#3\else#4\fi} +\def\form@wrap#1#2{% + \sbox\header@box{\headerstyle\white@uline{#1}}% + \length@test{\copy\header@box\quad#2}{}% + {\par\hangindent=1em\relax + \leavevmode\box\header@box\quad\CJKglue#2\par}} \def\form@line#1#2{% - \par\hangindent=1em% - \leavevmode - \setbox\header@box=\hbox{\headerstyle\white@uline{#1}}% - \setbox\temp@box=\hbox{\copy\header@box\quad#2}% - \def\glue@begin{\quad\hfill}% - \def\glue@end{\hfill\hfill\hbox{}}% - \ifdim\wd\temp@box>\linewidth - \def\glue@begin{\CJKglue\quad\CJKglue}% - \def\glue@end{}\fi - \box\header@box - \glue@begin#2\glue@end\par} + \form@wrap{#1}{#2}% + {\leavevmode\box\header@box + \quad\hfill#2\hskip\stretch2\null\par}} \def\form@cell#1#2{% - \leavevmode - \hbox{\headerstyle\white@uline{#1}}\nobreak - \;\hfill#2\hfill\;\hbox{}\penalty-1\relax\ignorespaces} + \form@wrap{#1}{#2}% + {\leavevmode\box\header@box + \;\hfill#2\hfill\;\null\penalty-1\relax\ignorespaces}} \def\heading@line#1{% - \setbox\temp@box=\hbox{#1}% - \ifdim\wd\temp@box>\linewidth - \centerline{\resizebox{\linewidth}{\height}{\box\temp@box}}% - \else - \centerline{\box\temp@box}% - \fi} + \length@test{#1}{}% + {\centerline{\resizebox{\linewidth}{\height}{\box\temp@box}}}% + {\centerline{\box\temp@box}}} \if@rulerhead \RequirePackage{rulerbox} \setlength\rulersep{-.2pt} @@ -309,9 +305,8 @@ \heading@line{\headingstyle\@subheading}\fi \if@rulerhead \nointerlineskip\vskip2pt\relax - \centerline{\hbox{}\hss - \rulerbox[tb]{\kern-.9mm\rule{6.18cm}{.4pt}\kern-.9mm}% - \hss\hbox{}}% + \centerline{% + \rulerbox[tb]{\kern-.9mm\rule{6.18cm}{.4pt}\kern-.9mm}}% \vskip5pt\relax \else \hrule\@height\NC@seprule @@ -326,13 +321,13 @@ \form@cell{采集日期}{\ColDate}% \if@internal\form@cell{标本份数}{\NumDup}\fi\par \form@line{产地}{\Location}% - \form@cell{经度}{\plus@one@long\Longitude}% - \form@cell{纬度}{\plus@one@lat\Latitude}\par - \form@cell{海拔}{\plus@one@m\Altitude}% + \form@cell{经度}{\add@long\Longitude}% + \form@cell{纬度}{\add@lat\Latitude}\par + \form@cell{海拔}{\add@m\Altitude}% \form@cell{生境}{\Habitat}\par \form@cell{生活型}{\LifeForm}\penalty-2\relax% - \form@cell{体高}{\plus@one@m\Height}% - \form@cell{胸径}{\plus@one@cm\DBH}\par + \form@cell{体高}{\add@m\Height}% + \form@cell{胸径}{\add@cm\DBH}\par \form@cell{科名}{\Family}% \form@cell{中文名}{\ChnName}\par \form@line{学名}{\col@latin{\LatName}} @@ -354,7 +349,23 @@ \fi \cutting@line} \RequirePackage{calc} -\def\makemap#1{% +\def\make@map#1{% + \setlength\map@x{\wd\csname#1@map\endcsname*% + \ratio{\Longitude\@unit-\csname#1@longmin\endcsname\@unit}% + {\csname#1@longmax\endcsname\@unit-\csname#1@longmin\endcsname\@unit}}% + \setlength\map@y{\ht\csname#1@map\endcsname*% + \ratio{\Latitude\@unit-\csname#1@latmin\endcsname\@unit}% + {\csname#1@latmax\endcsname\@unit-\csname#1@latmin\endcsname\@unit}}% + \begingroup\ooalign{% + \copy\csname#1@map\endcsname\cr + \hb@xt@\map@x{\hss\vb@xt@\map@y{\copy\pin@point\vss}}\cr}% + \endgroup} +\def\print@map#1{% + \vskip3.5mm\relax + \make@map{#1}% + \vskip\NC@margin + \cutting@line} +\def\choose@map#1{% \unless\if@drew@map@ \if\relax\Longitude\relax\else \if\relax\Latitude\relax\else @@ -362,42 +373,87 @@ \ifdim\Longitude\@unit<\csname#1@longmax\endcsname\@unit \ifdim\Latitude\@unit>\csname#1@latmin\endcsname\@unit \ifdim\Latitude\@unit<\csname#1@latmax\endcsname\@unit - \setlength\map@x{\wd\csname#1@map\endcsname*% - \ratio{\Longitude\@unit-\csname#1@longmin\endcsname\@unit}% - {\csname#1@longmax\endcsname\@unit-\csname#1@longmin\endcsname\@unit}} - \setlength\map@y{\ht\csname#1@map\endcsname*% - \ratio{\Latitude\@unit-\csname#1@latmin\endcsname\@unit}% - {\csname#1@latmax\endcsname\@unit-\csname#1@latmin\endcsname\@unit}} - \vskip3.5mm\relax - \begingroup\ooalign{% - \copy\csname#1@map\endcsname\cr - \hb@xt@\map@x{\hss\vb@xt@\map@y{\copy\pin@point\vss}}\cr} - \endgroup - \vskip\NC@margin - \cutting@line + \print@map{#1}% \@drew@map@true \fi\fi\fi\fi\fi\fi \fi} +\def\printmap{\ifmap\@for\@tmp:=\map@series\do{\choose@map{\@tmp}}\fi} +\@drew@map@false % \def\map@series{Dongguan,ChinaMainland} \def\map@series{ChinaMainland} \def\mapseries#1{\def\map@series{#1}} +\def\loop@the@loop#1{% + \loop\ifnum\repeat@cnt>\z@#1% + \advance\repeat@cnt-\@ne\repeat} \def\@Collect#1{% - \@drew@map@false \col@parse@params{#1}% \if@param@enough@ - \loop\ifnum\repeat@cnt>\z@ - \nointerlineskip - \begin{minipage}[c]{\linewidth}% - \vskip\NC@margin - \printheadings - \printform - \printbarcode - \ifmap\@for\@tmp:=\map@series\do{\makemap{\@tmp}}\fi - \end{minipage}% - \filbreak - \advance\repeat@cnt-\@ne\repeat + \loop@the@loop{% + \nointerlineskip + \begin{minipage}[c]{\linewidth}% + \vskip\NC@margin + \printheadings + \printform + \printbarcode + \printmap + \end{minipage}% + \filbreak} \fi} \def@to@eol\Collect\@Collect +% COLLECTING LABELS IN WESTERN LANGUAGES +\def\translation@asl{a.s.l.} +\def\translation@dbh{DBH} +\def\translation@tall{tall} +\def\aster{\ensuremath{\ast}\hss} +\def\printheadings@en{% + \if\relax\@heading\relax\else + \heading@line{\headingstyle\@heading} + \if\relax\@subheading\relax\else + \heading@line{\headingstyle\@subheading}\fi + \vskip2pt\relax + \centerline{\makebox[0.618\linewidth][s]{% + \aster\aster\aster\aster\aster\unskip}} + \vskip4pt\relax + \fi} +\def\init@punct{\def\the@punct{}}\init@punct +\def\push@punct#1{\def\the@punct{#1 }} +\def\pop@punct{\the@punct\init@punct} +\def\unless@empty#1#2#3#4{% + \edef\@tmp{#1}% + \unless\ifx\@tmp\empty + \pop@punct#2#1#3\push@punct{#4}\fi} +\def\print@col@num#1#2{% + \length@test{#1\hskip0.7em\relax#2}{0.85}% + {#1\hskip0.7em\relax\allowbreak\null\nobreak\hfill#2}% + {\leavevmode\box\temp@box}\par} +\def\capitalize@one#1{\uppercase{#1}} +\def\capitalize@first#1{% + \edef\@tmp{#1}% + \expandafter\capitalize@one\@tmp} +\def\printform@en{% + \raggedright + \unless@empty{\Family}{\textsc}{}{}\par + {\leftskip2em\relax\hangindent1em\relax + \unless@empty{\LatName}{\det@latin}{}{}\par} + \parskip=5pt\relax + \print@col@num{\Collector}{\#\,\ColNum}% + \unless@empty{\ColDate}{\capitalize@first}{}{;}% + \unless@empty{\Location}{}{}{,}% + \unless@empty{\Longitude}{\add@long}{}{,}% + \unless@empty{\Latitude}{\add@lat}{}{,}% + \unless@empty{\Altitude}{\add@m}{ \translation@asl}{}\push@punct{;}% + \unless@empty{\Habitat}{}{}{}\push@punct{.}\pop@punct\par + \unless@empty{\LifeForm}{\capitalize@first}{}{,}% + \unless@empty{\Height}{\add@m}{ \translation@tall}{,}% + \unless@empty{\DBH}{\translation@dbh\space\add@cm}{}{.}\push@punct{.}\pop@punct% + \Descr\par + \parskip\z@} +\def\@Collect@en#1{{% + \let\printheadings\printheadings@en + \let\printform\printform@en + \@Collect{#1}}} +\def@to@eol\Collect@en\@Collect@en +\let\collect\Collect@en % COMPONENTS OF IDENTIFICATION LABELS \if@det@barcode \RequirePackage{qrcode} @@ -438,6 +494,12 @@ \fi \@identifying@false} \def@to@eol\Identify\@Identify +% COLLECTING LABELS IN WESTERN LANGUAGES +\def\@Identify@en#1{{% + \let\detchinesestyle\detcommonnamestyle + \@Identify{#1}}} +\def@to@eol\Identify@en\@Identify@en +\let\identify\Identify@en % CATCODES PART III \catcode`\&\active \def&{et} diff --git a/macros/xetex/latex/nanicolle/nanicolle.pdf b/macros/xetex/latex/nanicolle/nanicolle.pdf deleted file mode 100644 index 797eacb915..0000000000 Binary files a/macros/xetex/latex/nanicolle/nanicolle.pdf and /dev/null differ diff --git a/macros/xetex/latex/nanicolle/nanicolle.tex b/macros/xetex/latex/nanicolle/nanicolle.tex deleted file mode 100644 index fef51adda8..0000000000 --- a/macros/xetex/latex/nanicolle/nanicolle.tex +++ /dev/null @@ -1,322 +0,0 @@ -%% nanicolle.tex -%% Copyright 2016--2019 Yuchang Yang < yang.yc.allium@gmail.com > -% -% 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.3c 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 Yuchang Yang. -% -% This work consists of: -% - the class file: [nanicolle.cls]; -% - the illustration files: [point.pdf, ChinaMainland.pdf, Dongguan.pdf]; -% - the manual files: [nanicolle.tex, nanicolle.pdf, README.md]; -% - the example files: [nanicolle-example.tex, nanicolle-example.pdf]. - -% arara: xelatex -% arara: xelatex - -\documentclass[a4paper]{ctexart} - \CTEXsetup[format={\Large\bfseries}]{section} - -\usepackage[margin=35mm]{geometry} -\usepackage{marvosym} -\usepackage{metalogo} -\usepackage{rulerbox} -% \usepackage{url} -\usepackage{color} - \definecolor{mikudark}{RGB}{19, 149, 139} -\usepackage{array} - \newcolumntype{+}{>{\global\let\currentrowstyle\relax}} - \newcolumntype{^}{>{\currentrowstyle}} - \newcommand{\rowstyle}[1]{\gdef\currentrowstyle{#1}#1\ignorespaces} -\usepackage{enumitem} - \setlist[description]{font=\color{mikudark}\bfseries} -\usepackage{multicol} - \setlength\columnsep{2.5em} - \setlength\columnseprule{0.4pt} -\usepackage{adjustbox} - -\makeatletter -\let\url\texttt -\let\emph\textbf -\let\pkgname\textsf -\let\uppercase\relax -\def\@fnsymbol#1{\ifcase#1\or*\or\Letter\fi} -\def\qtimes{\ensuremath{\times}} -\def\tab{\penalty-\@ne\ensuremath{\rightarrow}} -\def\uspace{\textvisiblespace\allowbreak} -\def\@lan{\raisebox{.2ex}{\ensuremath{\langle}}} -\def\@ran{\raisebox{.2ex}{\ensuremath{\rangle}}} -\def\param#1{\textrm{\@lan\textit{#1}\@ran}} -\def\stopurl{\rlap{\char00}} % WHY URL IS TO GRAB EVERYTHING IT SEES? -\long\def\cmd#1{{\ttfamily\color{mikudark}#1}} -\long\def\pbox#1{\leavevmode\parbox{.86\linewidth}{\cmd{#1}}\kern-.03\linewidth} -\long\edef\[#1\]{$$\noexpand\pbox{\noexpand\raggedright#1\par}$$} -\catcode`\$=\active -\def\check@nextchar{% - \if\@nextchar、\unskip\fi - \if\@nextchar,\unskip\fi - \if\@nextchar:\unskip\fi - \if\@nextchar;\unskip\fi - \if\@nextchar。\unskip\fi} -\def$#1${\CJKecglue\cmd{#1}\CJKecglue - \futurelet\@nextchar\check@nextchar} -\newcount\itemcnt - \def\clearcnt{\itemcnt\z@} - \def\@black#1{{\color{black}\rmfamily#1}} - \def\@theitem{\advance\itemcnt\@ne\@black{\romannumeral\the\itemcnt.\space}} - \def\@blackperiod{\@black{。}\@gobble} - \def\@blackcolon{\@black{;}\penalty-\@ne} - \def\ritem#1{\@theitem#1\@ifnextchar*\@blackperiod\@blackcolon} -\makeatother - -\title{植物标本标签文档类\pkgname{nanicolle}% - \footnote{本项目的Github仓库地址为\url{https://github.com/Mikumikunisiteageru/nanicolle}\stopurl 。}} -\author{杨宇昌% - \footnote{电子邮箱为\url{yang.yc.allium@gmail.com}\stopurl 。}% - \quad〔\textsc{Negimoriya}〕} -\date{2019年9月27日\qquad ver.~2.01} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{document} - -\maketitle - -\parskip=1ex\relax - -植物标本是经处理能够长期保存的植物材料。它们是植物居群的样本,通过标本可以了解植物居群。由于植物材料本身并不能完整地反映居群的重要信息,标本采集者需要作出补充并记录成\emph{采集标签},与标本一同保存。植物分类学者经研究可以判定标本对应居群所属的物种,其意见则以\emph{鉴定标签}的形式,附在标本上。 - -本文介绍的\LaTeX{}文档类\pkgname{nanicolle}可用于植物标本中文采集标签和鉴定标签的排版。两种标签分别用$\string\Collect$命令和$\string\Identify$名称产生。排好的标签可直接打印。 - -\pkgname{nanicolle}依赖\pkgname{ctex}宏集和\pkgname{graphicx}、\pkgname{geometry}、\pkgname{multicol}、\pkgname{calc}、\pkgname{listofitems}、\pkgname{color}、\pkgname{xstring}等宏包。目前,\pkgname{nanicolle}文档类仅支持\XeLaTeX{}编译方式。 - -\pkgname{nanicolle}按 The \LaTeX{} Project Public License (LPPL) 1.3c 协议\footnote{LPPL 1.3c 协议的详细内容见\url{http://www.latex-project.org/lppl.txt}\stopurl 。}授权。 - -\parskip=0ex\relax - -\vfill\tableofcontents\vfill - -\clearpage - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{\pkgname{nanicolle}类文档的结构}\label{usage} - -一份使用\pkgname{nanicolle}类的文档应是包含以下5部分、以后缀 \texttt{.tex} 结尾的纯文本: -\begin{enumerate} - \item 载入\pkgname{nanicolle}文档类,即$\string\documentclass[\param{选项}]\{nanicolle\}$。 - 其中,$\param{选项}$控制文档类的行为,例如$nomap$可抑制采集标签中的地图,$autoduplicate$则能按标本份数重复采集标签;选项超过一个时,其间要用$,$分隔。不需要加载选项时,可写$\string\documentclass\{nanicolle\}$。 - \item 在导言区使用$\string\heading$和$\string\subheading$命令定义个性化内容。要在采集标签上方添加统一的标题,可写$\string\heading\{\param{标题}\}$;副标题如需要则可由$\string\subheading\{\param{副标题}\}$命令产生。若跳过此部分,则采集标签上方无标题。 - \item 正文开始,即$\string\begin\{document\}$。 - \item 在正文中使用$\string\Collect$和$\string\Identify$两种命令分别产生采集标签和鉴定标签,每个命令占一行。两种命令的格式参见第 \ref{collect} 和第 \ref{identify} 节。 - \item 正文结束,即$\string\end\{document\}$。 -\end{enumerate} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{用\hbox{}$\textbackslash Collect$命令生成采集标签}\label{collect} - -$\string\Collect$命令的格式为 -\[% - \hangindent=2em\relax - \string\Collect - \tab\param{记录号}\tab\param{采集人}\tab\param{采集号}% - \tab\param{采集日期}\tab\param{科名}\tab\param{中文名}% - \tab\param{学名}\tab\param{照片号}\tab\param{标本份数}% - \tab\param{产地}\tab\param{经度}\tab\param{纬度}% - \tab\param{海拔}\tab\param{生境}\tab\param{生活型}% - \tab\param{体高}\tab\param{胸径}\tab\param{附注}% -\] -当中$\tab$表示水平制表符(U+0009,可按键盘Tab键输入)。每行最多能有一个$\string\Collect$命令;每个$\string\Collect$命令须出现在一行开始处,其所有参数必须出现在同一行中。 -某些参数可以为空,但$\tab$都须保留。 -以下就诸参数分别说明。 - -\begin{enumerate} - \item $\param{记录号}$:仅为数据组织方便而设,不在采集标签上出现。 - \item $\param{采集人}$:标本的采集者的姓名。如有多个采集者,应尽量列举姓名,其间可以用顿号分隔;不建议填写不包含人名的采集团队的名称。此参数不得为空。 - \item $\param{采集号}$:属于$\param{采集人}$中第一个采集者的记录标本采集的序列号码。建议为简单的整数,从1开始递增。 - \item $\param{采集日期}$:采集植物材料的日期,可使用$\param{年}.\param{月}.\param{日}$的阿拉伯数字表示。此参数不得为空。 - \item $\param{科名}$:临时鉴定的科的名称,建议使用中文表示。 - \item $\param{中文名}$:临时鉴定的植物中文名。 - \item $\param{学名}$:临时鉴定的植物学名,建议不带作者引证。当非空时,可用通式$\param{属级部分}\param{种级部分}\param{种下等级部分}$表示。 - 其中,$\param{属级部分}$有2类结构: - \[\clearcnt - \ritem{\param{属名}}% - \ritem{\qtimes\param{属名}}*\] - $\param{种级部分}$有9类结构: - \[\clearcnt - \ritem{\uspace sp.}% - \ritem{\uspace sp.\uspace nov.}% - \ritem{\uspace\param{种加词}}% - \ritem{\uspace\qtimes\param{种加词}}% - \ritem{\uspace aff.\uspace\param{种加词}}% - \ritem{\uspace aff.\uspace\qtimes\param{种加词}}% - \ritem{\uspace cf.\uspace\param{种加词}}% - \ritem{\uspace cf.\uspace\qtimes\param{种加词}}% - \ritem{\uspace '\param{栽培种名}'}*\] - 当中的$\uspace$表示一个空格(U+0020)。$\param{种下等级部分}$仅当$\param{种级部分}$为结构iii或结构iv时可以非空,此时它有4类结构: - \[\clearcnt - \ritem{\uspace subsp.\uspace\param{亚种加词}}% - \ritem{\uspace var.\uspace\param{变种加词}}% - \ritem{\uspace f.\uspace\param{变型加词}}% - \ritem{\uspace '\param{栽培品种名}'}*\] - \item $\param{照片号}$:仅为数据组织方便而设,不在采集标签上出现。 - \item $\param{标本份数}$:标本的同号复份数目,用正整数表示。不在采集标签上出现。当文档类的$\param{选项}$包含$autoduplicate$时,每个$\string\Collect$命令将输出$\param{标本份数}$张重复的采集标签。 - \item $\param{产地}$:植物材料的采集地的自然语言表述,要包含完整的省级、县级、乡级行政单元序列和小地点,小地点可参照地标表示,以便考证与回访。此参数不得为空。 - \item $\param{经度}$:植物材料采集地的经度坐标,用十进制的浮点数表示,以角度为单位,不带单位符号,正数为东经,负数为西经。不接受度分秒表示。 - \item $\param{纬度}$:植物材料采集地的纬度坐标,用十进制的浮点数表示,以角度为单位,不带单位符号,正数为北纬,负数为南纬。不接受度分秒表示。 - \item $\param{海拔}$:植物材料采集地的海拔高度,用浮点数表示,以米为单位,不带单位符号,可以为负数。 - \item $\param{生境}$:植物居群的野外生活环境,如$山地$、$林缘$、$溪边$等,但对于栽培的植物,应填写$栽培$而非具体的生活环境。 - \item $\param{生活型}$:植物居群的生活型,如$乔木$、$灌木$、$藤本$等。 - \item $\param{体高}$:植物居群中个体的典型高度,用浮点数表示,以米为单位,不带单位符号。 - \item $\param{胸径}$:植物居群中个体的典型胸径,用浮点数表示,以厘米为单位,不带单位符号。 - \item $\param{附注}$:包含其他在植物标本上无法观察的有价值的信息,如各部的颜色、气味,树皮的纹理,传粉者,植物在当地的俗名、用途、常见程度等。 -\end{enumerate} - -\pkgname{nanicolle}文档类默认在经纬度均非空且经度在东经73--136度间、纬度在北纬17--54度间时在采集标签下方输出地图,以标明该坐标的位置。要抑制这个功能,可以在载入文档类时使用$nomap$选项,见第 \ref{usage} 节。 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{用\hbox{}$\textbackslash Identify$命令生成鉴定标签}\label{identify} - -$\string\Identify$命令的格式为 -\[% - \hangindent=2em\relax - \string\Identify - \tab\param{记录号}\tab\param{学名}\tab\param{中文名}% - \tab\param{鉴定人}\tab\param{鉴定人标准形式}% - \tab\param{鉴定日期}\tab\param{批注}% -\] -和$\string\Collect$一样,每个$\string\Identify$命令及其所有参数需独占一行。以下就诸参数分别说明。 - -\begin{enumerate} - \item $\param{记录号}$:仅为数据组织方便而设,不在采集标签上出现。 - \item $\param{学名}$:正式鉴定的植物学名,须带有作者引证,可用通式$\param{属级部分}\param{种级部分}\param{种下等级部分}\param{作者引证}$表示。此参数不得为空。 - \item $\param{中文名}$:与$\param{学名}$相关联的中文种名。 - \item $\param{鉴定人}$:标本鉴定者的姓名。 - \item $\param{鉴定人标准形式}$:标本鉴定者的姓名在分类学上约定的标准形式。此参数与$\param{鉴定人}$不得同时为空。 - \item $\param{鉴定日期}$:鉴定标本的日期,格式同$\param{采集日期}$。此参数不得为空。 - \item $\param{批注}$:需另外表明的分类学意见。 -\end{enumerate} - -不同于$\string\Collect$命令,$\string\Identify$命令不带$\param{标本份数}$参数,故每个$\string\Identify$命令固定地输出一张鉴定标签。要输出重复的鉴定标签,只能手动复制命令所在的行。 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{其他问题} - -\subsection{用工作表软件储存原始数据} - -$\string\Collect$与$\string\Identify$之所以不遵照\LaTeX{}惯例而用制表符$\tab$作为参数的定界符,其本意是使得原始数据可以储存工作表(Spreadsheet)软件\footnote{常见的工作表软件如 Microsoft Office Excel。}中。当纯文本粘贴到工作表中时,换行符分隔各行,制表符分隔行内各列。当工作表的内容粘贴为纯文本时,各行由换行符分隔,行内各列由制表符分隔(形成TSV格式)。事实上,这种机制允许储存于工作表中的原始数据可以直接为\XeLaTeX{}引擎所读取。具体来说,可以建立一个形如表 \ref{table} 的工作表来储存原始数据。 -\begin{table}[htbp] - \centering - \begin{tabular}{|+c|*{8}{^c|}} - \hline - \rowstyle{\bfseries} 命令 & 记录号 & 采集人 & 采集号 & 采集日期 & 科名 & 中文名 & 学名 & \ensuremath{\cdots} \\\hline - \string\Collect & 1 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline - \string\Collect & 2 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline - \string\Collect & 3 & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} & \ensuremath{\cdots} \\\hline - \end{tabular} - \caption{储存采集标签原始数据的工作表示例}\label{table} -\end{table} -这样,工作表中的若干行被选中并复制到纯文本环境下后便直接转换成了$\string\Collect$或$\string\Identify$命令要求的格式。而工作表中的原始数据库在这些命令所要求的参数外还能储存更丰富的信息,这些额外信息会被$\string\Collect$或$\string\Identify$命令忽略,不影响标签的内容。 - -\subsection{PDF文件的打印设置} - -编译得到的PDF文件最终要用打印机打印并裁剪,成为可实际使用的标签。打印机的可打印范围一般比纸面小,为保留文件完整性,打印程序通常默认将文件缩小并布局在纸面中心。这样,按印出来的线条裁切,便会出现两侧的标签宽、中间的标签窄的现象。为避免这种问题,打印PDF文件时应选中“使用原始页面大小”选项。 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{完整实例} - -% \widowpenalty=10000\relax - -以下是一份符合\pkgname{nanicolle}规范的文档实例,保存为 \texttt{nanicolle-example.tex}。 -\[% - \clearcnt - \everypar={\hangindent=2em\relax\advance\itemcnt1\relax% - \leavevmode\llap{\number\itemcnt\quad}} - \xeCJKsetup{CJKecglue={}} - \string\documentclass[autoduplicate]\string{nanicolle\string}\par - \string\begin\string{document\string}\par - \string\Collect\tab 2912\tab 杨宇昌\tab 6159\tab 2018.9.24\tab 莎草科\tab 褐穗莎草\tab Cyperus\uspace fuscus\tab 7038\tab 1\tab 北京市怀柔区琉璃庙镇双文铺村白河湾湿地生态公园\tab 116.678772\tab 40.655164\tab 214\tab 河边荒草地\tab 披散草本\tab 0.2\tab \tab 须根甚浅,不过2--3\uspace cm;花的鳞片两侧紫褐色,中间绿色。\par - \string\Collect\tab 1997\tab 杨宇昌\tab 5731\tab 2018.5.8\tab 忍冬科\tab 苦糖果\tab Lonicera\uspace fragrantissima\uspace subsp.\uspace standishii\tab 7609\tab 2\tab 河北省邯郸市武安市管陶乡董家门村西至洞垴途中\tab \tab \tab 1356.0\tab 山坡灌草丛\tab 灌木\tab 3\tab \tab 果实橙红色,味甜微苦。\par - \string\Identify\tab 392\tab Allium\uspace atrosanguineum\uspace var.\uspace tibeticum\uspace (Regel)\uspace G.\uspace H.\uspace Zhu\uspace \string&\uspace Turland\tab 藏葱\tab 杨宇昌\tab \tab 2018.10.7\tab \par - \string\Identify\tab 176\tab Acer\uspace davidii\uspace subsp.\uspace grosseri\uspace (Pax)\uspace P.\uspace C.\uspace de\uspace Jong\tab 葛萝槭\tab 杨宇昌\tab \tab 2018.4.19\tab \par - \string\Identify\tab 230\tab Erysimum\uspace \qtimes cheiri\uspace (L.)\uspace Crantz\tab 桂竹香\tab 杨宇昌\tab \tab 2018.5.17\tab \par - \string\Identify\tab 590\tab Koenigia\uspace alpina\uspace (All.)\uspace T.\uspace M.\uspace Schust.\uspace \string&\uspace Reveal\tab 高山神血宁\tab 杨宇昌\tab \tab 2019.4.13\tab \par - \string\end\string{document\string}\par -\] -注意,每个$\string\Collect$或$\string\Identify$命令及其所有参数实际上均位于同一行中,换行只是便于展示。将此文档放置在 \texttt{nanicolle.cls} 所在的目录下,命令行中运行 \texttt{xelatex nanicolle-example},即可在同一目录中得到 \texttt{nanicolle-example.pdf},其效果见图 \ref{example}。 -% \clearpage - -\begin{figure}[htbp] - \centering - \fboxsep=-.2pt\relax - \hbox{}\hidewidth\rulerbox{\vbox{\kern-.2pt\hbox{\kern-.2pt\fbox{\includegraphics*[bb=0cm 0cm 14.85cm 21cm]{nanicolle-example.pdf}}\kern-.2pt}\kern-.2pt}}\hidewidth\hbox{}\par - \caption{样例PDF文件 \texttt{nanicolle-example.pdf} 的前2栏(左半页)}\label{example} -\end{figure} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{更新日志} -\begin{multicols}{2} -\begin{description}[style=nextline] - \item[ver. 2.01 (2019.9.27)] - 改进采集标签中下划线表的实现。\\ - 支持在附注等项目中直接用\LaTeX{}命令如 $\string\textit$ 等控制字体样式。\\ - 合并解析拉丁学名的两处代码,允许在采集标签的学名后引证作者。 - \item[ver. 2.00 (2019.4.28)] - 全部代码重构,打包为文档类,重新命名为\pkgname{nanicolle}。\\ - 新增地图自定义与自动选择功能。\\ - 暂时删去英文采集标签排版功能。\\ - 暂时删去标本条码标签排版功能。\\ - 暂时删去植物所建筑地图。\\ - 开始发布于CTAN和Github上。 - \item[ver. 1.14 (2018.12.2)] - 新增 $\textbackslash ifinternal$ 开关,以快速控制条码、照片号、标题等。 - \item[ver. 1.13 (2018.9.15)] - 改进采集标签中下划线表的实现。\\ - 修正地图中的国界。\\ - 采集标签中增加植物所建筑地图。\\ - 缩减采集标签中的悬挂缩进量。\\ - 代码模块化。 - \item[ver. 1.12 (2018.5.15)] - 优化拉丁学名断行位置。\\ - 调整标本条码标签的段落样式。 - \item[ver. 1.11 (2018.3.28)] - 调整原始数据结构。\\ - 鉴定标签中增加命名人标准缩写。 - \item[ver. 1.10 (2018.2.9)] - 采集标签中增加东莞市镇街地图。 - \item[ver. 1.09 (2018.1.28)] - 实现标本条码标签排版。 - \item[ver. 1.08 (2017.10.31)] - 采集标签中增加地理范围为经度 \ensuremath{73\mbox{--}136\,^\circ\mathrm E}、纬度 \ensuremath{17\mbox{--}54\,^\circ\mathrm N}的国界与中国省界地图。 - \item[ver. 1.07 (2017.10.22)] - 采集标签与鉴定标签中增加条码。\\ - 实现带有尼泊尔分区地图的英文采集标签排版,用于2017年中国—尼泊尔联合植物考察。 - \item[ver. 1.06 (2017.10.21)] - 采集标签中增加标题。 - \item[ver. 1.05 (2017.7.4)] - 调整页面布局,使标签尺寸缩小为原来的\ensuremath{\sqrt{2}/2},与A4台纸相配。\\ - 改进水平切割线的样式。 - \item[ver. 1.03 (2017.7.2)] - 参数的表示由\LaTeX{}格式改成TSV格式,方便用电子表格储存。\\ - 此版本曾发布于Github上。 - \item[ver. 1.02 (2016.8.6)] - 新造“\raisebox{-0.3pt}{\resizebox{10pt}{8.5pt}{\raisebox{8pt}{\clipbox{0 6.2pt 0 0pt}{苗}}\kern-10pt\relax 杭}}”字。 - \item[ver. 1.01 (2016.8.3)] - 实现采集标签与鉴定标签排版。 -\end{description} -\end{multicols} - -\end{document} -- cgit v1.2.3