# -*- mode: Perl -*-
# /=====================================================================\ #
# |  llncs.cls                                                          | #
# | 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;

foreach my $option (qw(envcountreset citeauthoryear oribibl orivec
  envcountsame envcountsect runningheads)) {
  DeclareOption($option, undef); }

# Anything else gets passed to article.
DeclareOption(undef, sub {
    PassOptions('article', 'cls', ToString(Expand(T_CS('\CurrentOption')))); });

ProcessOptions();
LoadClass('article');

RequirePackage('multicol');
RequirePackage('inst_support');

#======================================================================
DefMacro('\frontmatter', Tokens());

DefMacro('\subtitle{}', '\@add@frontmatter{ltx:subtitle}{#1}');

DefMacro('\emailname', 'E-mail');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email' name='#name'>#1</ltx:contact>",
  properties => sub { (name => Digest(T_CS('\emailname'))); });
DefMacro('\email Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}}');

DefMacro('\mailname', '\textit{Correspondence to}:');
DefConstructor('\@@@mail{}', "^ <ltx:contact role='address' name='#name'>#1</ltx:contact>",
  properties => sub { (name => Digest(T_CS('\mailname'))); });
DefMacro('\mail{}', '\@add@to@frontmatter{ltx:creator}{\@@@mail{#1}}');

DefMacro('\keywordname', '\textbf{Keywords}');
DefMacro('\keywords{}',  '\@add@frontmatter{ltx:keywords}[name={\keywordname}]{#1}');

DefMacro('\ackname', 'Acknowledgements');
DefConstructor('\acknowledgements', "<ltx:acknowledgements name='#name'>",
  properties => sub { (name => Digest(T_CS('\ackname'))); });
DefMacro('\acknowledgement', '\acknowledgements');
DefConstructor('\endacknowledgements', "</ltx:acknowledgements>");
DefConstructor('\endacknowledgement',  "</ltx:acknowledgements>");
Tag("ltx:acknowledgements", autoClose => 1);

DefConstructor('\url Semiverbatim', "<ltx:ref href='#1'>#1</ltx:ref>");

# DefMacro('\institutename',  Tokens());

# DefMacro('\authcount',Tokens());

DefRegister('\instindent' => Dimension(0));

# DefMacro('\lastand',Tokens());

DefRegister('\authrun'       => Tokens());    # Box!
DefRegister('\authorrunning' => Tokens());
DefRegister('\tocauthor'     => Tokens());    # Box!
DefRegister('\titrun'        => Tokens());    # Box!
DefRegister('\titlerunning'  => Tokens());
DefRegister('\toctitle{}'    => Tokens());

DefRegister('\tocchpnum'         => Dimension(0));
DefRegister('\tocsecnum'         => Dimension('15pt'));
DefRegister('\tocsubsecnum'      => Dimension('23pt'));
DefRegister('\tocsubsubsecnum'   => Dimension('27pt'));
DefRegister('\tocparanum'        => Dimension('35pt'));
DefRegister('\tocsubparanum'     => Dimension('43pt'));
DefRegister('\tocsectotal'       => Dimension(0));
DefRegister('\tocsubsectotal'    => Dimension(0));
DefRegister('\tocsubsubsectotal' => Dimension(0));
DefRegister('\tocparatotal'      => Dimension(0));

DefMacro('\addcontentsmark{}{}{}',    Tokens());
DefMacro('\addcontentsmarkwop{}{}{}', Tokens());
DefMacro('\addnumcontentsmark{}{}{}', Tokens());
DefMacro('\addtocmark[]{}{}{}',       Tokens());

#======================================================================
DefMacro('\mainmatter', Tokens());

NewCounter('chapter', 'document', idprefix => 'Pt', nested => ['section']);
DefMacro('\thechapter',    '\arabic{chapter}');
DefMacro('\chaptermark{}', Tokens());

# \spnewtheorem*{env}[numberedlike]{caption}[within]{capfont}{bodyfont}
# NOTE: Can I use latex's \newtheoremstyle, or do I need to copy & adapt it?
# Seems to be the same as \newtheoremstyle, but with additonal capfont & bodyfont
DefMacro('\spnewtheorem OptionalMatch:* {}[]{}[] {}{}', sub {
    my ($stomach, $flag, $thmset, $otherthmset, $type, $reset, $capfont, $bodyfont) = @_;
    $thmset      = ToString($thmset);
    $otherthmset = $otherthmset && ToString($otherthmset);
    $type        = undef if IsEmpty($type);
    $reset       = $reset ? ToString($reset) : undef;

    my $counter = $otherthmset || $thmset;
    my $swap    = LookupValue('thm@swap');
    my $style   = ToString(LookupValue('\thm@style'));

    if (!$otherthmset) {
      NewCounter($counter, $reset,
        idprefix => "Thm$counter");
      DefMacroI(T_CS("\\the$counter"), undef,
        "\\csname the$reset\\endcsname\\\@thmcountersep\\arabic{$counter}",
        scope => 'global')
        if $reset; }

# Swap causes you to get the odd (to me) order "4.1 Lemma", which breaks our new localization methods!!!
    DefEnvironmentI($thmset, "OptionalUndigested",
      "<ltx:theorem xml:id='#id' class='#class'>"
        . "#tags"
        . "<ltx:title font='#titlefont' _force_font='true'>#title</ltx:title>"
        . "#body",
      afterConstruct => sub { $_[0]->maybeCloseElement('ltx:theorem'); },
      beforeDigest   => sub {
        my $stylecmd = T_CS('\th@' . $style);
        if (!LookupDefinition($stylecmd)) {
          Warn('unexpected', $style, $_[0], "Unknown theoremstyle '$style'");
          $stylecmd = T_CS('\th@plain'); }
        Digest(Tokens($stylecmd)); },
      afterDigestBegin => sub { Digest($bodyfont); },
      properties       => sub {
        my %ctr   = ($counter ? ($flag ? RefStepID($counter) : RefStepCounter($counter)) : ());
        my $title = Digest(Tokens(T_BEGIN, $capfont->unlist,
            T_CS('\lx@tag'), T_BEGIN,
            ($swap
              ? (($flag ? () : (T_CS('\the' . $counter))),
                (!$flag && $type ? (T_SPACE)       : ()),
                ($type           ? ($type->unlist) : ()))
              : (($type ? ($type->unlist) : ()),
                (!$flag && $type ? (T_SPACE) : ()),
                ($flag           ? ()        : (T_CS('\the' . $counter))))),
            T_END,
            ($type && $_[1] ? (T_SPACE, T_OTHER('(')) : ()),
            ($_[1]          ? $_[1]->unlist           : ()),
            ($type && $_[1] ? (T_OTHER(')'))          : ()),
            T_CS('\the'), T_CS('\thm@headpunct'),
            T_END));
        (%ctr,
          title     => $title,
          titlefont => $title->getFont,
          class     => 'ltx_theorem_' . CleanClassName($thmset)); },
      scope => 'global');
});

RawTeX(<<'EOTeX');
\def\theoremname{Theorem}
\spnewtheorem{theorem}{Theorem}[section]{\bfseries}{\itshape}
\def\claimname{Claim}
\spnewtheorem*{claim}{Claim}{\itshape}{\rmfamily}
\def\proofname{Proof}
\spnewtheorem*{proof}{Proof}{\itshape}{\rmfamily}
\spnewtheorem{case}{Case}{\itshape}{\rmfamily}
\def\conjecturename{Conjecture}
\spnewtheorem{conjecture}{Conjecture}{\itshape}{\rmfamily}
\def\corollaryname{Corollary}
\spnewtheorem{corollary}{Corollary}{\bfseries}{\itshape}
\def\definitionname{Definition}
\spnewtheorem{definition}{Definition}{\bfseries}{\rmfamily}
\def\examplename{Example}
\spnewtheorem{example}{Example}{\itshape}{\rmfamily}
\def\exercisename{Exercise}
\spnewtheorem{exercise}{Exercise}{\bfseries}{\rmfamily}
\def\lemmaname{Lemma}
\spnewtheorem{lemma}{Lemma}{\bfseries}{\itshape}
\def\notename{Note}
\spnewtheorem{note}{Note}{\itshape}{\rmfamily}
\def\problemname{Problem}
\spnewtheorem{problem}{Problem}{\bfseries}{\rmfamily}
\def\propertyname{Property}
\spnewtheorem{property}{Property}{\itshape}{\rmfamily}
\def\propositionname{Proposition}
\spnewtheorem{proposition}{Proposition}{\bfseries}{\itshape}
\def\questionname{Question};
\spnewtheorem{question}{Question}{\itshape}{\rmfamily}
\def\solutionname{Solution}
\spnewtheorem{solution}{Solution}{\bfseries}{\rmfamily}
\def\remarkname{Remark}
\spnewtheorem{remark}{Remark}{\itshape}{\rmfamily}
EOTeX

#======================================================================
DefPrimitiveI('\bbbc',   undef, "\x{2102}");    #not sure if ok for the ones NOT of type I$
DefPrimitiveI('\bbbf',   undef, "\x{1D53D}");
DefPrimitiveI('\bbbh',   undef, "\x{210D}");
DefPrimitiveI('\bbbk',   undef, "\x{1D542}");
DefPrimitiveI('\bbbm',   undef, "\x{1D544}");
DefPrimitiveI('\bbbn',   undef, "\x{2115}");
DefPrimitiveI('\bbbone', undef, "\x{1D7D9}");
DefPrimitiveI('\bbbp',   undef, "\x{2119}");
DefPrimitiveI('\bbbq',   undef, "\x{211A}");
DefPrimitiveI('\bbbr',   undef, "\x{211D}");
DefPrimitiveI('\bbbs',   undef, "\x{1D54A}");
DefPrimitiveI('\bbbt',   undef, "\x{1D54B}");
DefPrimitiveI('\bbbz',   undef, "\x{2124}");

DefMath('\getsto', "\x{21C6}", role => 'ARROW');
DefMath('\lid',    "\x{2266}", role => 'RELOP', meaning => 'less-than-or-equals');
DefMath('\gid',    "\x{2267}", role => 'RELOP', meaning => 'greater-than-or-equals');
DefMath('\grole',  "\x{2277}", role => 'RELOP', meaning => 'greater-than-or-less-than');

DefConstructor('\squareforqed',
  "?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})");
DefMacro('\qed', '\squareforqed');

#======================================================================
DefMacro('\backmatter', Tokens());

#======================================================================
DefMacro('\andname',         'and');
DefMacro('\chaptername',     'Chapter');
DefMacro('\contriblistname', 'List of Contributors');
DefMacro('\lastandname',     ', and');
DefMacro('\noteaddname',     'Note added in proof');
DefMacro('\seename',         'see');
DefMacro('\subclassname',    '\textit{Subject Classification}:');

DefRegister('\fnindent' => Dimension(0));
DefMacro('\fnmsep',   '${}^{,}$');
DefMacro('\fnnstart', '0');

DefMacro('\calctocindent', Tokens());
DefMacro('\clearheadinfo', Tokens());
DefRegister('\headlineindent' => Dimension(0));
DefMacro('\thisbottomragged', Tokens());
Let('\ts', '\,');
DefEnvironment('{theopargself}', '#body');
DefMacro('\homedir', "\~{ }");
DefMacro('\idxquad', '\hskip 10pt\relax');
#======================================================================

# Newer llncs versions have an ORCID id macro
DefMacro('\orcidID Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@orcid{\@@orcid{#1}}}');
DefConstructor('\@@orcid{}', '<ltx:ref title="ORCID identifier" href="https://orcid.org/#1">#1</ltx:ref>');
DefConstructor('\@@@orcid{}', '^ <ltx:contact role="orcid">#1</ltx:contact>');

#  /--------------------------------------------------------------------\
# | INCOMPLETE IMPLEMENTATION                                            |
# | remove this comment, when done.                                      |
#  \--------------------------------------------------------------------/

# DefMacro('\hyperhrefextend',Tokens());

1;