diff --git a/NEWS.md b/NEWS.md index cffe93d6..1949fb9f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ - rticles now requires rmarkdown 2.32 or later and Pandoc 2.8 or later, matching rmarkdown's updated minimum Pandoc version ([rstudio/rmarkdown#2623](https://github.com/rstudio/rmarkdown/pull/2623)). +- `agu_article()` now uses Pandoc citeproc with the American Geophysical Union CSL style by default. Existing drafts containing only `agujournal2018.cls` must explicitly set `citation_package: natbib`; the format warns when the selected class and citation backend are incompatible (#606). + - Update `springer_article()` template to version 3 (December 2023): - BREAKING CHANGE: sn-mathphys.bst has been split into Numbered and Author year style namely `sn-mathphys-num.bst` and `sn-mathphys-ay.bst` respectively. Skeleton has been updated. If you have existing article, you need to use `sn-mathphys-num` or `sn-mathphys-ay` option now, instead of `sn-mathphys`. @@ -38,6 +40,8 @@ supported by the `copernicus.cls`, and fix an issue where the section headers we ## MINOR CHANGES +- Update `agu_article()` to AGU's September 2025 distribution of `agujournal2019.cls`, current manuscript guidance, and external TrackChanges setup (#606). + - Fix `agu_article()` table rendering with recent LaTeX distributions by using the text-mode table centering helper when available (#606). - Fix `biometrics_article()` rendering with LaTeX 2026 by preserving the LaTeX kernel's matching `\endtabular` implementation. diff --git a/R/article.R b/R/article.R index 97dde718..15e2de67 100644 --- a/R/article.R +++ b/R/article.R @@ -58,19 +58,100 @@ aea_article <- function(..., keep_tex = TRUE, ) } -#' @section `agu_article`: Format for creating a American Geophysical Union -#' (AGU) article. Adapted from -#' . +#' @section `agu_article`: Format for creating an American Geophysical Union +#' (AGU) article. Adapted from AGU's September 2025 LaTeX distribution of +#' `agujournal2019.cls` and the official [LaTeX submission +#' guidelines](https://www.agu.org/publications/authors/journals/latex-submissions). +#' +#' The default `citation_package = "default"` uses Pandoc citeproc with +#' the American Geophysical Union CSL style, following the approach used by +#' the Quarto AGU journal format. Use Markdown citation syntax in current +#' drafts. +#' +#' New drafts include `agujournal2019.cls`. Existing drafts that retain only +#' a project-local `agujournal2018.cls` remain supported but must explicitly +#' set `citation_package = "natbib"`. The format warns when the selected +#' class and citation backend are incompatible. If both classes are present, +#' the current 2019 class is used. #' @export #' @rdname article agu_article <- function(..., keep_tex = TRUE, - citation_package = "natbib", highlight = NULL, + citation_package = "default", highlight = NULL, md_extensions = c("-autolink_bare_uris", "-auto_identifiers")) { - pdf_document_format( + format <- pdf_document_format( "agu", keep_tex = keep_tex, highlight = highlight, citation_package = citation_package, md_extensions = md_extensions, ... ) + + pre_processor <- format$pre_processor + format$pre_processor <- function(metadata, input_file, runtime, knit_meta, + files_dir, output_dir) { + input_dir <- dirname(input_file) + legacy_class <- file.path(input_dir, "agujournal2018.cls") + current_class <- file.path(input_dir, "agujournal2019.cls") + has_legacy_class <- file.exists(legacy_class) + has_current_class <- file.exists(current_class) + use_current_class <- !has_legacy_class || has_current_class + + if (!use_current_class && citation_package != "natbib") { + warn_once( + "rticles.warn_agu_2018_citations", + "Detected only 'agujournal2018.cls', which expects ", + "`citation_package = \"natbib\"`. The selected '", + citation_package, + "' backend is unsupported for legacy raw \\citep and \\citet ", + "commands. Set natbib explicitly or update the draft to the 2019 class." + ) + } else if (!use_current_class) { + warn_once( + "rticles.warn_agu_2018", + "Detected 'agujournal2018.cls' next to the input file. ", + "This class remains supported for backward compatibility, but the ", + "article should be updated from the current `rticles::agu_article()` ", + "template to use 'agujournal2019.cls' and current AGU guidance." + ) + } else { + if (has_legacy_class && has_current_class) { + warn_once( + "rticles.warn_agu_both_classes", + "Detected both 'agujournal2018.cls' and 'agujournal2019.cls' next to ", + "the input file. The AGU template will use 'agujournal2019.cls'; you ", + "may remove the unused 'agujournal2018.cls' file." + ) + } + if (citation_package != "default") { + warn_once( + "rticles.warn_agu_2019_citations", + "The selected 2019 AGU class supports `citation_package = ", + "\"default\"` with citeproc and the AGU CSL style. The selected '", + citation_package, + "' backend is unsupported; the 2019 class does not provide natbib ", + "citation commands." + ) + } + } + + c( + if (is.function(pre_processor)) { + pre_processor( + metadata, input_file, runtime, knit_meta, files_dir, output_dir + ) + }, + if (use_current_class) { + rmarkdown::pandoc_variable_arg("rticles-agu-2019") + }, + if (citation_package == "default" && is.null(metadata$csl)) { + c( + "--csl", + rmarkdown::pandoc_path_arg(pkg_file_template( + "agu", "skeleton", "american-geophysical-union.csl" + )) + ) + } + ) + } + format } #' @section `amq_article`: Ce format a été adapté du format du bulletin de diff --git a/inst/rmarkdown/templates/agu/resources/template.tex b/inst/rmarkdown/templates/agu/resources/template.tex index c316460d..f8648cea 100644 --- a/inst/rmarkdown/templates/agu/resources/template.tex +++ b/inst/rmarkdown/templates/agu/resources/template.tex @@ -1,39 +1,18 @@ -%% March 2018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% AGUJournalTemplate.tex: this template file is for articles formatted with LaTeX +% AGU article template adapted from the September 2025 distribution of +% agujournal2019.cls. Existing rticles drafts may retain agujournal2018.cls. % -% This file includes commands and instructions -% given in the order necessary to produce a final output that will -% satisfy AGU requirements, including customized APA reference formatting. -% -% You may copy this file and give it your -% article name, and enter your text. -% -% -% Step 1: Set the \documentclass -% -% There are two options for article format: -% -% PLEASE USE THE DRAFT OPTION TO SUBMIT YOUR PAPERS. -% The draft option produces double spaced output. -% - -%% To submit your paper: +% Prefer the current class deterministically when both local classes exist. +$if(rticles-agu-2019)$ +\documentclass[$for(classoption)$$classoption$$sep$,$endfor$]{agujournal2019} + +% The 2019 class leaves revision packages to the document. The 2018 class +% already loads trackchanges and ulem, so reloading them would clash. +\usepackage[inline]{trackchanges} +\usepackage{soul} +$else$ \documentclass[$for(classoption)$$classoption$$sep$,$endfor$]{agujournal2018} -\usepackage{apacite} -\usepackage{url} %this package should fix any errors with URLs in refs. -%%%%%%% -% As of 2018 we recommend use of the TrackChanges package to mark revisions. -% The trackchanges package adds five new LaTeX commands: -% -% \note[editor]{The note} -% \annote[editor]{Text to annotate}{The note} -% \add[editor]{Text to add} -% \remove[editor]{Text to remove} -% \change[editor]{Text to remove}{Text to add} -% -% complete documentation is here: http://trackchanges.sourceforge.net/ -%%%%%%% +$endif$ %% Enter journal name below. @@ -113,6 +92,8 @@ $if(csl-refs)$ % Pandoc citation processing +\providecommand{\phantomsection}{} +\providecommand{\hypertarget}[2]{#2} $if(pandoc318)$ %From Pandoc 3.1.8 % definitions for citeproc citations @@ -281,13 +262,13 @@ % List up to three key points (at least one is required) % Key Points summarize the main points and conclusions of the article -% Each must be 100 characters or less with no special characters or punctuation +% Each must be 140 characters or fewer with no special characters or punctuation % Example: % \begin{keypoints} % \item List up to three key points (at least one is required) % \item Key Points summarize the main points and conclusions of the article -% \item Each must be 100 characters or less with no special characters or punctuation +% \item Each must be 140 characters or fewer with no special characters or punctuation % \end{keypoints} \begin{keypoints} @@ -312,16 +293,14 @@ $abstract$ \end{abstract} $if(plain_language_summary)$ -\noindent{\bf Plain language summary}\vskip-\parskip - -\noindent{$plain_language_summary$} -\vskip18pt +\section*{Plain Language Summary} +$plain_language_summary$ $endif$ $body$ -$if(bibliography)$ +$if(natbib)$$if(bibliography)$ \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} -$endif$ +$endif$$endif$ $for(include-after)$ $include-after$ diff --git a/inst/rmarkdown/templates/agu/skeleton/agujournal2019.cls b/inst/rmarkdown/templates/agu/skeleton/agujournal2019.cls new file mode 100644 index 00000000..75390bd4 --- /dev/null +++ b/inst/rmarkdown/templates/agu/skeleton/agujournal2019.cls @@ -0,0 +1,1302 @@ +\def\currversion{April 16, 2019} + + %****************************************************************% + %* *% + %* AGU Class File for all AGU Journals *% + %* *% + %* Written by Amy Hendrickson *% + %* TeXnology Inc.: 617 738-8029 *% + %* amyh@texnology.com *% + %* http://www.texnology.com *% + %* *% + %****************************************************************% + +%%% Updates by Dangerous Curve typesetting@dangerouscurve.org +%%% +%%% 2017-07-14 +%%% (Changes marked DC) +%%% +%%% Use BibLaTeX for change to APA style. +%%% Removed tracking-changes code. +%%% +%%% +%%% 2017-12-16 +%%% +%%% Remove biblatex. +%%% Use apacite instead of agufull08, + +%%% 2018-07-17 / NRV +%%% thanks to John Haiducek for help with citep error + +%%% 2019-01-14 / NRV +%%% Removed natbib, changed instructions for cite commands, added Appendix heading + +%%% 2019-4-16 / NRV +%%% Removed ulem to facilitate trackchanges +%%% Gave user more control over trackchanges options +%%% fixed typo in example citations + +\ProvidesClass{agujournal2019} + [01/14/2019] + +%% SEARCH BELOW FOR THE NUMBER TO FIND PARTICULAR MACRO GROUP + + %% Macro Contents: + %% 0) Usepackage graphicx, colorx, other .sty files which we'll need to have available. + + %% 1) Setting Default Dimensions + + %% 2) Global Parameters + + %% 3) Setting and Using Options + + %% 4) Font Family declarations + + %% 5) Running heads, Footnotes + + %% 6) Title Page: Journal Name, + %% Title, Authors, Affils, Corresponding Authors, Author Notes, Key Points; abstract + + %% 7) Section Commands + + %% 8) Figure and Table Captions + + %% 9) Listing + + %% 10) Etc.: Hyphenation Library, Quote, Extract + + %% 11) End Article: Appendix, Glossary, Acronyms, Notation, Acknowledgments + + %% 12) Bibliography, References + + %% 13) Track Changes + + %% 14) Supporting Information + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 0) Bringing in packages that we will need: + +%% Nicer font choice than Computer Modern: +%\RequirePackage{newtxtext,newtxmath} + +%% always will want this available +\RequirePackage{graphicx} + +%% to get illustrations to print, in spite of being in Draft mode: +\setkeys{Gin}{draft=false} + +%% xcolor.sty +\RequirePackage{xcolor} +\RequirePackage{url} + +%% for better track changes +%\RequirePackage{trackchanges} + +%% used for running head which is in light gray + +\definecolor{ltgray}{cmyk}{.12,0,0,.3} + +%% Line numbering +\RequirePackage{lineno} +%% add more space between text and number: +\advance\linenumbersep 12pt + +%% this package makes paragraphs indent after section heads +\RequirePackage{indentfirst} + + +%% \RaggedRight makes the right margin go in and out; if this is commented out +%% the default will be a right justified margin. +\RequirePackage{ragged2e} +\RaggedRightParindent=24pt +\advance\RaggedRightRightskip 24pt +\RaggedRight + +%% Defines \sidewaystable and \sidewaysfigure, preferred by AGU +\RequirePackage{rotating} +\newif\ifturnofflinenums +\let\savesidewaystable\sidewaystable +\let\savesidewaysfigure\sidewaysfigure +%% turns off line numbers in rotated tables and figures, aesthetic consideration, +%% not necessary. +\def\sidewaystable{\turnofflinenumstrue\savesidewaystable\centering} +\def\sidewaysfigure{\turnofflinenumstrue\savesidewaysfigure\centering} + +%%xx Use apacite. DC +%% Formats bibliography, this .sty file needs to be entered later +% \RequirePackage{natbib} + +%\PassOptionsToPackage{normalem}{ulem} +%\RequirePackage{ulem} + +%% <== End Bringing in Packages + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 1) Setting Default Dimensions + + %% Comment + %% parindent= indentation for every new paragraph + %% parskip= distance between paragraphs. Giving `plus .1pt' allows + %% a little stretch between paragraphs. If you don't like this stretch + %% you can set \parskip=0pt + +\parindent=24pt +\parskip=8pt % plus .1pt + + %% Comment + %% \textheight is distance from bottom of text, exclusive of running + %% foot, to top of text, exclusive of running head. + +\textheight = 9.25in + %% Comment + %% \textwidth= Width of text in normal page. Can change this width locally + %% with either \leftskip/\rightskip or change in \hsize, but will + %% still be able to return to the normal width by setting \hsize=\textwidth + %% Running head normally uses \textwidth as its width so that a change + %% in \hsize in text will not change width of running head or feet. + +\textwidth 5.5in + + %% Comment + %% \voffset moves the printed page up or down on the physical page. +\advance\voffset-.25in + + %% Comment + %% \hoffset moves the printed page left or right on the physical page. +\advance\hoffset.35in + + %% Comment + %% Setting page dimensions + %% See p. 84-- 85 in LaTeX Companion, Goosins, Mittlebach and Samarin + %% or p. 555--556 in A Guide to LaTeX, Kopka and Daly, both Addison Wesley + %% books. + + %% \topmargin space between top of page and running head + + %% \headheight height of running head + + %% \headsep space between running head and text + + %% \topskip space between top of text and baseline of first line + %% of text + + %% \footskip space between text and baseline of page number + + %% \columnsep space between two column text + + %% \columnseprule width of optional rule between columns, usually set to 0pt + + %% \footnotesep Distance between two footnotes + + %% \skip\footins Distance between text and footnote + + %% \floatsep Distance between float and another + %% float for single col floats. + + %% \textfloatsep Distance between float and text at top + %% or bottom of page. + + %% \intextsep Distance between float and text if float is mid page + %% or mid column + + %% \dblfloatsep For float spanning both columns in two column text, + %% above or below both columns, space between float and and float. + + +\topmargin0pt +\headheight 8pt +\headsep 6pt +\topskip 10pt +\footskip 36pt + +\columnsep 10pt +\columnseprule 0pt + +\footnotesep 6.65pt +\skip\footins 24pt plus .1pt minus .1pt + +\floatsep 12pt plus 2pt minus 2pt +\textfloatsep 36pt plus 2pt minus 4pt +\intextsep 24pt plus 2pt minus 2pt + +\dblfloatsep 12pt plus 2pt minus 2pt +\dbltextfloatsep 20pt plus 2pt minus 4pt + +%% float placement, used by output routine +\@fptop 0pt plus 1fil +\@fpsep 8pt plus 2fil +\@fpbot 0pt plus 1fil +\@dblfptop 0pt plus 1fil +\@dblfpsep 8pt plus 2fil +\@dblfpbot 0pt plus 1fil + + %% When using \marginpar, how wide can marginal note be? + +\marginparwidth .75in + + %% When using \marginpar, how much horizontal space between marginal + %% note and text + + \setlength\marginparsep{40\p@} + + %% When to push marginal note on to next page, minimum vertical space between + %% two marginal notes + +\setlength\marginparpush{5\p@} + + %% space added before trivlist, which is used in many other + %% macros, (for instance, verbatim environment) + %% if macro is called in vertical mode, otherwise only parskip + %% is added. Can set this without stretch if you don't like + %% the stretchy space added. + +\setlength\partopsep{2\p@ \@plus 1\p@ \@minus 1\p@} + + %% Comment + %% Setting parameters that control float placement + %% + %% \topnumber counter holds the maximum number of + %% floats that can appear on the top of a text page. + %% + %% \topfraction indicates the maximum part of a text page that can be + %% occupied by floats at the top. + %% + %% \bottomnumber counter holds the maximum number of + %% floats that can appear on the bottom of a text page. + %% + %% \bottomfraction indicates the maximum part of a text page that can be + %% occupied by floats at the bottom. + %% + %% \totalnumber indicates the maximum number of floats that can appear on + %% any text page. + %% + %% \textfraction indicates the minimum part of a text page that has to be + %% occupied by text. + %% + %% \floatpagefraction indicates the minimum part of a page that has to be + %% occupied by floating objects before a `float page' is produced. + %% + %% \dbltopnumber counter holds the maximum number of + %% two column floats that can appear on the top of a two column text + %% page. + %% + %% \dbltopfraction indicates the maximum part of a two column text page that + %% can be occupied by two column floats at the top. + %% + %% \dblfloatpagefraction indicates the minimum part of a page that has to be + %% occupied by two column wide floating objects before a `float + %% page' is produced. + %%% + +\setcounter{topnumber}{10} +\def\topfraction{.9} +\setcounter{bottomnumber}{10} +\def\bottomfraction{.1} +\setcounter{totalnumber}{10} +\def\textfraction{.2} +\def\floatpagefraction{.5} +\setcounter{dbltopnumber}{2} +\def\dbltopfraction{.7} +\def\dblfloatpagefraction{.5} + + %% Setting Array and Table Spacing + %% distance between columns in array +\setlength\arraycolsep{5\p@} + + %% distance between columns in tabular +\tabcolsep 6pt + + %% width of lines in array +\setlength\arrayrulewidth{.4\p@} + + %% horizontal space between two lines in array +\setlength\doublerulesep{2\p@} + + %% space between two lines in tabular +\setlength\tabbingsep{\labelsep} + + %% Minipage + %% minipage space +\skip\@mpfootins = \skip\footins + + %% Framebox \fbox{} or \framebox{} + %% space between line in framebox and text within it +\setlength\fboxsep{3\p@} + + %% width of ruled line in framebox +\setlength\fboxrule{.4\p@} + + +%%%%%%%%%%%%%%% <<== end dimensions + +% 2) %%% Global parameters ==>> + + %% Makes sure that there will not be any widow or club lines, + %% smaller numbers allow them occassionally, but you probably need + %% these set to 10000 so that there are never any + +\widowpenalty10000 +\clubpenalty10000 + + %% How many levels deep do you want sections to be numbered-- higher number + %% means more levels will be numbered. Here was are asking only for + %% sections to be numbered, not subsections, or subsubsection etc. +\setcounter{secnumdepth}{4} + + + %% To make left and right page position differently, and have + %% running heads be different on even and odd pages +\@twosidetrue + + %% Marginal notes should be on the left on even numbered pages; on + %% right on odd numbered pages. +\@mparswitchtrue + + %% Starting with one column text +\@twocolumnfalse + + %% openbib will allow separate lines for parts of bibliography + %% entries, default is to run different parts of bib entry into a + %% paragraph form. + +\newif\if@openbib +\@openbibfalse + + %% Conditionals that we can set and use later +\newif\if@openright +\newif\if@mainmatter +\newif\if@restonecol +\newif\if@titlepage +\newif\ifdraft +\newif\ifnumlines + + %% Comment + %% Set Names, to be used later, usually in more than one + %% macro. +\newcommand{\bibname}{Bibliography} +\newcommand{\figurename}{Figure} +\newcommand{\tablename}{Table} +\newcommand{\appendixname}{Appendix} + +%%% <== end global parameters + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 3) Declare Options and Use Default Options +\DeclareOption{draft}{\global\drafttrue} +\DeclareOption{linenumbers}{\global\numlinestrue} +\DeclareOption{final}{\setlength\overfullrule{0pt}\global\draftfalse} + +\ExecuteOptions{letterpaper,10pt,onecolumn,final,openright} +\ProcessOptions + +\ifnumlines +\linenumbers*[1] +\fi + +%% <==== End Setting Options + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 4) Font Family Info + +%% Comment +%% When \ifdraft is true it will make the baselineskip = \draftskip + +\newcount\draftskip +\draftskip=20 + +\newcommand{\@ptsize}{} + + %% Comment + %% Set font sizes, normal baselineskip, for the range of sizes, + %% changing baselineskip to be larger if draft option is true + %% \setfontsize takes the first arg as the size of the font and + %% the second as the size of the baselineskip + %% \abovedisplayskip and \belowdisplayskip is the space before and + %% after an equation, adjusted in some sizes. + + %% \Huge 25pt + %% \huge 20pt + %% \LARGE 17pt + %% \Large 14pt + %% \large 12pt + %% \normalsize 10 pt font + %% \small 9pt + %% \footnotesize 8pt + %% \scriptsize 7pt font + %% \tiny 5pt font + + +\renewcommand\normalsize{% +\ifdraft + \@setfontsize\normalsize\@xpt{\draftskip} +\else + \@setfontsize\normalsize\@xpt{12} +\fi + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI} +\normalsize + +\newcommand\bignormalsize{\@setfontsize\bignormalsize{10.5pt}{12}} + +\newcommand\small{% +\ifdraft + \@setfontsize\small\@ixpt{\draftskip}% +\else + \@setfontsize\small\@ixpt{14}% +\fi + \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus2\p@ + \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 4\p@ \@plus2\p@ \@minus2\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} + +\newcommand\footnotesize{% +\ifdraft + \@setfontsize\footnotesize\@viiipt{\draftskip}% +\else + \@setfontsize\footnotesize\@viiipt{12}% +\fi + \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus\p@ + \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 3\p@ \@plus\p@ \@minus\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} + +\newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} +\newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} +\newcommand\large{\ifdraft +\@setfontsize\large\@xiipt{\draftskip} +\else +\@setfontsize\large\@xiipt{14} +\fi +} + +\newcommand\Large{\ifdraft +\@setfontsize\Large\@xivpt{\draftskip} +\else +\@setfontsize\Large\@xivpt{18} +\fi} + +\newcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}} +\newcommand\huge{\@setfontsize\huge\@xxpt{25}} +\newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} + +%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% These definitions accomodate older font typeface commands, +%% that are still in use. + +\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand{\cal}{\@fontswitch{\relax}{\mathcal}} +\DeclareRobustCommand{\mit}{\@fontswitch{\relax}{\mathnormal}} + +%% end font family declarations +%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 5) Running heads and footnotes + +%% Running heads ===>>> + + %% unless we need these, leave these uncommented + \let\@mkboth\@gobbletwo + \let\chaptermark\@gobble + \let\sectionmark\@gobble + %% + +\def\ps@headings{\def\@oddfoot{\centerline{\small --\the\c@page--}} +\let\@evenfoot\@oddfoot +%% \thejournalname set with \journalname{} command; if not you will get a request to set +%% the journal name with \journalname{} +\def\@oddhead{\vbox to 0pt{\vss\centerline{\color{ltgray}\small manuscript +submitted to {\it \thejournalname}}\vskip24pt}} +\let\@evenhead\@oddhead +} + + + +%% After ps@headings is defined, now we use it to activate the definitions +\ps@headings + +%%% Footnotes + + %% save these definitions so that we can use them if + %% we don't like the redefinition +\let\savefootnote\footnote +\let\savefootnotetext\footnotetext + + %%% ruled line above footnote + + \renewcommand{\footnoterule}{% + \kern-3\p@ + \hrule width .4\columnwidth + \kern 2.6\p@} + + \let\savefootnoterule\footnoterule + +% turn off footnote rule, line at bottom of page above footnotes + \let\footnoterule\relax + +% can turn it back on by uncommenting +\let\footnoterule\savefootnoterule + +% Making footnote indent 1em +\long\def\@makefntext#1{% +\noindent\hspace*{1em}\@makefnmark\,#1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 6) Title Page: + %% Journal Name, running heads; + %% Title, Authors, Affils, Corresponding Authors, Author Notes, Key Points; + %% Starting article with abstract. + +%% Set journal name: +\def\journalname#1{\def\thejournalname{#1}} +\journalname{Please set Journal Name by using {\tt\string\journalname}} + + +%% Article Title +\def\title#1{\global\c@footnote=0\relax% +{\centering \Large\bf #1 \vskip14pt} +\def\thetitle{#1}} + +\def\authors#1{{\centering \normalsize\bf #1\vskip12pt}} +\def\affil#1{$^{#1}$\ignorespaces} +\def\affiliation#1#2{\vskip-.5\parskip\relax{\centering{\footnotesize +$^{#1}$#2\relax}\vskip-\parskip}} + +\def\correspondingauthor#1#2{{\let\@thefnmark\relax\@footnotetext{\noindent\vrule +height 18pt width0pt\relax\hbox to-8pt{}{\small +Corresponding author: #1, +{\tt #2}}}}} + +%% Used to send footnote to bottom of page when entered in \authors{} field. +\def\thanks#1{{\renewcommand\thefootnote{\@fnsymbol\c@footnote}% + \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% + \long\def\@makefntext##1{\noindent\hskip-9pt\hb@xt@1.8em{% + \hss\@textsuperscript{\normalfont\@thefnmark}}##1}\footnote{#1}\ + }} + +\def\keypoints{\vskip24pt\vskip1sp\subsection*{Key Points:} +\begin{itemize}} +\def\endkeypoints{\end{itemize}} + +\def\abstract{\newpage\noindent{\bf Abstract}\vskip-\parskip +\global\c@footnote=0\relax% +\noindent\ignorespaces} +\def\endabstract{\vskip18pt} + +%% <== End Title page and Abstract + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 7) Section Commands + +% SectionCounters, Header Level Counters ===>> + + %% the argument in square brackets is for the command that will reset + %% counter to zero +\newcounter {section} +\newcounter {subsection}[section] +\newcounter {subsubsection}[subsection] +\newcounter {paragraph}[subsubsection] +\newcounter {subparagraph}[paragraph] + + + %% Header Level Counters ==>> + %% Change to any level will change the levels below + + +\renewcommand{\thesection} {\arabic{section}} +\renewcommand{\thesubsection} {\thesection.\arabic{subsection}} +\renewcommand{\thesubsubsection}{\thesubsection.\arabic{subsubsection}} +\renewcommand{\theparagraph} {\thesubsubsection.\arabic{paragraph}} +\renewcommand{\thesubparagraph} {\theparagraph.\arabic{subparagraph}} + +\newcommand{\@chapapp}{\chaptername} + + %%% <<== End Header Level Counters + + %% Definition printed here so that you can see what the various arguments are + %% when used for \section, \subsection, etc, below + %% \newcommand{\section}{\@startsection {section}{1}{\z@}...} + + +% \@startsection {NAME}{LEVEL}{INDENT}{BEFORESKIP}{AFTERSKIP}{STYLE} +% optional * [ALTHEADING]{HEADING} +% Generic command to start a section. +% NAME : e.g., 'subsection' +% LEVEL : a number, denoting depth of section -- e.g., chapter=1, +% section = 2, etc. +% INDENT : Indentation of heading from left margin +% BEFORESKIP : Absolute value = skip to leave above the heading. +% If negative, then paragraph indent of text following +% heading is suppressed. +% AFTERSKIP : if positive, then skip to leave below heading, else +% negative of skip to leave to right of run-in heading. +% STYLE : commands to set style +% If '*' missing, then increments the counter. If it is present, then +% there should be no [ALTHEADING] argument. +% Uses the counter 'secnumdepth' whose value is the highest section +% level that is to be numbered. + + %% Startsection calls \@sect, the engine that formats each section + + %% the minus dimensions are used to tell LaTeX not to indent + %% the text following the section head + %% (silly, isn't it? but built into LaTeX) + %% You can add things like underline or uppercase to the last arg + %% to get those effects in a section head + +%% adds a little space after the section number, before following text. +\def\@seccntformat#1{\csname the#1\endcsname\ \ } + +\newcommand\section{\@startsection {section}{1}{\z@}% + {\ifdraft18pt plus 1pt minus + 1pt\else 12pt plus 1pt minus 1pt\fi}% + {1sp}% + {\bignormalsize\bfseries\boldmath}} + +\newcommand\subsection{\@startsection{subsection}{2}{\parindent}% + {\ifdraft 12pt\else 8pt\fi}% + {1sp}% + {\normalfont\bf\boldmath}} + +\newcommand\subsubsection{\@startsection{subsubsection}{3}{\parindent}% + {\ifdraft 12pt\else 8pt\fi}% + {1sp}% + {\normalfont\itshape\bfseries}} + +\newcommand\paragraph{\@startsection{paragraph}{4}{\parindent}% + {3pt plus 1pt minus 1pt}% + {-1em}% + {\normalfont\normalsize\itshape}} + +\newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}% + {3pt plus 1pt minus 1pt}% + {-1em}% + {\normalfont\normalsize\itshape}} + + %%% <<=== end section commands + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 8) Figure and Table Captions ==>>> + +\long\def\@caption#1[#2]#3{% + \par + \begingroup + \@parboxrestore + \normalsize +\linenumbers + \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \endgroup} +\def\@float#1{% + \@ifnextchar[% + {\@xfloat{#1}}% + {\edef\reserved@a{\noexpand\@xfloat{#1}[\csname fps@#1\endcsname]}% + \reserved@a}} +\def\@dblfloat{% + \if@twocolumn\let\reserved@a\@dbflt\else\let\reserved@a\@float\fi + \reserved@a} + + %% Name of Figure or Table is set with \figurename or \tablename above + %% \@float is what puts the text at the top or bottom of the page + %% \@dblfloat is for floats in two column text + +\newcounter{figure} +\renewcommand{\thefigure}{\arabic{figure}} + +\def\fps@figure{tbp} % position figure at top, bottom, or on its own page +\def\ftype@figure{1} % used for placing float in page +\def\ext@figure{lof} % send info to .lof file +\def\fnum@figure{\figurename~~\thefigure} % \figurename, defined above, + %% and the current state of figure counter + + %% \begin{figure} calls up float and gives it the {figure} argument, + %% which is then used to call up the definitions above, by using + %% \csname fps@\captype\endcsname, for instance, to get \fps@figure; + %% adjusting the macro to do different things depending on whether + %% figure, table, environment, or other term is used. + +\newenvironment{figure} + {\@float{figure}} + {\end@float} + + %% figure in two column text +\newenvironment{figure*} + {\@dblfloat{figure}} + {\end@dblfloat} + + %% Similar as the sequence of definitions above used for figure +\newcounter{table} +\renewcommand{\thetable}{\@arabic\c@table} +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\def\fnum@table{\tablename~\thetable} +\newenvironment{table} + {\@float{table}} + {\end@float} +\newenvironment{table*} + {\@dblfloat{table}} + {\end@dblfloat} + + %%%%%%%%%%%%%%%% + %% Setting space between caption in table or figure and the + %% table or figure +\newlength\abovecaptionskip +\newlength\belowcaptionskip +\setlength\abovecaptionskip{10\p@} +\setlength\belowcaptionskip{10\p@} + + %% to test in caption to see whether it is a figure or table +\def\xfigure{figure} + + %% Variation on LaTeX code + %% Skips below caption + %% an extra 3pt if it is a table to give extra space between caption + %% and table, since caption for table goes above table. + + %% \sbox\@tempboxa sets a temporary box so that we can measure + %% the width of the caption; if width is greater than .9\hsize + %% then make it format in a paragraph, otherwise center it. + + %% Test to see if it a figure or table: \ifx\@captype\xfigure + %% If figure, \vskip\belowcaptionskip + +\long\def\@makecaption#1#2{% +{\small +\ifx\@captype\xfigure +\vskip\abovecaptionskip\fi +{\ifturnofflinenums\else\ifnumlines\internallinenumbers\fi\fi + \sbox\@tempboxa{\bf#1.\quad \rm #2}% + \ifdim \wd\@tempboxa >.9\hsize +\bf #1.\quad\rm\relax #2\par + \else +{\centering + \bf #1.\rm\quad #2 +\vskip1sp} + \fi} +%% +\ifx\@captype\xfigure\else + \vskip\belowcaptionskip\fi +}} + + + %% Code to get text in tables to extend all the way to left and right + %% of table. The LaTeX table macros are made to allow space to the + %% left and the right of tables to accomodate vertical ruled lines. But + %% most publishers don't want vertical ruled lines. If the authors + %% don't use the ruled lines there would be extra white space without + %% the changes below. This code is very complicated, but you can see + %% the changed part. + +\def\xtable{table} +\def\@array[#1]#2{\setbox\@arstrutbox=\hbox{\vrule + height\arraystretch \ht\strutbox + depth\arraystretch \dp\strutbox + width\z@}\@mkpream{#2}\edef\@preamble{\halign \noexpand\@halignto +\bgroup% +\tabskip\z@\@arstrut\@preamble +\ifx\@captype\xtable\hskip-\tabcolsep\fi %% <==== Changed +\tabskip\z@ \cr}% +\let\@startpbox\@@startpbox \let\@endpbox\@@endpbox% + % Recent LaTeX kernels no longer enter math mode before \@array. + % Use their text-mode helper while retaining the older behavior. + \if #1t\vtop \else \if#1b\vbox \else + \ifdefined\vcenter@text\vcenter@text\else\vcenter\fi + \fi\fi% + \bgroup\let\par\relax% + \let\@sharp##\let\protect\relax \lineskip\z@\baselineskip\z@\@preamble} + + + %% Variation on code found in Latex.tex +\def\new@tabacol{\edef\@preamble{\@preamble\hskip0pt}} + +\def\@tabclassz{\ifcase \@lastchclass\@acolampacol% +\or \@ampacol \or + \or \or \@addamp \or \@acolampacol\or \@firstampfalse +\ifx\@captype\xtable \new@tabacol\else\@tabacol \fi% +\fi% +\edef\@preamble{\@preamble% + \ifcase \@chnum% + \hfil\ignorespaces\@sharp\unskip\hfil% + \or \ignorespaces\@sharp\unskip\hfil% + \or \hfil\hskip\z@ \ignorespaces\@sharp\unskip\fi}} + + %% This puts extra space between horizontal lines in tables. + %% If you want to use vertical lines in tables, you should use + %% \savehline rather than \hline, otherwise the vertical and + %% horizontal lines will not abutt. + + %% \noalign is a command that allows the uses to put something + %% between lines in a table. +\let\savehline\hline +\def\hline{\noalign{\vskip3pt}\savehline\noalign{\vskip3pt}} + + %% Simple macro for table notes, that makes sure that there is + %% a little space between the table and the notes, and that they + %% print in footnotesize. +\def\tablenotes{\vskip2pt\footnotesize} +\let\endtablenotes\relax + + %%% <<=== end Figure and Table Captions + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% 9) Listing, ==>> +\def\@listI{\leftmargin\leftmargini + \parsep 0\p@ %\@plus2\p@ \@minus0\p@ + \topsep 4\p@ %\@plus2\p@ \@minus0\p@ + \itemsep1\p@ %\@plus2\p@ \@minus0\p@ +} +\let\@listi\@listI +\@listi + +\def\@listii {\leftmargin\leftmarginii + \labelwidth\leftmarginii + \advance\labelwidth-\labelsep + \topsep 4\p@ \@plus2\p@ \@minus\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep} +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii + \advance\labelwidth-\labelsep + \topsep 2\p@ \@plus\p@\@minus\p@ + \parsep \z@ + \partopsep \p@ \@plus\z@ \@minus\p@ + \itemsep \topsep} +\def\@listiv {\leftmargin\leftmarginiv + \labelwidth\leftmarginiv + \advance\labelwidth-\labelsep} +\def\@listv {\leftmargin\leftmarginv + \labelwidth\leftmarginv + \advance\labelwidth-\labelsep} +\def\@listvi {\leftmargin\leftmarginvi + \labelwidth\leftmarginvi + \advance\labelwidth-\labelsep} + + %% amount left edge of text is indented relative to normal text + %% i is for first level in, ii is for second level in, etc. +\setlength\leftmargini {28pt} +\setlength\leftmarginii {11pt} +\setlength\leftmarginiii {1.87em} +\setlength\leftmarginiv {1.7em} +\setlength\leftmarginv {1em} +\setlength\leftmarginvi {1em} + + + %% default indentation for first level itemized lists +\setlength\leftmargin {\leftmargini} + + %% horizontal distance between item and following text +\setlength \labelsep {6pt} + + %% how wide should item be? +\setlength \labelwidth{\leftmargini} + + %% subtract width of label separation +\addtolength\labelwidth{-\labelsep} + + %% more listing defaults +\leftmargin\leftmargini +\labelwidth\leftmargini\advance\labelwidth-\labelsep + + +\@beginparpenalty -\@lowpenalty +\@endparpenalty -\@lowpenalty +\@itempenalty -\@lowpenalty + + %% defining listing markers for enumerate +\renewcommand{\theenumi}{\arabic{enumi}} +\renewcommand{\theenumii}{\alph{enumii}} +\renewcommand{\theenumiii}{\roman{enumiii}} +\renewcommand{\theenumiv}{\Alph{enumiv}} + + %% using listing markers for enumerate +\newcommand{\labelenumi}{\theenumi.\hskip-2pt} +\newcommand{\labelenumii}{(\theenumii)} +\newcommand{\labelenumiii}{\theenumiii.} +\newcommand{\labelenumiv}{\theenumiv.} + + %% crossreferencing for listing markers +\renewcommand{\p@enumii}{\theenumi} +\renewcommand{\p@enumiii}{\theenumi(\theenumii)} +\renewcommand{\p@enumiv}{\p@enumiii\theenumiii} + + %% listing markers for itemize (no crossreferencing needed) +\newcommand{\labelitemi}{\raise.4ex\hbox{\tiny$\bullet$}} +\newcommand{\labelitemii}{\normalfont\bfseries --} +\newcommand{\labelitemiii}{$\m@th\ast$} +\newcommand{\labelitemiv}{$\m@th\cdot$} + + %% Setting up description listing environment +\newenvironment{description} + {\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + {\endlist} + +\newcommand*{\descriptionlabel}[1]{\hspace\labelsep + \normalfont\bfseries #1} + +%%% <<=== end of listing commands + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% 10) ETC.: Month/year, Hyphenation Library, Quote, Quotation, Extract + +%% Month and Year + +% Nice example of \ifcase which takes a counter and activates +% the slot following the counter that matches the same number; +% \month expands to a number, so ifcase will activate the slot +% matching that number. Can use it for setting date in draft +% footnote if desired. Not activated at this time. + +\newcommand{\today}{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} + +% Hyphenation Library +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Hyphenation Library, add to this +%% list if desired + +\hyphenation{ +dem-o-graph-ics +mi-cro-ec-o-nom-ic +or-gan-i-za-tion +or-gan-i-za-tions +ra-tion-ale +sys-tem-at-i-cal-ly +} + + +%%%% Quote, Quotation, Extract + %% \newenvironment produces a \begin{}..\end{} macro set. + %% \newenvironment{}{} + %% {} + + %% For long quotation which runs more than one paragraph, + %% uses list environment to indent text, supplies dummy + %% item, \item[], since one item is required for every listing + %% environment or you will get an error message. + + %% quotation indents new paragraphs, while quote does not. + +\newenvironment{quotation} + {\small +\list{}{\listparindent 1.5em% + \itemindent \listparindent + \rightmargin \leftmargin + \parsep \z@ \@plus\p@}% + \item[]} + {\endlist} +\newenvironment{quote} + {\small +\list{}{\rightmargin\leftmargin}% + \item[]} + {\endlist} + + %% If \begin{extract}...\end{extract} is used you will get the same + %% results as \begin{quotation}...\end{quotation} + +\let\extract\quotation +\let\endextract\endquotation + + %% <<== end ETC.: Month/year, Hyphenation Library, Quote, Quotation, Extract + +%%%%%%%%% +% 11) End Article: Appendix, Glossary, Acronyms, Notation, Acknowledgments + +% Appendix: +\newcounter{appendnum} + +\newif\ifappendon +\newif\ifupperappend + +\def\appendix{% +\def\@currentlabel{\Alph{section}:} %xx Doesn't do much. Missing trailing space. DC +\@addtoreset{equation}{section} +\@addtoreset{table}{section} +\@addtoreset{figure}{section} +%% +\renewcommand{\thesection}{Appendix \Alph{section}} %xx Redefined below (by orginal author, not DC). DC +\renewcommand{\theequation}{\Alph{section}\arabic{equation}} +\renewcommand{\thefigure}{\Alph{section}\arabic{figure}} +\renewcommand{\thetable}{\Alph{section}\arabic{table}} +\global\appendontrue\goodbreak +\global\c@section=0 +\global\c@equation=0 +\def\thesection{Appendix \Alph{section}} %xx What puts the : in \ref. Taken out now. DC +\def\thesubsection{\Alph{section}\@arabic{\c@subsection}} +\def\thesubsubsection{\thesubsection\@arabic{\c@subsubsection}} +\def\thesubsubsubsection{\thesubsubsection\@arabic{\c@subsubsection}} +} +%%%%% end appendix + +%% Glossary +\def\glossary{\bgroup +\section*{Glossary} +\description +\def\term##1{\item[##1]}} +\def\endglossary{\enddescription\vskip12pt\egroup} +%% + +%% Acronyms +\def\acronyms{\bgroup +\section*{Acronyms} +\description +\def\acro##1{\item[##1]}} +\def\endacronyms{\enddescription\vskip12pt\egroup} + +%% Notation +\def\notation{\bgroup +\section*{Notation} +\description +\def\notation##1{\item[\boldmath ##1]}} +\def\endnotation{\enddescription\vskip12pt\egroup} + +%% Acknowledgments +\def\acknowledgments{\vskip12pt\noindent{\bf +Acknowledgments\vrule depth 6pt +width0pt\relax}\\*\noindent\ignorespaces} + +%%% <<=== end Appendix, Glossary, Acronyms, Notation, Acknowledgments + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 12) %% Bibliography, References ===>> + +%% Set bibliography style: This brings in agufull08.bst to format +%% bibliography when using BibTeX. +%\bibliographystyle{agufull08} +% +\bibliographystyle{apacite} + +%% In case you want to enter bib entries without using bibtex +\def\references{\thebibliography{}\item[]} +\let\endreferences\endthebibliography + +\def\@cite#1#2{{#1\if@tempswa , #2\fi}} + +\def\@citex[#1]#2{% + \let\@citea\@empty + \@cite{\@for\@citeb:=#2\do + {\@citea\def\@citea{,\penalty\@m\ }% + \edef\@citeb{\expandafter\@firstofone\@citeb}% + \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi + \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% + \G@refundefinedtrue + \@latex@warning + {Citation `\@citeb' on page \thepage \space undefined}}% + %% + %% This is changed from the default so that lengthy citations can + %% be broken across lines + {%\hbox{ +\csname b@\@citeb\endcsname%} +}}}{#1}} + +\newdimen\bibindent +\setlength\bibindent{1.5em} + +\def\refname{References} +\newenvironment{thebibliography}[1] + {\section*{\refname + \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \sloppy + \clubpenalty4000 + \@clubpenalty \clubpenalty + \widowpenalty4000% + \sfcode`\.\@m} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \endlist} + +\def\newblock{\hskip .11em\@plus.33em\@minus.07em} + + + + +% Formats bibliography, this .sty file needs to be entered here + + % +% When using NatBib, this sets brackets for citations: +%\renewcommand\NAT@open{(} \renewcommand\NAT@close{)} %xx Parens by default, but not using anyways. DC + +\RequirePackage{apacite} +%\RequirePackage{natbib} +\let\cite\shortcite %xx So get et al. with three authors the first time. +%\let\citep\shortcite %xx A natbib command. +%\let\citet\shortcite %xx Ditto. +\let\citeA\shortciteA %xx Ditto. + + + +%% end Bibliography, and References + +%%%%%%%%%%%%%%%%%%%%%%%%%%xx Removed. DC + +%%% Track Changes +%%% Amy Hendrickson, Feb 2016 +% +%\providecolor{trackcolor}{rgb}{1,0,0} +%\providecolor{explain}{rgb}{.5,0,.5} +% +%\newcount\refchangenumber +% +%\def\added{\@ifnextchar[{\xadded}{\yadded}} +% +%\long\def\xadded[#1]#2{% +%\ifdraft{\global\advance\refchangenumber by 1\relax% +%\ifnumlines +%\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}{}{}{}}\doit\fi% +%\color{trackcolor}(Added: #2)}%% +%\expandafter\gdef\csname +%changenum\the\refchangenumber\endcsname{Added: [#1] +%\textcolor{trackcolor}{#2}, }\else#2\fi} +% +%\long\def\yadded#1{% +%\ifdraft{\global\advance\refchangenumber by 1\relax% +%\ifnumlines +%\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}{}{}{}}\doit\fi% +%\color{trackcolor}(Added: #1)}%% +%\expandafter\gdef\csname changenum\the\refchangenumber\endcsname{Added: +%\textcolor{trackcolor}{#1}, }\else#1\fi} +% +%\def\deleted{\@ifnextchar[{\xdeleted}{\ydeleted}} +% +%\long\def\xdeleted[#1]#2{% +%\ifdraft{\global\advance\refchangenumber by 1\relax% +%\ifnumlines +%\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}{}{}{}}\doit\fi% +%\color{trackcolor}(Deleted: \sout{#2})}%% +%\expandafter\gdef\csname +%changenum\the\refchangenumber\endcsname{Deleted: [#1] +%\textcolor{trackcolor}{#2}, }\else#2\fi} +% +%\long\def\ydeleted#1{ +%\ifdraft +%\global\advance\refchangenumber by 1 +%\ifnumlines\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}}\doit\fi% +%{\color{trackcolor}(Deleted: \sout{#1})}% +%\expandafter\def\csname changenum\the\refchangenumber\endcsname{Deleted: +%{\color{trackcolor}\sout{#1}}, }\fi} +% +%\def\replaced{\@ifnextchar[{\xreplaced}{\yreplaced}} +% +%\long\def\xreplaced[#1]#2#3{% +%\ifdraft +%\global\advance\refchangenumber by 1 +%\ifnumlines\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}}\doit\fi% +%{\color{trackcolor}(Replaced: \sout{#2}} +%{\color{black}replaced with:} {\color{trackcolor} #3)}% +%\expandafter\gdef\csname +%changenum\the\refchangenumber\endcsname{Replaced: [#1] +%{\color{trackcolor}\sout{#2}} {\color{black} replaced with:} +%{\color{trackcolor}#3}, }\else#3\fi} +% +%\long\def\yreplaced#1#2{% +%\ifdraft +%\global\advance\refchangenumber by 1 +%\ifnumlines\xdef\doit{\noexpand\linelabel{\the\refchangenumber}}\doit\else% +%\xdef\doit{\noexpand\label{\the\refchangenumber}}\doit\fi% +%{\color{trackcolor}(Replaced: \sout{#1}} +%{\color{black}replaced with:} {\color{trackcolor} #2)}% +%\expandafter\gdef\csname changenum\the\refchangenumber\endcsname{Replaced: +%{\color{trackcolor}\sout{#1}} {\color{black} replaced with:} +%{\color{trackcolor}#2}, }\else#2\fi} +% +%\global\@mparswitchfalse +%\def\explain{\@ifnextchar[{\xexplain}{\yexplain}} +% +%%% +%\def\xexplain[#1]#2{\ifdraft\marginpar{\noindent{\color{red}\llap{\boldmath$\leftarrow$}\draftfalse\normalsize +%\baselineskip=11pt\relax[#1] #2\vskip1sp}}\fi} +% +%\def\yexplain#1{\ifdraft\marginpar{\noindent{\color{red}\llap{\boldmath$\leftarrow$}\draftfalse\normalsize +%\baselineskip=11pt\relax#1\vskip1sp}}\fi} +% +% +%\newcount\listchangenum +% +%\def\listofchanges{ +%\clearpage +%\ifdraft +%\ifnum\refchangenumber>0 +%\ifnumlines\nolinenumbers\fi +%\vskip36pt +%\vtop{\hrule +%\noindent{\vrule height 9pt width0pt depth 6pt\large\bf List of Changes} +%\hrule +%\vskip18pt} +%\nobreak +%{\parskip=4pt \parindent-18pt \leftskip=18pt +%\loop +%\vskip-1pt\relax +%\global\advance\listchangenum by 1\relax +%\expandafter\ifx\csname changenum\the\listchangenum\endcsname\relax +%\else +%\csname changenum\the\listchangenum\endcsname\ on page +%\pageref{\the\listchangenum}% +%\ifnumlines +%\setbox0=\hbox{\lineref{\the\listchangenum}}% +%\ifdim\wd0>20pt% +%\else% +%, line\ +%\lineref{\the\listchangenum}% +%\fi\fi. +%\repeat} +%\fi\fi +%\thispagestyle{empty} +%} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 14) Supporting Information +\def\supportinginfo#1{\newpage +{\large\bf\noindent Supporting Information for\vskip-6pt\noindent``#1''} +\vskip12pt} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Start page numbering, formatting + +\pagenumbering{arabic} +\widowpenalty=10000 +\clubpenalty=10000 +\ifdraft +\RaggedRight +\fi +\endinput diff --git a/inst/rmarkdown/templates/agu/skeleton/american-geophysical-union.csl b/inst/rmarkdown/templates/agu/skeleton/american-geophysical-union.csl new file mode 100644 index 00000000..3a6bf508 --- /dev/null +++ b/inst/rmarkdown/templates/agu/skeleton/american-geophysical-union.csl @@ -0,0 +1,703 @@ + + diff --git a/inst/rmarkdown/templates/agu/skeleton/skeleton.Rmd b/inst/rmarkdown/templates/agu/skeleton/skeleton.Rmd index 91c8b6b5..fe51c7f1 100644 --- a/inst/rmarkdown/templates/agu/skeleton/skeleton.Rmd +++ b/inst/rmarkdown/templates/agu/skeleton/skeleton.Rmd @@ -1,32 +1,21 @@ --- -# Choose from this list of Journals: -# JGR: Atmospheres, JGR: Biogeosciences, JGR: Earth Surface, -# JGR: Oceans, JGR: Planets, JGR: Solid Earth, JGR: Space Physics, -# Global Biogeochemical Cycles, Geophysical Research Letters, -# Paleoceanography and Paleoclimatology, Radio Science, Reviews of Geophysics, -# Tectonics, Space Weather, Water Resources Research, Geochemistry, Geophysics, -# Geosystems, Journal of Advances in Modeling Earth Systems (JAMES), -# Earth's Future, Earth and Space Science, Geohealth +# Choose an AGU journal, for example: JGR: Atmospheres, JGR: Biogeosciences, +# JGR: Earth Surface, JGR: Oceans, JGR: Planets, JGR: Solid Earth, +# JGR: Space Physics, Global Biogeochemical Cycles, Geophysical Research +# Letters, Paleoceanography and Paleoclimatology, Radio Science, Reviews of +# Geophysics, Tectonics, Space Weather, Water Resources Research, +# Geochemistry, Geophysics, Geosystems, Journal of Advances in Modeling Earth +# Systems (JAMES), Earth's Future, Earth and Space Science, or GeoHealth. journal: "JGR: Atmospheres" -# Use draft to submit a paper +# Use draft and line numbers for submission. classoption: "draft,linenumbers" -# A title should be specific, informative, and brief. Use -# abbreviations only if they are defined in the abstract. Titles that -# start with general keywords then specific terms are optimized in -# searches -title: "The title of my paper" -# First name or initial followed by last name -# Authors are individuals who have significantly contributed to the -# research and preparation of the article. Group authors are allowed, if -# each author in the group is separately identified in an appendix. -# Additional author notes should be indicated with +title: "The Title of My Paper" authors: - name: Andrew N. Other affil: 1 - thanks: Andrew's thanks + thanks: "Current address: Another institution, Germany" - name: Fred T. Secondauthor affil: 1 - thanks: "Current address: Some other place, Germany" - name: I. Ken Groupleader affil: "1, 2" affiliations: @@ -34,201 +23,178 @@ affiliations: name: "The first affiliation" - number: 2 name: "The second affiliation" -# More than one corresponding author is allowed in this LaTeX file and for -# publication; but only one corresponding author is allowed in our editorial system. +# The peer-review system accepts one corresponding author. corresponding_author: - name: I. Ken Groupleader email: groupleader@fancy.university.com -keypoints: - - "List up to three key points (at least one is required)" - - "Key Points summarize the main points and conclusions of the article" - - "Each must be 100 characters or less with no special characters or punctuation" -abstract: "A good abstract will begin with a short description of the problem being addressed, briefly describe the new data or analyses, then briefly states the main conclusion(s) and how they are supported and uncertainties." -plain_language_summary: "Some journals require a plain language summary. See: https://publications.agu.org/author-resource-center/text-requirements/#abstract" +# Supply one to three complete sentences, each no longer than 140 characters. +keypoints: + - "Key Points summarize the main findings and conclusions of the article." + - "Each Key Point is a complete sentence of no more than 140 characters." +abstract: "Briefly describe the problem, data or analyses, main conclusions, supporting evidence, and uncertainties." +# Write for a broad audience without specialist knowledge. This summary is +# required by some AGU journals; consult the current journal instructions. +plain_language_summary: "Explain the general problem, what was done, and the main result in language accessible to the science-interested public." output: rticles::agu_article bibliography: agutest.bib -header-includes: - - \usepackage{soulutf8} # For UTF8 chars in TrackChanges -# AGU recommends using the trackchanges LaTeX package in the edition process -# which is available from this link: -# https://publications.agu.org/files/2019/02/January-14-2019-latex-templates.zip +csl: american-geophysical-union.csl --- ```{r echo=FALSE} -# Some recommended settings. knitr::opts_chunk$set( echo = FALSE, - fig.pos = 'h', - out.extra = "", # To force the use of figure enviroment + fig.pos = "h", + out.extra = "", fig.cap = "Please caption every figure" ) ``` -```{r keypoints_check, echo=FALSE, results='asis', eval = TRUE} -# This chunk adds a warning if any keypoint is longer than 100 characters. -# To disable it, you can remove it or set eval to FALSE. -if (any(nchar(rmarkdown::metadata$keypoints) > 100)) { - cat("\\textcolor{red}{\\textbf{Warning}: keypoint(s)", - knitr::combine_words(which(nchar(rmarkdown::metadata$keypoints) > 100)), - "longer than 100 characters.}") +```{r keypoints_check, echo=FALSE, results='asis'} +# Remove this chunk or set eval = FALSE to disable the length check. +keypoint_lengths <- nchar(rmarkdown::metadata$keypoints) +if (any(keypoint_lengths > 140)) { + cat( + "\\textcolor{red}{\\textbf{Warning}: keypoint(s)", + knitr::combine_words(which(keypoint_lengths > 140)), + "longer than 140 characters.}" + ) } ``` -Suggested section heads - # Introduction -The main text should start with an introduction. Except for short manuscripts (such as comments and replies), the text should be divided into sections, each with its own heading. +Begin with an introduction. Except for short manuscripts such as comments and replies, divide the text into sections with informative headings. -Headings should be sentence fragments and do not begin with a lowercase letter or number. Capitalize the first letter of each word (except for prepositions, conjunctions, and articles that are three or fewer letters). +Headings should be sentence fragments. Capitalize the first letter of each major word, excluding short prepositions, conjunctions, and articles. # Materials and Methods -Here is text on Materials and Methods. - -Do not use bulleted lists; enumerated lists are okay. Use #. for list for a cleaner LaTeX output. +Describe the materials and methods. AGU discourages bulleted lists; enumerated lists are acceptable. #. First element - #. Second element -## A descriptive heading about methods +## A Descriptive Heading About Methods -Please use ONLY \\citet and \\citep for reference citations. -DO NOT use other cite commands (e.g., \\cite, \\citeyear, \\nocite, \\citealp, etc.). -Example \\citet and \\citep: - ...as shown by \citet{Levitus2012}, \citet{Nuncio2011} and \citet{Raphael2004} - ...as shown by \citep{Levitus2012}, \citep{Nuncio2011}, \citep{Raphael2004}. - ...has been shown \citep[e.g.,][]{Levitus2012, Nuncio2011, Raphael2004}. +The default citation backend uses Pandoc citeproc and the bundled American Geophysical Union CSL style. Use Markdown citations, including textual citations such as @Levitus2012 [p. 4] and parenthetical citations such as [e.g., @Nuncio2011, p. 5]. Citeproc formats both the in-text citations and reference list; raw LaTeX citation commands are not processed by this backend. # Data -Or section title might be a descriptive heading about data - -As of 2018 we recommend use of the TrackChanges package to mark revisions. The trackchanges package adds five new LaTeX commands: - -\\note[editor]{The note} - -\\annote[editor]{Text to annotate}{The note} - -\\add[editor]{Text to add} - -\\remove[editor]{Text to remove} +Describe the data used in the study. A required Open Research section near the end of the manuscript must state where the data, software, and other research objects supporting the conclusions can be obtained. -\\change[editor]{Text to remove}{Text to add} +AGU supports TrackChanges commands in revisions. The 2019 template configures the bundled package in inline mode; use `finalnew` instead when preparing a clean revision. Common commands include `\note[editor]{...}`, `\annote[editor]{...}{...}`, `\add[editor]{...}`, `\remove[editor]{...}`, and `\change[editor]{...}{...}`. -complete documentation is here: http://trackchanges.sourceforge.net/ +```{=latex} +This sentence contains \add{an example tracked addition}. +``` # Results -Or section title might be a descriptive heading about the results - -Enter Figures and Tables near as possible to where they are first mentioned: -DO NOT USE \\psfrag or \\subfigure commands. -DO NOT USE \\newcommand, \\renewcommand, or \\def, etc. +Place figures and tables near their first mention. Do not use `\psfrag` or `\subfigure`, and consolidate multipart figures into one figure file. -```{r} +```{r pressure-figure} plot(pressure) ``` -Example table - +```{=latex} \begin{table} - \caption{Time of the Transition Between Phase 1 and Phase 2$^{a}$} - \centering - \begin{tabular}{l c} - \hline - Run & Time (min) \\ - \hline - $l1$ & 260 \\ - $l2$ & 300 \\ - $l3$ & 340 \\ - $h1$ & 270 \\ - $h2$ & 250 \\ - $h3$ & 380 \\ - $r1$ & 370 \\ - $r2$ & 390 \\ - \hline - \multicolumn{2}{l}{$^{a}$Footnote text here.} - \end{tabular} - \end{table} - -AGU prefers the use of {sidewaystable} over {landscapetable} as it causes fewer problems. - -```{r, fig.env = "sidewaysfigure"} +\caption{Time of the Transition Between Phase 1 and Phase 2$^{a}$} +\centering +\begin{tabular}{l c} +\hline +Run & Time (min) \\ +\hline +$l1$ & 260 \\ +$l2$ & 300 \\ +$h1$ & 270 \\ +$h2$ & 250 \\ +\hline +\multicolumn{2}{l}{$^{a}$Footnote text here.} +\end{tabular} +\end{table} +``` + +AGU prefers `sidewaystable` to `landscapetable` for wide tables. + +```{r sideways-figure, fig.env='sidewaysfigure'} plot(pressure) ``` +```{=latex} \begin{sidewaystable} -\caption{Caption here} -\label{tab:signif_gap_clos} +\caption{An Example Sideways Table} +\label{tab:sideways} \begin{tabular}{ccc} -one&two&three\\ -four&five&six +one & two & three \\ +four & five & six \end{tabular} \end{sidewaystable} +``` -If using numbered lines, please surround equations with \\begin{linenomath\*}... \\end{linenomath\*} +When using line numbers, surround equations with `linenomath*`. +```{=latex} \begin{linenomath*} \begin{equation} -y|{f} \sim g(m, \sigma) +y \mid f \sim g(m, \sigma) \end{equation} \end{linenomath*} +``` # Conclusions -\appendix -\section{Here is a sample appendix} - -Optional Appendix goes here +Summarize the conclusions and their limitations. -Optional Glossary, Notation or Acronym section goes here: +```{=latex} +\appendix +\section{Sample Appendix} +\label{app:sample} -Glossary is only allowed in Reviews of Geophysics +Appendix sections, equations, figures, and tables use letter-prefixed numbering. -\begin{glossary} -\term{Term} - Term Definition here -\term{Term} - Term Definition here -\term{Term} - Term Definition here -\end{glossary} +\begin{equation} +1 + 1 = 2 +\label{eq:appendix} +\end{equation} +\begin{figure} +\centering +\rule{2cm}{1cm} +\caption{An appendix figure.} +\label{fig:appendix} +\end{figure} -\begin{acronyms} -\acro{Acronym} - Definition here -\acro{EMOS} - Ensemble model output statistics -\acro{ECMWF} - Centre for Medium-Range Weather Forecasts -\end{acronyms} +\begin{table} +\caption{An appendix table.} +\label{tab:appendix} +\centering +\begin{tabular}{lc} +Item & Value \\ +A & 1 +\end{tabular} +\end{table} +``` -\begin{notation} -\notation{$a+b$} Notation Definition here -\notation{$e=mc^2$} -Equation in German-born physicist Albert Einstein's theory of special -relativity that showed that the increased relativistic mass ($m$) of a -body comes from the energy of motion of the body—that is, its kinetic -energy ($E$)—divided by the speed of light squared ($c^2$). -\end{notation} +```{=latex} +\section*{Open Research} +``` +State where the data, software, notebooks, and other research objects supporting the conclusions can be accessed. Cite archived research objects in the reference list; “available from the authors” is not sufficient. -\acknowledgments -The acknowledgments must list: -A statement that indicates to the reader where the data -supporting the conclusions can be obtained (for example, in the -references, tables, supporting information, and other databases). +```{=latex} +\section*{Inclusion in Global Research Statement} +``` -All funding sources related to this work from all authors +If applicable, describe ethical and scientific considerations for international or community-based collaborations, including relevant permits, agreements, local contributions, and end users. Remove this optional section when it does not apply. -Any real or perceived financial conflicts of interests for any author +```{=latex} +\section*{Conflict of Interest Disclosure} +``` -Other affiliations for any author that may be perceived as having a conflict of -interest with respect to the results of this paper. +The authors declare no conflicts of interest relevant to this manuscript. -It is also the appropriate place to thank colleagues and other contributors. +```{=latex} +\acknowledgments +``` -AGU does not normally allow dedications. +Acknowledge funding, colleagues, contributors, and secondary affiliations here. Place acknowledgments after the main text and disclosure sections but before the bibliography. AGU does not normally allow dedications. diff --git a/man/article.Rd b/man/article.Rd index 3fdcb524..483a33b4 100644 --- a/man/article.Rd +++ b/man/article.Rd @@ -49,7 +49,7 @@ aea_article(..., keep_tex = TRUE, md_extensions = c("-autolink_bare_uris")) agu_article( ..., keep_tex = TRUE, - citation_package = "natbib", + citation_package = "default", highlight = NULL, md_extensions = c("-autolink_bare_uris", "-auto_identifiers") ) @@ -201,9 +201,20 @@ Economic Association (AER, AEJ, JEL, PP). } \section{\code{agu_article}}{ - Format for creating a American Geophysical Union -(AGU) article. Adapted from -\url{https://www.agu.org/publications}. + Format for creating an American Geophysical Union +(AGU) article. Adapted from AGU's September 2025 LaTeX distribution of +\code{agujournal2019.cls} and the official \href{https://www.agu.org/publications/authors/journals/latex-submissions}{LaTeX submission guidelines}. + +The default \code{citation_package = "default"} uses Pandoc citeproc with +the American Geophysical Union CSL style, following the approach used by +the Quarto AGU journal format. Use Markdown citation syntax in current +drafts. + +New drafts include \code{agujournal2019.cls}. Existing drafts that retain only +a project-local \code{agujournal2018.cls} remain supported but must explicitly +set \code{citation_package = "natbib"}. The format warns when the selected +class and citation backend are incompatible. If both classes are present, +the current 2019 class is used. } \section{\code{amq_article}}{ diff --git a/inst/rmarkdown/templates/agu/skeleton/agujournal2018.cls b/tests/testit/fixtures/agujournal2018.cls similarity index 100% rename from inst/rmarkdown/templates/agu/skeleton/agujournal2018.cls rename to tests/testit/fixtures/agujournal2018.cls diff --git a/tests/testit/helper-agu.R b/tests/testit/helper-agu.R new file mode 100644 index 00000000..99d9f858 --- /dev/null +++ b/tests/testit/helper-agu.R @@ -0,0 +1,190 @@ +agu_fixture <- function(...) { + test_root <- getOption("testit.test_dir") + stopifnot(length(test_root) == 1) + + paths <- file.path( + test_root, + c("testit/fixtures", "tests/testit/fixtures"), + ... + ) + path <- paths[file.exists(paths)] + stopifnot(length(path) == 1) + path +} + +prepare_agu_multiple_bibliographies <- function(path) { + rmd <- xfun::read_utf8(path) + bibliography <- grepl("^bibliography: agutest[.]bib$", rmd) + stopifnot(sum(bibliography) == 1) + rmd <- append( + rmd[-which(bibliography)], + c( + "bibliography:", + " - agutest.bib", + " - aguadditional.bib" + ), + after = which(bibliography) - 1 + ) + xfun::write_utf8( + c( + rmd, + "", + "An additional source is included [@Additional2026]." + ), + path + ) + xfun::write_utf8( + c( + "@article{Additional2026,", + " author = {Additional, Ada},", + " title = {An Additional Bibliography},", + " journal = {Journal of Tests},", + " year = {2026},", + " volume = {1},", + " pages = {1--2}", + "}" + ), + "aguadditional.bib" + ) +} + +prepare_agu_legacy <- function(path) { + xfun::write_utf8( + c( + "---", + 'journal: "JGR: Atmospheres"', + 'classoption: "draft,linenumbers"', + 'title: "Legacy AGU Draft"', + "authors:", + " - name: Legacy Author", + " affil: 1", + "affiliations:", + " - number: 1", + ' name: "Legacy University"', + "corresponding_author:", + " - name: Legacy Author", + " email: legacy@example.org", + "keypoints:", + ' - "This draft retains its project-local 2018 class."', + 'abstract: "A genuine legacy-class compatibility render."', + "output:", + " rticles::agu_article:", + " citation_package: natbib", + "bibliography: agutest.bib", + "---", + "", + "# Introduction", + "", + "A legacy textual citation uses \\citet{Levitus2012}.", + "A legacy parenthetical citation uses \\citep[see][p.~3]{Nuncio2011}.", + "", + "```{=latex}", + "\\begin{table}", + "\\caption{Legacy table compatibility}", + "\\centering", + "\\begin{tabular}{lc}", + "Item & Value \\\\", + "Legacy & 2018", + "\\end{tabular}", + "\\end{table}", + "```" + ), + path + ) + + stopifnot(file.remove("agujournal2019.cls")) + stopifnot(file.copy( + agu_fixture("agujournal2018.cls"), + "agujournal2018.cls" + )) +} + +retain_agu_latex_artifacts <- function(output_file) { + tex <- sub("[.]pdf$", ".tex", output_file) + tinytex::latexmk(tex, engine = "pdflatex", clean = FALSE) +} + +read_agu_artifact <- function(output_file, extension) { + path <- sub("[.]pdf$", extension, output_file) + stopifnot(file.exists(path)) + xfun::read_utf8(path) +} + +validate_agu_current <- function(output_file, path) { + retain_agu_latex_artifacts(output_file) + tex <- read_agu_artifact(output_file, ".tex") + aux <- read_agu_artifact(output_file, ".aux") + log <- read_agu_artifact(output_file, ".log") + + assert("current draft retains only the 2019 class branch", { + class_lines <- grep("^\\\\documentclass", tex, value = TRUE) + length(class_lines) == 1 && + grepl("{agujournal2019}", class_lines, fixed = TRUE) && + !grepl("{agujournal2018}", class_lines, fixed = TRUE) + }) + assert("current draft loads agujournal2019", { + any(grepl("Document Class: agujournal2019", log, fixed = TRUE)) + }) + assert("citeproc renders Markdown citations without natbib commands", { + all(c( + any(grepl("Levitus", tex, fixed = TRUE)), + any(grepl("Nuncio", tex, fixed = TRUE)), + !any(grepl("\\citep", tex, fixed = TRUE)), + !any(grepl("\\citet", tex, fixed = TRUE)) + )) + }) + assert("citeproc emits one reference list without BibTeX", { + sum(grepl("\\begin{CSLReferences}", tex, fixed = TRUE)) == 1 && + !any(grepl("\\bibliography{", tex, fixed = TRUE)) + }) + assert("track changes compile through the 2019 setup", { + any(grepl("\\add{an example tracked addition}", tex, fixed = TRUE)) + }) + assert("appendix counters use AGU letter prefixes", { + all(c( + any(grepl("newlabel{eq:appendix}{{A1}", aux, fixed = TRUE)), + any(grepl("newlabel{fig:appendix}{{A1}", aux, fixed = TRUE)), + any(grepl("newlabel{tab:appendix}{{A1}", aux, fixed = TRUE)) + )) + }) +} + +validate_agu_multiple_bibliographies <- function(output_file, path) { + retain_agu_latex_artifacts(output_file) + tex <- read_agu_artifact(output_file, ".tex") + + assert("citeproc includes references from multiple bibliography files", { + sum(grepl("\\begin{CSLReferences}", tex, fixed = TRUE)) == 1 && + any(grepl("An Additional Bibliography", tex, fixed = TRUE)) && + !any(grepl("\\bibliography{", tex, fixed = TRUE)) + }) +} + +validate_agu_legacy <- function(output_file, path) { + retain_agu_latex_artifacts(output_file) + tex <- read_agu_artifact(output_file, ".tex") + log <- read_agu_artifact(output_file, ".log") + + assert("legacy draft retains only the 2018 class branch", { + class_lines <- grep("^\\\\documentclass", tex, value = TRUE) + length(class_lines) == 1 && + grepl("{agujournal2018}", class_lines, fixed = TRUE) && + !grepl("{agujournal2019}", class_lines, fixed = TRUE) + }) + assert("legacy draft loads its local agujournal2018 class", { + any(grepl("Document Class: agujournal2018", log, fixed = TRUE)) + }) + assert("legacy natbib citations remain unchanged", { + all(c( + any(grepl("\\citet{Levitus2012}", tex, fixed = TRUE)), + any(grepl("\\citep[see][p.~3]{Nuncio2011}", tex, fixed = TRUE)) + )) + }) + assert("legacy draft explicitly selects natbib", { + any(grepl( + "citation_package: natbib", + xfun::read_utf8(path), + fixed = TRUE + )) + }) +} diff --git a/tests/testit/test-formats.R b/tests/testit/test-formats.R index 6687f259..0033c01d 100644 --- a/tests/testit/test-formats.R +++ b/tests/testit/test-formats.R @@ -60,6 +60,17 @@ test_format("acm") test_format("acs") test_format("aea") test_format("agu") +test_format("agu", validate = validate_agu_current) +test_format( + "agu", + transform = prepare_agu_multiple_bibliographies, + validate = validate_agu_multiple_bibliographies +) +test_format( + "agu", + transform = prepare_agu_legacy, + validate = validate_agu_legacy +) test_format("ajs", skip = !rmarkdown::pandoc_available("2.8")) test_format("amq") test_format("ams", skip = !rmarkdown::pandoc_available("2.10")) diff --git a/tests/testthat/test-agu_article.R b/tests/testthat/test-agu_article.R new file mode 100644 index 00000000..f96fb752 --- /dev/null +++ b/tests/testthat/test-agu_article.R @@ -0,0 +1,176 @@ +agu_pre_processor_args <- function(format, input_file, metadata = list()) { + format$pre_processor( + metadata = metadata, + input_file = input_file, + runtime = "static", + knit_meta = list(), + files_dir = NULL, + output_dir = dirname(input_file) + ) +} + +test_that("agu_article() uses citeproc by default", { + expect_identical(formals(agu_article)$citation_package, "default") +}) + +test_that("agu_article() supports natbib with a legacy local class", { + skip_if_not_pandoc("2.8") + withr::local_options(rticles.warn_agu_2018 = NULL) + article_dir <- withr::local_tempdir() + xfun::write_utf8("", file.path(article_dir, "agujournal2018.cls")) + format <- agu_article(citation_package = "natbib") + + expect_warning( + args <- agu_pre_processor_args( + format, + file.path(article_dir, "article.Rmd") + ), + regexp = "agujournal2018[.]cls.*backward compatibility" + ) + expect_no_warning( + agu_pre_processor_args(format, file.path(article_dir, "article.Rmd")) + ) + expect_false("rticles-agu-2019" %in% args) + expect_false("--csl" %in% args) +}) + +test_that("agu_article() warns once for citeproc with a legacy class", { + skip_if_not_pandoc("2.8") + withr::local_options(rticles.warn_agu_2018_citations = NULL) + article_dir <- withr::local_tempdir() + xfun::write_utf8("", file.path(article_dir, "agujournal2018.cls")) + format <- agu_article() + + expect_warning( + args <- agu_pre_processor_args( + format, + file.path(article_dir, "article.Rmd") + ), + regexp = "agujournal2018[.]cls.*expects.*natbib.*default.*unsupported" + ) + expect_no_warning( + agu_pre_processor_args(format, file.path(article_dir, "article.Rmd")) + ) + expect_false("rticles-agu-2019" %in% args) + expect_true("--csl" %in% args) +}) + +test_that("agu_article() warns once for natbib with the current class", { + skip_if_not_pandoc("2.8") + withr::local_options(rticles.warn_agu_2019_citations = NULL) + article_dir <- withr::local_tempdir() + xfun::write_utf8("", file.path(article_dir, "agujournal2019.cls")) + format <- agu_article(citation_package = "natbib") + + expect_warning( + args <- agu_pre_processor_args( + format, + file.path(article_dir, "article.Rmd") + ), + regexp = "2019 AGU class.*default.*natbib.*unsupported" + ) + expect_no_warning( + agu_pre_processor_args(format, file.path(article_dir, "article.Rmd")) + ) + expect_true("rticles-agu-2019" %in% args) + expect_false("--csl" %in% args) +}) + +test_that("agu_article() selects the current class when both are present", { + skip_if_not_pandoc("2.8") + withr::local_options(rticles.warn_agu_both_classes = NULL) + article_dir <- withr::local_tempdir() + xfun::write_utf8("", file.path(article_dir, "agujournal2018.cls")) + xfun::write_utf8("", file.path(article_dir, "agujournal2019.cls")) + format <- agu_article() + + expect_warning( + args <- agu_pre_processor_args( + format, + file.path(article_dir, "article.Rmd") + ), + regexp = "both.*will use 'agujournal2019[.]cls'.*remove" + ) + expect_no_warning( + agu_pre_processor_args(format, file.path(article_dir, "article.Rmd")) + ) + expect_true("rticles-agu-2019" %in% args) + expect_true("--csl" %in% args) +}) + +test_that("agu_article() supplies the AGU CSL unless metadata overrides it", { + skip_if_not_pandoc("2.8") + article_dir <- withr::local_tempdir() + input <- file.path(article_dir, "article.Rmd") + format <- agu_article() + + expect_no_warning(args <- agu_pre_processor_args(format, input)) + csl_arg <- match("--csl", args) + expect_false(is.na(csl_arg)) + expect_match(args[csl_arg + 1], "american-geophysical-union[.]csl$") + + expect_no_warning( + args <- agu_pre_processor_args( + format, + input, + metadata = list(csl = "custom.csl") + ) + ) + expect_false("--csl" %in% args) +}) + +test_that("AGU template selects classes without a natbib bridge", { + template <- xfun::read_utf8(find_resource("agu")) + template <- paste(template, collapse = "\n") + + expect_match( + template, + "(?s)\\$if\\(rticles-agu-2019\\)\\$.*agujournal2019.*\\$else\\$.*agujournal2018.*\\$endif\\$", + perl = TRUE + ) + expect_no_match( + template, + "\\\\IfFileExists\\{agujournal2019[.]cls\\}|agujournalTwentyNineteen" + ) + expect_no_match(template, "PassOptionsToPackage\\{natbibapa\\}\\{apacite\\}") + expect_no_match(template, "agu@@@cite|agu@@@citeA") + expect_match(template, "usepackage\\[inline\\]\\{trackchanges\\}") + expect_match(template, "\\$if\\(natbib\\)\\$\\$if\\(bibliography\\)\\$") +}) + +test_that("AGU template supports citeproc anchors and current keypoint guidance", { + template <- xfun::read_utf8(find_resource("agu")) + template <- paste(template, collapse = "\n") + + expect_match( + template, + "\\providecommand{\\hypertarget}[2]{#2}", + fixed = TRUE + ) +}) + +test_that("AGU citeproc style is bundled", { + csl <- xfun::read_utf8( + pkg_file_template("agu", "skeleton", "american-geophysical-union.csl") + ) + csl <- paste(csl, collapse = "\n") + + expect_match(csl, "American Geophysical Union", fixed = TRUE) + expect_match(csl, "citation-format=\"author-date\"", fixed = TRUE) + expect_match(csl, "creativecommons.org/licenses/by-sa/3.0", fixed = TRUE) +}) + +test_that("vendored AGU class is official 2019 with the table guard", { + class <- xfun::read_utf8( + pkg_file_template("agu", "skeleton", "agujournal2019.cls") + ) + class <- paste(class, collapse = "\n") + + expect_match(class, "\\\\def\\\\currversion\\{April 16, 2019\\}") + expect_match(class, "\\\\ProvidesClass\\{agujournal2019\\}") + expect_match( + class, + "\\\\ifdefined\\\\vcenter@text\\\\vcenter@text\\\\else\\\\vcenter\\\\fi" + ) + expect_no_match(class, "agujournal2018") +})