diff --git a/content/00.front-matter.md b/content/00.front-matter.md index ed5e3e0..7c81577 100644 --- a/content/00.front-matter.md +++ b/content/00.front-matter.md @@ -9,71 +9,9 @@ _A DOI-citable version of this manuscript is available at -This manuscript -{% if manubot.ci_source is defined and manubot.ci_source.provider == "appveyor" -%} -([permalink]({{manubot.ci_source.artifact_url}})) -{% elif manubot.html_url_versioned is defined -%} -([permalink]({{manubot.html_url_versioned}})) -{% endif -%} -was automatically generated -{% if manubot.ci_source is defined -%} -from [{{manubot.ci_source.repo_slug}}@{{manubot.ci_source.commit | truncate(length=7, end='', leeway=0)}}](https://github.com/{{manubot.ci_source.repo_slug}}/tree/{{manubot.ci_source.commit}}) -{% endif -%} -on {{manubot.generated_date_long}}. - + {% if manubot.date_long != manubot.generated_date_long -%} Published: {{manubot.date_long}} {% endif %} -## Authors - -{## Template for listing authors ##} -{% for author in manubot.authors %} -+ **{{author.name}}** - {% if author.corresponding is defined and author.corresponding == true -%}^[✉](#correspondence)^{%- endif -%} -
- {%- set has_ids = false %} - {%- if author.orcid is defined and author.orcid is not none %} - {%- set has_ids = true %} - ![ORCID icon](images/orcid.svg){.inline_icon width=16 height=16} - [{{author.orcid}}](https://orcid.org/{{author.orcid}}) - {%- endif %} - {%- if author.github is defined and author.github is not none %} - {%- set has_ids = true %} - · ![GitHub icon](images/github.svg){.inline_icon width=16 height=16} - [{{author.github}}](https://github.com/{{author.github}}) - {%- endif %} - {%- if author.twitter is defined and author.twitter is not none %} - {%- set has_ids = true %} - · ![Twitter icon](images/twitter.svg){.inline_icon width=16 height=16} - [{{author.twitter}}](https://twitter.com/{{author.twitter}}) - {%- endif %} - {%- if author.mastodon is defined and author.mastodon is not none and author["mastodon-server"] is defined and author["mastodon-server"] is not none %} - {%- set has_ids = true %} - · ![Mastodon icon](images/mastodon.svg){.inline_icon width=16 height=16} - [\@{{author.mastodon}}@{{author["mastodon-server"]}}](https://{{author["mastodon-server"]}}/@{{author.mastodon}}) - {%- endif %} - {%- if has_ids %} -
- {%- endif %} - - {%- if author.affiliations is defined and author.affiliations|length %} - {{author.affiliations | join('; ')}} - {%- endif %} - {%- if author.funders is defined and author.funders|length %} - · Funded by {{author.funders | join('; ')}} - {%- endif %} - -{% endfor %} - -::: {#correspondence} -✉ — Correspondence possible via {% if manubot.ci_source is defined -%}[GitHub Issues](https://github.com/{{manubot.ci_source.repo_slug}}/issues){% else %}GitHub Issues{% endif %} -{% if manubot.authors|map(attribute='corresponding')|select|max -%} -or email to -{% for author in manubot.authors|selectattr("corresponding") -%} -{{ author.name }} \<{{ author.email }}\>{{ ", " if not loop.last else "." }} -{% endfor %} -{% endif %} -::: diff --git a/content/01.abstract.md b/content/01.abstract.md index a9764c9..af136a6 100644 --- a/content/01.abstract.md +++ b/content/01.abstract.md @@ -1,3 +1,42 @@ -## Abstract {.page_break_before} +Supplementary Material +====================================== +Benchmarks +--------------------- + +We compare the speed of BioNumPy against other existing Python packages and commonly used non-Python tools on a set of typical bioinformatics tasks. As seen in Figure 1, we find that BioNumPy is generally considerably faster than vanilla Python solutions, as well as the commonly used Python packages BioPython and Biotite, which mostly rely on Python for-loops to perform operations on datasets. On problems where designated efficient bioinformatics tools are widely used (intersection of BED-files, kmer counting and VCF operations), we find that BioNumPy is close to, or as efficient as, tools written in C/C++ (BEDTools [@bedtools], Jellyfish [@jellyfish] and BCFTools [@bcftools]). A Snakemake pipeline for reproducing the results can be found at , along with an open invitation to expand the benchmark with additional tools and cases. + +![**Benchmarking BioNumPy against other tools and methods on various typical bioinformatics tasks.**](images/benchmarks.png){#fig:benchmarks} + +Reproducing a machine learning benchmark using BioNumPy +------------------------------------------------------------------------------------ +TODO + +To show how BioNumPy can be used to easily process and parse various biology data formats, we used BioNumPy to reproduce a recently published benchmark of a machine learning method [@sasse]. In the original work, the authors are using a combination of custom Python code and common bioinformatics tools (such as BCFTools [@bcftools]) to extract sequences around the transcription start sites of genes. We have forked the original repository and replaced all this code, which consisted of X lines of Python code and X lines of shell scripts, with only a few calls to BioNumPy (in total Y lines). + +Our fork is available at We believe this shows that BioNumPy quite easily can be used to cleanly integrate various biology file formats. + +BioNumPy Implementation details +---------------------------------------------------- + +BioNumPy internally stores sequence data (e.g. nucleotides or amino acids) as numeric values, allowing the use of standard NumPy arrays for data representation and processing. A key way BioNumpy achieves high performance is by storing multiple data entries in shared NumPy arrays. To illustrate the benefit of this approach, consider the example where we want to count the number of Gs and Cs in a large set of DNA sequences. Existing Python packages like BioPython and Biotite, do this by iterating over the sequences using Python for-loops, which is slow when the number of sequences is large. BioNumPy, however, stores all sequences in only one or a few shared NumPy arrays (Figure 3a), meaning that vectorized NumPy operations can be used to do the counting in a fraction of the time. + +Storing multiple elements in shared arrays is trivial if the elements all have the same size, since a matrix representation can be used. However, for biological data, it is common that data elements vary in size. For instance, sequences in FASTA files are rarely all of the exact same size. BioNumPy uses the RaggedArray data structure from the npstructures package (, developed in tandem with BioNumPy) to tackle this problem (Figure @fig:ragged_array). The RaggedArray can be seen as a matrix where rows can have different lengths. The npstructures RaggedArray implementation is compatible with most common NumPy operations, like indexing (Figure @fig:ragged_array b), vectorized operations (Figure @fig:ragged_array c), and reductions (Figure @fig:ragged_array d). As far as possible, objects in BioNumPy follow the array interoperability protocols defined by NumPy () + + +![ **Overview of the RaggedArray and EncodedRaggedArray data structures**. A RaggedArray is similar to a NumPy array/matrix but can represent a matrix consisting of rows with varying lengths (a). This makes it able to represent data with varying lengths efficiently in a shared data structure. A RaggedArray supports many of the same operations as NumPy arrays, such as indexing (b), vectorization (c) and reduction (d). An EncodedRaggedArray is a RaggedArray that supports storing and operating on non-numeric data (e.g. DNA sequences) by encoding the data and keeping track of the encoding (e). An EncodedRaggedArray supports the same operations as RaggedArrays (f). This figure is an adopted and modified version of Figure 1 in :cite:`numpy` and is licensed under a Creative Commons Attribution 4.0 International License (). +](images/ragged_array_figure.png){#fig:ragged_array} + + + + + +BioNumPy has been developed following the principles of continuous integration and distribution. The codebase is thoroughly and automatically tested through an extensive collection of unit tests, application tests, integration tests and property-based tests [@hypothesis]. New code changes are automatically benchmarked and tested before being automatically published, ensuring that updates can be frequent while high code quality is maintained. This workflow makes it safe and easy to allow contributions from new contributors, which is important for longevity and community adoption of the package. + + + +[@jellyfish]: doi:10.1093/bioinformatics/btr011 +[@bedtools]: doi: 10.1093/bioinformatics/btq033 +[@bcftools]: doi:10.1093/gigascience/giab008 +[@hypothesis]: doi:10.21105/joss.01891 diff --git a/content/02.delete-me.md b/content/02.delete-me.md deleted file mode 100644 index 1d57328..0000000 --- a/content/02.delete-me.md +++ /dev/null @@ -1,295 +0,0 @@ -This manuscript is a template (aka "rootstock") for [Manubot](https://manubot.org/ "Manubot"), a tool for writing scholarly manuscripts. -Use this template as a starting point for your manuscript. - -The rest of this document is a full list of formatting elements/features supported by Manubot. -Compare the input (`.md` files in the `/content` directory) to the output you see below. - -## Basic formatting - -**Bold** __text__ - -[Semi-bold text]{.semibold} - -[Centered text]{.center} - -[Right-aligned text]{.right} - -*Italic* _text_ - -Combined *italics and __bold__* - -~~Strikethrough~~ - -1. Ordered list item -2. Ordered list item - a. Sub-item - b. Sub-item - i. Sub-sub-item -3. Ordered list item - a. Sub-item - -- List item -- List item -- List item - -subscript: H~2~O is a liquid - -superscript: 2^10^ is 1024. - -[unicode superscripts](https://www.google.com/search?q=superscript+generator)⁰¹²³⁴⁵⁶⁷⁸⁹ - -[unicode subscripts](https://www.google.com/search?q=superscript+generator)₀₁₂₃₄₅₆₇₈₉ - -A long paragraph of text. -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - -Putting each sentence on its own line has numerous benefits with regard to [editing](https://asciidoctor.org/docs/asciidoc-recommended-practices/#one-sentence-per-line) and [version control](https://rhodesmill.org/brandon/2012/one-sentence-per-line/). - -Line break without starting a new paragraph by putting -two spaces at end of line. - -## Document organization - -Document section headings: - -# Heading 1 - -## Heading 2 - -### Heading 3 - -#### Heading 4 - -##### Heading 5 - -###### Heading 6 - -### A heading centered on its own printed page{.center .page_center} - - - -Horizontal rule: - ---- - -`Heading 1`'s are recommended to be reserved for the title of the manuscript. - -`Heading 2`'s are recommended for broad sections such as *Abstract*, *Methods*, *Conclusion*, etc. - -`Heading 3`'s and `Heading 4`'s are recommended for sub-sections. - -## Links - -Bare URL link: - -[Long link with lots of words and stuff and junk and bleep and blah and stuff and other stuff and more stuff yeah](https://manubot.org) - -[Link with text](https://manubot.org) - -[Link with hover text](https://manubot.org "Manubot Homepage") - -[Link by reference][manubot homepage] - -[Manubot Homepage]: https://manubot.org - -## Citations - -Citation by DOI [@doi:10.7554/eLife.32822]. - -Citation by PubMed Central ID [@pmc:PMC6103790]. - -Citation by PubMed ID [@pubmed:30718888]. - -Citation by Wikidata ID [@wikidata:Q56458321]. - -Citation by ISBN [@isbn:9780262517638]. - -Citation by URL [@{https://greenelab.github.io/meta-review/}]. - -Citation by alias [@deep-review]. - -Multiple citations can be put inside the same set of brackets [@doi:10.7554/eLife.32822; @deep-review; @isbn:9780262517638]. -Manubot plugins provide easier, more convenient visualization of and navigation between citations [@doi:10.1371/journal.pcbi.1007128; @pubmed:30718888; @pmc:PMC6103790; @deep-review]. - -Citation tags (i.e. aliases) can be defined in their own paragraphs using Markdown's reference link syntax: - -[@deep-review]: doi:10.1098/rsif.2017.0387 - -## Referencing figures, tables, equations - -Figure @fig:square-image - -Figure @fig:wide-image - -Figure @fig:tall-image - -Figure @fig:vector-image - -Table @tbl:bowling-scores - -Equation @eq:regular-equation - -Equation @eq:long-equation - -## Quotes and code - -> Quoted text - -> Quoted block of text -> -> Two roads diverged in a wood, and I— -> I took the one less traveled by, -> And that has made all the difference. - -Code `in the middle` of normal text, aka `inline code`. - -Code block with Python syntax highlighting: - -```python -from manubot.cite.doi import expand_short_doi - -def test_expand_short_doi(): - doi = expand_short_doi("10/c3bp") - # a string too long to fit within page: - assert doi == "10.25313/2524-2695-2018-3-vliyanie-enhansera-copia-i-insulyatora-gypsy-na-sintez-ernk-modifikatsii-hromatina-i-svyazyvanie-insulyatornyh-belkov-vtransfetsirovannyh-geneticheskih-konstruktsiyah" -``` - -Code block with no syntax highlighting: - -``` -Exporting HTML manuscript -Exporting DOCX manuscript -Exporting PDF manuscript -``` - -## Figures - -![ -**A square image at actual size and with a bottom caption.** -Loaded from the latest version of image on GitHub. -](https://github.com/manubot/resources/raw/15493970f8882fce22bef829619d3fb37a613ba5/test/square.png "Square image"){#fig:square-image} - -![ -**An image too wide to fit within page at full size.** -Loaded from a specific (hashed) version of the image on GitHub. -](https://github.com/manubot/resources/raw/15493970f8882fce22bef829619d3fb37a613ba5/test/wide.png "Wide image"){#fig:wide-image} - -![ -**A tall image with a specified height.** -Loaded from a specific (hashed) version of the image on GitHub. -](https://github.com/manubot/resources/raw/15493970f8882fce22bef829619d3fb37a613ba5/test/tall.png "Tall image"){#fig:tall-image height=3in} - -![ -**A vector `.svg` image loaded from GitHub.** -The parameter `sanitize=true` is necessary to properly load SVGs hosted via GitHub URLs. -White background specified to serve as a backdrop for transparent sections of the image. -Note that if you want to export to Word (`.docx`), you need to download the image and reference it locally (e.g. `content/images/vector.svg`) instead of using a URL. -](https://raw.githubusercontent.com/manubot/resources/main/test/vector.svg?sanitize=true "Vector image"){#fig:vector-image height=2.5in .white} - -## Tables - -| *Bowling Scores* | Jane | John | Alice | Bob | -|:-----------------|:-------------:|:-------------:|:-------------:|:-------------:| -| Game 1 | 150 | 187 | 210 | 105 | -| Game 2 | 98 | 202 | 197 | 102 | -| Game 3 | 123 | 180 | 238 | 134 | - -Table: A table with a top caption and specified relative column widths. -{#tbl:bowling-scores} - -| | Digits 1-33 | Digits 34-66 | Digits 67-99 | Ref. | -|:--------|:-----------------------------------|:----------------------------------|:----------------------------------|:------------------------------------------------------------| -| pi | 3.14159265358979323846264338327950 | 288419716939937510582097494459230 | 781640628620899862803482534211706 | [`piday.org`](https://www.piday.org/million/) | -| e | 2.71828182845904523536028747135266 | 249775724709369995957496696762772 | 407663035354759457138217852516642 | [`nasa.gov`](https://apod.nasa.gov/htmltest/gifcity/e.2mil) | - -Table: A table too wide to fit within page. -{#tbl:constant-digits} - -| | **Colors** | | -|:--------:|:--------------------------------:|:--------------------:| -| **Size** | **Text Color** | **Background Color** | -| big | blue | orange | -| small | black | white | - -Table: A table with merged cells using the `attributes` plugin. -{#tbl: merged-cells} - -## Equations - -A LaTeX equation: - -$$\int_0^\infty e^{-x^2} dx=\frac{\sqrt{\pi}}{2}$$ {#eq:regular-equation} - -An equation too long to fit within page: - -$$x = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9$$ {#eq:long-equation} - -## Special - - [WARNING]{.semibold} _The following features are only supported and intended for `.html` and `.pdf` exports._ -_Journals are not likely to support them, and they may not display correctly when converted to other formats such as `.docx`._ - -[Link styled as a button](https://manubot.org "Manubot Homepage"){.button} - -Adding arbitrary HTML attributes to an element using Pandoc's attribute syntax: - -::: {#some_id_1 .some_class style="background: #ad1457; color: white; margin-left: 40px;" title="a paragraph of text" data-color="white" disabled="true"} -Manubot Manubot Manubot Manubot Manubot. -Manubot Manubot Manubot Manubot. -Manubot Manubot Manubot. -Manubot Manubot. -Manubot. -::: - -Adding arbitrary HTML attributes to an element with the Manubot `attributes` plugin (more flexible than Pandoc's method in terms of which elements you can add attributes to): - -Manubot Manubot Manubot Manubot Manubot. -Manubot Manubot Manubot Manubot. -Manubot Manubot Manubot. -Manubot Manubot. -Manubot. - - -Available background colors for text, images, code, banners, etc: - -`white`{.white} -`lightgrey`{.lightgrey} -`grey`{.grey} -`darkgrey`{.darkgrey} -`black`{.black} -`lightred`{.lightred} -`lightyellow`{.lightyellow} -`lightgreen`{.lightgreen} -`lightblue`{.lightblue} -`lightpurple`{.lightpurple} -`red`{.red} -`orange`{.orange} -`yellow`{.yellow} -`green`{.green} -`blue`{.blue} -`purple`{.purple} - -Using the [Font Awesome](https://fontawesome.com/) icon set: - - - - - - -[ - **Light Grey Banner**
-useful for *general information* - [manubot.org](https://manubot.org/) -]{.banner .lightgrey} - -[ - **Blue Banner**
-useful for *important information* - [manubot.org](https://manubot.org/) -]{.banner .lightblue} - -[ - **Light Red Banner**
-useful for *warnings* - [manubot.org](https://manubot.org/) -]{.banner .lightred} diff --git a/content/images/benchmarks.png b/content/images/benchmarks.png new file mode 100644 index 0000000..43bb498 Binary files /dev/null and b/content/images/benchmarks.png differ diff --git a/content/images/ragged_array_figure.png b/content/images/ragged_array_figure.png new file mode 100644 index 0000000..7c27f02 Binary files /dev/null and b/content/images/ragged_array_figure.png differ diff --git a/content/images/ragged_array_figure.svg b/content/images/ragged_array_figure.svg new file mode 100644 index 0000000..a3827ab --- /dev/null +++ b/content/images/ragged_array_figure.svg @@ -0,0 +1,10074 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A + C + A + C + T + T + T + A + C + G + C + G + + + + + + + T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A + C + A + C + T + T + T + A + C + G + C + G + + + + + + + T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A + C + A + C + T + T + T + A + C + G + C + G + + + + + + + T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a Data structure (RaggedArray) + + + + data + data type + shape + strides + + + + + + (24, 8) + 8 byte integer + + + + + + + + 2 x 8 = 24 bytes to jump one row down + + The third row has two elements + + + + + + b Indexing + x[:,1:] + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + with slices + x[:,-1] + + x[x > 10] + + c Vectorization + d Reduction + x = RaggedArray([[0, 1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12]]) + + x = bnp.as_encoded_array(["ACAC", "TTT", "AC", "GCGT], encoding=bnp.DNAEncoding) + + + + + x + 0 + 1 + 0 + 1 + 3 + 3 + 3 + 0 + 1 + 2 + 1 + 2 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + data + encoding + + + + + RaggedArray DNAEncoding e EncodedRaggedArray + x[:,1:] + + x == "C" + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + False + False + False + False + False + False + True + False + Boolean RaggedArray EncodedRaggedArray x[x=="C"] + + EncodedRaggedArray + np.sum(x=="C", axis=1) + + + + + + + + + + + + + + + + + + + + + + + + + 2 + 1 + 0 + 1 + NumPy array f EncodedRaggedArrays support NumPy operations + + np.sum(x=="C", axis=0) + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 3 + 1 + NumPy array True + A: 0, C: 1, G: 2, T: 3 True + False + + + 0 1 2 3 4 5 6 7 8 9 10 11 12 + + + + + + + + + + + + + + + 4 3 2 4 + + + + + + x[:,::2] + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + with slicesand steps + + + + + 3 6 8 12 + + + + + + + 11 12 + + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + = + + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + + + + + 13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + sum axis=1 6 + 15 + 15 + 42 + + sum axis=0 + + + + + + + + + + + + + + + + + + + + + + + + 20 + 19 + 24 + 15 + + + + diff --git a/content/metadata.yaml b/content/metadata.yaml index ccf8d55..c117e37 100644 --- a/content/metadata.yaml +++ b/content/metadata.yaml @@ -1,30 +1,8 @@ --- -title: "Manuscript Title" +title: "Supplementary material for: Array programming for Biology" date: null # Defaults to date generated, but can specify like '2022-10-31'. keywords: - markdown - publishing - manubot lang: en-US -authors: - - github: johndoe - name: John Doe - initials: JD - orcid: XXXX-XXXX-XXXX-XXXX - twitter: johndoe - mastodon: johndoe - mastodon-server: mastodon.social - email: john.doe@something.com - affiliations: - - Department of Something, University of Whatever - funders: - - Grant XXXXXXXX - - github: janeroe - name: Jane Roe - initials: JR - orcid: XXXX-XXXX-XXXX-XXXX - email: jane.roe@whatever.edu - affiliations: - - Department of Something, University of Whatever - - Department of Whatever, University of Something - corresponding: true