# -*- mode: Perl -*-
# /=====================================================================\ #
# | acronym | #
# | Implementation for LaTeXML | #
# |=====================================================================| #
# | Part of LaTeXML: | #
# | Public domain software, produced as part of work done by the | #
# | United States Government & not subject to copyright in the US. | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
DefMacro('\acsfont{}', '#1');
DefMacro('\acffont{}', '#1');
DefMacro('\acfsfont{}', '#1');
DefConditional('\ifAC@footnote');
DefConditional('\ifAC@nohyperlinks');
DefConditional('\ifAC@printonlyused');
DefConditional('\ifAC@withpage');
DefConditional('\ifAC@smaller');
DefConditional('\ifAC@dua'); # dua = don't use acronmyms
DefConditional('\ifAC@nolist');
DefConditional('\ifAC@starred');
DefMacro('\AC@placelabel{}', '');
#======================================================================
# Whether an acronym is used or not
DefPrimitive('\lx@AC@used{}', sub {
AssignValue('ACROUSED@' . ToString($_[1]) => 1, 'global'); });
DefPrimitive('\AC@logged{}', sub { }); # ???
DefMacro('\acused{}', '\AC@logged{#1}');
DefMacro('\acronymused{}', '\AC@logged{#1}');
DefMacro('\acresetall', ''); # ????
DefMacro('\lx@AC@if{}{}{}', sub {
my ($gullet, $id, $short, $long) = @_;
my $key = 'ACROUSED@' . ToString($_[1]);
if (LookupValue($key)) {
$short->unlist; }
else {
AssignValue($key => 1, 'global');
$long->unlist; } });
#======================================================================
# Acronyms in the Text
# NOTE: replacement of acronyms (short, long, whatever) should EXCLUDE \acroextra
# BUT those should be present in an acronym list!
# Acronym lists can (optionally) only include the acronyms actually used in the text!
# \lx@acronym{acronym}{listname}{showform}
DefConstructor('\lx@acronym Undigested {}{}{}',
"<ltx:glossaryref key='#2' inlist='#3' show='#4'/>",
reversion => '#1{#2}');
DefMacro('\AC@acs{}', '\lx@acronym{\acs}{#1}{acronym}{short}');
DefMacro('\AC@acl{}', '\lx@acronym{\acl}{#1}{acronym}{long}');
DefMacro('\AC@acsp{}', '\lx@acronym{\acsp}{#1}{acronym}{short-plural}');
DefMacro('\AC@aclp{}', '\lx@acronym{\aclp}{#1}{acronym}{long-plural}');
DefMacro('\AC@acsi{}', '\lx@acronym{\acsi}{#1}{acronym}{short-indefinite}');
DefMacro('\AC@aclI{}', '\lx@acronym{\aclI}{#1}{acronym}{long-indefinite}');
# Short form
DefMacro('\acs OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acsa');
DefMacro('\acsa{}', '\@acs{#1}');
DefMacro('\@acs{}', '\acsfont{\AC@acs{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
# Long form
DefMacro('\acl OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@acl');
DefMacro('\@acl{}', '\acsfont{\AC@acl{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
# Full form: Long (short)
DefMacro('\acf OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfa');
DefMacro('\acfa{}', '\@acf{#1}');
DefMacro('\@acf{}',
'\ifAC@footnote\acsfont{\AC@acs{#1}}\footnote{\AC@placelabel{#1} \AC@acl{#1}}
\else\acffont{\AC@placelabel{#1} \AC@acl{#1} \acfsfont{(\acsfont{\AC@acs{#1}})}}\fi
\ifAC@starred\else\lx@AC@used{#1}\fi');
# Italicized long (short)
DefMacro('\acfi OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfia');
DefMacro('\acfia{}', '{\itshape\AC@acl{#1} }(\ifAC@starred\acs*{#1}\else\acs{#1}\fi)');
# Auto form
DefMacro('\ac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@ac');
DefMacro('\@ac{}',
'\lx@AC@if{#1}{\ifAC@starred\acs*{#1}\else\acs{#1}\fi}{\ifAC@starred\acf*{#1}\else\acf{#1}\fi}');
# Indefinite article form
DefMacro('\iac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@iac');
DefMacro('\Iac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@Iac');
DefMacro('\@iac{}', '\@iaci{#1} \ifAC@starred\ac*{#1}\else\ac{#1}\fi');
DefMacro('\@Iac{}', '\@firstupper{\@iaci{#1}} \ifAC@starred\ac*{#1}\else\ac{#1}\fi');
# \@firstupper
# \newcommand*{\@iaci}[1]{%
# \ifcsname fn@#1@IL\endcsname
# \ifAC@dua
# \csname fn@#1@IL\endcsname%
# \else
# \expandafter\ifx\csname ac@#1\endcsname\AC@used%
# \csname fn@#1@IS\endcsname%
# \else
# \csname fn@#1@IL\endcsname%
# \fi
# \fi
# \else
# a%
# \fi
# Plural forms
DefMacro('\acsp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acspa');
DefMacro('\acspa{}', '\@acsp{#1}');
DefMacro('\@acsp{}', '\acsfont{\AC@acsp{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\aclp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@aclp');
DefMacro('\@aclp{}', '\AC@aclp{#1}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acfp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfpa');
DefMacro('\acfpa{}', '\@acfp{#1}');
DefMacro('\@acfp{}',
'\ifAC@footnote\acsfont{\AC@acsp{#1}}\footnote{\AC@placelabel{#1} \AC@aclp{#1}}
\else\acffont{\AC@placelabel{#1} \AC@aclp{#1} \acfsfont{(\acsfont{\AC@acsp{#1}})}}\fi
\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@acp');
DefMacro('\@acp{}', '\lx@AC@if{#1}{\AC@acsp{#1}}{\AC@aclp{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acsu OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acsua');
DefMacro('\acsua{}', '\ifAC@starred\acs*{#1}\else\acs{#1}\fi\acused{#1}');
DefMacro('\aclu OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\aclua');
DefMacro('\aclua{}', '\ifAC@starred\acl*{#1}\else\acl{#1}\fi\acused{#1}');
#======================================================================
# Defining Acronyms
DefEnvironment('{acronym}[]',
"<ltx:glossary lists='acronym' class='ltx_acronym'>"
. "<ltx:glossarylist>"
. "#body"
. "</ltx:glossarylist>"
. "</ltx:glossary>",
beforeDigest => sub { Let('\acro', '\lx@acro@item');
Let('\acrodef', '\lx@acro@item'); },
afterDigest => sub { noteBackmatterElement($_[1], 'ltx:glossary'); },
beforeConstruct => sub { adjustBackmatterElement($_[0], $_[1]); });
DefMacro('\acroextra{}', '#1');
# \lx@acro@item{key}{short}{long}
DefMacro('\lx@acro@item{}[]{}',
'\lx@acro@@item{#1}{\ifx.#2.#1\else#2\fi}{#3}');
DefMacro('\lx@acro@@item{}{}{}',
'\lx@acro@@@item{#1}{#2}{#3}{{\let\acroextra\@gobble #2}}{{\let\acroextra\@gobble #3}}');
DefConstructor('\lx@acro@@@item{}{}{}{}{}',
"<ltx:glossaryentry inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='label'>#2</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='short'>#4</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='long'>#5</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='definition'>#3</ltx:glossaryphrase>"
. "</ltx:glossaryentry>");
Tag('ltx:glossaryentry', afterClose => sub { GenerateID(@_, ''); });
DefMacro('\acrodef{}[]{}',
'\lx@acro@@def{#1}{\ifx.#2.#1\else#2\fi}{#3}');
DefMacro('\lx@acro@@def{}{}{}',
'\lx@acro@@@def{#1}{#2}{#3}{{\let\acroextra\@gobble #2}}{{\let\acroextra\@gobble #3}}');
DefConstructor('\lx@acro@@@def{}{}{}{}{}',
"<ltx:glossarydefinition inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='label'>#2</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='short'>#4</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='long'>#5</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='definition'>#3</ltx:glossaryphrase>"
. "</ltx:glossarydefinition>");
Tag('ltx:glossarydefinition', afterClose => sub { GenerateID(@_, ''); });
# Should these be allowed inside ltx:glossarylist, or float outside it?
Let('\newacro', '\acrodef');
Let('\acro', '\acrodef');
# The following define additional forms of the acronym expansions.
# They should be recorded in the document & scanned in post-processing,
# but need not appear within the acronym glossary.
# Non-standard definite articles
DefMacro('\lx@acro@phrase{}{}{}', '{\let\acroextra\@gobble\lx@@acro@phrase{#1}{#2}{#3}}');
# Let this float up, since it can be used within a glossarylist, but shouldn't end up there.
DefConstructor('\lx@@acro@phrase{}{}{}',
"^ <ltx:glossarydefinition inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='#2'>#3</ltx:glossaryphrase>"
. "</ltx:glossarydefinition>");
DefMacro('\acrodefindefinite{}{}{}',
'\lx@acro@phrase{#1}{short-indefinite}{#2}\lx@acro@phrase{#1}{long-indefinite}{#3}');
Let('\acroindefinite', '\acrodefindefinite');
Let('\newacroindefinite', '\acrodefindefinite');
# Non-standard plural forms
DefMacro('\acrodefplural{}[]{}',
'\lx@acro@phrase{#1}{short-plural}{\ifx.#2.#1\else#2\fi}\lx@acro@phrase{#1}{long-plural}{#3}');
Let('\acroplural', '\acrodefplural');
Let('\newacroplural', '\acrodefplural');
#======================================================================
1;