# -*- mode: Perl -*-
# /=====================================================================\ #
# |  aa_support                                                         | #
# | 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.     | #
# |---------------------------------------------------------------------| #
# | Thanks to the arXMLiv group for initial implementation              | #
# |---------------------------------------------------------------------| #
# | 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;

# support for aa.cls, aa.sty, ...
#  Astronomy & Astrophysics
# See https://www.aanda.org/for-authors/latex-issues/texnical-background-information
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Class Options
# Ignorable options
foreach my $option (qw(10pt 11pt 12pt twoside onecolumn twocolumn
  draft final referee
  leqno fleqn longauth rnote
  oldversion
  runningheads
  envcountreset envcountsect
  structabstract traditabstract
  letter)) {
  DeclareOption($option, undef); }
DeclareOption('openbib', sub {
    RequireResource(undef, type => 'text/css', content => '.ltx_bibblock{display:block;}'); });

DeclareOption('cm',            sub { RequirePackage('textcomp'); });
DeclareOption('bibnumber',     sub { RequirePackage('natbib'); });
DeclareOption('bibauthoryear', sub { RequirePackage('natbib'); });
#DeclareOption(undef,sub {
#  PassOptions('article','cls',ToString(Expand(T_CS('\CurrentOption')))); });

ExecuteOptions(qw(a4paper twocolumn utf8 hideoverfull bibauthoryear));
ProcessOptions();

RequirePackage('inst_support');
RequirePackage('calc');
RequirePackage('etex');
RequirePackage('fontenc');
RequirePackage('geometry');
RequirePackage('setspace');
RequirePackage('fancyhdr');
#RequirePackage('cuted');
RequirePackage('amsmath');
RequirePackage('amssymb');
RequirePackage('xcolor');
RequirePackage('url');
RequirePackage('enumerate');
RequirePackage('longtable');
RequirePackage('xspace');
RequirePackage('babel');
RequirePackage('rotating');
#RequirePackage('answers');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# The Manuscript Header

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

# "Structured" abstract
# Note that they suggest either a 5 or 1 argument version!
# NOT an environment!!!
DefMacro('\abstract@old{}',
  '\@add@frontmatter{ltx:abstract}{#1}');

# Apparently args #2--#4 are required non-empty.
DefMacro('\abstract@new{}{}{}{}{}',
         '\@add@frontmatter{ltx:abstract}[name={\abstractname}]{'
         .'\ifx.#1.\else\textit{Context. }#1\par\fi'
         .'\textit{Aims. }#2\par'
         .'\textit{Methods. }#3\par'
         .'\textit{Results. }#4\par'
         .'\ifx.#5.\else\textit{Conclusions. }#5\fi'
         .'}');

DefMacro('\abstract{}', sub {
    my ($gullet, $arg1) = @_;
    $gullet->skipSpaces;    # I think?
    ((T_CS($gullet->ifNext(T_BEGIN)
          ? '\abstract@new' : '\abstract@old')),
      T_BEGIN, $arg1->unlist, T_END); });
# Keywords
DefMacroI('\keywordname', undef, '\sffamily\bfseries Key Words.');
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}[name={\keywordname}]{#1}');

# Formatting the header and running title
DefRegister('\titlerunning',  Tokens());    # Ignorable
DefRegister('\authorrunning', Tokens());
#DefRegister('\authrun'=>Box());
#DefRegister('\titrun'=>Box());
DefMacro('\authrun', '');
DefMacro('\titrun',  '');

# undocumented ?
DefMacro('\offprints{}', '\@add@frontmatter{ltx:note}[role=offprints]{#1}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}}');

DefMacro('\journalname{}', '');
DefMacro('\rnotename',     '(Research Note)');
DefMacro('\rnotname',      '(RN)');

# should add a note?
DefMacro('\headnote{}',   '\@add@frontmatter{ltx:note}{#1}');
DefMacro('\dedication{}', '\@add@frontmatter{ltx:note}[role=dedicatory]{#1}');
DefConstructor('\@@@mail{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\mail Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@mail{#1}}');
DefMacro('\mailname',          '\it Correspondence to \/');
DefMacro('\doi{}',             '\@add@frontmatter{ltx:classification}[scheme=doi]{#1}');

DefMacro('\idline{}{}',    '');                             # ?
DefMacro('\msnr{}',        '');                             # ??
DefMacro('\institutename', '');                             # ?
DefMacro('\hugehead',      '');
DefMacro('\AALogo',        'Astronomy and Astrophysics');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# The main text

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

RawTeX(<<'EoTeX');
\newtheorem*{proof}{Proof}{\it}{\rm}
\newtheorem{corollary}[theorem]{Corollary}{\bf}{\it}
\newtheorem{definition}[theorem]{Definition}{\bf}{\rm}
\newtheorem{example}[theorem]{Example}{\it}{\rm}
\newtheorem{exercise}[theorem]{Exercise}{\it}{\rm}
\newtheorem{lemma}[theorem]{Lemma}{\bf}{\it}
\newtheorem{note}[theorem]{Note}{\it}{\rm}
\newtheorem{problem}[theorem]{Problem}{\it}{\rm}
\newtheorem{proposition}[theorem]{Proposition}{\bf}{\it}
\newtheorem{question}[theorem]{Question}{\it}{\rm}
\newtheorem{remark}[theorem]{Remark}{\it}{\rm}
\newtheorem{solution}[theorem]{Solution}{\it}{\rm}
EoTeX

DefMacro('\noteaddname', 'Note added in proof');
DefEnvironment('{noteadd}', "<ltx:note>#body</ltx:note>");

# Undocumented, but something like:
DefMacro('\thesaurus{}', '');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Redefine equations (bizarrely) to allow $ within
DefEnvironment('{equation}',
  "<ltx:equation xml:id='#id'>"
    . "#tags"
    . "<ltx:Math mode='display'>"
    . "<ltx:XMath>"
    . "#body"
    . "</ltx:XMath>"
    . "</ltx:Math>"
    . "</ltx:equation>",
  mode         => 'display_math',
  beforeDigest => sub {
    prepareEquationCounter(numbered => 1, preset => 1);
    beforeEquation();
    Let(T_MATH, T_CS('\@dollar@in@mathmode')); },
  afterDigestBody => sub {
    afterEquation($_[1]); },
  locked => 1);

# Note: In ams, this DOES get a number if \tag is used!
DefEnvironment('{equation*}',
  "<ltx:equation xml:id='#id'>"
    . "#tags"
    . "<ltx:Math mode='display'>"
    . "<ltx:XMath>"
    . "#body"
    . "</ltx:XMath>"
    . "</ltx:Math>"
    . "</ltx:equation>",
  mode         => 'display_math',
  beforeDigest => sub {
    prepareEquationCounter(numbered => undef, preset => 1);
    beforeEquation();
    Let(T_MATH, T_CS('\@dollar@in@mathmode')); },
  afterDigestBody => sub {
    afterEquation($_[1]); },
  locked => 1);

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Figures
# the usual...
### Let('\sidecaption','\caption');  NO!!!
# Should be something like this
# DefMacro('\sidecaption Until:\caption', ... );
# but let's just ignore it for now.
DefMacro('\sidecaption', '');

# NOTE: Sort this out!!
# I'm a little unclear how this is supposed to be used -- it isn't documented.
# Clearly it provides for sub-numbered figures, but
# are people supposed to put multiple figure environments within {figure}
# or just multiple graphics and multiple captions?
# The latter, probably, but....
DefMacro('\resetsubfig{}', '');    #
DefMacro('\subfigures',    '');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Tables
# the usual...

# Actually not sure exactly what this is,
#   \longtab{num}{table}
DefMacro('\longtab{}', '');    # just let it do the table contents as usual.

# variations of footnote used within tables
Let('\tablefoot', '\footnote');
DefMacro('\tablefootmark{}',   '\footnotemark[$#1$]');
DefMacro('\tablefoottext{}{}', '\footnotetext[$#1$]{#2}');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# References
# the usual...

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Typography

DefMacro('\vec{}', '\ensuremath{\@vec{#1}}');
DefMath('\@vec{}', '#1', role => 'ID', font => { forcebold => 1 });
DefMacro('\tens{}', '\ensuremath{\@tens{#1}}');
DefMath('\@tens{}', '\mathsf{#1}', role => 'ID');    # semantics?

# \ion{symbol}{ionization}
# Note that semantics could be useful!
DefMacro('\ion{}{}', '{#1 \textsc{#2}}');

# \element[charge][nucleons][protons][neutrons]{symbol}
DefMacro('\element[][][][]{}', '\ensuremath{\@element[#1][#2][#3][#4]{\mathrm{#5}}}');

DefConstructor('\@element[][][][]{}', sub {
    my ($document, $charge, $nucleons, $protons, $neutrons, $element, %props) = @_;
    my $level = $props{scriptlevel};
    my $node  = $document->insertElement('ltx:XMArg', $element);
    $node = wrapIsotope($document, $node, $charge,   'post', 'SUPER', $level) if $charge;
    $node = wrapIsotope($document, $node, $neutrons, 'post', 'SUB',   $level) if $neutrons;
    $node = wrapIsotope($document, $node, $nucleons, 'pre',  'SUPER', $level) if $nucleons;
    $node = wrapIsotope($document, $node, $protons,  'pre',  'SUB',   $level) if $protons;
    $node; });

sub wrapIsotope {
  my ($document, $node, $script, $x, $y, $l) = @_;
  my $new = $document->openElement('ltx:XMApp');
  $document->insertElement('ltx:XMTok', undef, role => $y . 'SCRIPTOP', scriptpos => "$x$l");
  $new->appendChild($node);
  $document->insertElement('ltx:XMWrap', $script);
  $document->closeElement('ltx:XMApp');
  return $new; }

DefPrimitiveI('\sun',      undef, "\x{2609}");
DefPrimitiveI('\diameter', undef, "\x{2300}");

DefPrimitiveI('\degr',   undef, UTF(0xB0));
DefPrimitiveI('\arcmin', undef, "\x{2032}");
DefPrimitiveI('\arcsec', undef, "\x{2033}");

DefMath('\la',    "\x{2272}", role => 'RELOP', meaning => 'less-than-or-similar-to');
DefMath('\ga',    "\x{2273}", role => 'RELOP', meaning => 'greater-than-or-similar-to');
DefMath('\cor',   "\x{2258}", role => 'RELOP', meaning => 'corresonds-to');
DefMath('\sol',   "\x{2A9D}", role => 'RELOP', meaning => 'similar-to-or-less-than');
DefMath('\sog',   "\x{2A9E}", role => 'RELOP', meaning => 'similar-to-or-greater-than');
DefMath('\lse',   "\x{2A8D}", role => 'RELOP', meaning => 'less-than-or-similar-to-or-equal');
DefMath('\gse',   "\x{2A8E}", role => 'RELOP', meaning => 'greater-than-or-similar-to-or-equal');
DefMath('\leogr', "\x{2276}", role => 'RELOP', meaning => 'less-than-or-greater-than');
DefMath('\grole', "\x{2277}", role => 'RELOP', meaning => 'greater-than-or-less-than');
DefMath('\loa',   "\x{2A85}", role => 'RELOP', meaning => 'less-than-or-approximately-equals');
DefMath('\goa',   "\x{2A86}", role => 'RELOP', meaning => 'greater-than-or-approximately-equals');
DefMath('\lid',   "\x{2266}", role => 'RELOP', meaning => 'less-than-or-equals');
DefMath('\gid',   "\x{2267}", role => 'RELOP', meaning => 'greater-than-or-equals');

DefMath('\getsto', "\x{21C6}", role => 'ARROW');

# Various degrees etc.
# Copied from aas_support
DefConstructor('\aas@@fstack{}',
  "<ltx:XMApp role='POSTFIX'>"
    . "<ltx:XMTok role='SUPERSCRIPTOP' scriptpos='#scriptpos'/>"
    . "<ltx:XMTok>.</ltx:XMTok>"
    . "<ltx:XMWrap>#1</ltx:XMWrap>"
    . "</ltx:XMApp>",
  properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } },
  mode       => 'math', bounded => 1);
DefMacro('\aas@fstack{}', '\ensuremath{\aas@@fstack{#1}}');
DefMacro('\fd',           '\aas@fstack{d}');
DefMacro('\fh',           '\aas@fstack{h}');
DefMacro('\fm',           '\aas@fstack{m}');
DefMacro('\fs',           '\aas@fstack{s}');
DefMacro('\fdg',          '\aas@fstack{\circ}');
DefMacro('\farcm',        '\aas@fstack{\prime}');
DefMacro('\farcs',        '\aas@fstack{\prime\prime}');
DefMacro('\fp',           '\aas@fstack{p}');

DefConstructor('\mathsc{}', '#1', bounded => 1, requireMath => 1,
  font => { family => 'smallcaps', series => 'medium', shape => 'upright' });

# NOTE: Would like to see this used; do these put a \sim or \approx underneath something?
#DefMacro('\udtw','');
#DefMacro('\utw','');

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

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}");

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Appendices
# The usual...

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Online material
# Support for adsurl URLs containing unescaped % characters, e.g. %26
# in A&A URLs
DefConstructor('\bib@field@default@adsurl Verbatim',
  "<ltx:bib-url href='#1'>ADS entry</ltx:bib-url>");

# We could probably do more with these if they were used consistently...
# example use is [\eprint[arXiv]{astro-ph/0212111}], in a bibitem
DefMacro('\eprint[]{}', '{\tt\if!#1!#2\else#1:#2\fi}');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Astronomical objects

DefConstructor('\object Semiverbatim',
  "<ltx:text class='ltx_ast_objectname'>#1</ltx:text>");
DefMacro('\listofobjects',  '');
DefMacro('\listobjectname', 'List of Objects');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Extra stuff
DefMacro('\setitemindent{}',     '');    # Ignorable
DefMacro('\setitemitemindent{}', '');

DefMacro('\andname', 'and');
#DefMacro('\lastand','');
DefMacro('\lastandname', ', and');

DefMacro('\AASection{}', '');            # Ignorable
DefMacro('\Online',      '');

# Random dimensions, or spacing; would anyone use?
DefRegister('\aftertext'         => Dimension('5pt'));
DefRegister('\betweenumberspace' => Dimension('3.33pt'));
DefRegister('\figcapgap'         => Dimension('5pt'));
DefRegister('\tabcapgap'         => Dimension('10pt'));
DefRegister('\figgap'            => Dimension('1cc'));
DefRegister('\headerboxheight'   => Dimension('143pt'));
DefRegister('\headlineindent'    => Dimension('1.166cm'));
DefRegister('\instindent'        => Dimension(0));
DefMacro('\leftlegendglue', '');
DefRegister('\logodepth' => Dimension('1.3cm'));

DefMacro('\capstrut',         '');
DefMacro('\captionstyle',     '');
DefMacro('\clearelargs',      '');
DefMacro('\errorref',         '@latex@error{Citations are not allowed in the abstract}');
DefMacro('\floatcounterend',  '.');
DefMacro('\sectcounterend',   '.');
DefMacro('\floatlegendstyle', '\bf');
DefMacro('\thisbottomragged', '');
DefMacro('\ts',               '\thinspace');
DefMacro('\fnmsep',           '\unskip$^,$');                                               # ?
DefMacro('\makeheadbox',      '');
#DefMacro('\stripauthor','');
#DefMacro('\theapsection','Appendix \@Alph\c@section:');
#DefMacro('\theapsubsection','\@Alph\c@section.\@arabic\c@subsection.');
#DefMacro('\theapsubsubsection','\theheapsubsection\@arabic\c@subsubsection');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Journal shorthands
DefMacro('\aj',       'AJ');
DefMacro('\actaa',    'Acta Astron.');
DefMacro('\araa',     'ARA\&A');
DefMacro('\apj',      'ApJ');
DefMacro('\apjl',     'ApJ');
DefMacro('\apjs',     'ApJS');
DefMacro('\ao',       'Appl.~Opt.');
DefMacro('\apss',     'Ap\&SS');
DefMacro('\aap',      'A\&A');
DefMacro('\aapr',     'A\&A~Rev.');
DefMacro('\aaps',     'A\&AS');
DefMacro('\azh',      'AZh');
DefMacro('\baas',     'BAAS');
DefMacro('\bac',      'Bull. astr. Inst. Czechosl.');
DefMacro('\caa',      'Chinese Astron. Astrophys.');
DefMacro('\cjaa',     'Chinese J. Astron. Astrophys.');
DefMacro('\icarus',   'Icarus');
DefMacro('\jcap',     'J. Cosmology Astropart. Phys.');
DefMacro('\jrasc',    'JRASC');
DefMacro('\mnras',    'MNRAS');
DefMacro('\memras',   'MmRAS');
DefMacro('\na',       'New A');
DefMacro('\nar',      'New A Rev.');
DefMacro('\pasa',     'PASA');
DefMacro('\pra',      'Phys.~Rev.~A');
DefMacro('\prb',      'Phys.~Rev.~B');
DefMacro('\prc',      'Phys.~Rev.~C');
DefMacro('\prd',      'Phys.~Rev.~D');
DefMacro('\pre',      'Phys.~Rev.~E');
DefMacro('\prl',      'Phys.~Rev.~Lett.');
DefMacro('\pasp',     'PASP');
DefMacro('\pasj',     'PASJ');
DefMacro('\qjras',    'QJRAS');
DefMacro('\rmxaa',    'Rev. Mexicana Astron. Astrofis.');
DefMacro('\skytel',   'S&T');
DefMacro('\solphys',  'Sol.~Phys.');
DefMacro('\sovast',   'Sov.~Ast.');
DefMacro('\ssr',      'Space~Sci.~Rev.');
DefMacro('\zap',      'ZAp');
DefMacro('\nat',      'Nature');
DefMacro('\iaucirc',  'IAU~Circ.');
DefMacro('\aplett',   'Astrophys.~Lett.');
DefMacro('\apspr',    'Astrophys.~Space~Phys.~Res.');
DefMacro('\bain',     'Bull.~Astron.~Inst.~Netherlands');
DefMacro('\fcp',      'Fund.~Cosmic~Phys.');
DefMacro('\gca',      'Geochim.~Cosmochim.~Acta.');
DefMacro('\grl',      'Geochim.~Res.~Lett.');
DefMacro('\jcp',      'J.~Chem.~Phys.');
DefMacro('\jgr',      'J.~Geophys.~Res.');
DefMacro('\jqsrt',    'J.~Quant.~Spec.~Radiat.~Transf.');
DefMacro('\memsai',   'Mem.~Soc.~Astron.~Italiana');
DefMacro('\nphysa',   'Nucl.~Phys.~A');
DefMacro('\physrep',  'Phys.~Rep');
DefMacro('\physscr',  'Phys.~Scr');
DefMacro('\planss',   'Planet.~Space~Sci.');
DefMacro('\procspie', 'Proc.~SPIE');
Let('\astap',   '\aap');
Let('\apjlett', '\ajpl');
Let('\apjsupp', '\ajps');
Let('\applopt', '\ao');

DefMacro('\errorref', '');
DefEnvironment('{stopref}', '#1');

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
