├── .gitignore ├── .nojekyll ├── .quartoignore ├── CITATION.cff ├── LICENSE ├── Makefile ├── README.md ├── README.qmd ├── _extensions └── apaquarto │ ├── ORCID-iD_icon-vector.svg │ ├── _apa_title.qmd │ ├── _extension.yml │ ├── apa.csl │ ├── apa.css │ ├── apa.scss │ ├── apaafternote.lua │ ├── apaandcite.lua │ ├── apaappendixlatex.lua │ ├── apacaption.lua │ ├── apaciteappendix.lua │ ├── apaextractfigure.lua │ ├── apafgtb.lua │ ├── apafigtblappendix.lua │ ├── apafigurewidthlatex.lua │ ├── apafloat.lua │ ├── apafloatlatex.lua │ ├── apafloatstoend.lua │ ├── apaheader.lua │ ├── apalanguage.lua │ ├── apamasked.lua │ ├── apanote.lua │ ├── apanotelatex.lua │ ├── apaomitrefsdiv.lua │ ├── apaoneauthoraffiliation.lua │ ├── apaquarto.docx │ ├── apaquarto.md │ ├── apaquote.lua │ ├── apastriptitle.lua │ ├── apatemplate.tex │ ├── apatwocolumnlatex.lua │ ├── before-body.tex │ ├── citeprocr.lua │ ├── crossrefprefix.lua │ ├── doc-class.tex │ ├── docxlinenumber.lua │ ├── docxstyler.lua │ ├── frontmatter.lua │ ├── header.tex │ ├── journalmode.lua │ ├── latexnoindent.lua │ ├── markdowntable.lua │ ├── styles.css │ ├── title-block.html │ ├── title.tex │ ├── typst │ ├── formattypst.lua │ ├── typst-show.typ │ └── typst-template.typ │ └── wordcount.lua ├── _quarto.yml ├── apa-cv.csl ├── apa.csl ├── apaquarto.Rproj ├── apaquarto.scss ├── bibliography.bib ├── changelog.qmd ├── docs ├── .nojekyll ├── changelog.html ├── example_journal.pdf ├── example_manuscript.pdf ├── img │ ├── console.png │ ├── insertchunk.png │ ├── keyboardwithbacktick.jpeg │ ├── menuworkingdirectory.png │ ├── newquartodocument.png │ └── terminal.png ├── index.html ├── installation.html ├── options.html ├── resources.html ├── sampleimage.png ├── search.json ├── site_libs │ ├── bootstrap │ │ ├── bootstrap-6df5d5a5ee0e45f2903de4150438d49a.min.css │ │ ├── bootstrap-icons.css │ │ └── bootstrap.min.js │ ├── clipboard │ │ └── clipboard.min.js │ ├── quarto-contrib │ │ ├── glightbox │ │ │ ├── glightbox.min.css │ │ │ ├── glightbox.min.js │ │ │ └── lightbox.css │ │ └── kbd │ │ │ ├── kbd.css │ │ │ └── kbd.js │ ├── quarto-html │ │ ├── anchor.min.js │ │ ├── popper.min.js │ │ ├── quarto-syntax-highlighting-81b5c3e63835cfde897ecd3d35a35a41.css │ │ ├── quarto.js │ │ ├── tippy.css │ │ └── tippy.umd.min.js │ ├── quarto-nav │ │ ├── headroom.min.js │ │ └── quarto-nav.js │ ├── quarto-search │ │ ├── autocomplete.umd.js │ │ ├── fuse.min.js │ │ └── quarto-search.js │ └── tabwid-1.1.3 │ │ ├── tabwid.css │ │ └── tabwid.js ├── writing.html └── writing_files │ └── figure-html │ ├── fig-myplot-1.png │ ├── fig-myplot2-1.png │ └── fig-myplot3-1.png ├── example.qmd ├── example_journal.pdf ├── example_manuscript.pdf ├── img ├── console.png ├── cover.png ├── docx.png ├── insertchunk.png ├── journalmode.png ├── keyboardwithbacktick.jpeg ├── menuworkingdirectory.png ├── newquartodocument.png ├── terminal.png └── yamlmetadata.png ├── index.qmd ├── installation.qmd ├── options.qmd ├── references.bib ├── resources.qmd ├── sampleimage.png ├── site_libs ├── bootstrap │ ├── bootstrap-6df5d5a5ee0e45f2903de4150438d49a.min.css │ ├── bootstrap-icons.css │ ├── bootstrap-icons.woff │ └── bootstrap.min.js ├── clipboard │ └── clipboard.min.js ├── quarto-contrib │ ├── glightbox │ │ ├── glightbox.min.css │ │ ├── glightbox.min.js │ │ └── lightbox.css │ └── kbd │ │ ├── kbd.css │ │ └── kbd.js ├── quarto-html │ ├── anchor.min.js │ ├── popper.min.js │ ├── quarto-syntax-highlighting-81b5c3e63835cfde897ecd3d35a35a41.css │ ├── quarto.js │ ├── tippy.css │ └── tippy.umd.min.js ├── quarto-nav │ ├── headroom.min.js │ └── quarto-nav.js ├── quarto-search │ ├── autocomplete.umd.js │ ├── fuse.min.js │ └── quarto-search.js └── tabwid-1.1.3 │ ├── tabwid.css │ └── tabwid.js ├── template.qmd └── writing.qmd /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .httr-oauth 3 | .Rdata 4 | .Rhistory 5 | .Rproj.user 6 | /.luarc.json 7 | /.quarto/ 8 | apa_processed.docx 9 | asdf* 10 | example.html 11 | example.docx 12 | example.pdf 13 | example.aux 14 | example.bbl 15 | example.rmarkdown 16 | example.ttt 17 | example.fff 18 | example.log 19 | example.tex 20 | example.typ 21 | example-pdf-man.pdf 22 | example_files/ 23 | Features.html 24 | minimal.docx 25 | minimal.html 26 | minimal.pdf 27 | minimal.tex 28 | minimal.ttt 29 | minimal_files/ 30 | NEWS.html 31 | README.qmd 32 | tempate.docx.docx 33 | template.aux 34 | template.bbl 35 | template.docx 36 | template.docx.md 37 | template.fff 38 | template.html 39 | template.log 40 | template.md 41 | template.native 42 | template.pdf 43 | template.pdf.md 44 | template.pdf.native 45 | template.rmarkdown 46 | template.ttt 47 | template.tex 48 | template.out 49 | template_files/ 50 | test.* 51 | test_* 52 | test_files/ 53 | testdocs.R 54 | try* 55 | lorem.bib 56 | apa.csl 57 | *.pptx 58 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/.nojekyll -------------------------------------------------------------------------------- /.quartoignore: -------------------------------------------------------------------------------- 1 | _quarto.yml 2 | apa.csl 3 | apa-cv.csl 4 | apaquarto.Rproj 5 | apaquarto.scss 6 | changelog.qmd 7 | CITATION.cff 8 | example.html 9 | example_files/ 10 | docs 11 | index.qmd 12 | img/ 13 | img/sample_image 14 | img/console.png 15 | img/cover.png 16 | img/docx.png 17 | img/insertchunk.png 18 | img/journalmode.png 19 | img/keyboardwithbacktick.jpeg 20 | img/menuworkingdirectory.png 21 | img/newquartodocument.png 22 | img/yamlmetadata.png 23 | img/terminal.png 24 | installation.qmd 25 | Makefile 26 | options.qmd 27 | README.qmd 28 | references.bib 29 | resources.qmd 30 | template.pdf 31 | example_journal.pdf 32 | example_manuscript.pdf 33 | example-pdf-man.pdf 34 | template_journal.pdf 35 | template_manuscript.pdf 36 | template.rmarkdown 37 | template.tex 38 | writing.qmd 39 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # This CITATION.cff file was generated with cffinit. 2 | # Visit https://bit.ly/cffinit to generate yours today! 3 | 4 | cff-version: 1.2.0 5 | title: apaquarto 6 | message: >- 7 | If you use this software, please cite it using the 8 | metadata from this file. 9 | type: software 10 | authors: 11 | - given-names: William Joel 12 | family-names: Schneider 13 | email: w.joel.schneider@gmail.com 14 | affiliation: Temple University 15 | orcid: 'https://orcid.org/0000-0002-8393-5316' 16 | repository-code: 'https://github.com/wjschne/apaquarto' 17 | url: 'https://wjschne.github.io/apaquarto/' 18 | abstract: >- 19 | A quarto extension for creating APA7 documents in .docx, 20 | .html, and .pdf formats 21 | keywords: 22 | - APA-Style 23 | - Quarto Extension 24 | license: CC0-1.0 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE = example.qmd 2 | 3 | all: pdf typst docx 4 | 5 | pdf: pdf-man pdf-doc pdf-jou 6 | typst: typst-man typst-doc typst-jou 7 | 8 | pdf-man: $(SOURCE) 9 | quarto render $< --to apaquarto-pdf \ 10 | --output example-$@.pdf \ 11 | -M documentmode:man 12 | 13 | pdf-doc: $(SOURCE) 14 | quarto render $< --to apaquarto-pdf \ 15 | --output example-$@.pdf \ 16 | -M documentmode:doc 17 | 18 | pdf-jou: $(SOURCE) 19 | quarto render $< --to apaquarto-pdf \ 20 | --output example-$@.pdf \ 21 | -M documentmode:jou 22 | 23 | docx: $(SOURCE) 24 | quarto render $< --to apaquarto-docx \ 25 | --output example-$@.docx 26 | 27 | typst-man: $(SOURCE) 28 | quarto render $< --to apaquarto-typst \ 29 | --output example-$@.pdf 30 | 31 | typst-doc: $(SOURCE) 32 | quarto render $< --to apaquarto-typst \ 33 | --output example-$@.pdf 34 | 35 | typst-jou: $(SOURCE) 36 | quarto render $< --to apaquarto-typst \ 37 | --output example-$@.pdf 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Quarto Extension for Creating APA 7 Style Documents 2 | 3 | 4 | any text: you like 5 | 6 | This article template creates [APA Style 7th Edition 7 | documents](https://apastyle.apa.org/) in .docx, .html. and .pdf. The 8 | .pdf format can be rendered via Latex (i.e., apaquarto-pdf) or via Typst 9 | (apaquarto-typst). The Typst output for this extension is still 10 | experimental and requires Quarto 1.5 or greater. 11 | 12 | Because the .docx format is still widely used—and often required—my main 13 | priority was to ensure compatibility for .docx. This is still a work in 14 | progress, and I encourage filing a “New Issue” on GitHub if something 15 | does not work of if there is a feature missing. 16 | 17 | See [instructions and template options for apaquarto 18 | here](https://wjschne.github.io/apaquarto/). 19 | 20 | [Version History](https://wjschne.github.io/apaquarto/changelog.html) 21 | 22 | ## Example Outputs 23 | 24 | The apaquarto-docx form looks like this: 25 | 26 | ![Preview of .docx output](img/docx.png) 27 | 28 | The .html and .pdf output (in manuscript mode) look similar. The .pdf in 29 | journal mode looks like this: 30 | 31 | ![Preview of .pdf output in journal mode](img/journalmode.png) 32 | 33 | ## Creating a New Article 34 | 35 | You can create a new article with apaquarto’s template file. There are 36 | two ways to do so. 37 | 38 | 1. Via the R console 39 | 2. Via the terminal 40 | 41 | If you are an R user, you might prefer the R console method. Anyone, 42 | including R users, can use the second method. 43 | 44 | ### Using R via the R Console 45 | 46 | If you are an R user, you can install extensions with the [quarto 47 | package](https://quarto-dev.github.io/quarto-r/) (version = 1.4 or 48 | higher). The quarto package is not Quarto itself, but it provides 49 | convenient functions to interact with Quarto. 50 | 51 | If the quarto package is not installed, you can can install it by 52 | running this code in the console: 53 | 54 | ``` r 55 | # latest release version 56 | install.packages("quarto") 57 | ``` 58 | 59 | Once the quarto package is installed, you can install a quarto extension 60 | template by setting your working directory to the folder where you want 61 | the template to be installed (e.g., `setwd("path/to/my/folder")`) and 62 | then running this: 63 | 64 | ``` r 65 | quarto::quarto_use_template("wjschne/apaquarto") 66 | ``` 67 | 68 | A prompt will ask if you trust the author (me) not to run malicious 69 | code. To proceed, answer `Yes` or just `Y`. 70 | 71 | ### Using the Terminal 72 | 73 | If you are not an R user, you can create a new article directly in the 74 | terminal. Navigate to the folder where you want to create your file 75 | (e.g., `cd path/to/my/folder`), and run this command: 76 | 77 | ``` bash 78 | quarto use template wjschne/apaquarto 79 | ``` 80 | 81 | In RStudio, the terminal is in a tab next to the console. If you cannot 82 | see a terminal tab next to the console, use the keyboard shortcut 83 | Alt-Shift-R to make a terminal appear. 84 | 85 | Entering the command above will prompt a question about whether you 86 | trust the author of the extension to not run malicious code. If you 87 | answer Yes, you will be prompted to name a new folder where the 88 | extension will be installed. 89 | 90 | ## Template file 91 | 92 | After installation, you will see a template file in the folder you 93 | select. The template file will have the same name as the folder you 94 | installed the template to and ends with `.qmd`. This file has most of 95 | the options already filled out and explains how and why to change them. 96 | It also has a examples of how to use the extension in the text. 97 | 98 | If you prefer a minimal template, you can start with the `minimal.qmd` 99 | file instead. 100 | 101 | ## Adding apaquarto to an Existing Document or Project 102 | 103 | You can add the apaquarto extension to an existing file or project in 104 | one of two ways: 105 | 106 | 1. Via the R console 107 | 2. Via the terminal 108 | 109 | ### Creating a New Document Via the R console 110 | 111 | If you are an R user, you can install extensions with the [quarto 112 | package](https://quarto-dev.github.io/quarto-r/) (version = 1.4 or 113 | higher). The quarto package is not Quarto itself, but it provides 114 | convenient functions to interact with Quarto. 115 | 116 | If the quarto package is not installed, you can can install it by 117 | running this code in the console: 118 | 119 | ``` r 120 | # latest release version 121 | install.packages("quarto") 122 | ``` 123 | 124 | In RStudio, open the project that contains the file to which you want to 125 | add apaquarto. If your file is not part of a project, set the working 126 | directory to the same folder as the file (e.g., 127 | `setwd("path/to/my/folder")`). 128 | 129 | Run this code in the console: 130 | 131 | ``` r 132 | quarto::quarto_use_template("wjschne/apaquarto") 133 | ``` 134 | 135 | ### Creating a New Document Via the Terminal 136 | 137 | To add this format to an existing document, navigate to the folder where 138 | the existing .qmd you wish to use and then run: 139 | 140 | ``` bash 141 | quarto add wjschne/apaquarto 142 | ``` 143 | 144 | ### Add apaquarto to the Document’s Metadata: 145 | 146 | You can select one of three formats: .docx, .pdf, or .html. When 147 | writing, I prefer to output to .html, because it renders quickly. Then I 148 | switch to .docx or .pdf, depending on where I need to submit the paper. 149 | 150 | You can add all of these formats or any combination of them: 151 | 152 | ``` yaml 153 | format: 154 | apaquarto-docx: default 155 | apaquarto-html: default 156 | apaquarto-pdf: default 157 | apaquarto-typst: default 158 | ``` 159 | 160 | Here is a minimal example of what the YAML metadata might look like: 161 | 162 | ``` yaml 163 | --- 164 | title: "My Paper's Title: A Full Analysis of Everything" 165 | shorttitle: "My Paper's Title" 166 | author: 167 | - name: W. Joel Schneider 168 | corresponding: true 169 | orcid: 0000-0002-8393-5316 170 | email: schneider@temple.edu 171 | affiliations: 172 | - name: Temple University 173 | department: College of Education and Human Development 174 | address: 1301 Cecil B. Moore Ave. 175 | city: Philadelphia 176 | region: PA 177 | postal-code: 19122-6091 178 | abstract: "This is my abstract." 179 | keywords: [keyword1, keyword2] 180 | author-note: 181 | disclosures: 182 | conflict of interest: The author has no conflict of interest to declare. 183 | bibliography: mybibfile.bib 184 | format: 185 | apaquarto-docx: default 186 | apaquarto-html: default 187 | apaquarto-pdf: default 188 | apaquarto-typst: default 189 | --- 190 | ``` 191 | 192 | ## Updating to the latest version of apaquarto 193 | 194 | In the terminal, run 195 | 196 | ``` bash 197 | quarto update wjschne/apaquarto 198 | ``` 199 | 200 | ## Removing apaquarto 201 | 202 | In the terminal, run 203 | 204 | ``` bash 205 | quarto remove wjschne/apaquarto 206 | ``` 207 | -------------------------------------------------------------------------------- /README.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "A Quarto Extension for Creating APA 7 Style Documents" 3 | format: gfm 4 | editor: source 5 | engine: knitr 6 | --- 7 | any text: you like 8 | 9 | This article template creates [APA Style 7th Edition documents](https://apastyle.apa.org/) in .docx, .html. and .pdf. The .pdf format can be rendered via Latex (i.e., apaquarto-pdf) or via Typst (apaquarto-typst). The Typst output for this extension is still experimental and requires Quarto 1.5 or greater. 10 | 11 | Because the .docx format is still widely used---and often required---my main priority was to ensure compatibility for .docx. This is still a work in progress, and I encourage filing a "New Issue" on GitHub if something does not work of if there is a feature missing. 12 | 13 | 14 | 15 | See [instructions and template options for apaquarto here](https://wjschne.github.io/apaquarto/). 16 | 17 | [Version History](https://wjschne.github.io/apaquarto/changelog.html) 18 | 19 | ## Example Outputs 20 | 21 | The apaquarto-docx form looks like this: 22 | 23 | ![Preview of .docx output](img/docx.png) 24 | 25 | The .html and .pdf output (in manuscript mode) look similar. The .pdf in journal mode looks like this: 26 | 27 | ![Preview of .pdf output in journal mode](img/journalmode.png) 28 | 29 | 30 | ## Creating a New Article 31 | 32 | You can create a new article with apaquarto's template file. There are two ways to do so. 33 | 34 | 1. Via the R console 35 | 2. Via the terminal 36 | 37 | If you are an R user, you might prefer the R console method. Anyone, including R users, can use the second method. 38 | 39 | 40 | 41 | ### Using R via the R Console 42 | 43 | If you are an R user, you can install extensions with the [quarto package](https://quarto-dev.github.io/quarto-r/) (version = 1.4 or higher). The quarto package is not Quarto itself, but it provides convenient functions to interact with Quarto. 44 | 45 | If the quarto package is not installed, you can can install it by running this code in the console: 46 | 47 | ```{r} 48 | #| eval: false 49 | # latest release version 50 | install.packages("quarto") 51 | ``` 52 | 53 | Once the quarto package is installed, you can install a quarto extension template by setting your working directory to the folder where you want the template to be installed (e.g., `setwd("path/to/my/folder")`) and then running this: 54 | 55 | ```{r} 56 | #| eval: false 57 | quarto::quarto_use_template("wjschne/apaquarto") 58 | ``` 59 | 60 | A prompt will ask if you trust the author (me) not to run malicious code. To proceed, answer `Yes` or just `Y`. 61 | 62 | 63 | 64 | ### Using the Terminal 65 | 66 | If you are not an R user, you can create a new article directly in the terminal. Navigate to the folder where you want to create your file (e.g., `cd path/to/my/folder`), and run this command: 67 | 68 | ``` bash 69 | quarto use template wjschne/apaquarto 70 | ``` 71 | 72 | In RStudio, the terminal is in a tab next to the console. If you cannot see a terminal tab next to the console, use the keyboard shortcut Alt-Shift-R to make a terminal appear. 73 | 74 | Entering the command above will prompt a question about whether you trust the author of the extension to not run malicious code. If you answer Yes, you will be prompted to name a new folder where the extension will be installed. 75 | 76 | ## Template file 77 | 78 | After installation, you will see a template file in the folder you select. The template file will have the same name as the folder you installed the template to and ends with `.qmd`. This file has most of the options already filled out and explains how and why to change them. It also has a examples of how to use the extension in the text. 79 | 80 | If you prefer a minimal template, you can start with the `minimal.qmd` file instead. 81 | 82 | ## Adding apaquarto to an Existing Document or Project 83 | 84 | You can add the apaquarto extension to an existing file or project in one of two ways: 85 | 86 | 1. Via the R console 87 | 2. Via the terminal 88 | 89 | ### Creating a New Document Via the R console 90 | 91 | If you are an R user, you can install extensions with the [quarto package](https://quarto-dev.github.io/quarto-r/) (version = 1.4 or higher). The quarto package is not Quarto itself, but it provides convenient functions to interact with Quarto. 92 | 93 | If the quarto package is not installed, you can can install it by running this code in the console: 94 | 95 | ```{r} 96 | #| eval: false 97 | # latest release version 98 | install.packages("quarto") 99 | ``` 100 | 101 | In RStudio, open the project that contains the file to which you want to add apaquarto. If your file is not part of a project, set the working directory to the same folder as the file (e.g., `setwd("path/to/my/folder")`). 102 | 103 | Run this code in the console: 104 | 105 | ```{r} 106 | #| eval: false 107 | quarto::quarto_use_template("wjschne/apaquarto") 108 | ``` 109 | 110 | ### Creating a New Document Via the Terminal 111 | 112 | To add this format to an existing document, navigate to the folder where the existing .qmd you wish to use and then run: 113 | 114 | ``` bash 115 | quarto add wjschne/apaquarto 116 | ``` 117 | 118 | ### Add apaquarto to the Document's Metadata: 119 | 120 | You can select one of three formats: .docx, .pdf, or .html. When writing, I prefer to output to .html, because it renders quickly. Then I switch to .docx or .pdf, depending on where I need to submit the paper. 121 | 122 | You can add all of these formats or any combination of them: 123 | 124 | ``` yaml 125 | format: 126 | apaquarto-docx: default 127 | apaquarto-html: default 128 | apaquarto-pdf: default 129 | apaquarto-typst: default 130 | ``` 131 | 132 | 133 | Here is a minimal example of what the YAML metadata might look like: 134 | 135 | ``` yaml 136 | --- 137 | title: "My Paper's Title: A Full Analysis of Everything" 138 | shorttitle: "My Paper's Title" 139 | author: 140 | - name: W. Joel Schneider 141 | corresponding: true 142 | orcid: 0000-0002-8393-5316 143 | email: schneider@temple.edu 144 | affiliations: 145 | - name: Temple University 146 | department: College of Education and Human Development 147 | address: 1301 Cecil B. Moore Ave. 148 | city: Philadelphia 149 | region: PA 150 | postal-code: 19122-6091 151 | abstract: "This is my abstract." 152 | keywords: [keyword1, keyword2] 153 | author-note: 154 | disclosures: 155 | conflict of interest: The author has no conflict of interest to declare. 156 | bibliography: mybibfile.bib 157 | format: 158 | apaquarto-docx: default 159 | apaquarto-html: default 160 | apaquarto-pdf: default 161 | apaquarto-typst: default 162 | --- 163 | ``` 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | ## Updating to the latest version of apaquarto 172 | 173 | In the terminal, run 174 | 175 | ``` bash 176 | quarto update wjschne/apaquarto 177 | ``` 178 | 179 | 180 | ## Removing apaquarto 181 | 182 | In the terminal, run 183 | 184 | ``` bash 185 | quarto remove wjschne/apaquarto 186 | ``` 187 | 188 | 189 | -------------------------------------------------------------------------------- /_extensions/apaquarto/ORCID-iD_icon-vector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 14 | 16 | 17 | -------------------------------------------------------------------------------- /_extensions/apaquarto/_extension.yml: -------------------------------------------------------------------------------- 1 | title: My Document in APA Style, Seventh Edition 2 | author: W. Joel Schneider 3 | version: 5.0.1 4 | quarto-required: ">=1.4.549" 5 | contributes: 6 | formats: 7 | common: 8 | execute: 9 | echo: false 10 | citeproc: false 11 | link-citations: true 12 | fig-cap-location: top 13 | tbl-cap-location: top 14 | cap-location: top 15 | csl: apa.csl 16 | toc: false 17 | fig-width: 6.5 18 | fig-height: 6.5 19 | crossref: 20 | subref-labels: alpha A 21 | suppress-title-page: false 22 | suppress-title-page-number: false 23 | suppress-title: false 24 | suppress-short-title: false 25 | suppress-author: false 26 | suppress-affiliation: false 27 | suppress-author-note: false 28 | suppress-orcid: false 29 | suppress-status-change-paragraph: false 30 | suppress-disclosures-paragraph: false 31 | suppress-credit-statement: false 32 | suppress-corresponding-paragraph: false 33 | suppress-corresponding-group: false 34 | suppress-corresponding-department: false 35 | suppress-corresponding-affiliation-name: false 36 | suppress-corresponding-address: false 37 | suppress-corresponding-city: false 38 | suppress-corresponding-region: false 39 | suppress-corresponding-postal-code: false 40 | suppress-corresponding-email: false 41 | suppress-abstract: false 42 | suppress-impact-statement: false 43 | suppress-keywords: false 44 | suppress-title-introduction: false 45 | no-ampersand-parenthetical: false 46 | language: 47 | citation-last-author-separator: "and" 48 | citation-masked-author: "Masked Author" 49 | citation-masked-title: "Masked Title" 50 | citation-masked-date: "n.d." 51 | email: "Email" 52 | figure-table-note: "Note" 53 | title-block-author-note: "Author Note" 54 | title-block-correspondence-note: "Correspondence concerning this article should be addressed to" 55 | title-block-role-introduction: "Author roles were classified using the Contributor Role Taxonomy (CRediT; https://credit.niso.org/) as follows:" 56 | title-impact-statement: "Impact Statement" 57 | references-meta-analysis: "Las referencias marcadas con un asterisco indican estudios incluidos en el metanálisis." 58 | filters: 59 | # Sets language defaults other than English 60 | - at: pre-ast 61 | path: apalanguage.lua 62 | # Prepare plain markdown tables to be used by crossrefprefix.lua 63 | - at: pre-ast 64 | path: markdowntable.lua 65 | # Give figures and tables appendix prefixes 66 | - at: pre-ast 67 | path: crossrefprefix.lua 68 | # Move figures and tables to end of document 69 | - at: pre-ast 70 | path: apafloatstoend.lua 71 | # Give error message to early versions of apaquarto 72 | - at: pre-ast 73 | path: apafgtb.lua 74 | # Set latex document mode 75 | - at: pre-ast 76 | path: journalmode.lua 77 | # Set latex images to column width by default 78 | - at: pre-ast 79 | path: apafigurewidthlatex.lua 80 | # Make apa-note an attribute of figure in latex 81 | - at: pre-ast 82 | path: apanotelatex.lua 83 | # Make appendices citable with apx prefix 84 | - at: pre-ast 85 | path: apaciteappendix.lua 86 | # Add a refs div if it was omitted. 87 | - at: pre-ast 88 | path: apaomitrefsdiv.lua 89 | - at: post-ast 90 | path: apamasked.lua 91 | - at: post-ast 92 | path: apatwocolumnlatex.lua 93 | - at: pre-quarto 94 | path: apaheader.lua 95 | - at: pre-quarto 96 | path: apastriptitle.lua 97 | - at: pre-quarto 98 | path: wordcount.lua 99 | - at: pre-quarto 100 | path: frontmatter.lua 101 | - at: pre-quarto 102 | path: apaquote.lua 103 | - at: pre-quarto 104 | path: latexnoindent.lua 105 | - at: pre-quarto 106 | path: apafigtblappendix.lua 107 | - at: post-quarto 108 | path: apafloatlatex.lua 109 | - at: post-quarto 110 | path: apaoneauthoraffiliation.lua 111 | - at: post-render 112 | path: apaextractfigure.lua 113 | - at: post-render 114 | path: apanote.lua 115 | - at: post-render 116 | path: apafloat.lua 117 | - at: post-render 118 | path: apacaption.lua 119 | - at: post-render 120 | path: apaafternote.lua 121 | - at: post-render 122 | path: citeprocr.lua 123 | - at: post-render 124 | path: apaandcite.lua 125 | - at: post-render 126 | path: apaappendixlatex.lua 127 | native: default 128 | html: 129 | toc: true 130 | toc-location: left 131 | anchor-sections: false 132 | fig-cap-location: top 133 | html-math-method: katex 134 | mainfont: Times, Times New Roman, serif 135 | grid: 136 | body-width: "7in" 137 | css: apa.css 138 | theme: 139 | - apa.scss 140 | template-partials: 141 | - title-block.html 142 | knitr: 143 | opts_chunk: 144 | dev: svglite 145 | pdf: 146 | documentclass: apa7 147 | pdf-engine: xelatex 148 | suppress-bibliography: false 149 | hyperrefoptions: 150 | - linktoc=none 151 | block-headings: false 152 | template: apatemplate.tex 153 | mainfontfallback: Arial 154 | template-partials: 155 | - doc-class.tex 156 | - title.tex 157 | - before-body.tex 158 | - header.tex 159 | classoption: "colorlinks=true,linkcolor=blue,citecolor=blue,urlcolor=blue" 160 | docx: 161 | reference-doc: apaquarto.docx 162 | filters: 163 | - at: post-quarto 164 | path: docxstyler.lua 165 | - at: post-render 166 | path: docxlinenumber.lua 167 | knitr: 168 | opts_chunk: 169 | dev: ragg_png 170 | typst: 171 | filters: 172 | - at: post-quarto 173 | path: typst/formattypst.lua 174 | template-partials: 175 | - typst/typst-template.typ 176 | - typst/typst-show.typ 177 | format-resources: 178 | - apa.csl 179 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apa.css: -------------------------------------------------------------------------------- 1 | body {line-height: 2em; font-size: 12pt} 2 | 3 | p {text-indent: 0.5in; margin: 0; line-height: 2em} 4 | div.Author p { 5 | text-indent: 0; 6 | } 7 | .FigureTitle {font-weight: bold; margin: 5pt 0; font-size: 12pt; color: black;} 8 | .FigureTitle p {text-indent: 0; text-align: left;} 9 | .FigureNote p {text-indent: 0; margin: 0; padding: 0} 10 | .Caption {font-style: italic; font-size: 12pt; color: black; text-align: left} 11 | .Caption p {text-indent: 0; font-size: 12pt;} 12 | .quarto-float, .quarto-float-tbl, .figure {margin: 0; margin-block-start: 0; margin-block-end: 0; margin-block-start: 0; margin-inline-start: 0; margin-inline-end: 0} 13 | 14 | h1, h2, h3, h4, h5 {border: none; margin: 0; padding: 0;line-height: 2; text-indent: 0 } 15 | 16 | h1 {text-align: center;} 17 | h3 {font-style: italic} 18 | h4 {font-weight: bold} 19 | 20 | h4, h5 { 21 | text-indent: 0.5in; 22 | display:inline-block; 23 | margin: 0 24 | } 25 | 26 | h5 { 27 | font-style: italic; 28 | } 29 | 30 | h4 + p, h5 + p { 31 | display:inline; 32 | text-indent: 0; 33 | } 34 | 35 | 36 | .Compact { 37 | line-height: 1em; 38 | text-indent: 0; 39 | margin: 0; 40 | } 41 | 42 | 43 | 44 | 45 | 46 | 47 | td p, th p, li p {text-indent: 0; margin: 0;} 48 | 49 | 50 | 51 | li p {text-indent: 0; margin: 0;} 52 | 53 | .subtitle {font-size: 12pt; text-align: center; color: #303030; font-weight: bold;} 54 | 55 | blockquote, .blockquote {border: none; margin: 0 .5in; padding: 0; font-style: normal; color: #303030;} 56 | 57 | .Author {text-align:center; text-indent: 0} 58 | 59 | .cell-output-display p {text-indent: 0} 60 | 61 | div.hanging-indent {margin-left: 0.5in; text-indent: -0.5in} 62 | 63 | div.hanging-indent .csl-entry {margin-left: 0; text-indent: -0.5in;} 64 | 65 | .katex {font-size: 1em;} 66 | .katex-display {font-size: 1.1em;} 67 | 68 | .NoIndent p {text-indent: 0} 69 | 70 | blockquote p:nth-child(1) {text-indent: 0} 71 | 72 | .table { 73 | border-top: 1px solid black; 74 | border-bottom: 1px solid black; 75 | } 76 | 77 | .table>thead { 78 | border-bottom: 1px solid black; 79 | } 80 | 81 | .table>:not(caption)>*>* { 82 | border-bottom: none; 83 | } 84 | 85 | .tabwid {padding: 0} 86 | 87 | .AbstractFirstParagraph p {text-indent: 0} -------------------------------------------------------------------------------- /_extensions/apaquarto/apa.scss: -------------------------------------------------------------------------------- 1 | /*-- scss:defaults --*/ 2 | // Base document colors 3 | $body-bg: white; 4 | $body-color: #303030; 5 | $link-color: #75AADB; 6 | $font-size-root: 12pt; 7 | $bs-body-font-size: 1rem; 8 | $h1-font-size: $font-size-root !default; 9 | $h2-font-size: $font-size-root !default; 10 | $h3-font-size: $font-size-root !default; 11 | $h4-font-size: $font-size-root !default; 12 | $h5-font-size: $font-size-root !default; 13 | $table-striped-bg: #FFFFFF; 14 | // Code blocks 15 | $code-block-bg-alpha: -.8; 16 | 17 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apaafternote.lua: -------------------------------------------------------------------------------- 1 | -- Do not run on latex 2 | if FORMAT == "latex" then 3 | return 4 | end 5 | 6 | -- The spacing in paragraphs after a figure or table 7 | -- without a note makes a special style necessary. 8 | 9 | -- Set custom style in paragraph by setting it in a custom div 10 | local function makeafternote(p) 11 | div = pandoc.Div(p) 12 | div.classes:insert("AfterWithoutNote") 13 | div.attributes['custom-style'] = 'AfterWithoutNote' 14 | return div 15 | end 16 | 17 | 18 | function Pandoc(doc) 19 | local hblocks = {} 20 | local isfloatref = false 21 | 22 | -- Loop through all blocks in reverse 23 | for i = #doc.blocks - 1, 1, -1 do 24 | -- Look for a div followed by a paragraph 25 | if doc.blocks[i+1].t == "Para" and doc.blocks[i].t == "Div" then 26 | -- If the div is a figure or table without a note, 27 | -- set the paragraph's custom style to be AfterWithoutNote 28 | if (doc.blocks[i].attributes["custom-style"] == "FigureWithoutNote") or doc.blocks[i].identifier:find("^tbl%-") then 29 | doc.blocks[i+1] = makeafternote(doc.blocks[i+1]) 30 | end 31 | end 32 | end 33 | return pandoc.Pandoc(doc.blocks, doc.meta) 34 | end 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apaandcite.lua: -------------------------------------------------------------------------------- 1 | -- For now, apa.csl cannot handle different separators for in-text 2 | -- and parenthetical citations. Forthcoming updates to csl will handle 3 | -- them automatically. 4 | -- This filter finds in-text citations with multiple authors and converts 5 | -- the ampersand to "and" (or whatever separator specified in the yaml 6 | -- language field "citation-last-author-separator") 7 | 8 | -- This filter also implements possessive citations. For example: 9 | -- @schneider2021 ['s] primary findings were replicated in our study. 10 | -- becomes: 11 | -- Schneider's (2021) primary findings were replicated in our study. 12 | 13 | local andreplacement = "and" 14 | local makelinks = false 15 | local no_ampersand_parenthetical = false 16 | 17 | -- make string, if it exists, else return default 18 | local stringify = function(s, default) 19 | if s then 20 | s = pandoc.utils.stringify(s) 21 | else 22 | if default then 23 | s = default 24 | else 25 | s = "" 26 | end 27 | end 28 | return s 29 | end 30 | 31 | -- Get alternate separator, if it exists 32 | local function get_and(m) 33 | if m.language and m.language["citation-last-author-separator"] then 34 | andreplacement = stringify( 35 | m.language["citation-last-author-separator"], 36 | andreplacement) 37 | end 38 | if m["link-citations"] then 39 | makelinks = true 40 | end 41 | 42 | if m["no-ampersand-parenthetical"] then 43 | no_ampersand_parenthetical = true 44 | end 45 | end 46 | 47 | local function replace_and(ct) 48 | 49 | if ct.citations[1].mode == "AuthorInText" or no_ampersand_parenthetical then 50 | -- Replace ampersand 51 | ---Adapted from Samuel Dodson 52 | ---https://github.com/citation-style-language/styles/issues/3748#issuecomment-430871259 53 | ct.content = ct.content:walk { 54 | Str = function(s) 55 | if s.text == "&" then 56 | s.text = andreplacement 57 | end 58 | return s 59 | end 60 | } 61 | 62 | -- Make possessive citation if suffix = 's 63 | if ct.citations[1].suffix and #ct.citations[1].suffix > 0 then 64 | if ct.citations[1].suffix[1].text == "’s" or ct.citations[1].suffix[1].text == "'s" then 65 | if ct.content then 66 | local intLeftParen = 0 67 | for i, j in pairs(ct.content) do 68 | if j.tag == "Str" and string.find(j.text, "’s") then 69 | j.text = string.gsub(j.text, "’s", "") 70 | end 71 | if j.tag == "Str" and string.find(j.text, "%(") then 72 | intLeftParen = i 73 | end 74 | end 75 | if intLeftParen > 2 then 76 | ct.content[intLeftParen - 2].text = ct.content[intLeftParen - 2].text .. "’s" 77 | end 78 | end 79 | end 80 | end 81 | if FORMAT == "typst" then 82 | return ct.content 83 | else 84 | return ct 85 | end 86 | 87 | end 88 | if FORMAT == "typst" then 89 | return ct.content 90 | end 91 | end 92 | 93 | return { 94 | { Meta = get_and }, 95 | { Cite = replace_and } 96 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apaappendixlatex.lua: -------------------------------------------------------------------------------- 1 | -- This filter inserts the appendix macro in latex documents 2 | if FORMAT ~= "latex" then 3 | return 4 | end 5 | 6 | local afterrefs = false 7 | 8 | -- Word for appendix 9 | local appendixword = "Appendix" 10 | getappendixword = function(meta) 11 | if meta.language and meta.language["crossref-apx-prefix"] then 12 | appendixword = pandoc.utils.stringify(meta.language["crossref-apx-prefix"]) 13 | end 14 | end 15 | 16 | -- Count how many appendices there are 17 | local appendixcount = 0 18 | -- Count how many level 1 headers are in each appendix 19 | local appendixheadercount = {} 20 | 21 | 22 | 23 | local count_headers_in_appendix = function(h) 24 | -- Is the level 1 header an appendix? 25 | if h.level == 1 and h.content[1] and h.content[1].text == appendixword then 26 | appendixcount = appendixcount + 1 27 | appendixheadercount[appendixcount] = 0 28 | -- Is the level 1 header in an appendix? 29 | elseif appendixcount > 0 and h.level == 1 then 30 | appendixheadercount[appendixcount] = appendixheadercount[appendixcount] + 1 31 | end 32 | end 33 | 34 | 35 | -- Count how many appendices there are 36 | local appendixcount2 = 0 37 | 38 | local make_appendix = function(h) 39 | 40 | if h.level == 1 and h.content[1].text == appendixword then 41 | appendixcount2 = appendixcount2 + 1 42 | -- If this is the first appendix, then start the appendix section 43 | if appendixcount2 == 1 then 44 | -- If user did not supply an appendix title, then make a blank title 45 | if appendixheadercount[appendixcount2] == 0 then 46 | return {pandoc.RawBlock("latex", "\\appendix"), pandoc.RawBlock("latex", "\\section{}\\label{" .. h.identifier .. "}")} 47 | else 48 | return {pandoc.RawBlock("latex", "\\appendix")} 49 | end 50 | else 51 | -- If user did not supply an appendix title, then make a blank title 52 | if appendixheadercount[appendixcount2] == 0 then 53 | return pandoc.RawBlock("latex", "\\section{}\\label{" .. h.identifier .. "}") 54 | else 55 | return pandoc.RawBlock("latex", "") 56 | end 57 | end 58 | end 59 | end 60 | 61 | 62 | 63 | return { 64 | { Meta = getappendixword }, 65 | { Block = findappendixheader }, 66 | { Header = count_headers_in_appendix }, 67 | { Header = make_appendix } 68 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apacaption.lua: -------------------------------------------------------------------------------- 1 | -- Get names for Figure and Table in language specified in lang field 2 | local figureword = "Figure" 3 | local tableword = "Table" 4 | local labelnum = "" 5 | 6 | local function gettablefig(m) 7 | -- Get names for Figure and Table specified in language field 8 | if m.language then 9 | if m.language["crossref-fig-title"] then 10 | figureword = pandoc.utils.stringify(m.language["crossref-fig-title"]) 11 | end 12 | 13 | if m.language["crossref-tbl-title"] then 14 | tableword = pandoc.utils.stringify(m.language["crossref-tbl-title"]) 15 | end 16 | else 17 | 18 | end 19 | end 20 | 21 | 22 | -- Format caption 23 | local caption_formatter = function(p) 24 | -- If the paragraph content's first element is the figureword or tableword 25 | if p.content[1] and (p.content[1].text == figureword or p.content[1].text == tableword) then 26 | -- If the paragraph content's second element is a non-breaking space 27 | if p.content[2] and p.content[2].text == '\u{a0}' then 28 | -- If the paragraph content's fourth element is a colon 29 | if p.content[4] and p.content[4].text == ':' then 30 | local figuretitle = pandoc.Para({}) 31 | local figurecaption = pandoc.Para({}) 32 | 33 | local intStart = 0 34 | -- separate figure title from figure caption 35 | for i, v in ipairs(p.content) do 36 | -- Figure/table title 37 | if i > intStart and i < intStart + 4 then 38 | if i == 3 then 39 | -- Figure or table number 40 | v = pandoc.Str(labelnum) 41 | end 42 | figuretitle.content:extend({v}) 43 | end 44 | -- Figure/table caption 45 | if i > intStart + 5 then 46 | figurecaption.content:extend({v}) 47 | end 48 | end 49 | -- enclose figure/table title in a div with custom style 50 | local figuretitlediv = pandoc.Div(figuretitle) 51 | figuretitlediv.classes:insert("FigureTitle") 52 | figuretitlediv.attributes["custom-style"] = "FigureTitle" 53 | -- enclose figure/table caption in a div with custom style 54 | local figurecaptiondiv = pandoc.Div(figurecaption) 55 | figurecaptiondiv.classes:insert("Caption") 56 | figurecaptiondiv.attributes["custom-style"] = "Caption" 57 | return {figuretitlediv, figurecaptiondiv} 58 | end 59 | end 60 | end 61 | end 62 | 63 | local divcaption = function(div) 64 | if div.identifier:find("^tbl%-") or div.identifier:find("^fig%-") then 65 | 66 | -- Get figure/table prefix and number 67 | if div.attributes.prefix then 68 | if div.attributes.fignum then 69 | -- Have to remove subfigure letters if present 70 | labelnum = div.attributes.prefix .. string.match(div.attributes.fignum, "%d+") 71 | end 72 | if div.attributes.tblnum then 73 | labelnum = div.attributes.prefix .. string.match(div.attributes.tblnum, "%d+") 74 | end 75 | end 76 | 77 | if FORMAT == "html" then 78 | div.content = div.content:walk {Plain = caption_formatter} 79 | end 80 | if FORMAT == "docx" then 81 | -- Remove raw openxml from div 82 | div.content = div.content:walk {RawInline = function(ri) return {} end} 83 | div.content = div.content:walk {Para = caption_formatter} 84 | end 85 | return div 86 | end 87 | 88 | end 89 | 90 | return { 91 | {Meta = gettablefig}, 92 | {Div = divcaption} 93 | } 94 | 95 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apaciteappendix.lua: -------------------------------------------------------------------------------- 1 | 2 | local appendixcount = 0 3 | local app = {} 4 | local kAriaExpanded = "aria-expanded" 5 | local refhyperlinks = true 6 | -- Word for appendix 7 | local appendixword = "Appendix" 8 | 9 | getappendixword = function(meta) 10 | if meta.language and meta.language["crossref-apx-prefix"] then 11 | appendixword = pandoc.utils.stringify(meta.language["crossref-apx-prefix"]) 12 | end 13 | end 14 | 15 | local function cite_appendix(ct) 16 | 17 | 18 | local floatreftext 19 | 20 | --Is the citation a reference to a section? 21 | if #ct.citations == 1 and (string.find(ct.citations[1].id, "^sec%-") or string.find(ct.citations[1].id, "^apx%-")) and app[ct.citations[1].id] then 22 | 23 | 24 | 25 | -- Text for section reference 26 | if appendixcount == 1 then 27 | floatreftext = pandoc.Inlines({pandoc.Str(appendixword)}) 28 | else 29 | floatreftext = pandoc.Inlines({pandoc.Str(appendixword), pandoc.Str('\u{a0}'), pandoc.Str(app[ct.citations[1].id])}) 30 | end 31 | 32 | 33 | 34 | if floatreftext == nil then 35 | quarto.log.warning("Cannot find @" .. ct.citations[1].id) 36 | return floatreftext 37 | end 38 | if refhyperlinks then 39 | -- create link 40 | local reflink = pandoc.Link(floatreftext, "#" .. ct.citations[1].id) 41 | reflink.classes = {"quarto-xref"} 42 | reflink.attributes[kAriaExpanded] = "false" 43 | return reflink 44 | else 45 | return floatreftext 46 | end 47 | 48 | 49 | end 50 | 51 | 52 | 53 | 54 | 55 | end 56 | 57 | local function getappendix(h) 58 | if h.attr.attributes.appendixtitle then 59 | app[h.identifier] = h.attr.attributes.appendixtitle 60 | appendixcount = appendixcount + 1 61 | end 62 | 63 | end 64 | 65 | 66 | return { 67 | {Meta = getappendixword}, 68 | {Header = getappendix}, 69 | { Cite = cite_appendix } 70 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apaextractfigure.lua: -------------------------------------------------------------------------------- 1 | --- This filter only runs on docx format 2 | if FORMAT ~= "docx" then 3 | return 4 | end 5 | 6 | -- Quarto encloses tables and figures in a table environment 7 | -- This function removes that table environment 8 | function Table(tb) 9 | local mydivs = pandoc.List() 10 | tb:walk { 11 | Div = function(div) 12 | if div.identifier:find("^tbl%-") or div.identifier:find("^fig%-") then 13 | div.content = div.content:walk {RawInline = function(ri) return {} end} 14 | mydivs:insert(div) 15 | end 16 | end 17 | } 18 | if #mydivs > 0 then return mydivs end 19 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apafgtb.lua: -------------------------------------------------------------------------------- 1 | Str = function(str) 2 | if str.text:match("^{apafg%-") or str.text:match("^{apatb%-") then 3 | error("A previous version of this extension used the apafg- prefix for figure chunk labels and apatb- prefix for tables. Replace all instances of apafg- with the standard Quarto prefix fig-. Likewise, replace the non-standard apatb- prefix with the standard Quarto prefix tbl-. Also replace all text references to figures and tables using standard Quarto syntax. For example, {apafg-myplot} should now be @fig-myplot instead.") 4 | end 5 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apafigtblappendix.lua: -------------------------------------------------------------------------------- 1 | if FORMAT == "latex" then 2 | return 3 | end 4 | 5 | local i = 1 6 | local tbl = {} 7 | local fig = {} 8 | local app = {} 9 | local kAriaExpanded = "aria-expanded" 10 | -- Get names for Figure and Table in language specified in lang field 11 | local figureword = "Figure" 12 | local tableword = "Table" 13 | local appendixword = "Appendix" 14 | local refhyperlinks = true 15 | local appendixcount = 0 16 | 17 | local function gettablefig(m) 18 | -- Get names for Figure and Table specified in language field 19 | if m.language then 20 | if m.language["crossref-fig-title"] then 21 | figureword = pandoc.utils.stringify(m.language["crossref-fig-title"]) 22 | end 23 | 24 | if m.language["crossref-tbl-title"] then 25 | tableword = pandoc.utils.stringify(m.language["crossref-tbl-title"]) 26 | end 27 | 28 | if m.language and m.language["crossref-apx-prefix"] then 29 | appendixword = pandoc.utils.stringify(m.language["crossref-apx-prefix"]) 30 | end 31 | else 32 | 33 | end 34 | 35 | if m["ref-hyperlink"] == false then 36 | refhyperlinks = false 37 | end 38 | 39 | -- Create arrays with figure and table information 40 | while quarto._quarto.ast.custom_node_data[tostring(i)] do 41 | float = quarto._quarto.ast.custom_node_data[tostring(i)] 42 | --Is the float a table? 43 | if float.identifier and string.find(float.identifier, "^tbl%-") then 44 | -- is the table already in the array? 45 | if tbl[float.identifier] then 46 | -- Table is already in the array. Do not add. 47 | else 48 | --Add table to array 49 | tbl[float.identifier] = float.attributes.prefix .. float.attributes.tblnum 50 | end 51 | end 52 | --Is the float a figure? 53 | if float.identifier and string.find(float.identifier, "^fig%-") then 54 | -- is the figure already in the array? 55 | if fig[float.identifier] then 56 | -- Figure is already in the array. Do not add. 57 | else 58 | --Add figure to array 59 | fig[float.identifier] = float.attributes.prefix .. float.attributes.fignum 60 | end 61 | end 62 | i = i + 1 63 | end 64 | end 65 | 66 | local function getappendix(h) 67 | if h.attr.attributes.appendixtitle then 68 | app[h.identifier] = h.attr.attributes.appendixtitle 69 | appendixcount = appendixcount + 1 70 | end 71 | 72 | end 73 | 74 | 75 | local function figtblconvert(ct) 76 | 77 | 78 | local floatreftext 79 | --Is the citation a reference to a table? 80 | if #ct.citations == 1 and string.find(ct.citations[1].id, "^tbl%-")then 81 | 82 | if tbl[ct.citations[1].id] then 83 | -- Text for table reference 84 | floatreftext = pandoc.Inlines({pandoc.Str(tableword), pandoc.Str('\u{a0}'), pandoc.Str(tbl[ct.citations[1].id])}) 85 | end 86 | end 87 | --Is the citation a reference to a figure? 88 | if #ct.citations == 1 and string.find(ct.citations[1].id, "^fig%-") then 89 | -- Text for figure reference 90 | if fig[ct.citations[1].id] then 91 | floatreftext = pandoc.Inlines({pandoc.Str(figureword), pandoc.Str('\u{a0}'), pandoc.Str(fig[ct.citations[1].id])}) 92 | end 93 | end 94 | 95 | --Is the citation a reference to a section? 96 | if #ct.citations == 1 and string.find(ct.citations[1].id, "^sec%-") and app[ct.citations[1].id] then 97 | 98 | -- Text for section reference 99 | if appendixcount == 1 then 100 | floatreftext = pandoc.Inlines({pandoc.Str(appendixword)}) 101 | else 102 | floatreftext = pandoc.Inlines({pandoc.Str(appendixword), pandoc.Str('\u{a0}'), pandoc.Str(app[ct.citations[1].id])}) 103 | end 104 | 105 | 106 | end 107 | 108 | 109 | --Is the citation a reference to a table or figure? 110 | if #ct.citations == 1 and string.find(ct.citations[1].id, "^fig%-") or string.find(ct.citations[1].id, "^tbl%-") or string.find(ct.citations[1].id, "^sec%-") then 111 | if floatreftext == nil then 112 | quarto.log.warning("Cannot find @" .. ct.citations[1].id) 113 | return floatreftext 114 | end 115 | if refhyperlinks then 116 | -- create link 117 | local reflink = pandoc.Link(floatreftext, "#" .. ct.citations[1].id) 118 | reflink.classes = {"quarto-xref"} 119 | reflink.attributes[kAriaExpanded] = "false" 120 | return reflink 121 | else 122 | return floatreftext 123 | end 124 | end 125 | end 126 | 127 | 128 | return{ 129 | {Meta = gettablefig}, 130 | {Header = getappendix}, 131 | {Cite = figtblconvert} 132 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apafigurewidthlatex.lua: -------------------------------------------------------------------------------- 1 | if FORMAT ~= "latex" then 2 | return 3 | end 4 | -- Insert column width for figures if not set 5 | Div = function(div) 6 | if div.identifier:find("^fig%-") then 7 | div.content = div.content:walk { 8 | Image = function(img) 9 | if img.attributes.width == nil then 10 | img.attributes.width = "\\columnwidth" 11 | end 12 | return img 13 | end 14 | } 15 | end 16 | 17 | div.content = div.content:walk { 18 | Figure = function(fg) 19 | if fg.identifier:find("^fig%-") then 20 | fg.content = fg.content:walk { 21 | Image = function(img) 22 | if img.attributes.width == nil then 23 | img.attributes.width = "\\columnwidth" 24 | end 25 | return img 26 | end 27 | } 28 | return fg 29 | end 30 | end 31 | } 32 | return div 33 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apafloat.lua: -------------------------------------------------------------------------------- 1 | -- Finds divs that are Tables and Figures. 2 | -- Adds FigureWithNote or FigureWithoutNote class to the Div 3 | function Pandoc (doc) 4 | local isfigure = false 5 | local istable = false 6 | local hasnote = false 7 | for i = 1, #doc.blocks, 1 do 8 | isfigure = false 9 | istable = false 10 | hasnote = false 11 | if doc.blocks[i].identifier then 12 | if doc.blocks[i].identifier:find("^fig%-") then 13 | isfigure = true 14 | 15 | end 16 | if doc.blocks[i].identifier:find("^tbl%-") then 17 | istable = true 18 | 19 | end 20 | 21 | end 22 | if doc.blocks[i].t == "Div" then 23 | 24 | doc.blocks[i].content:walk { 25 | Div = function(div) 26 | if div.identifier then 27 | if div.identifier:find("^fig%-") then 28 | isfigure = true 29 | 30 | 31 | end 32 | if div.identifier:find("^tbl%-") then 33 | istable = true 34 | end 35 | end 36 | end 37 | } 38 | end 39 | if isfigure or istable then 40 | if istable and FORMAT == "docx" then 41 | doc.blocks[i].content = doc.blocks[i].content:walk { 42 | Table = function(tb) 43 | 44 | if tb.classes:includes("do-not-create-environment") then 45 | 46 | else 47 | tb.classes:insert(1, "do-not-create-environment") 48 | return tb 49 | end 50 | 51 | end 52 | } 53 | 54 | end 55 | 56 | 57 | if doc.blocks[i].attributes["apa-note"] then 58 | doc.blocks[i].classes:insert("FigureWithNote") 59 | doc.blocks[i].attributes["custom-style"] = "FigureWithNote" 60 | else 61 | doc.blocks[i].classes:insert("FigureWithoutNote") 62 | doc.blocks[i].attributes["custom-style"] = "FigureWithoutNote" 63 | end 64 | end 65 | end 66 | return doc 67 | end 68 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apafloatlatex.lua: -------------------------------------------------------------------------------- 1 | if FORMAT ~= "latex" then 2 | return 3 | end 4 | 5 | 6 | local noteword = "Note" 7 | 8 | -- from quarto-cli/src/resources/pandoc/datadir/init.lua 9 | -- global quarto params 10 | local paramsJson = quarto.base64.decode(os.getenv("QUARTO_FILTER_PARAMS")) 11 | local quartoParams = quarto.json.decode(paramsJson) 12 | local function param(name, default) 13 | -- get name from quartoParams, if possible 14 | local value = quartoParams[name] 15 | if value == nil then 16 | -- get name from quartoParams.language, if possible 17 | if quartoParams.language then 18 | value = quartoParams.language[name] 19 | end 20 | -- If still nil, then assign default 21 | if value == nil then 22 | value = default 23 | end 24 | end 25 | return value 26 | end 27 | 28 | 29 | -- Is the .pdf in journal mode? 30 | local journalmode = false 31 | local manuscriptmode = true 32 | local noteprefix = "\\noindent \\emph{Note.} " 33 | local beforenote = "" 34 | local getmode = function(meta) 35 | local documentmode = pandoc.utils.stringify(meta["documentmode"]) 36 | journalmode = documentmode == "jou" 37 | manuscriptmode = documentmode == "man" 38 | -- Find word for "note" 39 | if not meta.language["figure-table-note"] then 40 | if param("callout-note-title") then 41 | meta.language["figure-table-note"] = param("callout-note-title") 42 | end 43 | end 44 | noteprefix = "\\noindent \\emph{" .. meta.language["figure-table-note"] .. ".} " 45 | 46 | end 47 | 48 | 49 | 50 | -- Split string function 51 | function string:split(delimiter) 52 | local result = { } 53 | local from = 1 54 | local delim_from, delim_to = string.find( self, delimiter, from ) 55 | while delim_from do 56 | from = delim_to + 1 57 | delim_from, delim_to = string.find( self, delimiter, from ) 58 | end 59 | table.insert( result, string.sub( self, from ) ) 60 | return result 61 | end 62 | 63 | local processfloat = function(float) 64 | if float.attributes["disable-apaquarto-processing"] then 65 | 66 | if not (float.attributes["disable-apaquarto-processing"] == "false") then 67 | 68 | return float 69 | end 70 | end 71 | -- default float position 72 | local floatposition = "[!htbp]" 73 | local p = {} 74 | if float.attributes["fig-pos"] then 75 | if pandoc.utils.stringify(float.attributes["fig-pos"]) == "false" then 76 | floatposition = "[!htbp]" 77 | else 78 | floatposition = "[" .. float.attributes["fig-pos"] .. "]" 79 | end 80 | end 81 | 82 | if float.type == "Table" then 83 | -- Default table environment 84 | local latextableenv = "table" 85 | -- Manuscript spacing before note needs adjustment ment 86 | if manuscriptmode then 87 | beforenote = "\\vspace{-20pt}\n" 88 | if float.attributes["beforenotespace"] then 89 | 90 | beforenote = "\\vspace{" .. float.attributes["beforenotespace"] .. "}\n" 91 | end 92 | 93 | 94 | end 95 | if journalmode then 96 | -- No spacing in before note in journalmode 97 | beforenote = "" 98 | if float.attributes["beforenotespace"] then 99 | beforenote = "\\vspace{" .. float.attributes["beforenotespace"] .. "}\n" 100 | end 101 | -- Table environment in journal mode 102 | latextableenv = "ThreePartTable" 103 | end 104 | 105 | -- Table enironment for apa-twocolumn floats 106 | if float.attributes then 107 | if float.attributes["apa-twocolumn"] then 108 | if float.attributes["apa-twocolumn"] == "true" then 109 | if journalmode then 110 | latextableenv = "twocolumntable" 111 | end 112 | 113 | end 114 | end 115 | end 116 | 117 | -- Add note 118 | if float.attributes["apa-note"] then 119 | p = pandoc.Span(pandoc.RawInline("latex", beforenote .. noteprefix)) 120 | local apanotestr = quarto.utils.string_to_inlines(float.attributes["apa-note"]) 121 | 122 | for i, v in ipairs(apanotestr) do 123 | p.content:insert(v) 124 | end 125 | end 126 | 127 | local captionsubspan = pandoc.Span({ 128 | pandoc.RawInline("latex", "\\label"), 129 | pandoc.RawInline("latex", "{"), 130 | pandoc.RawInline("latex", float.identifier), 131 | pandoc.RawInline("latex", "}") 132 | }) 133 | 134 | -- Adjust space after caption in manuscript mode 135 | local aftercaption = "" 136 | if manuscriptmode then 137 | aftercaption = "\n\\vspace{-20pt}" 138 | if float.attributes["after-caption-space"] then 139 | aftercaption = "\\vspace{" .. float.attributes["after-caption-space"] .. "}\n" 140 | end 141 | 142 | end 143 | 144 | -- Make caption 145 | local captionspan = pandoc.Span({ 146 | pandoc.RawInline("latex", "\\caption"), 147 | pandoc.RawInline("latex", "{"), 148 | pandoc.Span(float.caption_long.content), 149 | captionsubspan, 150 | pandoc.RawInline("latex", "}" .. aftercaption) 151 | 152 | }) 153 | 154 | 155 | -- Make table 156 | local returnblock = pandoc.Div({ 157 | pandoc.RawBlock("latex", "\\begin{" .. latextableenv .. "}"), 158 | captionspan, 159 | float.content, 160 | p, 161 | pandoc.RawBlock("latex", "\\end{" .. latextableenv .. "}") 162 | } 163 | ) 164 | 165 | if journalmode then 166 | 167 | returnblock = pandoc.Div({ 168 | pandoc.RawBlock("latex", "\\begin{" .. latextableenv .. "}"), 169 | float.__quarto_custom_node, 170 | p, 171 | pandoc.RawBlock("latex", "\\end{" .. latextableenv .. "}") 172 | }) 173 | 174 | end 175 | 176 | return returnblock 177 | end 178 | 179 | if float.type == "Figure" then 180 | local hasnote = false 181 | local apanote 182 | local twocolumn = false 183 | local latexenv = "figure" 184 | -- Get apa-note from image, if possible 185 | float.content:walk { 186 | Image = function(img) 187 | if img.attributes["apa-note"] then 188 | hasnote = true 189 | apanote = img.attributes["apa-note"] 190 | end 191 | 192 | if img.attributes["beforenotespace"] then 193 | beforenote = "\\vspace{" .. img.attributes["beforenotespace"] .. "}\n" 194 | end 195 | if img.attributes["apa-twocolumn"] then 196 | if img.attributes["apa-twocolumn"] == "true" then 197 | twocolumn = true 198 | end 199 | end 200 | end 201 | } 202 | 203 | if twocolumn then 204 | latexenv = "figure*" 205 | end 206 | 207 | -- Make note 208 | if hasnote or twocolumn then 209 | if hasnote then 210 | 211 | p = pandoc.Span(pandoc.RawInline("latex", beforenote .. noteprefix)) 212 | local apanotestr = quarto.utils.string_to_inlines(apanote) 213 | 214 | for i, v in ipairs(apanotestr) do 215 | p.content:insert(v) 216 | end 217 | end 218 | 219 | local captionsubspan = pandoc.Span({ 220 | pandoc.RawInline("latex", "\\label"), 221 | pandoc.RawInline("latex", "{"), 222 | pandoc.Str(float.identifier), 223 | pandoc.RawInline("latex", "}") 224 | }) 225 | 226 | local captionspan = pandoc.Span({ 227 | pandoc.RawInline("latex", "\\caption"), 228 | pandoc.RawInline("latex", "{"), 229 | pandoc.Span(float.caption_long.content), 230 | captionsubspan, 231 | pandoc.RawInline("latex", "}") 232 | }) 233 | 234 | if float.attributes.prefix ~= "" then 235 | floatposition = "" 236 | end 237 | 238 | local returnblock = pandoc.Div({ 239 | pandoc.RawBlock("latex", "\\begin{" .. latexenv .. "}" .. floatposition), 240 | captionspan, 241 | float.content, 242 | p, 243 | pandoc.RawBlock("latex", "\\end{" .. latexenv .. "}") 244 | }) 245 | 246 | return returnblock 247 | end 248 | 249 | end 250 | end 251 | 252 | 253 | return { 254 | { Meta = getmode }, 255 | { FloatRefTarget = processfloat } 256 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apafloatstoend.lua: -------------------------------------------------------------------------------- 1 | if FORMAT == "latex" then 2 | return 3 | end 4 | Pandoc = function(doc) 5 | local tbl = {} 6 | local fig = {} 7 | local appendixword = "Appendix" 8 | local movefloatstoend = true 9 | if doc.meta.language and doc.meta.language["crossref-apx-prefix"] then 10 | appendixword = pandoc.utils.stringify(doc.meta.language["crossref-apx-prefix"]) 11 | end 12 | 13 | 14 | if doc.meta.floatsintext and pandoc.utils.stringify(doc.meta.floatsintext) == "true" then 15 | movefloatstoend = false 16 | end 17 | 18 | 19 | if movefloatstoend then 20 | for i = #doc.blocks, 1, -1 do 21 | if doc.blocks[i].identifier then 22 | if doc.blocks[i].identifier:find("^tbl%-") then 23 | if doc.blocks[i].attributes and doc.blocks[i].attributes.prefix == "" then 24 | if FORMAT == "docx" then 25 | table.insert(tbl, 1, pandoc.RawBlock('openxml', '')) 26 | end 27 | if FORMAT == "typst" then 28 | table.insert(tbl, 1, pandoc.RawBlock('typst', '#pagebreak(weak: true)')) 29 | end 30 | table.insert(tbl, 1, doc.blocks[i]) 31 | doc.blocks:remove(i) 32 | end 33 | else 34 | if doc.blocks[i].identifier:find("^fig%-") then 35 | if doc.blocks[i].attributes and doc.blocks[i].attributes.prefix == "" then 36 | if FORMAT == "docx" then 37 | table.insert(fig, 1, pandoc.RawBlock('openxml', '')) 38 | end 39 | if FORMAT == "typst" then 40 | table.insert(fig, 1, pandoc.RawBlock('typst', '#pagebreak(weak: true)')) 41 | end 42 | table.insert(fig, 1, doc.blocks[i]) 43 | doc.blocks:remove(i) 44 | end 45 | else 46 | local hasfig = false 47 | doc.blocks[i]:walk { 48 | Figure = function(fg) 49 | if fg.identifier then 50 | if fg.identifier:find("^fig%-") then 51 | if fg.attributes and fg.attributes.prefix == "" then 52 | hasfig = true 53 | end 54 | end 55 | end 56 | end 57 | } 58 | if hasfig then 59 | if FORMAT == "docx" then 60 | table.insert(fig, 1, pandoc.RawBlock('openxml', '')) 61 | end 62 | if FORMAT == "typst" then 63 | table.insert(fig, 1, pandoc.RawBlock('typst', '#pagebreak(weak: true)')) 64 | end 65 | table.insert(fig, 1, doc.blocks[i]) 66 | doc.blocks:remove(i) 67 | hasfig = false 68 | else 69 | 70 | end 71 | end 72 | end 73 | 74 | end 75 | 76 | end 77 | end 78 | 79 | 80 | -- Insert page breaks for each appendix in docx and typst 81 | -- html does not need page breaks, and latex inserts pagebreaks automatically 82 | if FORMAT == "docx" or FORMAT == "typst" then 83 | for i = #doc.blocks, 1, -1 do 84 | if doc.blocks[i].tag == "Header" then 85 | if doc.blocks[i].level == 1 and doc.blocks[i].content[1].text == appendixword then 86 | if FORMAT == "docx" then 87 | table.insert(doc.blocks, i, pandoc.RawBlock('openxml', '')) 88 | end 89 | if FORMAT == "typst" then 90 | table.insert(doc.blocks, i, pandoc.RawBlock('typst', '#pagebreak(weak: true)')) 91 | end 92 | end 93 | end 94 | end 95 | end 96 | 97 | if movefloatstoend then 98 | 99 | -- Find block where appendices begin 100 | local appendixblock = 0 101 | for i = 1, #doc.blocks, 1 do 102 | if doc.blocks[i].tag == "Header" then 103 | if doc.blocks[i].level == 1 and doc.blocks[i].content[1].text == appendixword and appendixblock== 0 then 104 | appendixblock = i 105 | end 106 | end 107 | end 108 | 109 | -- If there are no appendices, insert figures and tables at the end 110 | if appendixblock == 0 then 111 | if #tbl > 0 then 112 | doc.blocks:extend(tbl) 113 | end 114 | if #fig > 0 then 115 | doc.blocks:extend(fig) 116 | end 117 | else 118 | -- Insert figures and tables before appendices 119 | if #fig > 0 then 120 | for i = #fig, 1, -1 do 121 | doc.blocks:insert(appendixblock, fig[i]) 122 | end 123 | end 124 | if #tbl > 0 then 125 | for i = #tbl, 1, -1 do 126 | doc.blocks:insert(appendixblock, tbl[i]) 127 | end 128 | end 129 | end 130 | end 131 | 132 | return doc 133 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apaheader.lua: -------------------------------------------------------------------------------- 1 | -- Formats level 4 and 5 headers for APA format. 2 | 3 | -- Does the string end with a specific character? 4 | ---http://lua-users.org/wiki/StringRecipes 5 | local function ends_with(str, ending) 6 | return string.sub(str.text, -1) == ending 7 | end 8 | 9 | 10 | function Header (hx) 11 | if hx.level > 3 then 12 | -- Add a period unless a punctuation mark is already present 13 | if not (ends_with(hx.content[#hx.content],".") or ends_with(hx.content[#hx.content],"?") or ends_with(hx.content[#hx .content],"?")) then 14 | hx.content[#hx.content + 1] = pandoc.Str(".") 15 | end 16 | if FORMAT == "docx" then 17 | -- Adds a "Style Separator" character that allows the headier to appear as if it were on the same line as the subsequent paragraph. 18 | local htext = pandoc.utils.stringify(hx.content) 19 | local prefix = "" 20 | local suffix = " " 21 | return pandoc.RawBlock('openxml', prefix .. htext .. suffix) 22 | end 23 | return hx 24 | end 25 | end 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apalanguage.lua: -------------------------------------------------------------------------------- 1 | -- This filter allows English language defaults to be changed 2 | -- to any other language (or any other English words) 3 | 4 | -- from quarto-cli/src/resources/pandoc/datadir/init.lua 5 | -- global quarto params 6 | local paramsJson = quarto.base64.decode(os.getenv("QUARTO_FILTER_PARAMS")) 7 | local quartoParams = quarto.json.decode(paramsJson) 8 | 9 | local function param(name, default) 10 | -- get name from quartoParams, if possible 11 | local value = quartoParams[name] 12 | if value == nil then 13 | -- get name from quartoParams.language, if possible 14 | if quartoParams.language then 15 | value = quartoParams.language[name] 16 | end 17 | -- If still nil, then assign default 18 | if value == nil then 19 | value = default 20 | end 21 | end 22 | return value 23 | end 24 | 25 | -- Fields and their defaults 26 | local fields = { 27 | {field = "crossref-fig-title", default = "Figure"}, 28 | {field = "crossref-tbl-title", default = "Table"}, 29 | {field = "crossref-apx-title", default = "Appendix"}, 30 | {field = "citation-last-author-separator", default = "and"}, 31 | {field = "citation-masked-author", default = "Masked Citation"}, 32 | {field = "citation-masked-title", default = "Masked Title"}, 33 | {field = "citation-masked-date", default = "n.d."}, 34 | {field = "email", default = "Email"}, 35 | {field = "figure-table-note", default = "Note"}, 36 | {field = "section-title-abstract", default = "Abstract"}, 37 | {field = "section-title-appendixes", default = "Appendices"}, 38 | {field = "section-title-references", default = "References"}, 39 | {field = "title-block-author-note", default = "Author Note"}, 40 | {field = "title-block-correspondence-note", default = "Correspondence concerning this article should be addressed to"}, 41 | {field = "title-block-keywords", default = "Keywords"}, 42 | {field = "title-block-role-introduction", default = "Author roles were classified using the Contributor Role Taxonomy (CRediT; https://credit.niso.org/) as follows:"}, 43 | {field = "title-impact-statement", "Impact Statement"}, 44 | {field = "title-word-count", default = "Word Count"}, 45 | {field = "references-meta-analysis", default = "References marked with an asterisk indicate studies included in the meta-analysis."}, 46 | } 47 | 48 | Meta = function(m) 49 | -- Make empty language table if it does not exist 50 | if not m.language then 51 | m.language = {} 52 | end 53 | 54 | 55 | 56 | -- Find word for "note" 57 | if not m.language["figure-table-note"] then 58 | if param("callout-note-title") then 59 | m.language["figure-table-note"] = param("callout-note-title") 60 | end 61 | end 62 | 63 | -- Find word for "Appendix" 64 | if not m.language["crossref-apx-prefix"] then 65 | if param("crossref-apx-prefix") then 66 | m.language["crossref-apx-prefix"] = param("crossref-apx-prefix") 67 | end 68 | end 69 | 70 | for i,x in ipairs(fields) do 71 | -- In case someone assigned variable to top-level meta instead of to language 72 | if m[x.field] then 73 | m.language[x.field] = m[x.field] 74 | end 75 | -- If field not assisned, assign default 76 | if not m.language[x.field] then 77 | m.language[x.field] = param(x.field, x.default) 78 | if m.crossref then 79 | if m.crossref[x.field:gsub("^crossref%-", "")] then 80 | m.language[x.field] = pandoc.utils.stringify(m.crossref[x.field:gsub("^crossref%-", "")]) 81 | end 82 | end 83 | end 84 | end 85 | 86 | return m 87 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apamasked.lua: -------------------------------------------------------------------------------- 1 | --List of masked citations 2 | local maskedcitations = pandoc.List() 3 | 4 | --Retrieves citations from metadata 5 | local function getmasked(meta) 6 | if meta["masked-citations"] and meta["mask"] and pandoc.utils.stringify(meta["mask"]) == "true" then 7 | local maskedstrings = meta["masked-citations"] 8 | for i, v in pairs(maskedstrings) do 9 | maskedcitations:insert(pandoc.utils.stringify(v)) 10 | end 11 | end 12 | end 13 | 14 | --Finds citations to be masked and converts them to masked citations 15 | local function maskcite(cite) 16 | local k = 0 17 | local km = 0 18 | local maskid = "maskedreference" 19 | 20 | for i, v in pairs(cite.citations) do 21 | if maskedcitations:includes(v.id) then 22 | v.id = maskid 23 | v.suffix = nil 24 | k = k + 1 25 | 26 | end 27 | end 28 | 29 | if k > 0 then 30 | for i = #cite.citations, 1, -1 do 31 | if cite.citations[i].id == maskid then 32 | km = km + 1 33 | if km ~= k then 34 | cite.citations:remove(i) 35 | end 36 | end 37 | end 38 | return cite 39 | end 40 | end 41 | 42 | 43 | return { 44 | {Meta = getmasked}, 45 | {Cite = maskcite} 46 | } 47 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apanote.lua: -------------------------------------------------------------------------------- 1 | -- This filter prints the apa-note, if present 2 | 3 | -- Do nothing if latex 4 | if FORMAT == "latex" then 5 | return 6 | end 7 | 8 | -- Default word for note 9 | local beginapanote = "Note" 10 | -- Replace note word, if specified 11 | local function getnote(m) 12 | if m.language and m.language["figure-table-note"] then 13 | beginapanote = pandoc.utils.stringify(m.language["figure-table-note"]) 14 | end 15 | end 16 | 17 | local function apanote(elem) 18 | if elem.attributes["apa-note"] then 19 | hasnote = true 20 | -- If div contains another div with apa-note, do nothing 21 | elem.content:walk { 22 | Div = function(div) 23 | if div.attributes["apa-note"] then 24 | hasnote = false 25 | end 26 | end 27 | } 28 | if hasnote then 29 | -- Make note 30 | local apanotepara = pandoc.Para({pandoc.Emph(pandoc.Str(beginapanote)), pandoc.Str("."),pandoc.Space()}) 31 | apanotepara.content:extend(quarto.utils.string_to_inlines(elem.attributes["apa-note"])) 32 | local apanote = pandoc.Div(apanotepara) 33 | 34 | apanote.attributes['custom-style'] = 'FigureNote' 35 | apanote.classes:extend({"FigureNote"}) 36 | return {elem, apanote} 37 | end 38 | end 39 | end 40 | 41 | return { 42 | {Meta = getnote}, 43 | {Div = apanote} 44 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apanotelatex.lua: -------------------------------------------------------------------------------- 1 | if FORMAT ~= "latex" then 2 | return 3 | end 4 | -- If div if a figure with apa-note, then insert it into the image 5 | Div = function(div) 6 | if div.attributes then 7 | if div.attributes["apa-note"] then 8 | if div.identifier:find("^fig%-") then 9 | div.content = div.content:walk { 10 | Image = function(img) 11 | img.attributes["apa-note"] = div.attributes["apa-note"] 12 | return img 13 | end 14 | } 15 | end 16 | 17 | div.content = div.content:walk { 18 | Figure = function(fg) 19 | if fg.identifier:find("^fig%-") then 20 | fg.content = fg.content:walk { 21 | Image = function(img) 22 | img.attributes["apa-note"] = div.attributes["apa-note"] 23 | return img 24 | end 25 | } 26 | return fg 27 | end 28 | end 29 | } 30 | return div 31 | end 32 | end 33 | end 34 | 35 | 36 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apaomitrefsdiv.lua: -------------------------------------------------------------------------------- 1 | -- This filter adds a refdiv if there is a Reference header but no refdiv 2 | 3 | local hasrefdiv = false 4 | local referenceword = "References" 5 | local appendixword = "Appendix" 6 | local appendixcount = 0 7 | 8 | 9 | -- Change Appendix A to Appendix if there is only one appendix. 10 | local fixloneappendix = function(h) 11 | if appendixcount == 1 then 12 | 13 | if h.level == 1 then 14 | hcontent = pandoc.utils.stringify(h.content) 15 | if hcontent == appendixword .. " A" or hcontent == "Appendix A" then 16 | h.content = h.content[1] 17 | return h 18 | end 19 | end 20 | end 21 | end 22 | 23 | return { 24 | { 25 | Meta = function(meta) 26 | if meta.language then 27 | -- Is there another word for reference section? 28 | if meta.language["section-title-references"] then 29 | referenceword = pandoc.utils.stringify(meta.language["section-title-references"]) 30 | end 31 | if meta.language["crossref-apx-prefix"] then 32 | appendixword = pandoc.utils.stringify(meta.language["crossref-apx-prefix"]) 33 | end 34 | end 35 | end 36 | }, 37 | { Div = function(div) 38 | if div.identifier and div.identifier == "refs" then 39 | -- There is a refdiv 40 | hasrefdiv = true 41 | end 42 | end 43 | }, 44 | { Header = function(h) 45 | if h.attr.attributes.appendixtitle then 46 | appendixcount = appendixcount + 1 47 | end 48 | if h.content and ((pandoc.utils.stringify(h.content) == referenceword) or (pandoc.utils.stringify(h.content) == "References")) then 49 | if hasrefdiv then 50 | -- Do nothing because there is a refdiv 51 | else 52 | -- Add refdiv after References header 53 | local refdiv = pandoc.Div({}) 54 | refdiv.identifier = "refs" 55 | refdiv.classes:insert("references") 56 | return {h, refdiv} 57 | end 58 | end 59 | end }, 60 | { Header = fixloneappendix 61 | } 62 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/apaoneauthoraffiliation.lua: -------------------------------------------------------------------------------- 1 | -- Latex needs to know if there is only one author and/or one affiliation 2 | -- Checks to make sure all authors have an affiliation (or address) 3 | Meta = function(meta) 4 | -- Is the only one author? 5 | if meta["by-author"] then 6 | if #meta["by-author"] == 1 then 7 | meta.oneauthor = true 8 | else 9 | meta.oneauthor = false 10 | end 11 | else 12 | -- There are no authors 13 | error("At least one author must be specified in your yaml metadata. \nFor example, \n\nauthor:\n - name: Fred Jones\n affiliations: Generic University\n email: fred.jones@generic.edu\n corresponding: true\n") 14 | end 15 | 16 | -- Is the only one affiliation? 17 | if meta["by-affiliation"] then 18 | if #meta["by-affiliation"] == 1 then 19 | meta.oneaffiliation = true 20 | else 21 | meta.oneaffiliation = false 22 | end 23 | end 24 | 25 | local corresponsingauthor = false 26 | -- Does every author have an affiliation? 27 | if meta["by-author"] then 28 | for i,j in pairs(meta["by-author"]) do 29 | if j.attributes then 30 | if j.attributes.corresponding then 31 | corresponsingauthor = true 32 | end 33 | end 34 | if not j.affiliations then 35 | local au = pandoc.utils.stringify(j.name.literal) 36 | error("No affiliation listed for " .. au .. "\nAll authors must have an affiliation. For example,\n\nauthor:\n - name: " .. au .. "\n affiliations: Genereric University\n\nIf authors are unaffiliated, list a city, as well as a region and/or country.\nFor example, \n\nauthor:\n - name: " .. au .. "\n affiliations:\n city: Los Angeles\n region: CA\n") 37 | end 38 | end 39 | end 40 | 41 | if not corresponsingauthor then 42 | error("At least one author needs to marked as the corresponding author. For example, \n\nauthor:\n - name: Fred Jones\n affiliations: Generic University\n email: fred.jones@generic.edu\n corresponding: true\n") 43 | end 44 | return(meta) 45 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apaquarto.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/_extensions/apaquarto/apaquarto.docx -------------------------------------------------------------------------------- /_extensions/apaquarto/apaquarto.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/_extensions/apaquarto/apaquarto.md -------------------------------------------------------------------------------- /_extensions/apaquarto/apaquote.lua: -------------------------------------------------------------------------------- 1 | -- In blockquotes with multiple paragraphs, give special 2 | -- style to paragraphs after the first paragraph 3 | 4 | --- This filter only runs on docx format 5 | if FORMAT ~= "docx" then 6 | return 7 | end 8 | 9 | BlockQuote = function (element) 10 | local i = 0 11 | return pandoc.walk_block(element, { 12 | Para = function (el) 13 | i = i + 1 14 | -- Is this after the first paragraph? 15 | if i > 1 then 16 | return pandoc.Div({el}, pandoc.Attr("", {}, {["custom-style"]="NextBlockText"})) 17 | else 18 | return el 19 | end 20 | end 21 | }) 22 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/apastriptitle.lua: -------------------------------------------------------------------------------- 1 | 2 | --- Does the string end with a specific character? 3 | --- http://lua-users.org/wiki/StringRecipes 4 | local function ends_with(str, ending) 5 | return string.sub(str.text, -1) == ending 6 | end 7 | 8 | --- Trim string 9 | local function trim(s) 10 | local l = 1 11 | while string.sub(s,l,l) == ' ' do 12 | l = l+1 13 | end 14 | local r = string.len(s) 15 | while string.sub(s,r,r) == ' ' do 16 | r = r-1 17 | end 18 | return string.sub(s,l,r) 19 | end 20 | 21 | --- Put a space before the string 22 | local function prependspace(s) 23 | if s then 24 | return " " .. pandoc.utils.stringify(s) 25 | else 26 | return "" 27 | end 28 | end 29 | 30 | -- Are the affiliations different or same across authors? 31 | local are_affiliations_different = function(authors) 32 | -- Superscript id 33 | local superii = "" 34 | 35 | -- List of superii 36 | local hash = {} 37 | -- index of superii 38 | local res = {} 39 | 40 | --Check if affilations are the same for each author 41 | for i, a in ipairs(authors) do 42 | superii = "" 43 | if a.affiliations then 44 | for j, aff in ipairs(a.affiliations) do 45 | if j > 1 then 46 | superii = superii .. "," 47 | end 48 | superii = superii .. aff.number 49 | end 50 | end 51 | 52 | if (not hash[superii]) then 53 | res[#res+1] = superii 54 | hash[superii] = true 55 | end 56 | 57 | end 58 | 59 | return #res > 1 60 | end 61 | 62 | local function makeauthorname(a) 63 | 64 | local authorname = a.literal 65 | -- Make author name 66 | if pandoc.utils.type(a.literal) == "List" then 67 | if a.literal[1].literal then 68 | authorname = a[1].literal 69 | else 70 | authorname = "" 71 | authorname = authorname .. prependspace(a.literal[1].given) 72 | authorname = authorname .. prependspace(a.literal[1]["dropping-particle"]) 73 | authorname = authorname .. prependspace(a.literal[1]["non-dropping-particle"]) 74 | authorname = authorname .. prependspace(a.literal[1].family) 75 | authorname = pandoc.Inlines(trim(authorname)) 76 | end 77 | end 78 | return authorname 79 | end 80 | 81 | Meta = function(meta) 82 | meta.apatitle = nil 83 | meta.apatitledisplay = nil 84 | if meta.title then 85 | meta.apatitle = meta.title:clone() 86 | meta.apatitledisplay = meta.title:clone() 87 | end 88 | 89 | if meta["by-author"] then 90 | meta.affiliationsdifferent = are_affiliations_different(meta["by-author"]) 91 | 92 | for i,j in ipairs(meta["by-author"]) do 93 | j.apaauthordisplay = makeauthorname(j.name) 94 | end 95 | end 96 | 97 | if meta.subtitle then 98 | if not ends_with(meta.apatitledisplay[#meta.apatitledisplay], ":") then 99 | meta.apatitledisplay:insert(pandoc.Str(":")) 100 | end 101 | meta.apatitledisplay:insert(pandoc.Space()) 102 | meta.apatitledisplay:extend(meta.subtitle) 103 | end 104 | meta.apasubtitle = meta.subtitle 105 | meta.apaauthor = meta.author 106 | meta.apadate = meta.date 107 | meta.apaabstract = meta.abstract 108 | if meta.documentmode then 109 | else 110 | meta.documentmode = "man" 111 | end 112 | --Prevents pandoc from fomatting .docx document the way it thinks it should. 113 | if FORMAT == "docx" then 114 | meta.title = nil 115 | meta.subtitle = nil 116 | meta.author = nil 117 | meta.date = nil 118 | meta.abstract = nil 119 | end 120 | return meta 121 | end 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /_extensions/apaquarto/apatemplate.tex: -------------------------------------------------------------------------------- 1 | $doc-class.tex()$ 2 | \usepackage{amsmath} 3 | \usepackage{amssymb} 4 | 5 | $if(docmode)$ 6 | \geometry{inner=1in, outer=1in} 7 | \fancyhfoffset[LE,RO]{0cm} 8 | $endif$ 9 | 10 | $if(geometry)$ 11 | \geometry{$for(geometry)$$geometry$$sep$,$endfor$} 12 | \fancyhfoffset[LE,RO]{0cm} 13 | $endif$ 14 | 15 | $if(lang)$ 16 | \usepackage[bidi=default]{babel} 17 | $if(babel-lang)$ 18 | \babelprovide[main,import]{$babel-lang$} 19 | $if(title-block-keywords)$ 20 | \StartBabelCommands{$babel-lang$}{captions} [unicode, fontenc=TU EU1 EU2, charset=utf8] \SetString{\keywordname}{$title-block-keywords$} 21 | \EndBabelCommands 22 | $endif$ 23 | 24 | 25 | $if(mainfont)$ 26 | \babelfont{rm}[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$$if(mainfontfallback)$,RawFeature={fallback=mainfontfallback}$endif$]{$mainfont$} 27 | $endif$ 28 | $endif$ 29 | $for(babel-otherlangs)$ 30 | \babelprovide[import]{$babel-otherlangs$} 31 | $endfor$ 32 | $for(babelfonts/pairs)$ 33 | \babelfont[$babelfonts.key$]{rm}{$babelfonts.value$} 34 | $endfor$ 35 | % get rid of language-specific shorthands (see #6817): 36 | \let\LanguageShortHands\languageshorthands 37 | \def\languageshorthands#1{} 38 | $endif$ 39 | 40 | \RequirePackage{longtable} 41 | \RequirePackage{threeparttablex} 42 | 43 | $header.tex()$ 44 | 45 | $if(highlighting-macros)$ 46 | $highlighting-macros$ 47 | $endif$ 48 | 49 | $tightlist.tex()$ 50 | 51 | $tables.tex()$ 52 | 53 | $graphics.tex()$ 54 | 55 | 56 | $citations.tex()$ 57 | 58 | 59 | $if(numbered-lines)$ 60 | \usepackage[nolongtablepatch]{lineno} 61 | \linenumbers 62 | $endif$ 63 | 64 | $if(linestretch)$ 65 | \setstretch{$linestretch$} 66 | $endif$ 67 | 68 | $if(mathspec)$ 69 | \usepackage{mathspec} 70 | $endif$ 71 | 72 | $if(mainfont)$ 73 | \usepackage{fontspec} 74 | $else$ 75 | \usepackage{newtx} 76 | $endif$ 77 | 78 | \defaultfontfeatures{Scale=MatchLowercase}$-- must come before Beamer theme 79 | \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} 80 | 81 | $if(fontfamily)$ 82 | \usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} 83 | $endif$ 84 | $if(mainfont)$ 85 | \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$$if(mainfontfallback)$,RawFeature={fallback=mainfontfallback}$endif$]{$mainfont$} 86 | $endif$ 87 | $if(sansfont)$ 88 | \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$$if(sansfontfallback)$,RawFeature={fallback=sansfontfallback}$endif$]{$sansfont$} 89 | $endif$ 90 | $if(monofont)$ 91 | \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$} 92 | $endif$ 93 | 94 | $for(fontfamilies)$ 95 | \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$if(monofontfallback)$,RawFeature={fallback=monofontfallback}$endif$]{$monofont$} 96 | $endfor$ 97 | 98 | $if(mathfont)$ 99 | \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} 100 | $endif$ 101 | 102 | $if(CJKmainfont)$ 103 | \usepackage{xeCJK} 104 | \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} 105 | $if(CJKsansfont)$ 106 | \setCJKsansfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKsansfont$} 107 | $endif$ 108 | $if(CJKmonofont)$ 109 | \setCJKmonofont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmonofont$} 110 | $endif$ 111 | $endif$ 112 | 113 | $title.tex()$ 114 | 115 | $if(journalmode)$ 116 | \usepackage{pbalance} 117 | % \usepackage{float} 118 | \makeatletter 119 | \let\oldtpt\ThreePartTable 120 | \let\endoldtpt\endThreePartTable 121 | \def\ThreePartTable{\@ifnextchar[\ThreePartTable@i \ThreePartTable@ii} 122 | \def\ThreePartTable@i[#1]{\begin{figure}[!htbp] 123 | \onecolumn 124 | \begin{minipage}{0.485\textwidth} 125 | \oldtpt[#1] 126 | } 127 | \def\ThreePartTable@ii{\begin{figure}[!htbp] 128 | \onecolumn 129 | \begin{minipage}{0.48\textwidth} 130 | \oldtpt 131 | } 132 | \def\endThreePartTable{ 133 | \endoldtpt 134 | \end{minipage} 135 | \twocolumn 136 | \end{figure}} 137 | \makeatother 138 | 139 | 140 | \makeatletter 141 | \let\endoldlt\endlongtable 142 | \def\endlongtable{ 143 | \hline 144 | \endoldlt} 145 | \makeatother 146 | 147 | \newenvironment{twocolumntable}% environment name 148 | {% begin code 149 | \begin{table*}[!htbp]% 150 | \onecolumn% 151 | }% 152 | {% 153 | \twocolumn% 154 | \end{table*}% 155 | }% end code 156 | $else$ 157 | \makeatletter 158 | \let\endoldlt\endlongtable 159 | \def\endlongtable{ 160 | \hline 161 | \endoldlt 162 | } 163 | \makeatother 164 | $if(floatsintext)$ 165 | $else$ 166 | $if(manuscriptmode)$ 167 | \RequirePackage{longtable} 168 | \DeclareDelayedFloatFlavor{longtable}{table} 169 | $endif$ 170 | $endif$ 171 | $endif$ 172 | 173 | \urlstyle{same} 174 | 175 | 176 | $for(header-insert)$ 177 | $header-insert$ 178 | $endfor$ 179 | 180 | $for(header-includes)$ 181 | $header-includes$ 182 | $endfor$ 183 | 184 | % From https://tex.stackexchange.com/a/645996/211326 185 | %%% apa7 doesn't want to add appendix section titles in the toc 186 | %%% let's make it do it 187 | \makeatletter 188 | \xpatchcmd{\appendix} 189 | {\par} 190 | {\addcontentsline{toc}{section}{\@currentlabelname}\par} 191 | {}{} 192 | \makeatother 193 | 194 | %% Disable longtable counter 195 | %% https://tex.stackexchange.com/a/248395/211326 196 | 197 | \usepackage{etoolbox} 198 | 199 | \makeatletter 200 | \patchcmd{\LT@caption} 201 | {\bgroup} 202 | {\bgroup\global\LTpatch@captiontrue} 203 | {}{} 204 | \patchcmd{\longtable} 205 | {\par} 206 | {\par\global\LTpatch@captionfalse} 207 | {}{} 208 | \apptocmd{\endlongtable} 209 | {\ifLTpatch@caption\else\addtocounter{table}{-1}\fi} 210 | {}{} 211 | \newif\ifLTpatch@caption 212 | \makeatother 213 | 214 | \begin{document} 215 | 216 | $if(suppress-title-page)$ 217 | $else$ 218 | \maketitle 219 | $endif$ 220 | 221 | $if(toc)$ 222 | \hypertarget{toc}{} 223 | \tableofcontents 224 | \newpage 225 | \section[Introduction]{$title$} 226 | $else$ 227 | $if(suppress-title-page)$ 228 | $if(suppress-title-introduction)$ 229 | $else$ 230 | \section[Introduction]{$title$} 231 | $endif$ 232 | $endif$ 233 | $endif$ 234 | 235 | $if(numbersections)$ 236 | \setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} 237 | $else$ 238 | \setcounter{secnumdepth}{-\maxdimen} % remove section numbering 239 | $endif$ 240 | 241 | \setlength\LTleft{0pt} 242 | 243 | $if(numbered-lines)$ 244 | \resetlinenumber[1] 245 | $endif$ 246 | 247 | $body$ 248 | 249 | $before-bib.tex()$ 250 | 251 | $if(zeroitations)$ 252 | $biblio.tex()$ 253 | $endif$ 254 | 255 | $for(include-after)$ 256 | $include-after$ 257 | $endfor$ 258 | 259 | $after-body.tex()$ 260 | 261 | 262 | \end{document} -------------------------------------------------------------------------------- /_extensions/apaquarto/apatwocolumnlatex.lua: -------------------------------------------------------------------------------- 1 | -- Inserts apa-twocolumn div property into image 2 | 3 | -- This filter for latex only 4 | if FORMAT ~= "latex" then 5 | return 6 | end 7 | 8 | Div = function(div) 9 | if div.attributes then 10 | if div.attributes["apa-twocolumn"] then 11 | div.content = div.content:walk { 12 | Image = function(img) 13 | img.attributes["apa-twocolumn"] = div.attributes["apa-twocolumn"] 14 | return img 15 | end 16 | } 17 | return div 18 | end 19 | end 20 | end 21 | 22 | 23 | -------------------------------------------------------------------------------- /_extensions/apaquarto/before-body.tex: -------------------------------------------------------------------------------- 1 | $if(numbered-lines)$ 2 | \linenumbers 3 | $endif$ 4 | 5 | $if(title)$ 6 | \maketitle 7 | $endif$ 8 | 9 | $if(numbered-lines)$ 10 | \resetlinenumber[1] 11 | $endif$ -------------------------------------------------------------------------------- /_extensions/apaquarto/citeprocr.lua: -------------------------------------------------------------------------------- 1 | -- This filter does 3 things. 2 | -- 1. It runs citeproc. Citeproc is needed so that the apaandcite.lua filter can do its job. 3 | -- 2. It removes the References Header if there are no citations and sets the zerocitations slot in the metadata 4 | -- 3. Makes citations in nocite have asterisks unless meta-analysis is false 5 | 6 | -- Counter for citation 7 | local n_citations = 0 8 | local referenceword = "References" 9 | local maskedauthor = "Masked Citation" 10 | local maskedtitle = "Masked Title" 11 | local maskeddate = "n.d." 12 | local metaanalysis = true 13 | local metareferencesentence = "References marked with an asterisk indicate studies included in the meta-analysis." 14 | 15 | return { 16 | { 17 | Cite = function(ct) 18 | -- count citations 19 | n_citations = n_citations + 1 20 | end 21 | }, 22 | { 23 | Meta = function(meta) 24 | -- count references in nocite 25 | if meta.nocite then 26 | meta.nocite:walk { 27 | Cite = function(ct) 28 | n_citations = n_citations + 1 29 | end 30 | } 31 | end 32 | 33 | -- Need to tell latex if there are no citations 34 | if n_citations == 0 then 35 | meta.zerocitations = true 36 | else 37 | meta.zerocitations = false 38 | end 39 | -- Nocite citations are marked as part of meta-analysis unless 40 | -- meta-analysis field set to false 41 | if meta["meta-analysis"] == false then 42 | metaanalysis = false 43 | else 44 | -- If there are nocite citations (and meta-analysis field is 45 | -- not false), then this is a meta-analysis 46 | if meta.nocite then 47 | metaanalysis = true 48 | else 49 | metaanalysis = false 50 | end 51 | end 52 | 53 | if meta.language then 54 | -- Is there another word for reference section? 55 | if meta.language["section-title-references"] then 56 | referenceword = pandoc.utils.stringify(meta.language["section-title-references"]) 57 | end 58 | -- Is there another phrase for masked references? 59 | if meta.language["citation-masked-author"] then 60 | maskedauthor = pandoc.utils.stringify(meta.language["citation-masked-author"]) 61 | end 62 | -- Is there another phrase for masked titles? 63 | if meta.language["citation-masked-title"] then 64 | maskedtitle = pandoc.utils.stringify(meta.language["citation-masked-title"]) 65 | end 66 | -- Is there another phrase for masked sources? 67 | if meta.language["citation-masked-source"] then 68 | maskedsource = pandoc.utils.stringify(meta.language["citation-masked-source"]) 69 | end 70 | -- Is there another phrase for masked dates? 71 | if meta.language["citation-masked-date"] then 72 | maskeddate = pandoc.utils.stringify(meta.language["citation-masked-date"]) 73 | end 74 | -- Is there another phrase for meta-analysis reference explanation? 75 | if meta.language["references-meta-analysis"] then 76 | metareferencesentence = pandoc.utils.stringify(meta.language["references-meta-analysis"]) 77 | end 78 | end 79 | 80 | return meta 81 | end 82 | 83 | }, 84 | { 85 | Div = function(div) 86 | if div.identifier and div.identifier == "refs" then 87 | -- remove reference div if there are no citations 88 | if n_citations == 0 then 89 | return {} 90 | end 91 | end 92 | end 93 | }, 94 | { 95 | Header = function(h) 96 | if pandoc.utils.stringify(h.content) == referenceword then 97 | if n_citations == 0 then 98 | return {} 99 | else 100 | if metaanalysis then 101 | return {h, pandoc.Para(metareferencesentence)} 102 | end 103 | end 104 | end 105 | end 106 | }, 107 | { 108 | Pandoc = function(doc) 109 | doc.meta.references = pandoc.utils.references(doc) 110 | maskedref = { 111 | author = pandoc.List:new({ {literal = maskedauthor}}), 112 | id = "maskedreference", 113 | issued = {literal = maskeddate}, 114 | title = pandoc.Inlines(maskedtitle), 115 | type = "book" 116 | } 117 | doc.meta.references:insert(maskedref) 118 | doc.meta.bibliography = nil 119 | 120 | --look up nocite references 121 | local ct_meta = {} 122 | if metaanalysis then 123 | if doc.meta.nocite then 124 | doc.meta.nocite:walk { 125 | Cite = function(ct) 126 | ct_meta[ct.citations[1].id] = true 127 | end 128 | } 129 | 130 | -- If reference is in nocite, then place an asterisk in front. 131 | for i,j in pairs(doc.meta.references) do 132 | if ct_meta[j.id] then 133 | if j.author[1].literal then 134 | j.author[1].literal = "*" .. j.author[1].literal 135 | else 136 | if j.author[1].family then 137 | j.author[1].family = "*" .. j.author[1].family 138 | end 139 | end 140 | end 141 | end 142 | end 143 | end 144 | local d = pandoc.utils.citeproc(doc) 145 | if FORMAT == "typst" then 146 | d.meta.citeproc = true 147 | end 148 | return d 149 | end 150 | 151 | } 152 | } 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /_extensions/apaquarto/crossrefprefix.lua: -------------------------------------------------------------------------------- 1 | -- This filter creates prefixes for figures and tables in appendices. 2 | 3 | -- List of appendix names 4 | local abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 5 | -- Default prefix 6 | local prefix = "" 7 | -- Default pre-prefex if appendices exceed 26 8 | local preprefix = "" 9 | -- Prefix counter 10 | local intprefix = 0 11 | -- Pre-prefix counter 12 | local intpreprefix = 0 13 | -- Table counter 14 | local tblnum = 0 15 | -- Figure counter 16 | local fignum = 0 17 | -- Appendix counter 18 | local appnum = 0 19 | -- Table table 20 | local tbl = {} 21 | -- Figure table 22 | local fig = {} 23 | -- New style already used 24 | local newsppendixstyle = true 25 | 26 | -- Word for appendix 27 | local appendixword = "Appendix" 28 | getappendixword = function(meta) 29 | if meta.language and meta.language["crossref-apx-prefix"] then 30 | appendixword = pandoc.utils.stringify(meta.language["crossref-apx-prefix"]) 31 | end 32 | end 33 | 34 | 35 | -- return table number associated with id 36 | local tbllabel = function(id) 37 | if id ~= "" then 38 | -- Is id in tbl? 39 | if tbl[id] then 40 | -- Do nothing 41 | else 42 | -- Add id to tbl 43 | tblnum = tblnum + 1 44 | tbl[id] = tblnum 45 | end 46 | return tbl[id] 47 | end 48 | end 49 | 50 | -- return figure number associated with id 51 | local figlabel = function(id, ss) 52 | if id ~= "" then 53 | -- Is id in fig? 54 | if fig[id] then 55 | -- Do nothing 56 | else 57 | if ss then 58 | -- Add id to fig 59 | fig[id] = fignum .. ss 60 | else 61 | -- increment fignum 62 | fignum = fignum + 1 63 | -- Add id to fig 64 | fig[id] = fignum 65 | end 66 | 67 | 68 | 69 | end 70 | end 71 | 72 | return fig[id] 73 | end 74 | 75 | 76 | 77 | local walkblock = function(b) 78 | -- Increment prefix for every level-1 header starting with Appendix 79 | 80 | if b.tag == "Header" and b.level == 1 then 81 | 82 | local headerfirstword = pandoc.utils.stringify(b.content[1]) 83 | if headerfirstword == appendixword or headerfirstword == "Appendix" or (b.identifier and b.identifier:find("^apx%-")) then 84 | 85 | if (headerfirstword == appendixword or headerfirstword == "Appendix") and newsppendixstyle then 86 | print("This style of creating appendices is deprecated:\n\n# Appendix A\n\n#Relationship Descriptive Scale\n\nInstead, use a single descriptive level-1 heading,\nfollowed by a an identifier with the apx prefix:\n\n# Relationship Description Scale {@apx-relationship}\n") 87 | newsppendixstyle = false 88 | end 89 | 90 | 91 | appnum = appnum + 1 92 | if intprefix == 26 then 93 | intprefix = 0 94 | intpreprefix = intpreprefix + 1 95 | preprefix = preprefix .. pandoc.text.sub(abc,intpreprefix,intpreprefix) 96 | end 97 | intprefix = intprefix + 1 98 | tblnum = 0 99 | fignum = 0 100 | prefix = preprefix .. pandoc.text.sub(abc,intprefix,intprefix) 101 | if b.attr then 102 | b.attr.attributes.appendixtitle = prefix 103 | end 104 | end 105 | end 106 | 107 | -- Assign prefixes and numbers 108 | if b.identifier then 109 | 110 | if b.identifier:find("^tbl%-") then 111 | b.attributes.prefix = prefix 112 | b.attributes.tblnum = tbllabel(b.identifier) 113 | else 114 | 115 | if b.identifier:find("^fig%-") then 116 | 117 | 118 | b.attributes.prefix = prefix 119 | b.attributes.fignum = figlabel(b.identifier) 120 | b.content:walk { 121 | Image = function(img) 122 | img.attributes.prefix = prefix 123 | img.attributes.fignum = figlabel(b.identifier) 124 | end 125 | } 126 | 127 | 128 | 129 | local subfigcount = 0 130 | 131 | -- Find subfigures 132 | b.content:walk { 133 | Block = function(bb) 134 | if bb.identifier then 135 | if bb.identifier:find("^fig%-") then 136 | subfigcount = subfigcount + 1 137 | b.attributes.hassubfigs = "true" 138 | bb.attributes.prefix = prefix 139 | bb.attributes.subfigscript = pandoc.text.sub(abc,subfigcount,subfigcount) 140 | bb.attributes.fignum = figlabel(bb.identifier, bb.attributes.subfigscript) 141 | end 142 | end 143 | end 144 | } 145 | 146 | else 147 | 148 | b:walk { 149 | Figure = function(fg) 150 | if fg.identifier then 151 | if fg.identifier:find("^fig%-") then 152 | fg.attributes.prefix = prefix 153 | fg.attributes.fignum = figlabel(fg.identifier) 154 | fg.content:walk { 155 | Image = function(img) 156 | img.attributes.prefix = prefix 157 | img.attributes.fignum = figlabel(fg.identifier) 158 | end 159 | } 160 | end 161 | end 162 | end 163 | } 164 | end 165 | end 166 | 167 | if b.identifier:find("^apx%-") then 168 | local a = pandoc.Header(1, appendixword .. " " .. prefix) 169 | return pandoc.List({a,b}) 170 | else 171 | return b 172 | end 173 | 174 | end 175 | end 176 | 177 | 178 | 179 | local filter = {traverse = 'topdown', 180 | Meta = getappendixword, 181 | Block = walkblock 182 | } 183 | 184 | return filter 185 | 186 | 187 | -------------------------------------------------------------------------------- /_extensions/apaquarto/doc-class.tex: -------------------------------------------------------------------------------- 1 | \documentclass[ 2 | $if(documentmode)$ 3 | $documentmode$, 4 | $endif$ 5 | $if(floatsintext)$ 6 | floatsintext, 7 | $endif$ 8 | longtable, 9 | $if(a4paper)$ 10 | a4paper, 11 | $endif$ 12 | nolmodern, 13 | notxfonts, 14 | notimes, 15 | $if(nofontenc)$ 16 | nofontenc, 17 | $endif$ 18 | $if(suppress-title-introduction)$ 19 | donotrepeattitle, 20 | $endif$ 21 | $if(biblatex)$ 22 | biblatex, 23 | $endif$ 24 | $if(notab)$ 25 | notab, 26 | $endif$ 27 | $if(helv)$ 28 | helv, 29 | $endif$ 30 | $if(nosf)$ 31 | nosf, 32 | $endif$ 33 | $if(tt)$ 34 | tt, 35 | $endif$ 36 | $if(draftfirst)$ 37 | draftfirst, 38 | $endif$ 39 | $if(draftall)$ 40 | draftall, 41 | $endif$ 42 | $if(mask)$ 43 | mask, 44 | $endif$ 45 | $for(classoption)$ 46 | $classoption$$sep$, 47 | $endfor$ 48 | ]{$documentclass$} 49 | 50 | 51 | -------------------------------------------------------------------------------- /_extensions/apaquarto/docxlinenumber.lua: -------------------------------------------------------------------------------- 1 | --- Makes numbered lines in docx if numbered-lines is true 2 | 3 | --- This filter only runs on docx format 4 | if FORMAT ~= "docx" then 5 | return 6 | end 7 | 8 | function Math(eq) 9 | if eq.mathtype == "InlineMath" then 10 | if eq.text == "\\LaTeX" then 11 | return pandoc.Str("LaTeX") 12 | end 13 | if eq.text == "\\TeX" then 14 | return pandoc.Str("TeX") 15 | end 16 | end 17 | end 18 | 19 | 20 | function Pandoc(doc) 21 | if doc.meta["numbered-lines"] then 22 | if pandoc.utils.stringify(doc.meta["numbered-lines"]) == "true" then 23 | doc.blocks:insert( 24 | pandoc.RawBlock("openxml", 25 | '') 26 | ) 27 | return doc 28 | end 29 | end 30 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/docxstyler.lua: -------------------------------------------------------------------------------- 1 | --- This filter converts the class in customclasses 2 | 3 | --- This filter only runs on docx format 4 | if FORMAT ~= "docx" then 5 | return 6 | end 7 | 8 | --- Is the class included in the customclasses table? 9 | --- https://stackoverflow.com/a/2282542/4513316 10 | function utils_Set(list) 11 | local set = {} 12 | for _, l in ipairs(list) do set[l] = true end 13 | return set 14 | end 15 | 16 | -- Classes that are converted. Add additional classes as needed. 17 | customclasses = { 18 | "Author", 19 | "AuthorNote", 20 | "Abstract", 21 | "AbstractFirstParagraph", 22 | "FigureTitle", 23 | "FigureNote", 24 | "FigureWithNote", 25 | "FigureWithoutNote", 26 | "Caption", 27 | "Compact", 28 | "NoIndent", 29 | "NextBlockText", 30 | "AfterWithoutNote", 31 | "H4", 32 | "H5" 33 | } 34 | 35 | -- Consult some value 36 | _set = utils_Set(customclasses) 37 | 38 | 39 | -- https://jmablog.com/post/pandoc-filters/ 40 | local function customstyler(elem) 41 | if _set[elem.classes[1]] then 42 | elem.attributes['custom-style'] = elem.classes[1] 43 | return elem 44 | end 45 | end 46 | 47 | return { 48 | {Span = customstyler}, 49 | {Div = customstyler} 50 | } 51 | -------------------------------------------------------------------------------- /_extensions/apaquarto/header.tex: -------------------------------------------------------------------------------- 1 | \makeatletter 2 | \renewcommand{\paragraph}{\@startsection{paragraph}{4}{\parindent}% 3 | {0\baselineskip \@plus 0.2ex \@minus 0.2ex}% 4 | {-.5em}% 5 | {\normalfont\normalsize\bfseries\typesectitle}} 6 | 7 | \renewcommand{\subparagraph}[1]{\@startsection{subparagraph}{5}{0.5em}% 8 | {0\baselineskip \@plus 0.2ex \@minus 0.2ex}% 9 | {-\z@\relax}% 10 | {\normalfont\normalsize\bfseries\itshape\hspace{\parindent}{#1}\textit{\addperi}}{\relax}} 11 | \makeatother 12 | 13 | 14 | 15 | 16 | \usepackage{longtable, booktabs, multirow, multicol, colortbl, hhline, caption, array, float, xpatch} 17 | \usepackage{subcaption} 18 | 19 | 20 | \renewcommand\thesubfigure{\Alph{subfigure}} 21 | \setcounter{topnumber}{2} 22 | \setcounter{bottomnumber}{2} 23 | \setcounter{totalnumber}{4} 24 | \renewcommand{\topfraction}{0.85} 25 | \renewcommand{\bottomfraction}{0.85} 26 | \renewcommand{\textfraction}{0.15} 27 | \renewcommand{\floatpagefraction}{0.7} 28 | 29 | \usepackage{tcolorbox} 30 | \tcbuselibrary{listings,theorems, breakable, skins} 31 | \usepackage{fontawesome5} 32 | 33 | \definecolor{quarto-callout-color}{HTML}{909090} 34 | \definecolor{quarto-callout-note-color}{HTML}{0758E5} 35 | \definecolor{quarto-callout-important-color}{HTML}{CC1914} 36 | \definecolor{quarto-callout-warning-color}{HTML}{EB9113} 37 | \definecolor{quarto-callout-tip-color}{HTML}{00A047} 38 | \definecolor{quarto-callout-caution-color}{HTML}{FC5300} 39 | \definecolor{quarto-callout-color-frame}{HTML}{ACACAC} 40 | \definecolor{quarto-callout-note-color-frame}{HTML}{4582EC} 41 | \definecolor{quarto-callout-important-color-frame}{HTML}{D9534F} 42 | \definecolor{quarto-callout-warning-color-frame}{HTML}{F0AD4E} 43 | \definecolor{quarto-callout-tip-color-frame}{HTML}{02B875} 44 | \definecolor{quarto-callout-caution-color-frame}{HTML}{FD7E14} 45 | 46 | %\newlength\Oldarrayrulewidth 47 | %\newlength\Oldtabcolsep 48 | 49 | 50 | \usepackage{hyperref} 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /_extensions/apaquarto/journalmode.lua: -------------------------------------------------------------------------------- 1 | -- Sets journalmode in latex. Latex templates only read logical values. 2 | if FORMAT:match 'latex' then 3 | -- Sets journal mode 4 | function Meta(m) 5 | if m.documentmode then 6 | if pandoc.utils.stringify(m.documentmode) == 'jou' then 7 | m.journalmode = true 8 | m.manuscriptmode = false 9 | m.docmode = false 10 | m.studentmode = false 11 | end 12 | if pandoc.utils.stringify(m.documentmode) == 'man' then 13 | m.journalmode = false 14 | m.manuscriptmode = true 15 | m.docmode = false 16 | m.studentmode = false 17 | end 18 | if pandoc.utils.stringify(m.documentmode) == 'doc' then 19 | m.journalmode = false 20 | m.manuscriptmode = false 21 | m.docmode = true 22 | m.studentmode = false 23 | end 24 | if pandoc.utils.stringify(m.documentmode) == 'stu' then 25 | m.journalmode = false 26 | m.manuscriptmode = false 27 | m.docmode = false 28 | m.studentmode = true 29 | end 30 | else 31 | m.journalmode = false 32 | m.manuscriptmode = true 33 | end 34 | return m 35 | end 36 | 37 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/latexnoindent.lua: -------------------------------------------------------------------------------- 1 | -- Sets paragraph indenting 2 | 3 | if FORMAT:match 'latex' then 4 | 5 | local indenter = '\\setlength\\parindent{0.5in}' 6 | 7 | local setindent = function(m) 8 | if pandoc.utils.stringify(m.documentmode) == 'jou' then 9 | indenter = '\\setlength\\parindent{0.15in}' 10 | end 11 | 12 | end 13 | 14 | local indenter = function(div) 15 | 16 | if div.classes:includes 'NoIndent' then 17 | div.content = div.content:walk { 18 | Para = function(p) 19 | p.content:insert(1, pandoc.RawInline("latex", "\\noindent ")) 20 | return p 21 | end 22 | } 23 | return(div) 24 | end 25 | end 26 | 27 | local fixlatexcommand = function(m) 28 | if m.text == "\\LaTeX" then 29 | return pandoc.RawInline("latex", m.text) 30 | end 31 | end 32 | 33 | return { 34 | { Meta = setindent }, 35 | { Div = indenter }, 36 | { Math = fixlatexcommand} 37 | } 38 | end 39 | 40 | -------------------------------------------------------------------------------- /_extensions/apaquarto/markdowntable.lua: -------------------------------------------------------------------------------- 1 | if FORMAT == "latex" then 2 | return 3 | end 4 | 5 | -- This filter finds and assigns the table identifier in plain 6 | -- markdown tables so that the crossrefprefix.lua filter can find it. 7 | 8 | Table = function(tb) 9 | 10 | if tb.caption.long then 11 | tb.caption.long:walk{ 12 | Str = function(s) 13 | if s.text:find("%{%#tbl%-%w+") then 14 | tb.identifier = s.text:match("tbl%-%w+") 15 | end 16 | end 17 | } 18 | return tb 19 | end 20 | end -------------------------------------------------------------------------------- /_extensions/apaquarto/styles.css: -------------------------------------------------------------------------------- 1 | /* TODO: Use css to format the HTML output */ 2 | -------------------------------------------------------------------------------- /_extensions/apaquarto/title-block.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/_extensions/apaquarto/title-block.html -------------------------------------------------------------------------------- /_extensions/apaquarto/title.tex: -------------------------------------------------------------------------------- 1 | $if(suppress-title)$ 2 | \title{} 3 | $else$ 4 | $if(apatitledisplay)$ 5 | \title{$apatitledisplay$} 6 | $else$ 7 | \title{No Title Set: Set title field in yaml} 8 | $endif$ 9 | $endif$ 10 | 11 | 12 | $if(suppress-short-title)$ 13 | \shorttitle{} 14 | $else$ 15 | $if(shorttitle)$ 16 | \shorttitle{$shorttitle$} 17 | $else$ 18 | $if(apatitle)$ 19 | \shorttitle{$apatitle$} 20 | $else$ 21 | \shorttitle{No Shorttitle Set: Set title or shorttitle in yaml} 22 | $endif$ 23 | $endif$ 24 | $endif$ 25 | 26 | 27 | \usepackage{etoolbox} 28 | 29 | 30 | $if(journal)$ 31 | \journal{$journal$} 32 | $endif$ 33 | $if(volume)$ 34 | \volume{$volume$} 35 | $endif$ 36 | $if(course)$ 37 | \course{$course$} 38 | $endif$ 39 | $if(professor)$ 40 | \professor{$professor$} 41 | $endif$ 42 | $if(duedate)$ 43 | \duedate{$duedate$} 44 | $endif$ 45 | 46 | $if(copyrightnotice)$ 47 | \ccoppy{\textcopyright~$copyrightnotice$} 48 | $endif$ 49 | 50 | $if(copyrighttext)$ 51 | \copnum{$copyrighttext$} 52 | $endif$ 53 | 54 | $if(suppress-author)$ 55 | \author{~} 56 | $else$ 57 | 58 | $if(oneauthor)$ 59 | \author{$for(by-author)$$by-author.apaauthordisplay$$sep$,$endfor$} 60 | $else$ 61 | 62 | $if(oneaffiliation)$ 63 | 64 | \authorsnames{$for(by-author)$$by-author.apaauthordisplay$$sep$,$endfor$} 65 | 66 | $else$ 67 | 68 | $if(affiliationsdifferent)$ 69 | 70 | $if(suppress-affiliation)$ 71 | \authorsnames{$for(by-author)$$by-author.apaauthordisplay$$sep$,$endfor$} 72 | $else$ 73 | \authorsnames[$for(by-author)${$for(by-author.affiliations)$$it.number$$sep$,$endfor$}$sep$,$endfor$]{$for(by-author)$$by-author.apaauthordisplay$$sep$,$endfor$} 74 | $endif$ 75 | 76 | 77 | $else$ 78 | 79 | \authorsnames{$for(by-author)$$by-author.apaauthordisplay$$sep$,$endfor$} 80 | 81 | $endif$ 82 | 83 | $endif$ 84 | 85 | $endif$ 86 | 87 | $endif$ 88 | 89 | $if(suppress-affiliation)$ 90 | \affiliation{} 91 | $else$ 92 | $if(oneaffiliation)$ 93 | 94 | \affiliation{ 95 | $for(by-affiliation)$ 96 | {$if(it.name)$$if(it.department)$$it.department$, $endif$$it.name$$else$$if(it.city)$$it.city$, $endif$$if(it.region)$$it.region$ $endif$$if(it.country)$$it.country$$endif$$endif$}$sep$,$endfor$} 97 | 98 | $else$ 99 | 100 | \authorsaffiliations{ 101 | $for(by-affiliation)$ 102 | {$if(it.name)$$if(it.department)$$it.department$, $endif$$it.name$$else$$if(it.city)$$it.city$, $endif$$if(it.region)$$it.region$ $endif$$if(it.country)$$it.country$$endif$$endif$}$sep$,$endfor$} 103 | 104 | $endif$ 105 | $endif$ 106 | 107 | 108 | 109 | $if(suppress-author)$ 110 | $else$ 111 | \leftheader{$if(by-author/allbutlast)$$for(by-author/allbutlast)$$by-author.name.family$$sep$, $endfor$$for(by-author/last)$ and $by-author.name.family$$endfor$$else$$for(by-author/last)$$by-author.name.family$$endfor$$endif$} 112 | $endif$ 113 | 114 | $if(date)$ 115 | \date{$date$} 116 | $endif$ 117 | 118 | 119 | $if(suppress-abstract)$ 120 | $else$ 121 | $if(abstract)$ 122 | \abstract{$abstract$ $if(impact-statement)$ \section{$language.title-impact-statement$} \noindent $impact-statement$ $endif$} 123 | $endif$ 124 | $endif$ 125 | 126 | $if(suppress-keywords)$ 127 | $else$ 128 | $if(keywords)$\keywords{$for(keywords)$$it$$sep$, $endfor$}$endif$ 129 | $endif$ 130 | 131 | $if(suppress-author-note)$ 132 | $else$ 133 | \authornote{$if(suppress-orcid)$$else$$for(by-author)$$if(it.orcid)$\par{\addORCIDlink{$it.apaauthordisplay$}{$it.orcid$}}$endif$$endfor$$endif$ 134 | $if(suppress-status-change-paragraph)$$else$$if(author-note.status-changes)$\par{$for(author-note.status-changes.affiliation-change)$$it$$sep$$endfor$ $for(author-note.status-changes.deceased)$$it$$sep$$endfor$}$endif$$endif$ 135 | \par{$if(suppress-disclosures-paragraph)$$else$$for(author-note.disclosures.study-registration)$$it$$sep$$endfor$ $for(author-note.disclosures.data-sharing)$$it$$sep$$endfor$ $for(author-note.disclosures.related-report)$$it$$sep$$endfor$ $for(author-note.disclosures.conflict-of-interest)$$it$$sep$$endfor$ $for(author-note.disclosures.financial-support)$$it$$sep$$endfor$ $for(author-note.disclosures.gratitude)$$it$$sep$$endfor$ $for(author-note.disclosures.authorship-agreements)$$it$$sep$$endfor$$endif$ $if(suppress-credit-statement)$$else$${for(by-author/first)}${if(it.roles)}$if(language.title-block-role-introduction)$$language.title-block-role-introduction$ $else$Author roles were classified using the Contributor Role Taxonomy (CRediT; https://credit.niso.org/) as follows: $endif$${for(by-author)}${if(it.roles)}${it.apaauthordisplay}: ${for(it.roles)}${it.role}$sep$, ${endfor}${endif}${endfor}${endif}${endfor}${for(by-author/rest)}${if(it.roles)}${for(by-author)}${if(it.roles)}; ${it.apaauthordisplay}: ${for(it.roles)}${it.role}$sep$, ${endfor}${endif}${endfor}${endif}${endfor}$endif$} 136 | $if(nocorrespondence)$ 137 | $else$ 138 | $if(suppress-corresponding-paragraph)$ 139 | $else$ 140 | $if(author-note.correspondence-note)$ 141 | \par{$author-note.correspondence-note$} 142 | $else$ 143 | \par{$language.title-block-correspondence-note$ $for(by-author)$$if(it.attributes.corresponding)$$it.apaauthordisplay$$for(by-author.affiliations)$$if(it.address)$$if(suppress-corresponding-department)$$else$$if(it.department)$, $it.department$$endif$$endif$$if(suppress-corresponding-affiliation-name)$$else$$if(it.name)$, $it.name$$endif$$endif$$if(suppress-corresponding-address)$$else$$if(it.address)$, $it.address$$endif$$endif$$if(suppress-corresponding-city)$$else$$if(it.city)$, $it.city$$endif$$endif$$if(suppress-corresponding-region)$$else$$if(it.region)$, $it.region$$endif$$endif$$if(suppress-corresponding-postal-code)$$else$$if(it.postal-code)$ $it.postal-code$$endif$$endif$$if(suppress-corresponding-country)$$else$$if(it.country)$, $it.country$$endif$$endif$$endif$$endfor$$if(suppress-corresponding-email)$$else$$if(it.email)$, $language.email$: \href{mailto:$it.email$}{$it.email$}$endif$$endif$$endif$$endfor$} 144 | $endif$ 145 | $endif$ 146 | $endif$ 147 | } 148 | $endif$ 149 | -------------------------------------------------------------------------------- /_extensions/apaquarto/typst/formattypst.lua: -------------------------------------------------------------------------------- 1 | if FORMAT ~='typst' then 2 | return 3 | end 4 | 5 | 6 | 7 | return { 8 | { 9 | -- Replace LaTeX logo 10 | Math = function(eq) 11 | if eq.mathtype == "InlineMath" then 12 | if eq.text == "\\LaTeX" then 13 | return pandoc.Str("LaTeX") 14 | end 15 | if eq.text == "\\TeX" then 16 | return pandoc.Str("TeX") 17 | end 18 | end 19 | end 20 | }, 21 | { 22 | Div = function(div) 23 | -- Center author and affiliation 24 | if div.classes:includes("Author") then 25 | return {pandoc.RawBlock('typst', "#set align(center)"), div, pandoc.RawBlock('typst', "#set align(left)")} 26 | end 27 | 28 | -- Hanging indent on refs 29 | if div.identifier == "refs" then 30 | return {pandoc.RawBlock("typst", "#set par(first-line-indent: 0in, hanging-indent: 0.5in)"), div, pandoc.RawBlock("typst","#set par(first-line-indent: 0.5in, hanging-indent: 0in)") } 31 | end 32 | 33 | if div.classes:includes("NoIndent") then 34 | return {pandoc.RawBlock('typst', "#set par(first-line-indent: 0mm)"), div, pandoc.RawBlock('typst', "#set par(first-line-indent: firstlineindent)")} 35 | end 36 | end 37 | } , 38 | { 39 | Pandoc = function (doc) 40 | -- typst aggressively wants to make first paragraphs after something not indented. 41 | -- APA style wants almost all paragraphs to be indented. 42 | -- This function inserts a blank paragraph and then negative vertical space 43 | -- before any first paragraph. Hoping that typst will fix this and that this function 44 | -- becomes unnecessary. 45 | local appendixword = "Appendix" 46 | if doc.meta.language and doc.meta.language["crossref-apx-prefix"] then 47 | appendixword = pandoc.utils.stringify(doc.meta.language["crossref-apx-prefix"]) 48 | end 49 | 50 | for i = #doc.blocks, 1, -1 do 51 | if doc.blocks[i].t == "Para" and doc.blocks[i-1].t ~= "Para" then 52 | if doc.blocks[i-1].t == "Header" and doc.blocks[i-1].level > 3 then 53 | --Do nothing 54 | else 55 | doc.blocks:insert(i, pandoc.RawBlock("typst", "#par()[#text(size:0.5em)[#h(0.0em)]]\n#v(-18pt)")) 56 | end 57 | end 58 | -- Count appendices 59 | if doc.blocks[i].t == "Header" and doc.blocks[i].level == 1 and doc.blocks[i].content[1].text == appendixword then 60 | doc.blocks:insert(i+1, pandoc.RawBlock("typst", "#counter(figure.where(kind: \"quarto-float-fig\")).update(0)\n#counter(figure.where(kind: \"quarto-float-tbl\")).update(0)\n#appendixcounter.step()")) 61 | end 62 | end 63 | return doc 64 | end 65 | } 66 | } -------------------------------------------------------------------------------- /_extensions/apaquarto/typst/typst-show.typ: -------------------------------------------------------------------------------- 1 | #show: document => $documentmode$( 2 | $if(suppress-short-title)$ 3 | $else$ 4 | $if(shorttitle)$ 5 | runninghead: "$shorttitle$", 6 | $else$ 7 | $if(title)$ 8 | runninghead: "$title$", 9 | $endif$ 10 | $endif$ 11 | $endif$ 12 | $if(papersize)$ 13 | paper: "$papersize$", 14 | $endif$ 15 | $if(margin)$ 16 | margin: ($for(margin/pairs)$$margin.key$: $margin.value$,$endfor$), 17 | $endif$ 18 | $if(mainfont)$ 19 | font: ("$mainfont$",), 20 | $endif$ 21 | $if(fontsize)$ 22 | fontsize: $fontsize$, 23 | $endif$ 24 | $if(leading)$ 25 | leading: $leading$, 26 | spacing: $leading$, 27 | $endif$ 28 | $if(spacing)$ 29 | spacing: $spacing$, 30 | leading: $leading$ 31 | $endif$ 32 | $if(lang)$ 33 | lang: "$lang$", 34 | $endif$ 35 | $if(cols)$ 36 | cols: $cols$, 37 | $endif$ 38 | $if(toc)$ 39 | toc: "true", 40 | $endif$ 41 | document, 42 | ) 43 | -------------------------------------------------------------------------------- /_extensions/apaquarto/typst/typst-template.typ: -------------------------------------------------------------------------------- 1 | //#assert(sys.version.at(1) >= 11 or sys.version.at(0) > 0, message: "This template requires Typst Version 0.11.0 or higher. The version of Quarto you are using uses Typst version is " + str(sys.version.at(0)) + "." + str(sys.version.at(1)) + "." + str(sys.version.at(2)) + ". You will need to upgrade to Quarto 1.5 or higher to use apaquarto-typst.") 2 | 3 | // counts how many appendixes there are 4 | #let appendixcounter = counter("appendix") 5 | // make latex logo 6 | // https://github.com/typst/typst/discussions/1732#discussioncomment-11286036 7 | #let TeX = { 8 | set text(font: "New Computer Modern",) 9 | let t = "T" 10 | let e = text(baseline: 0.22em, "E") 11 | let x = "X" 12 | box(t + h(-0.14em) + e + h(-0.14em) + x) 13 | } 14 | 15 | #let LaTeX = { 16 | set text(font: "New Computer Modern") 17 | let l = "L" 18 | let a = text(baseline: -0.35em, size: 0.66em, "A") 19 | box(l + h(-0.32em) + a + h(-0.13em) + TeX) 20 | } 21 | 22 | #let firstlineindent=0.5in 23 | 24 | 25 | 26 | // documentmode: man 27 | #let man( 28 | title: none, 29 | runninghead: none, 30 | margin: (x: 1in, y: 1in), 31 | paper: "us-letter", 32 | font: ("Times", "Times New Roman"), 33 | fontsize: 12pt, 34 | leading: 18pt, 35 | spacing: 18pt, 36 | firstlineindent: 0.5in, 37 | toc: false, 38 | lang: "en", 39 | cols: 1, 40 | doc, 41 | ) = { 42 | 43 | set page( 44 | margin: margin, 45 | paper: paper, 46 | header-ascent: 50%, 47 | header: grid( 48 | columns: (9fr, 1fr), 49 | align(left)[#upper[#runninghead]], 50 | align(right)[#context counter(page).display()] 51 | ) 52 | ) 53 | 54 | 55 | 56 | 57 | set table( 58 | stroke: (x, y) => ( 59 | top: if y <= 1 { 0.5pt } else { 0pt }, 60 | bottom: .5pt, 61 | ) 62 | ) 63 | 64 | set par( 65 | justify: false, 66 | leading: leading, 67 | first-line-indent: firstlineindent 68 | ) 69 | 70 | // Also "leading" space between paragraphs 71 | set block(spacing: spacing, above: spacing, below: spacing) 72 | 73 | set text( 74 | font: font, 75 | size: fontsize, 76 | lang: lang 77 | ) 78 | 79 | show link: set text(blue) 80 | 81 | show quote: set pad(x: 0.5in) 82 | show quote: set par(leading: leading) 83 | show quote: set block(spacing: spacing, above: spacing, below: spacing) 84 | // show LaTeX 85 | show "TeX": TeX 86 | show "LaTeX": LaTeX 87 | 88 | // format figure captions 89 | show figure.where(kind: "quarto-float-fig"): it => block(width: 100%, breakable: false)[ 90 | #if int(appendixcounter.display().at(0)) > 0 [ 91 | #heading(level: 2, outlined: false)[#it.supplement #appendixcounter.display("A")#it.counter.display()] 92 | ] else [ 93 | #heading(level: 2, outlined: false)[#it.supplement #it.counter.display()] 94 | ] 95 | #align(left)[#par[#emph[#it.caption.body]]] 96 | #align(center)[#it.body] 97 | ] 98 | 99 | // format table captions 100 | show figure.where(kind: "quarto-float-tbl"): it => block(width: 100%, breakable: false)[#align(left)[ 101 | 102 | #if int(appendixcounter.display().at(0)) > 0 [ 103 | #heading(level: 2, outlined: false)[#it.supplement #appendixcounter.display("A")#it.counter.display()] 104 | ] else [ 105 | #heading(level: 2, outlined: false)[#it.supplement #it.counter.display()] 106 | ] 107 | #par[#emph[#it.caption.body]] 108 | #block[#it.body] 109 | ]] 110 | 111 | // Redefine headings up to level 5 112 | show heading.where( 113 | level: 1 114 | ): it => block(width: 100%, below: leading, above: leading)[ 115 | #set align(center) 116 | #set text(size: fontsize) 117 | #it.body 118 | ] 119 | 120 | show heading.where( 121 | level: 2 122 | ): it => block(width: 100%, below: leading, above: leading)[ 123 | #set align(left) 124 | #set text(size: fontsize) 125 | #it.body 126 | ] 127 | 128 | show heading.where( 129 | level: 3 130 | ): it => block(width: 100%, below: leading, above: leading)[ 131 | #set align(left) 132 | #set text(size: fontsize, style: "italic") 133 | #it.body 134 | ] 135 | 136 | show heading.where( 137 | level: 4 138 | ): it => text( 139 | size: 1em, 140 | weight: "bold", 141 | it.body 142 | ) 143 | 144 | show heading.where( 145 | level: 5 146 | ): it => text( 147 | size: 1em, 148 | weight: "bold", 149 | style: "italic", 150 | it.body 151 | ) 152 | 153 | if cols == 1 { 154 | doc 155 | } else { 156 | columns(cols, gutter: 4%, doc) 157 | } 158 | 159 | 160 | } 161 | 162 | -------------------------------------------------------------------------------- /_extensions/apaquarto/wordcount.lua: -------------------------------------------------------------------------------- 1 | local word_count = 0 2 | 3 | local function count_words_in_string(str) 4 | local _, count = string.gsub(str, "%S+", "") 5 | return count 6 | end 7 | 8 | 9 | local function count_words_in_inlines(inlines) 10 | for _, inline in ipairs(inlines) do 11 | if inline.t == "Str" then 12 | if inline.text:match("%P") then 13 | word_count = word_count + 1 14 | end 15 | end 16 | if inline.t == "Code" or inline.t == "CodeBlock" then 17 | 18 | word_count = word_count + count_words_in_string(inline.text) 19 | end 20 | 21 | if inline.t == "Cite" then 22 | word_count = word_count + 1 23 | end 24 | 25 | if inline.t == "Span" or inline.t == "Emph" or inline.t == "Strong" or inline.t == "Link" or inline.t == "Quoted" or inline.t == "Para" or inline.t == "Strikeout" then 26 | count_words_in_inlines(inline.content) 27 | end 28 | end 29 | end 30 | 31 | local function processblocks(b) 32 | 33 | for _, block in ipairs(b) do 34 | if block.t == "Para" or block.t == "Plain" or block.t == "Header" or block.t == "BlockQuote" then 35 | count_words_in_inlines(block.content) 36 | end 37 | if block.t == "Div" then 38 | processblocks(block.content) 39 | end 40 | end 41 | end 42 | 43 | function Note(el) 44 | processblocks(el.content) 45 | end 46 | 47 | function Math(el) 48 | word_count = word_count + count_words_in_string(el.text) 49 | end 50 | 51 | function CodeBlock(el) 52 | word_count = word_count + count_words_in_string(el.text) 53 | end 54 | 55 | function BulletList(el) 56 | for _, block in ipairs(el.content) do 57 | processblocks(block) 58 | end 59 | end 60 | 61 | function OrderedList(el) 62 | for _, block in ipairs(el.content) do 63 | processblocks(block) 64 | end 65 | end 66 | 67 | function DefinitionList(el) 68 | for _, block in ipairs(el.content) do 69 | processblocks(block) 70 | end 71 | end 72 | 73 | function Pandoc(doc) 74 | processblocks(doc.blocks) 75 | doc.meta.wordn = word_count 76 | return doc 77 | end 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /_quarto.yml: -------------------------------------------------------------------------------- 1 | project: 2 | type: website 3 | output-dir: docs 4 | render: 5 | - index.qmd 6 | - installation.qmd 7 | - options.qmd 8 | - writing.qmd 9 | - resources.qmd 10 | - changelog.qmd 11 | 12 | website: 13 | title: "APA Style Documents with apaquarto" 14 | navbar: 15 | left: 16 | - text: Introduction 17 | href: index.qmd 18 | - installation.qmd 19 | - options.qmd 20 | - writing.qmd 21 | - resources.qmd 22 | - changelog.qmd 23 | right: 24 | - icon: github 25 | href: https://github.com/wjschne/apaquarto 26 | text: Source 27 | 28 | bibliography: bibliography.bib 29 | 30 | knitr: true 31 | 32 | format: 33 | html: 34 | theme: 35 | - spacelab 36 | - apaquarto.scss 37 | tbl-cap-location: top 38 | toc: true 39 | toc-location: left 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /apaquarto.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: a541ce95-7477-460a-85bc-f0675c35fe1c 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: knitr 14 | LaTeX: XeLaTeX 15 | 16 | BuildType: Makefile 17 | -------------------------------------------------------------------------------- /apaquarto.scss: -------------------------------------------------------------------------------- 1 | /*-- scss:defaults --*/ 2 | 3 | 4 | /*-- scss:rules --*/ 5 | 6 | pre>code.sourceCode {white-space: pre-wrap;} 7 | 8 | p code:not(.sourceCode), li code:not(.sourceCode), td code:not(.sourceCode) { 9 | background: transparent; 10 | 11 | } 12 | 13 | tr:nth-child(even) { 14 | background-color: #e1e7ed; 15 | } 16 | 17 | li.nav-item {border-color: red;} 18 | 19 | -------------------------------------------------------------------------------- /bibliography.bib: -------------------------------------------------------------------------------- 1 | @book{brownHowKilledPluto2012, 2 | address = {New York}, 3 | title = {How {I} killed {Pluto} and why it had it coming}, 4 | publisher = {Spiegel \& Grau}, 5 | author = {Brown, Mike}, 6 | year = {2012}, 7 | } 8 | 9 | @book{CameronTrivedi2013, 10 | author = {A. Colin Cameron and Pravin K. Trivedi}, 11 | title = {Regression Analysis of Count Data}, 12 | year = {2013}, 13 | edition = {2nd}, 14 | publisher = {Cambridge University Press}, 15 | address = {Cambridge}, 16 | doi = {10.1017/CBO9781139013567} 17 | } 18 | @book{cohen2003applied, 19 | title = {Applied multiple regression/correlation analysis for the behavioral sciences}, 20 | author = {Cohen, Jacob and Cohen, Patricia and West, Stephen G and Aiken, Leona S}, 21 | year = {2003}, 22 | edition = {3rd}, 23 | publisher = {Lawrence Erlbaum Associates} 24 | } 25 | @book{austenMansfieldPark1990, 26 | title = {Mansfield {P}ark}, 27 | author = {Austen, Jane}, 28 | year = {1990}, 29 | origdate = {1814}, 30 | publisher = {Oxford University Press} 31 | } 32 | 33 | @incollection{schneider2012cattell, 34 | title = {The {{Cattell-Horn-Carroll}} Model of Intelligence}, 35 | booktitle = {Contemporary Intellectual Assessment: {{Theories}}, Tests, and Issues}, 36 | author = {Schneider, William Joel and McGrew, Kevin S.}, 37 | editor = {Flanagan, Dawn P. and Harrison, Patti L.}, 38 | date = {2012}, 39 | edition = {3}, 40 | pages = {99--144}, 41 | publisher = {Guilford Press}, 42 | location = {New York}, 43 | url = {https://psycnet.apa.org/record/2012-09043-004}, 44 | isbn = {978-1-60918-995-2}, 45 | annotation = {pubid:roLk4NBRz8UC} 46 | } 47 | @article{schneider2015intelligence, 48 | title={Intelligence is multidimensional: Theoretical review and implications of specific cognitive abilities}, 49 | author={Schneider, W Joel and Newman, Daniel A}, 50 | journal={Human Resource Management Review}, 51 | volume={25}, 52 | number={1}, 53 | pages={12--27}, 54 | year={2015}, 55 | publisher={Elsevier} 56 | } 57 | @article{bentley1929instructions, 58 | title={Instructions in regard to preparation of manuscript.}, 59 | author={Bentley, Madison and Peerenboom, CA and Hodge, FW and Passano, Edward B and Warren, HC and Washburn, MF}, 60 | journal={Psychological Bulletin}, 61 | volume={26}, 62 | number={2}, 63 | pages={57}, 64 | year={1929}, 65 | publisher={Psychological Review Company} 66 | } 67 | @book{americanpsychologicalassociationPublicationManualAmerican2020, 68 | title = {Publication Manual of the {American Psychological Association}}, 69 | author = {{American Psychological Association}}, 70 | year = {2020}, 71 | edition = {7}, 72 | publisher = {Author}, 73 | address = {Washington, D.C.}, 74 | doi = {10.1037/0000173-000}, 75 | } 76 | @book{ConciseGuideAPA2020, 77 | title = {Concise Guide to {{APA Style}}: {{The}} Official {{APA Style}} Guide for Students (7th Ed.).}, 78 | shorttitle = {Concise Guide to {{APA Style}}}, 79 | year = {2020}, 80 | author = {{American Psychological Association}}, 81 | publisher = {Author}, 82 | address = {Washington}, 83 | doi = {10.1037/0000173-000}, 84 | url = {http://content.apa.org/books/16157-000}, 85 | urldate = {2024-03-02}, 86 | isbn = {978-1-4338-3273-4 978-1-4338-3276-5}, 87 | langid = {english} 88 | } 89 | @book{americanpsychologicalassociationMasteringAPAStyle2021, 90 | title = {Mastering {APA Style} student workbook.}, 91 | year = {2021}, 92 | author = {{American Psychological Association}}, 93 | publisher = {Author}, 94 | address = {Washington}, 95 | doi = {10.1037/0000271-000}, 96 | isbn = {978-1-4338-3854-5}, 97 | langid = {english} 98 | } 99 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/.nojekyll -------------------------------------------------------------------------------- /docs/example_journal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/example_journal.pdf -------------------------------------------------------------------------------- /docs/example_manuscript.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/example_manuscript.pdf -------------------------------------------------------------------------------- /docs/img/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/console.png -------------------------------------------------------------------------------- /docs/img/insertchunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/insertchunk.png -------------------------------------------------------------------------------- /docs/img/keyboardwithbacktick.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/keyboardwithbacktick.jpeg -------------------------------------------------------------------------------- /docs/img/menuworkingdirectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/menuworkingdirectory.png -------------------------------------------------------------------------------- /docs/img/newquartodocument.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/newquartodocument.png -------------------------------------------------------------------------------- /docs/img/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/img/terminal.png -------------------------------------------------------------------------------- /docs/sampleimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/sampleimage.png -------------------------------------------------------------------------------- /docs/site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.11 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1 { 2 | function guessOS() { 3 | const userAgent = window.navigator.userAgent; 4 | if (userAgent.includes("Mac OS")) { 5 | return { 6 | name: "mac", 7 | }; 8 | } else if (userAgent.includes("Windows")) { 9 | return { 10 | name: "windows", 11 | }; 12 | } else { 13 | return { 14 | name: "linux", 15 | }; 16 | } 17 | } 18 | const os = guessOS(); 19 | 20 | // deno-lint-ignore no-window-prefix 21 | window.addEventListener("DOMContentLoaded", (_) => { 22 | for (const el of Array.from(document.querySelectorAll("kbd"))) { 23 | el.classList.add("kbd"); 24 | if (el.dataset[os.name] !== undefined) { 25 | el.innerText = el.dataset[os.name]; 26 | } 27 | if (os.name === "mac") { 28 | el.innerText = el.innerText 29 | .replaceAll(/command-?/gi, "⌘") 30 | .replaceAll(/cmd-?/gi, "⌘") 31 | .replaceAll(/shift-?/gi, "⇧") 32 | .replaceAll(/ctrl-?/gi, "⌃") 33 | .replaceAll(/control-?/gi, "⌃") 34 | .replaceAll(/option-?/gi, "⌥"); 35 | } 36 | } 37 | }); 38 | })(); 39 | -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/anchor.min.js: -------------------------------------------------------------------------------- 1 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 2 | // 3 | // AnchorJS - v5.0.0 - 2023-01-18 4 | // https://www.bryanbraun.com/anchorjs/ 5 | // Copyright (c) 2023 Bryan Braun; Licensed MIT 6 | // 7 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 8 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(globalThis,function(){"use strict";return function(A){function u(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function d(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],u(this.options),this.add=function(A){var e,t,o,i,n,s,a,r,l,c,h,p=[];if(u(this.options),0!==(e=d(A=A||"h2, h3, h4, h5, h6")).length){for(null===document.head.querySelector("style.anchorjs")&&((A=document.createElement("style")).className="anchorjs",A.appendChild(document.createTextNode("")),void 0===(h=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(A):document.head.insertBefore(A,h),A.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",A.sheet.cssRules.length),A.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); 9 | // @license-end -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/quarto-syntax-highlighting-81b5c3e63835cfde897ecd3d35a35a41.css: -------------------------------------------------------------------------------- 1 | /* quarto syntax highlight colors */ 2 | :root { 3 | --quarto-hl-ot-color: #003B4F; 4 | --quarto-hl-at-color: #657422; 5 | --quarto-hl-ss-color: #20794D; 6 | --quarto-hl-an-color: #5E5E5E; 7 | --quarto-hl-fu-color: #4758AB; 8 | --quarto-hl-st-color: #20794D; 9 | --quarto-hl-cf-color: #003B4F; 10 | --quarto-hl-op-color: #5E5E5E; 11 | --quarto-hl-er-color: #AD0000; 12 | --quarto-hl-bn-color: #AD0000; 13 | --quarto-hl-al-color: #AD0000; 14 | --quarto-hl-va-color: #111111; 15 | --quarto-hl-bu-color: inherit; 16 | --quarto-hl-ex-color: inherit; 17 | --quarto-hl-pp-color: #AD0000; 18 | --quarto-hl-in-color: #5E5E5E; 19 | --quarto-hl-vs-color: #20794D; 20 | --quarto-hl-wa-color: #5E5E5E; 21 | --quarto-hl-do-color: #5E5E5E; 22 | --quarto-hl-im-color: #00769E; 23 | --quarto-hl-ch-color: #20794D; 24 | --quarto-hl-dt-color: #AD0000; 25 | --quarto-hl-fl-color: #AD0000; 26 | --quarto-hl-co-color: #5E5E5E; 27 | --quarto-hl-cv-color: #5E5E5E; 28 | --quarto-hl-cn-color: #8f5902; 29 | --quarto-hl-sc-color: #5E5E5E; 30 | --quarto-hl-dv-color: #AD0000; 31 | --quarto-hl-kw-color: #003B4F; 32 | } 33 | 34 | /* other quarto variables */ 35 | :root { 36 | --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 37 | } 38 | 39 | pre > code.sourceCode > span { 40 | color: #003B4F; 41 | } 42 | 43 | code span { 44 | color: #003B4F; 45 | } 46 | 47 | code.sourceCode > span { 48 | color: #003B4F; 49 | } 50 | 51 | div.sourceCode, 52 | div.sourceCode pre.sourceCode { 53 | color: #003B4F; 54 | } 55 | 56 | code span.ot { 57 | color: #003B4F; 58 | font-style: inherit; 59 | } 60 | 61 | code span.at { 62 | color: #657422; 63 | font-style: inherit; 64 | } 65 | 66 | code span.ss { 67 | color: #20794D; 68 | font-style: inherit; 69 | } 70 | 71 | code span.an { 72 | color: #5E5E5E; 73 | font-style: inherit; 74 | } 75 | 76 | code span.fu { 77 | color: #4758AB; 78 | font-style: inherit; 79 | } 80 | 81 | code span.st { 82 | color: #20794D; 83 | font-style: inherit; 84 | } 85 | 86 | code span.cf { 87 | color: #003B4F; 88 | font-weight: bold; 89 | font-style: inherit; 90 | } 91 | 92 | code span.op { 93 | color: #5E5E5E; 94 | font-style: inherit; 95 | } 96 | 97 | code span.er { 98 | color: #AD0000; 99 | font-style: inherit; 100 | } 101 | 102 | code span.bn { 103 | color: #AD0000; 104 | font-style: inherit; 105 | } 106 | 107 | code span.al { 108 | color: #AD0000; 109 | font-style: inherit; 110 | } 111 | 112 | code span.va { 113 | color: #111111; 114 | font-style: inherit; 115 | } 116 | 117 | code span.bu { 118 | font-style: inherit; 119 | } 120 | 121 | code span.ex { 122 | font-style: inherit; 123 | } 124 | 125 | code span.pp { 126 | color: #AD0000; 127 | font-style: inherit; 128 | } 129 | 130 | code span.in { 131 | color: #5E5E5E; 132 | font-style: inherit; 133 | } 134 | 135 | code span.vs { 136 | color: #20794D; 137 | font-style: inherit; 138 | } 139 | 140 | code span.wa { 141 | color: #5E5E5E; 142 | font-style: italic; 143 | } 144 | 145 | code span.do { 146 | color: #5E5E5E; 147 | font-style: italic; 148 | } 149 | 150 | code span.im { 151 | color: #00769E; 152 | font-style: inherit; 153 | } 154 | 155 | code span.ch { 156 | color: #20794D; 157 | font-style: inherit; 158 | } 159 | 160 | code span.dt { 161 | color: #AD0000; 162 | font-style: inherit; 163 | } 164 | 165 | code span.fl { 166 | color: #AD0000; 167 | font-style: inherit; 168 | } 169 | 170 | code span.co { 171 | color: #5E5E5E; 172 | font-style: inherit; 173 | } 174 | 175 | code span.cv { 176 | color: #5E5E5E; 177 | font-style: italic; 178 | } 179 | 180 | code span.cn { 181 | color: #8f5902; 182 | font-style: inherit; 183 | } 184 | 185 | code span.sc { 186 | color: #5E5E5E; 187 | font-style: inherit; 188 | } 189 | 190 | code span.dv { 191 | color: #AD0000; 192 | font-style: inherit; 193 | } 194 | 195 | code span.kw { 196 | color: #003B4F; 197 | font-weight: bold; 198 | font-style: inherit; 199 | } 200 | 201 | .prevent-inlining { 202 | content: ".tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} -------------------------------------------------------------------------------- /docs/site_libs/quarto-nav/headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); 8 | -------------------------------------------------------------------------------- /docs/site_libs/tabwid-1.1.3/tabwid.css: -------------------------------------------------------------------------------- 1 | .tabwid { 2 | font-size: initial; 3 | padding-bottom: 1em; 4 | } 5 | 6 | .tabwid table{ 7 | border-spacing:0px !important; 8 | border-collapse:collapse; 9 | line-height:1; 10 | margin-left:auto; 11 | margin-right:auto; 12 | border-width: 0; 13 | border-color: transparent; 14 | caption-side: top; 15 | } 16 | .tabwid-caption-bottom table{ 17 | caption-side: bottom; 18 | } 19 | .tabwid_left table{ 20 | margin-left:0; 21 | } 22 | .tabwid_right table{ 23 | margin-right:0; 24 | } 25 | .tabwid td, .tabwid th { 26 | padding: 0; 27 | } 28 | .tabwid a { 29 | text-decoration: none; 30 | } 31 | .tabwid thead { 32 | background-color: transparent; 33 | } 34 | .tabwid tfoot { 35 | background-color: transparent; 36 | } 37 | .tabwid table tr { 38 | background-color: transparent; 39 | } 40 | .katex-display { 41 | margin: 0 0 !important; 42 | } 43 | -------------------------------------------------------------------------------- /docs/site_libs/tabwid-1.1.3/tabwid.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function(event) { 2 | var els = document.querySelectorAll(".tabwid"); 3 | var tabwid_link = document.querySelector('link[href*="tabwid.css"]') 4 | if (tabwid_link === null) { 5 | const tabwid_styles = document.evaluate("//style[contains(., 'tabwid')]", document, null, XPathResult.ANY_TYPE, null ); 6 | tabwid_link = tabwid_styles.iterateNext(); 7 | } 8 | 9 | Array.prototype.forEach.call(els, function(template) { 10 | const dest = document.createElement("div"); 11 | template.parentNode.insertBefore(dest, template.nextSibling) 12 | dest.setAttribute("class", "flextable-shadow-host"); 13 | const fantome = dest.attachShadow({mode: 'open'}); 14 | fantome.appendChild(template); 15 | if (tabwid_link !== null) { 16 | fantome.appendChild(tabwid_link.cloneNode(true)); 17 | } 18 | }); 19 | 20 | const shadowHosts = document.querySelectorAll('.flextable-shadow-host:not(:has(div > table.no-shadow-dom))'); 21 | shadowHosts.forEach(host => { 22 | if (host.shadowRoot) { 23 | const spanElements = host.shadowRoot.querySelector('div > table > caption > span[id]'); 24 | if (spanElements) { 25 | const id = spanElements.getAttribute("id"); 26 | host.setAttribute("id", id); 27 | } 28 | } 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /docs/writing_files/figure-html/fig-myplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/writing_files/figure-html/fig-myplot-1.png -------------------------------------------------------------------------------- /docs/writing_files/figure-html/fig-myplot2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/writing_files/figure-html/fig-myplot2-1.png -------------------------------------------------------------------------------- /docs/writing_files/figure-html/fig-myplot3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/docs/writing_files/figure-html/fig-myplot3-1.png -------------------------------------------------------------------------------- /example_journal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/example_journal.pdf -------------------------------------------------------------------------------- /example_manuscript.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/example_manuscript.pdf -------------------------------------------------------------------------------- /img/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/console.png -------------------------------------------------------------------------------- /img/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/cover.png -------------------------------------------------------------------------------- /img/docx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/docx.png -------------------------------------------------------------------------------- /img/insertchunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/insertchunk.png -------------------------------------------------------------------------------- /img/journalmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/journalmode.png -------------------------------------------------------------------------------- /img/keyboardwithbacktick.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/keyboardwithbacktick.jpeg -------------------------------------------------------------------------------- /img/menuworkingdirectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/menuworkingdirectory.png -------------------------------------------------------------------------------- /img/newquartodocument.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/newquartodocument.png -------------------------------------------------------------------------------- /img/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/terminal.png -------------------------------------------------------------------------------- /img/yamlmetadata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/img/yamlmetadata.png -------------------------------------------------------------------------------- /index.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to apaquarto" 3 | engine: knitr 4 | --- 5 | 6 | Style guides facilitate scientific communication. Because scholars often write about inherently difficult topics, preventing any *avoidable* barriers to communication is all the more necessary. Style guides make information easier to absorb because it is presented in a predictable sequence and a familiar format. Still, in removing unnecessary barriers to communication on the reader's end, style guides themselves often place unnecessary roadblocks before the writer. 7 | 8 | [APA style](https://apastyle.apa.org/) is fussier than most discipline-specific guides. Because it was introduced in the pre-computer age [@bentley1929instructions], its quirks and charms resist easy automation. Even after decades of experience, I still need to look things up. Constantly. The basics of APA style are easy enough to learn, but there are a lot of particulars to keep in mind. Not only are there rules and exceptions to rules to remember, there are exceptions to the exceptions that must not be forgotten. 9 | 10 | I wrote [apaquarto](https://github.com/wjschne/apaquarto) so that I would never have to worry about APA style ever again. With very little extra effort, your documents are formatted according to APA style. In @fig-manuscript we see an example of apaquarto's output to "manuscript mode". Switching the document to "journal model, produces output formatted like an APA journal (see @fig-journal). 11 | 12 | ::: {#fig-manuscript fig-cap="Example document in manuscript mode"} 13 | ```{=html} 14 |

Unable to display PDF file. Download instead.

15 | ``` 16 | ::: 17 | 18 | ::: {#fig-journal fig-cap="Example document in journal mode"} 19 | ```{=html} 20 |

Unable to display PDF file. Download instead.

21 | ``` 22 | ::: 23 | 24 | # Quarto makes writing scientific documents easier 25 | 26 | The apaquarto extension is built on [Quarto](https://quarto.org/), an open-source publishing system specifically adapted for scientific and technical documents such as journal articles, books, blogs, slides, and dashboards, and websites. Not only does Quarto offer considerable flexibility by itself, it was designed to be extensible. Thus, Quarto can take care of most of the formatting, and an extension can be written to handle whatever specific formatting rules a style guide requires. The apaquarto extension takes care of all the fussy details of APA-style so that you can focus on the content of your writing. 27 | 28 | **You do not need to know any programming languages to use Quarto.** You can use it in a completely non-technical way to write well-formatted text, tables, figures, and references. However, if your document communicates the results from data analyses, then Quarto offers you something quite remarkable. You can perform your analyses and communicate your findings in the same file! That is, you write text and code together in a source document and then you "render" the document into its final format (e.g., .html, .pdf, .docx). So instead of performing your analyses elsewhere (e.g., SPSS) and then copying the results into a word processor (e.g., MS Word), you build your document in one step. 29 | 30 | The advantages of this kind of workflow are profound. If you discover a mistake in your analysis, there is no need to find and replace the primary results and their downstream consequences scattered throughout the document. Instead, you just re-render the document, and everything in it is updated. When the document is published, the Quarto file serves as a fully reproducible record of your analysis. Making the Quarto file available in a public repository increases trust in your work because anyone can inspect it and trace any result you report back to the source code that created it. 31 | -------------------------------------------------------------------------------- /references.bib: -------------------------------------------------------------------------------- 1 | 2 | @inbook{ 3 | schneiderCattellHornCarrollTheoryCognitive2018, 4 | place={New York}, 5 | edition={4}, 6 | title={The Cattell-Horn-Carroll theory of cognitive abilities}, 7 | ISBN={978-1-4625-3578-1}, 8 | url={https://www.guilford.com/books/Contemporary-Intellectual-Assessment/Flanagan-McDonough/9781462552030}, 9 | booktitle={Contemporary intellectual assessment: Theories, tests, and issues}, 10 | publisher={Guilford Press}, 11 | author={Schneider, William Joel and McGrew, Kevin S}, 12 | editor={Flanagan, Dawn P. and McDonough, Erin M.}, 13 | year={2018}, 14 | pages={73–130} } 15 | 16 | @inbook{ 17 | schneiderCattellHornCarrollTheoryCognitive2018, 18 | place={New York}, 19 | edition={4}, 20 | title={The Cattell-Horn-Carroll theory of cognitive abilities}, 21 | ISBN={978-1-4625-3578-1}, 22 | url={https://www.guilford.com/books/Contemporary-Intellectual-Assessment/Flanagan-McDonough/9781462552030}, 23 | booktitle={Contemporary intellectual assessment: Theories, tests, and issues}, 24 | publisher={Guilford Press}, 25 | author={Schneider, William Joel and McGrew, Kevin S}, 26 | editor={Flanagan, Dawn P. and McDonough, Erin M.}, 27 | year={2018}, 28 | pages={73–130} } 29 | 30 | @inbook{ 31 | schneiderCattellHornCarrollTheoryCognitive2018, 32 | place={New York}, 33 | edition={4}, 34 | title={The Cattell-Horn-Carroll theory of cognitive abilities}, 35 | ISBN={978-1-4625-3578-1}, 36 | url={https://www.guilford.com/books/Contemporary-Intellectual-Assessment/Flanagan-McDonough/9781462552030}, 37 | booktitle={Contemporary intellectual assessment: Theories, tests, and issues}, 38 | publisher={Guilford Press}, 39 | author={Schneider, William Joel and McGrew, Kevin S}, 40 | editor={Flanagan, Dawn P. and McDonough, Erin M.}, 41 | year={2018}, 42 | pages={73–130} } 43 | -------------------------------------------------------------------------------- /resources.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Resources" 3 | csl: apa-cv.csl 4 | suppress-bibliography: true 5 | bibliography: bibliography.bib 6 | --- 7 | 8 | ## APA-Style Online 9 | 10 | * [APA Style (apa.org)](https://apastyle.apa.org/) 11 | * [APA Style Blog](https://apastyle.apa.org/blog) 12 | 13 | 14 | ## APA-Style Books 15 | 16 | * @americanpsychologicalassociationPublicationManualAmerican2020 17 | * @ConciseGuideAPA2020 18 | * @americanpsychologicalassociationMasteringAPAStyle2021 19 | 20 | ## APA-Style Helper Functions in R 21 | 22 | Many packages have helper functions for reporting statistics in and creating tables and figures in APA Style. Here are a few: 23 | 24 | * [rempsyc](https://rempsyc.remi-theriault.com/index.html) 25 | * [papaja](https://frederikaust.com/papaja_man/reporting.html) 26 | * [apa](https://github.com/dgromer/apa) 27 | * [apaTables](https://dstanley4.github.io/apaTables/) 28 | 29 | ## Alternatives to apaquarto 30 | 31 | To my knowledge, there is no working quarto extension other than apaquarto that takes a comprehensive approach to APA style with output options in .docx, .html, and .pdf. However, there are other ways to automate the production of APA-style documents. 32 | 33 | ### APA style with knitr and $\LaTeX$ 34 | 35 | The ability to automate APA style via $\LaTeX$ has been around for some time---first via [apa](https://ctan.org/pkg/apa) (APA Style, 5th Edition), then via [apa6](https://ctan.org/pkg/apa6) (APA Style, 6th Edition), and now via [apa7](https://ctan.org/pkg/apa7) (APA Style, 7th Edition). The apaquarto package uses [apa7](https://ctan.org/pkg/apa7) to create .pdf documents. To intermingle R code and $\LaTeX$ code in the same document, R-users could write in an .Rnw file using [sweave or knitr](https://support.posit.co/hc/en-us/articles/200552056-Using-Sweave-and-knitr). I still do so when I need the full flexibility of $\LaTeX$. 36 | 37 | ### APA style with Rmarkdown and papaja 38 | 39 | Unfortunately, most psychology journals require submissions in MS Word (and most collaborators do as well). Learning $\LaTeX$ is fun for some people (e.g., me), but most will not bother. With the arrival of Rmarkdown, it became possible to automate document production with a system that takes just a few minutes to learn. 40 | 41 | The [papaja](https://github.com/crsh/papaja) package by Frederick Aust uses Rmarkdown syntax and does a fantastic job of creating APA-style (6th Edition) documents in .pdf and [gets close to perfect .docx output](https://frederikaust.com/papaja_man/limitations.html#microsoft-word-documents). With a bit of tweaking, [papaja can do most of APA Style (7th Edition)](https://github.com/crsh/papaja/issues/342) for .pdf documents. 42 | 43 | ### APA style with Quarto and Typst 44 | 45 | Matti Vuore is working on an [APA-like quarto extension](https://github.com/mvuorre/quarto-apaish) that uses [Typst](https://typst.app/) instead of $\LaTeX$. As of 2024-02-27, there are aspects of APA style missing, but it looks promising. Because Typst offers many advantages over $\LaTeX$ (e.g., easy reconfiguration and much faster rendering), I would like to adapt apaquarto to use Typst as well. The development of Typst is fast and ongoing, so it will be interesting to see what the future holds. 46 | 47 | -------------------------------------------------------------------------------- /sampleimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/sampleimage.png -------------------------------------------------------------------------------- /site_libs/bootstrap/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wjschne/apaquarto/a043211bc7f8189ad30fa3c6d2058c3140631a38/site_libs/bootstrap/bootstrap-icons.woff -------------------------------------------------------------------------------- /site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.11 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1 { 2 | function guessOS() { 3 | const userAgent = window.navigator.userAgent; 4 | if (userAgent.includes("Mac OS")) { 5 | return { 6 | name: "mac", 7 | }; 8 | } else if (userAgent.includes("Windows")) { 9 | return { 10 | name: "windows", 11 | }; 12 | } else { 13 | return { 14 | name: "linux", 15 | }; 16 | } 17 | } 18 | const os = guessOS(); 19 | 20 | // deno-lint-ignore no-window-prefix 21 | window.addEventListener("DOMContentLoaded", (_) => { 22 | for (const el of Array.from(document.querySelectorAll("kbd"))) { 23 | el.classList.add("kbd"); 24 | if (el.dataset[os.name] !== undefined) { 25 | el.innerText = el.dataset[os.name]; 26 | } 27 | if (os.name === "mac") { 28 | el.innerText = el.innerText 29 | .replaceAll(/command-?/gi, "⌘") 30 | .replaceAll(/cmd-?/gi, "⌘") 31 | .replaceAll(/shift-?/gi, "⇧") 32 | .replaceAll(/ctrl-?/gi, "⌃") 33 | .replaceAll(/control-?/gi, "⌃") 34 | .replaceAll(/option-?/gi, "⌥"); 35 | } 36 | } 37 | }); 38 | })(); 39 | -------------------------------------------------------------------------------- /site_libs/quarto-html/anchor.min.js: -------------------------------------------------------------------------------- 1 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 2 | // 3 | // AnchorJS - v5.0.0 - 2023-01-18 4 | // https://www.bryanbraun.com/anchorjs/ 5 | // Copyright (c) 2023 Bryan Braun; Licensed MIT 6 | // 7 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 8 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(globalThis,function(){"use strict";return function(A){function u(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function d(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],u(this.options),this.add=function(A){var e,t,o,i,n,s,a,r,l,c,h,p=[];if(u(this.options),0!==(e=d(A=A||"h2, h3, h4, h5, h6")).length){for(null===document.head.querySelector("style.anchorjs")&&((A=document.createElement("style")).className="anchorjs",A.appendChild(document.createTextNode("")),void 0===(h=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(A):document.head.insertBefore(A,h),A.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",A.sheet.cssRules.length),A.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); 9 | // @license-end -------------------------------------------------------------------------------- /site_libs/quarto-html/quarto-syntax-highlighting-81b5c3e63835cfde897ecd3d35a35a41.css: -------------------------------------------------------------------------------- 1 | /* quarto syntax highlight colors */ 2 | :root { 3 | --quarto-hl-ot-color: #003B4F; 4 | --quarto-hl-at-color: #657422; 5 | --quarto-hl-ss-color: #20794D; 6 | --quarto-hl-an-color: #5E5E5E; 7 | --quarto-hl-fu-color: #4758AB; 8 | --quarto-hl-st-color: #20794D; 9 | --quarto-hl-cf-color: #003B4F; 10 | --quarto-hl-op-color: #5E5E5E; 11 | --quarto-hl-er-color: #AD0000; 12 | --quarto-hl-bn-color: #AD0000; 13 | --quarto-hl-al-color: #AD0000; 14 | --quarto-hl-va-color: #111111; 15 | --quarto-hl-bu-color: inherit; 16 | --quarto-hl-ex-color: inherit; 17 | --quarto-hl-pp-color: #AD0000; 18 | --quarto-hl-in-color: #5E5E5E; 19 | --quarto-hl-vs-color: #20794D; 20 | --quarto-hl-wa-color: #5E5E5E; 21 | --quarto-hl-do-color: #5E5E5E; 22 | --quarto-hl-im-color: #00769E; 23 | --quarto-hl-ch-color: #20794D; 24 | --quarto-hl-dt-color: #AD0000; 25 | --quarto-hl-fl-color: #AD0000; 26 | --quarto-hl-co-color: #5E5E5E; 27 | --quarto-hl-cv-color: #5E5E5E; 28 | --quarto-hl-cn-color: #8f5902; 29 | --quarto-hl-sc-color: #5E5E5E; 30 | --quarto-hl-dv-color: #AD0000; 31 | --quarto-hl-kw-color: #003B4F; 32 | } 33 | 34 | /* other quarto variables */ 35 | :root { 36 | --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 37 | } 38 | 39 | pre > code.sourceCode > span { 40 | color: #003B4F; 41 | } 42 | 43 | code span { 44 | color: #003B4F; 45 | } 46 | 47 | code.sourceCode > span { 48 | color: #003B4F; 49 | } 50 | 51 | div.sourceCode, 52 | div.sourceCode pre.sourceCode { 53 | color: #003B4F; 54 | } 55 | 56 | code span.ot { 57 | color: #003B4F; 58 | font-style: inherit; 59 | } 60 | 61 | code span.at { 62 | color: #657422; 63 | font-style: inherit; 64 | } 65 | 66 | code span.ss { 67 | color: #20794D; 68 | font-style: inherit; 69 | } 70 | 71 | code span.an { 72 | color: #5E5E5E; 73 | font-style: inherit; 74 | } 75 | 76 | code span.fu { 77 | color: #4758AB; 78 | font-style: inherit; 79 | } 80 | 81 | code span.st { 82 | color: #20794D; 83 | font-style: inherit; 84 | } 85 | 86 | code span.cf { 87 | color: #003B4F; 88 | font-weight: bold; 89 | font-style: inherit; 90 | } 91 | 92 | code span.op { 93 | color: #5E5E5E; 94 | font-style: inherit; 95 | } 96 | 97 | code span.er { 98 | color: #AD0000; 99 | font-style: inherit; 100 | } 101 | 102 | code span.bn { 103 | color: #AD0000; 104 | font-style: inherit; 105 | } 106 | 107 | code span.al { 108 | color: #AD0000; 109 | font-style: inherit; 110 | } 111 | 112 | code span.va { 113 | color: #111111; 114 | font-style: inherit; 115 | } 116 | 117 | code span.bu { 118 | font-style: inherit; 119 | } 120 | 121 | code span.ex { 122 | font-style: inherit; 123 | } 124 | 125 | code span.pp { 126 | color: #AD0000; 127 | font-style: inherit; 128 | } 129 | 130 | code span.in { 131 | color: #5E5E5E; 132 | font-style: inherit; 133 | } 134 | 135 | code span.vs { 136 | color: #20794D; 137 | font-style: inherit; 138 | } 139 | 140 | code span.wa { 141 | color: #5E5E5E; 142 | font-style: italic; 143 | } 144 | 145 | code span.do { 146 | color: #5E5E5E; 147 | font-style: italic; 148 | } 149 | 150 | code span.im { 151 | color: #00769E; 152 | font-style: inherit; 153 | } 154 | 155 | code span.ch { 156 | color: #20794D; 157 | font-style: inherit; 158 | } 159 | 160 | code span.dt { 161 | color: #AD0000; 162 | font-style: inherit; 163 | } 164 | 165 | code span.fl { 166 | color: #AD0000; 167 | font-style: inherit; 168 | } 169 | 170 | code span.co { 171 | color: #5E5E5E; 172 | font-style: inherit; 173 | } 174 | 175 | code span.cv { 176 | color: #5E5E5E; 177 | font-style: italic; 178 | } 179 | 180 | code span.cn { 181 | color: #8f5902; 182 | font-style: inherit; 183 | } 184 | 185 | code span.sc { 186 | color: #5E5E5E; 187 | font-style: inherit; 188 | } 189 | 190 | code span.dv { 191 | color: #AD0000; 192 | font-style: inherit; 193 | } 194 | 195 | code span.kw { 196 | color: #003B4F; 197 | font-weight: bold; 198 | font-style: inherit; 199 | } 200 | 201 | .prevent-inlining { 202 | content: ".tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} -------------------------------------------------------------------------------- /site_libs/quarto-nav/headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); 8 | -------------------------------------------------------------------------------- /site_libs/quarto-nav/quarto-nav.js: -------------------------------------------------------------------------------- 1 | const headroomChanged = new CustomEvent("quarto-hrChanged", { 2 | detail: {}, 3 | bubbles: true, 4 | cancelable: false, 5 | composed: false, 6 | }); 7 | 8 | const announceDismiss = () => { 9 | const annEl = window.document.getElementById("quarto-announcement"); 10 | if (annEl) { 11 | annEl.remove(); 12 | 13 | const annId = annEl.getAttribute("data-announcement-id"); 14 | window.localStorage.setItem(`quarto-announce-${annId}`, "true"); 15 | } 16 | }; 17 | 18 | const announceRegister = () => { 19 | const annEl = window.document.getElementById("quarto-announcement"); 20 | if (annEl) { 21 | const annId = annEl.getAttribute("data-announcement-id"); 22 | const isDismissed = 23 | window.localStorage.getItem(`quarto-announce-${annId}`) || false; 24 | if (isDismissed) { 25 | announceDismiss(); 26 | return; 27 | } else { 28 | annEl.classList.remove("hidden"); 29 | } 30 | 31 | const actionEl = annEl.querySelector(".quarto-announcement-action"); 32 | if (actionEl) { 33 | actionEl.addEventListener("click", function (e) { 34 | e.preventDefault(); 35 | // Hide the bar immediately 36 | announceDismiss(); 37 | }); 38 | } 39 | } 40 | }; 41 | 42 | window.document.addEventListener("DOMContentLoaded", function () { 43 | let init = false; 44 | 45 | announceRegister(); 46 | 47 | // Manage the back to top button, if one is present. 48 | let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop; 49 | const scrollDownBuffer = 5; 50 | const scrollUpBuffer = 35; 51 | const btn = document.getElementById("quarto-back-to-top"); 52 | const hideBackToTop = () => { 53 | btn.style.display = "none"; 54 | }; 55 | const showBackToTop = () => { 56 | btn.style.display = "inline-block"; 57 | }; 58 | if (btn) { 59 | window.document.addEventListener( 60 | "scroll", 61 | function () { 62 | const currentScrollTop = 63 | window.pageYOffset || document.documentElement.scrollTop; 64 | 65 | // Shows and hides the button 'intelligently' as the user scrolls 66 | if (currentScrollTop - scrollDownBuffer > lastScrollTop) { 67 | hideBackToTop(); 68 | lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; 69 | } else if (currentScrollTop < lastScrollTop - scrollUpBuffer) { 70 | showBackToTop(); 71 | lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; 72 | } 73 | 74 | // Show the button at the bottom, hides it at the top 75 | if (currentScrollTop <= 0) { 76 | hideBackToTop(); 77 | } else if ( 78 | window.innerHeight + currentScrollTop >= 79 | document.body.offsetHeight 80 | ) { 81 | showBackToTop(); 82 | } 83 | }, 84 | false 85 | ); 86 | } 87 | 88 | function throttle(func, wait) { 89 | var timeout; 90 | return function () { 91 | const context = this; 92 | const args = arguments; 93 | const later = function () { 94 | clearTimeout(timeout); 95 | timeout = null; 96 | func.apply(context, args); 97 | }; 98 | 99 | if (!timeout) { 100 | timeout = setTimeout(later, wait); 101 | } 102 | }; 103 | } 104 | 105 | function headerOffset() { 106 | // Set an offset if there is are fixed top navbar 107 | const headerEl = window.document.querySelector("header.fixed-top"); 108 | if (headerEl) { 109 | return headerEl.clientHeight; 110 | } else { 111 | return 0; 112 | } 113 | } 114 | 115 | function footerOffset() { 116 | const footerEl = window.document.querySelector("footer.footer"); 117 | if (footerEl) { 118 | return footerEl.clientHeight; 119 | } else { 120 | return 0; 121 | } 122 | } 123 | 124 | function dashboardOffset() { 125 | const dashboardNavEl = window.document.getElementById( 126 | "quarto-dashboard-header" 127 | ); 128 | if (dashboardNavEl !== null) { 129 | return dashboardNavEl.clientHeight; 130 | } else { 131 | return 0; 132 | } 133 | } 134 | 135 | function updateDocumentOffsetWithoutAnimation() { 136 | updateDocumentOffset(false); 137 | } 138 | 139 | function updateDocumentOffset(animated) { 140 | // set body offset 141 | const topOffset = headerOffset(); 142 | const bodyOffset = topOffset + footerOffset() + dashboardOffset(); 143 | const bodyEl = window.document.body; 144 | bodyEl.setAttribute("data-bs-offset", topOffset); 145 | bodyEl.style.paddingTop = topOffset + "px"; 146 | 147 | // deal with sidebar offsets 148 | const sidebars = window.document.querySelectorAll( 149 | ".sidebar, .headroom-target" 150 | ); 151 | sidebars.forEach((sidebar) => { 152 | if (!animated) { 153 | sidebar.classList.add("notransition"); 154 | // Remove the no transition class after the animation has time to complete 155 | setTimeout(function () { 156 | sidebar.classList.remove("notransition"); 157 | }, 201); 158 | } 159 | 160 | if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { 161 | sidebar.style.top = "0"; 162 | sidebar.style.maxHeight = "100vh"; 163 | } else { 164 | sidebar.style.top = topOffset + "px"; 165 | sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; 166 | } 167 | }); 168 | 169 | // allow space for footer 170 | const mainContainer = window.document.querySelector(".quarto-container"); 171 | if (mainContainer) { 172 | mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; 173 | } 174 | 175 | // link offset 176 | let linkStyle = window.document.querySelector("#quarto-target-style"); 177 | if (!linkStyle) { 178 | linkStyle = window.document.createElement("style"); 179 | linkStyle.setAttribute("id", "quarto-target-style"); 180 | window.document.head.appendChild(linkStyle); 181 | } 182 | while (linkStyle.firstChild) { 183 | linkStyle.removeChild(linkStyle.firstChild); 184 | } 185 | if (topOffset > 0) { 186 | linkStyle.appendChild( 187 | window.document.createTextNode(` 188 | section:target::before { 189 | content: ""; 190 | display: block; 191 | height: ${topOffset}px; 192 | margin: -${topOffset}px 0 0; 193 | }`) 194 | ); 195 | } 196 | if (init) { 197 | window.dispatchEvent(headroomChanged); 198 | } 199 | init = true; 200 | } 201 | 202 | // initialize headroom 203 | var header = window.document.querySelector("#quarto-header"); 204 | if (header && window.Headroom) { 205 | const headroom = new window.Headroom(header, { 206 | tolerance: 5, 207 | onPin: function () { 208 | const sidebars = window.document.querySelectorAll( 209 | ".sidebar, .headroom-target" 210 | ); 211 | sidebars.forEach((sidebar) => { 212 | sidebar.classList.remove("sidebar-unpinned"); 213 | }); 214 | updateDocumentOffset(); 215 | }, 216 | onUnpin: function () { 217 | const sidebars = window.document.querySelectorAll( 218 | ".sidebar, .headroom-target" 219 | ); 220 | sidebars.forEach((sidebar) => { 221 | sidebar.classList.add("sidebar-unpinned"); 222 | }); 223 | updateDocumentOffset(); 224 | }, 225 | }); 226 | headroom.init(); 227 | 228 | let frozen = false; 229 | window.quartoToggleHeadroom = function () { 230 | if (frozen) { 231 | headroom.unfreeze(); 232 | frozen = false; 233 | } else { 234 | headroom.freeze(); 235 | frozen = true; 236 | } 237 | }; 238 | } 239 | 240 | window.addEventListener( 241 | "hashchange", 242 | function (e) { 243 | if ( 244 | getComputedStyle(document.documentElement).scrollBehavior !== "smooth" 245 | ) { 246 | window.scrollTo(0, window.pageYOffset - headerOffset()); 247 | } 248 | }, 249 | false 250 | ); 251 | 252 | // Observe size changed for the header 253 | const headerEl = window.document.querySelector("header.fixed-top"); 254 | if (headerEl && window.ResizeObserver) { 255 | const observer = new window.ResizeObserver(() => { 256 | setTimeout(updateDocumentOffsetWithoutAnimation, 0); 257 | }); 258 | observer.observe(headerEl, { 259 | attributes: true, 260 | childList: true, 261 | characterData: true, 262 | }); 263 | } else { 264 | window.addEventListener( 265 | "resize", 266 | throttle(updateDocumentOffsetWithoutAnimation, 50) 267 | ); 268 | } 269 | setTimeout(updateDocumentOffsetWithoutAnimation, 250); 270 | 271 | // fixup index.html links if we aren't on the filesystem 272 | if (window.location.protocol !== "file:") { 273 | const links = window.document.querySelectorAll("a"); 274 | for (let i = 0; i < links.length; i++) { 275 | if (links[i].href) { 276 | links[i].dataset.originalHref = links[i].href; 277 | links[i].href = links[i].href.replace(/\/index\.html/, "/"); 278 | } 279 | } 280 | 281 | // Fixup any sharing links that require urls 282 | // Append url to any sharing urls 283 | const sharingLinks = window.document.querySelectorAll( 284 | "a.sidebar-tools-main-item, a.quarto-navigation-tool, a.quarto-navbar-tools, a.quarto-navbar-tools-item" 285 | ); 286 | for (let i = 0; i < sharingLinks.length; i++) { 287 | const sharingLink = sharingLinks[i]; 288 | const href = sharingLink.getAttribute("href"); 289 | if (href) { 290 | sharingLink.setAttribute( 291 | "href", 292 | href.replace("|url|", window.location.href) 293 | ); 294 | } 295 | } 296 | 297 | // Scroll the active navigation item into view, if necessary 298 | const navSidebar = window.document.querySelector("nav#quarto-sidebar"); 299 | if (navSidebar) { 300 | // Find the active item 301 | const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); 302 | if (activeItem) { 303 | // Wait for the scroll height and height to resolve by observing size changes on the 304 | // nav element that is scrollable 305 | const resizeObserver = new ResizeObserver((_entries) => { 306 | // The bottom of the element 307 | const elBottom = activeItem.offsetTop; 308 | const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; 309 | 310 | // The element height and scroll height are the same, then we are still loading 311 | if (viewBottom !== navSidebar.scrollHeight) { 312 | // Determine if the item isn't visible and scroll to it 313 | if (elBottom >= viewBottom) { 314 | navSidebar.scrollTop = elBottom; 315 | } 316 | 317 | // stop observing now since we've completed the scroll 318 | resizeObserver.unobserve(navSidebar); 319 | } 320 | }); 321 | resizeObserver.observe(navSidebar); 322 | } 323 | } 324 | } 325 | }); 326 | -------------------------------------------------------------------------------- /site_libs/tabwid-1.1.3/tabwid.css: -------------------------------------------------------------------------------- 1 | .tabwid { 2 | font-size: initial; 3 | padding-bottom: 1em; 4 | } 5 | 6 | .tabwid table{ 7 | border-spacing:0px !important; 8 | border-collapse:collapse; 9 | line-height:1; 10 | margin-left:auto; 11 | margin-right:auto; 12 | border-width: 0; 13 | border-color: transparent; 14 | caption-side: top; 15 | } 16 | .tabwid-caption-bottom table{ 17 | caption-side: bottom; 18 | } 19 | .tabwid_left table{ 20 | margin-left:0; 21 | } 22 | .tabwid_right table{ 23 | margin-right:0; 24 | } 25 | .tabwid td, .tabwid th { 26 | padding: 0; 27 | } 28 | .tabwid a { 29 | text-decoration: none; 30 | } 31 | .tabwid thead { 32 | background-color: transparent; 33 | } 34 | .tabwid tfoot { 35 | background-color: transparent; 36 | } 37 | .tabwid table tr { 38 | background-color: transparent; 39 | } 40 | .katex-display { 41 | margin: 0 0 !important; 42 | } 43 | -------------------------------------------------------------------------------- /site_libs/tabwid-1.1.3/tabwid.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function(event) { 2 | var els = document.querySelectorAll(".tabwid"); 3 | var tabwid_link = document.querySelector('link[href*="tabwid.css"]') 4 | if (tabwid_link === null) { 5 | const tabwid_styles = document.evaluate("//style[contains(., 'tabwid')]", document, null, XPathResult.ANY_TYPE, null ); 6 | tabwid_link = tabwid_styles.iterateNext(); 7 | } 8 | 9 | Array.prototype.forEach.call(els, function(template) { 10 | const dest = document.createElement("div"); 11 | template.parentNode.insertBefore(dest, template.nextSibling) 12 | dest.setAttribute("class", "flextable-shadow-host"); 13 | const fantome = dest.attachShadow({mode: 'open'}); 14 | fantome.appendChild(template); 15 | if (tabwid_link !== null) { 16 | fantome.appendChild(tabwid_link.cloneNode(true)); 17 | } 18 | }); 19 | 20 | const shadowHosts = document.querySelectorAll('.flextable-shadow-host:not(:has(div > table.no-shadow-dom))'); 21 | shadowHosts.forEach(host => { 22 | if (host.shadowRoot) { 23 | const spanElements = host.shadowRoot.querySelector('div > table > caption > span[id]'); 24 | if (spanElements) { 25 | const id = spanElements.getAttribute("id"); 26 | host.setAttribute("id", id); 27 | } 28 | } 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /template.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "My Title" 3 | shorttitle: "Short Title in Running Header" 4 | author: 5 | - name: Jane Doe 6 | corresponding: true 7 | orcid: 0000-0000-0000-0001 8 | email: janedoe@generic.edu 9 | affiliations: 10 | - name: Generic University 11 | department: Department of Scholarly Studies 12 | address: 1234 Capital St. 13 | city: New York 14 | region: NY 15 | country: USA 16 | postal-code: 12084-1234 17 | author-note: 18 | status-changes: 19 | affiliation-change: ~ 20 | deceased: ~ 21 | disclosures: 22 | study-registration: ~ 23 | data-sharing: ~ 24 | related-report: ~ 25 | conflict-of-interest: ~ 26 | financial-support: ~ 27 | gratitude: ~ 28 | authorship-agreements: ~ 29 | abstract: "This document is a template." 30 | keywords: [Keyword 1, Keyword 2, Keyword 3] 31 | bibliography: bibliography.bib 32 | format: 33 | apaquarto-docx: default 34 | apaquarto-html: default 35 | apaquarto-typst: default 36 | apaquarto-pdf: 37 | documentmode: man 38 | --- 39 | 40 | 41 | 42 | This is my first paragraph. Any section headings in the introduction should be in levels 2--5. 43 | 44 | # Method 45 | 46 | ## Participants 47 | 48 | ## Measures 49 | 50 | ## Procedure 51 | 52 | # Results 53 | 54 | # Discussion 55 | 56 | ## Limitations and Future Directions 57 | 58 | ## Conclusion 59 | 60 | # References 61 | 62 | 63 | 64 | ::: {#refs} 65 | ::: 66 | 67 | # This Section Is an Appendix {#apx-a} 68 | 69 | 70 | # Another Appendix {#apx-b} --------------------------------------------------------------------------------