diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8ff43005..38b4a2b2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -45,7 +45,8 @@ jobs: run: | templatekit check \ --ignore "project_templates/technote_rst/testn-000/technote.toml" \ - --ignore "project_templates/technote_md/testn-000/technote.toml" + --ignore "project_templates/technote_md/testn-000/technote.toml" \ + --ignore "project_templates/technote_typst/testn-000/technote.toml" # Test TeX builds only with the latest Python version, since they're # fairly heavy-weight and the Python version shouldn't matter. diff --git a/SConstruct b/SConstruct index fcf2c494..17918661 100644 --- a/SConstruct +++ b/SConstruct @@ -7,6 +7,7 @@ SConscript( "project_templates/nbreport/SConscript", "project_templates/technote_rst/SConscript", "project_templates/technote_md/SConscript", + "project_templates/technote_typst/SConscript", "project_templates/technote_latex/SConscript", "project_templates/technote_aastex/SConscript", "project_templates/technote_adasstex/SConscript", diff --git a/project_templates/technote_md/testn-000/technote.toml b/project_templates/technote_md/testn-000/technote.toml index 343c00eb..e45fd77a 100644 --- a/project_templates/technote_md/testn-000/technote.toml +++ b/project_templates/technote_md/testn-000/technote.toml @@ -4,7 +4,7 @@ series_id = "TESTN" canonical_url = "https://testn-000.lsst.io" github_url = "https://github.com/lsst/testn-000" github_default_branch = "main" -date_created = 2026-07-15T19:16:17Z +date_created = 2026-07-18T23:33:23Z organization.name = "NSF-DOE Vera C. Rubin Observatory" organization.ror = "https://ror.org/048g3cy84" license.id = "CC-BY-4.0" diff --git a/project_templates/technote_rst/testn-000/technote.toml b/project_templates/technote_rst/testn-000/technote.toml index 8eaa34f6..0efe853d 100644 --- a/project_templates/technote_rst/testn-000/technote.toml +++ b/project_templates/technote_rst/testn-000/technote.toml @@ -4,7 +4,7 @@ series_id = "TESTN" canonical_url = "https://testn-000.lsst.io" github_url = "https://github.com/lsst/testn-000" github_default_branch = "main" -date_created = 2026-07-15T19:16:17Z +date_created = 2026-07-18T23:33:23Z organization.name = "NSF-DOE Vera C. Rubin Observatory" organization.ror = "https://ror.org/048g3cy84" license.id = "CC-BY-4.0" diff --git a/project_templates/technote_typst/CHANGELOG.md b/project_templates/technote_typst/CHANGELOG.md new file mode 100644 index 00000000..019e7ae0 --- /dev/null +++ b/project_templates/technote_typst/CHANGELOG.md @@ -0,0 +1,5 @@ +# Change log + +## 2026-07-18 + +- Initial proof-of-concept Typst technote template. diff --git a/project_templates/technote_typst/README.md b/project_templates/technote_typst/README.md new file mode 100644 index 00000000..ebd32a18 --- /dev/null +++ b/project_templates/technote_typst/README.md @@ -0,0 +1,44 @@ +# technote_typst + +**Rubin technical note repository, based on Typst.** + +This template generates a new technical note (technote) repository that is written in [Typst](https://typst.app) and published as a PDF, in the style of Rubin's LaTeX technotes. +Rubin technotes, in general, let you document technical designs, proposals, product overviews, results of prototyping experiments, and other types of documentation that doesn't fit in either the change-controlled document tree, or in user documentation. +See [Technotes for stand-alone technical documentation in the Developer Guide](https://developer.lsst.io/project-docs/technotes.html). + +The document metadata lives in `technote.toml`, using the same schema as Markdown and reStructuredText technotes, so `documenteer technote add-author` and `sync-authors` manage the author list from the central author database. +The Rubin document template is consumed as the `rubin-technote` Typst package, which the Makefile fetches from [lsst-texmf](https://github.com/lsst/lsst-texmf) as a vendored package, and the shared Rubin bibliographies are downloaded by a `sync-bibs` make target. + +## Template variables + +### cookiecutter.title + +The title of the technote. + +### cookiecutter.description + +A short description of the technote's content and purpose, used as the initial abstract. + +### cookiecutter.series + +The identifier of the technote series. + +### cookiecutter.serial_number + +The serial number, assigned by the Slack bot or the next available number in the series. + +### cookiecutter.author_id + +The author's ID in lsst-texmf's [authordb.yaml](https://github.com/lsst/lsst-texmf/blob/main/etc/authordb.yaml) file. + +### cookiecutter.first_author_given, first_author_family, first_author_orcid, first_author_affil_name, first_author_affil_internal_id, first_author_affil_address + +The first author's name, ORCID iD, and affiliation, written into `technote.toml`. + +### cookiecutter.github_org + +The GitHub organization where the technote resides. + +### cookiecutter.copyright_year, copyright_holder + +The copyright statement written into the COPYRIGHT file. diff --git a/project_templates/technote_typst/SConscript b/project_templates/technote_typst/SConscript new file mode 100644 index 00000000..efbbbddd --- /dev/null +++ b/project_templates/technote_typst/SConscript @@ -0,0 +1,18 @@ +from templatekit.builder import cookiecutter_project_builder + +# Run cookiecutter to generate the 'TESTN-000' report +env = Environment(BUILDERS={"Cookiecutter": cookiecutter_project_builder}) +env.Cookiecutter( + AlwaysBuild(Dir("TESTN-000")), + "cookiecutter.json", + cookiecutter_context={ + "series": "TESTN", + "first_author_given": "First", + "first_author_family": "Author", + "first_author_orcid": "https://orcid.org/0000-0003-3001-676X", + "first_author_author_id": "test", + "first_author_affil_name": "Rubin Observatory", + "first_author_affil_internal_id": "RubinObs", + "first_author_affil_address": "950 N. Cherry Ave., Tucson, AZ 85719, USA", + }, +) diff --git a/project_templates/technote_typst/cookiecutter.json b/project_templates/technote_typst/cookiecutter.json new file mode 100644 index 00000000..6a2efb22 --- /dev/null +++ b/project_templates/technote_typst/cookiecutter.json @@ -0,0 +1,57 @@ +{ + "author_id": "ID from lsst-texmf/etc/authordb.yaml", + "series": [ + "DMTN", + "CTN", + "ITTN", + "RTN", + "PSTN", + "SMTN", + "SOTN", + "SQR", + "TSTN", + "TESTN" + ], + "serial_number": "000", + "title": "Document Title", + "repo_name": "{{ cookiecutter.series.lower() }}-{{ cookiecutter.serial_number }}", + "github_org": [ + "lsst", + "lsst-dm", + "lsst-it", + "lsst-pst", + "lsst-sims", + "lsst-so", + "lsst-sqre", + "lsst-tstn", + "lsst-sqre-testing" + ], + "github_namespace": "{{ cookiecutter.github_org }}/{{ cookiecutter.repo_name }}", + "docushare_url": "", + "url": "https://{{ cookiecutter.series.lower() }}-{{ cookiecutter.serial_number }}.lsst.io", + "description": "A short description of this document", + "copyright_year": "{% now 'utc', '%Y' %}", + "copyright_holder": [ + "Association of Universities for Research in Astronomy, Inc. (AURA)", + "Brookhaven Science Associates, LLC", + "California Institute of Technology", + "Fermi Research Alliance, LLC", + "The Board of Trustees of the Leland Stanford Junior University, through SLAC National Accelerator Laboratory", + "The Trustees of Princeton University", + "University of Illinois Board of Trustees", + "University of Washington" + ], + "first_author_given": "", + "first_author_family": "", + "first_author_orcid": "", + "first_author_affil_name": "", + "first_author_affil_internal_id": "", + "first_author_affil_address": "", + "_copy_without_render": [ + "*.bib" + ], + "_extensions": [ + "jinja2_time.TimeExtension", + "templatekit.TemplatekitExtension" + ] +} diff --git a/project_templates/technote_typst/templatekit.yaml b/project_templates/technote_typst/templatekit.yaml new file mode 100644 index 00000000..16d81379 --- /dev/null +++ b/project_templates/technote_typst/templatekit.yaml @@ -0,0 +1,76 @@ +name: "Technote (Typst)" +group: "Documents" +dialog_title: "Create a Typst technote" +dialog_fields: + - key: "title" + label: "Technote title" + placeholder: "" + hint: "Don't include the document's handle and avoid Typst markup." + component: "textarea" + - key: "description" + label: "Abstract or description" + hint: "Plain text works best here." + component: "textarea" + placeholder: "" + - key: "author_id" + label: "First author's ID" + hint: "ID is a key from lsst-texmf's authordb.yaml (http://ls.st/uyr)" + component: "text" + placeholder: "" + - label: "Series" + component: "select" + preset_options: + - label: "DMTN" + value: "dmtn" + presets: + series: "DMTN" + github_org: "lsst-dm" + - label: "CTN" + value: "ctn" + presets: + series: "CTN" + github_org: "lsst" + - label: "ITTN" + value: "ittn" + presets: + series: "ITTN" + github_org: "lsst-it" + - label: "PSTN" + value: "PSTN" + presets: + series: "PSTN" + github_org: "lsst-pst" + org: "PST" + - label: "RTN" + value: "rtn" + presets: + series: "RTN" + github_org: "lsst" + - label: "SMTN" + value: "smtn" + presets: + series: "SMTN" + github_org: "lsst-sims" + - label: "SOTN" + value: "sotn" + presets: + series: "SOTN" + github_org: "lsst-so" + - label: "SQR" + value: "sqr" + presets: + series: "SQR" + github_org: "lsst-sqre" + - label: "TSTN" + value: "tstn" + presets: + series: "TSTN" + github_org: "lsst-tstn" + - label: "Test" + value: "test" + presets: + series: "TESTN" + github_org: "lsst-sqre-testing" + - label: "Initial copyright holder" + key: "copyright_holder" + component: "select" diff --git a/project_templates/technote_typst/testn-000/.github/workflows/ci.yaml b/project_templates/technote_typst/testn-000/.github/workflows/ci.yaml new file mode 100644 index 00000000..41863b7a --- /dev/null +++ b/project_templates/technote_typst/testn-000/.github/workflows/ci.yaml @@ -0,0 +1,125 @@ +name: CI + +'on': [push, pull_request, workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 # full history for landing-page metadata + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Python install + run: | + python -m pip install --upgrade pip + python -m pip install "lander<2.0.0" setuptools + + - uses: typst-community/setup-typst@v5 + with: + typst-version: '0.15.0' + + - name: Typst build + run: make pdf + + # Independent audit of the archival (PDF/A-2a) and accessibility + # (PDF/UA-1) conformance that the build enforces, using veraPDF. + # This covers the machine-checkable requirements; alt-text quality + # and reading order still need human review. + - name: Validate PDF/A and PDF/UA conformance + run: | + for flavour in 2a ua1; do + docker run --rm -v "$PWD":/data verapdf/cli \ + --flavour $flavour --format text \ + "/data/TESTN-000.pdf" \ + | tee "verapdf-$flavour.txt" + done + ! grep -h "^FAIL" verapdf-*.txt + + # The landing page metadata comes from technote.toml and from the + # compiled document's own front matter, so author, + # title, and abstract changes are picked up automatically. + - name: Landing page upload + if: ${{ github.event_name == 'push' }} + env: + LTD_PASSWORD: ${{ secrets.LTD_PASSWORD }} + LTD_USERNAME: ${{ secrets.LTD_USERNAME }} + run: | + python3 - <<'EOF' + import json + import os + import subprocess + import tomllib + + with open("technote.toml", "rb") as fh: + technote = tomllib.load(fh)["technote"] + + # The flags mirror the compile command in the Makefile. + query = subprocess.run( + [ + "typst", "query", + "--root", ".", + "--package-path", ".typst-packages", + "--font-path", ".typst-packages/preview/rubin-technote/0.1.0/fonts", + "index.typ", + "", + "--field", "value", + "--one", + ], + check=True, + capture_output=True, + text=True, + ) + front_matter = json.loads(query.stdout) + + def plain_text(node): + """Flatten queried Typst content to plain text.""" + if node is None: + return "" + if isinstance(node, str): + return node + if isinstance(node, list): + return "".join(plain_text(child) for child in node) + if isinstance(node, dict): + func = node.get("func") + if func == "text": + return node.get("text", "") + if func == "space": + return " " + if func in ("parbreak", "linebreak"): + return "\n" + return plain_text( + node.get("children") or node.get("body") or node.get("child") + ) + return "" + + authors = [ + " ".join( + part + for part in (author["name"].get("given"), author["name"]["family"]) + if part + ) + for author in technote.get("authors", []) + ] + command = [ + "lander", + "--upload", + "--pdf", "TESTN-000.pdf", + "--ltd-product", "testn-000", + "--handle", technote["id"], + "--title", plain_text(front_matter["title"]).strip(), + "--authors", json.dumps(authors), + "--repo-url", technote["github_url"], + "--repo-branch", os.environ["GITHUB_REF_NAME"], + ] + abstract = plain_text(front_matter.get("abstract")).strip() + if abstract: + command.extend(("--abstract", abstract)) + subprocess.run(command, check=True) + EOF diff --git a/project_templates/technote_typst/testn-000/.gitignore b/project_templates/technote_typst/testn-000/.gitignore new file mode 100644 index 00000000..df98c4d1 --- /dev/null +++ b/project_templates/technote_typst/testn-000/.gitignore @@ -0,0 +1,7 @@ +*.pdf +lsstbib/ +.typst-packages/ +.typst-tmp/ +.tox/ +venv/ +.venv/ diff --git a/project_templates/technote_typst/testn-000/.pre-commit-config.yaml b/project_templates/technote_typst/testn-000/.pre-commit-config.yaml new file mode 100644 index 00000000..adb4c767 --- /dev/null +++ b/project_templates/technote_typst/testn-000/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + # - id: trailing-whitespace + - id: check-yaml + - id: check-toml diff --git a/project_templates/technote_typst/testn-000/COPYRIGHT b/project_templates/technote_typst/testn-000/COPYRIGHT new file mode 100644 index 00000000..8861def3 --- /dev/null +++ b/project_templates/technote_typst/testn-000/COPYRIGHT @@ -0,0 +1 @@ +Copyright 2026 Association of Universities for Research in Astronomy, Inc. (AURA) diff --git a/project_templates/technote_typst/testn-000/LICENSE b/project_templates/technote_typst/testn-000/LICENSE new file mode 100644 index 00000000..2f244ac8 --- /dev/null +++ b/project_templates/technote_typst/testn-000/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/project_templates/technote_typst/testn-000/Makefile b/project_templates/technote_typst/testn-000/Makefile new file mode 100644 index 00000000..757f8e8c --- /dev/null +++ b/project_templates/technote_typst/testn-000/Makefile @@ -0,0 +1,78 @@ +DOCNAME = TESTN-000 + +TEMPLATE_VERSION = 0.1.0 +PACKAGE_DIR = .typst-packages/preview/rubin-technote/$(TEMPLATE_VERSION) +LSST_TEXMF_REF ?= main +BIB_FILES = lsst.bib lsst-dm.bib refs.bib refs_ads.bib books.bib + +# The git state is stamped into the document's front matter. +GITVERSION := $(shell git log -1 --date=short --pretty=%h) +GITSTATUS := $(shell git status --porcelain) +ifneq "$(GITSTATUS)" "" + GITDIRTY = -dirty +endif + +# Enforced PDF standards: archival (PDF/A-2a) and accessible (PDF/UA-1) +# output, making missing alt text a compilation failure. Set PDF_STANDARD +# to empty to explicitly opt out of the enforcement. +PDF_STANDARD ?= a-2a,ua-1 + +.PHONY: +init: + pip install tox pre-commit + pre-commit install + +.PHONY: +pdf: $(PACKAGE_DIR) lsstbib + typst compile --root . \ + --package-path .typst-packages \ + --font-path $(PACKAGE_DIR)/fonts \ + --input source-version=$(GITVERSION)$(GITDIRTY) \ + $(if $(PDF_STANDARD),--pdf-standard $(PDF_STANDARD)) \ + index.typ $(DOCNAME).pdf + +# Fetch the rubin-technote Typst template as a vendored package. Set +# LSST_TEXMF_DIR to copy it from a local lsst-texmf checkout instead of +# downloading it from GitHub. +$(PACKAGE_DIR): + mkdir -p $(PACKAGE_DIR) +ifdef LSST_TEXMF_DIR + cp -R $(LSST_TEXMF_DIR)/typst-lsstdoc/. $(PACKAGE_DIR) +else + mkdir -p .typst-tmp + curl -fsSL https://github.com/lsst/lsst-texmf/archive/refs/heads/$(LSST_TEXMF_REF).tar.gz \ + | tar -xz -C .typst-tmp + cp -R .typst-tmp/*/typst-lsstdoc/. $(PACKAGE_DIR) + rm -rf .typst-tmp +endif + +.PHONY: +template: $(PACKAGE_DIR) + +lsstbib: + mkdir -p lsstbib + for bib in $(BIB_FILES); do \ + curl -fsSL -o lsstbib/$$bib \ + https://raw.githubusercontent.com/lsst/lsst-texmf/main/texmf/bibtex/bib/$$bib; \ + done + +.PHONY: +sync-bibs: + rm -rf lsstbib + $(MAKE) lsstbib + +.PHONY: +add-author: + tox run -e add-author + +.PHONY: +sync-authors: + tox run -e sync-authors + +.PHONY: +lint: + tox run -e lint + +.PHONY: +clean: + rm -rf $(DOCNAME).pdf lsstbib .typst-packages .typst-tmp .tox diff --git a/project_templates/technote_typst/testn-000/README.md b/project_templates/technote_typst/testn-000/README.md new file mode 100644 index 00000000..6aa42756 --- /dev/null +++ b/project_templates/technote_typst/testn-000/README.md @@ -0,0 +1,43 @@ +[![Website](https://img.shields.io/badge/testn--000-lsst.io-brightgreen.svg)](https://testn-000.lsst.io) +[![CI](https://github.com/lsst/testn-000/actions/workflows/ci.yaml/badge.svg)](https://github.com/lsst/testn-000/actions/workflows/ci.yaml) + +# Document Title + +## TESTN-000 + +A short description of this document + +**Links:** + +- Publication URL: https://testn-000.lsst.io +- GitHub repository: https://github.com/lsst/testn-000 +- Build system: https://github.com/lsst/testn-000/actions/ + + +## Build this technical note + +You can clone this repository and build the technote locally if your system has [Typst](https://typst.app) 0.15 or later and Python 3.11 or later: + +```sh +git clone https://github.com/lsst/testn-000 +cd testn-000 +make init +make pdf +``` + +The first `make pdf` downloads the `rubin-technote` Typst template and the shared Rubin bibliographies; set `LSST_TEXMF_DIR` to a local [lsst-texmf](https://github.com/lsst/lsst-texmf) checkout to copy the template from there instead. +Repeat the `make pdf` command to rebuild the technote after making changes. +If you need to delete any intermediate files for a clean build, run `make clean`. + +The built technote is located at `TESTN-000.pdf`. + +## Publishing changes to the web + +This technote is published to https://testn-000.lsst.io whenever you push changes to the `main` branch on GitHub. +When you push changes to another branch, a preview of the technote is published to https://testn-000.lsst.io/v. + +## Editing this technical note + +The main content of this technote is in `index.typ` (a [Typst](https://typst.app/docs) file). +Metadata, authors, and the document status are in the `technote.toml` file; run `make add-author` to add an author from the central author database and `make sync-authors` to refresh existing author entries. +Run `make sync-bibs` to refresh the shared Rubin bibliographies in `lsstbib/`. diff --git a/project_templates/technote_typst/testn-000/index.typ b/project_templates/technote_typst/testn-000/index.typ new file mode 100644 index 00000000..8a066154 --- /dev/null +++ b/project_templates/technote_typst/testn-000/index.typ @@ -0,0 +1,30 @@ +#import "@preview/rubin-technote:0.1.0": citeds, citedsp, lsstdoc, note, technote-args, warning + +// Shared Rubin bibliographies are materialized into lsstbib/ by +// `make sync-bibs` (run automatically by `make pdf`). +#let bibliographies = ( + read("local.bib", encoding: none), + read("lsstbib/lsst.bib", encoding: none), + read("lsstbib/lsst-dm.bib", encoding: none), + read("lsstbib/refs.bib", encoding: none), + read("lsstbib/refs_ads.bib", encoding: none), + read("lsstbib/books.bib", encoding: none), +) + +// Metadata, authors, and document status come from technote.toml, which +// `make add-author` and `make sync-authors` keep up to date. +#show: lsstdoc.with( + ..technote-args(toml("technote.toml")), + title: "Document Title", + abstract: [ + A short description of this document + ], + bibliography: bibliographies, +) + += Introduction + +Add content here. +Other Rubin documents can be referenced by their handles, for example +the science requirements #citeds("LPM-17"), and ordinary citations use +Typst's `@` syntax against the shared bibliographies or `local.bib`. diff --git a/project_templates/technote_typst/testn-000/local.bib b/project_templates/technote_typst/testn-000/local.bib new file mode 100644 index 00000000..e69de29b diff --git a/project_templates/technote_typst/testn-000/requirements.txt b/project_templates/technote_typst/testn-000/requirements.txt new file mode 100644 index 00000000..470a7ae8 --- /dev/null +++ b/project_templates/technote_typst/testn-000/requirements.txt @@ -0,0 +1 @@ +documenteer[technote]>=2.0.0,<3 diff --git a/project_templates/technote_typst/testn-000/technote.toml b/project_templates/technote_typst/testn-000/technote.toml new file mode 100644 index 00000000..e45fd77a --- /dev/null +++ b/project_templates/technote_typst/testn-000/technote.toml @@ -0,0 +1,23 @@ +[technote] +id = "TESTN-000" +series_id = "TESTN" +canonical_url = "https://testn-000.lsst.io" +github_url = "https://github.com/lsst/testn-000" +github_default_branch = "main" +date_created = 2026-07-18T23:33:23Z +organization.name = "NSF-DOE Vera C. Rubin Observatory" +organization.ror = "https://ror.org/048g3cy84" +license.id = "CC-BY-4.0" + +[technote.status] +state = "draft" + +[[technote.authors]] +name.given = "First" +name.family = "Author" +internal_id = "ID from lsst-texmf/etc/authordb.yaml" +orcid = "https://orcid.org/0000-0003-3001-676X" +[[technote.authors.affiliations]] +name = "Rubin Observatory" +internal_id = "RubinObs" +address = "950 N. Cherry Ave., Tucson, AZ 85719, USA" diff --git a/project_templates/technote_typst/testn-000/tox.ini b/project_templates/technote_typst/testn-000/tox.ini new file mode 100644 index 00000000..d5f7b6f9 --- /dev/null +++ b/project_templates/technote_typst/testn-000/tox.ini @@ -0,0 +1,21 @@ +[tox] +environments = lint +isolated_build = True + +[testenv] +skip_install = true +deps = + -rrequirements.txt + +[testenv:lint] +deps = pre-commit +commands = + pre-commit run --all-files + +[testenv:add-author] +commands = + documenteer technote add-author + +[testenv:sync-authors] +commands = + documenteer technote sync-authors diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/.github/workflows/ci.yaml b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.github/workflows/ci.yaml new file mode 100644 index 00000000..4a6202b6 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.github/workflows/ci.yaml @@ -0,0 +1,125 @@ +name: CI + +'on': [push, pull_request, workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 # full history for landing-page metadata + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Python install + run: | + python -m pip install --upgrade pip + python -m pip install "lander<2.0.0" setuptools + + - uses: typst-community/setup-typst@v5 + with: + typst-version: '0.15.0' + + - name: Typst build + run: make pdf + + # Independent audit of the archival (PDF/A-2a) and accessibility + # (PDF/UA-1) conformance that the build enforces, using veraPDF. + # This covers the machine-checkable requirements; alt-text quality + # and reading order still need human review. + - name: Validate PDF/A and PDF/UA conformance + run: | + for flavour in 2a ua1; do + docker run --rm -v "$PWD":/data verapdf/cli \ + --flavour $flavour --format text \ + "/data/{{ cookiecutter.series }}-{{ cookiecutter.serial_number }}.pdf" \ + | tee "verapdf-$flavour.txt" + done + ! grep -h "^FAIL" verapdf-*.txt + + # The landing page metadata comes from technote.toml and from the + # compiled document's own front matter, so author, + # title, and abstract changes are picked up automatically. + - name: Landing page upload + if: {% raw %}${{ github.event_name == 'push' }}{% endraw %} + env: + LTD_PASSWORD: {% raw %}${{ secrets.LTD_PASSWORD }}{% endraw %} + LTD_USERNAME: {% raw %}${{ secrets.LTD_USERNAME }}{% endraw %} + run: | + python3 - <<'EOF' + import json + import os + import subprocess + import tomllib + + with open("technote.toml", "rb") as fh: + technote = tomllib.load(fh)["technote"] + + # The flags mirror the compile command in the Makefile. + query = subprocess.run( + [ + "typst", "query", + "--root", ".", + "--package-path", ".typst-packages", + "--font-path", ".typst-packages/preview/rubin-technote/0.1.0/fonts", + "index.typ", + "", + "--field", "value", + "--one", + ], + check=True, + capture_output=True, + text=True, + ) + front_matter = json.loads(query.stdout) + + def plain_text(node): + """Flatten queried Typst content to plain text.""" + if node is None: + return "" + if isinstance(node, str): + return node + if isinstance(node, list): + return "".join(plain_text(child) for child in node) + if isinstance(node, dict): + func = node.get("func") + if func == "text": + return node.get("text", "") + if func == "space": + return " " + if func in ("parbreak", "linebreak"): + return "\n" + return plain_text( + node.get("children") or node.get("body") or node.get("child") + ) + return "" + + authors = [ + " ".join( + part + for part in (author["name"].get("given"), author["name"]["family"]) + if part + ) + for author in technote.get("authors", []) + ] + command = [ + "lander", + "--upload", + "--pdf", "{{ cookiecutter.series }}-{{ cookiecutter.serial_number }}.pdf", + "--ltd-product", "{{ cookiecutter.series.lower() }}-{{ cookiecutter.serial_number }}", + "--handle", technote["id"], + "--title", plain_text(front_matter["title"]).strip(), + "--authors", json.dumps(authors), + "--repo-url", technote["github_url"], + "--repo-branch", os.environ["GITHUB_REF_NAME"], + ] + abstract = plain_text(front_matter.get("abstract")).strip() + if abstract: + command.extend(("--abstract", abstract)) + subprocess.run(command, check=True) + EOF diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/.gitignore b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.gitignore new file mode 100644 index 00000000..df98c4d1 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.gitignore @@ -0,0 +1,7 @@ +*.pdf +lsstbib/ +.typst-packages/ +.typst-tmp/ +.tox/ +venv/ +.venv/ diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/.pre-commit-config.yaml b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.pre-commit-config.yaml new file mode 100644 index 00000000..adb4c767 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + # - id: trailing-whitespace + - id: check-yaml + - id: check-toml diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/COPYRIGHT b/project_templates/technote_typst/{{cookiecutter.repo_name}}/COPYRIGHT new file mode 100644 index 00000000..0d8da6ea --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/COPYRIGHT @@ -0,0 +1 @@ +Copyright {{ cookiecutter.copyright_year }} {{ cookiecutter.copyright_holder }} diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/LICENSE b/project_templates/technote_typst/{{cookiecutter.repo_name}}/LICENSE new file mode 100644 index 00000000..2f244ac8 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/Makefile b/project_templates/technote_typst/{{cookiecutter.repo_name}}/Makefile new file mode 100644 index 00000000..9a0a8ed2 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/Makefile @@ -0,0 +1,78 @@ +DOCNAME = {{ cookiecutter.series }}-{{ cookiecutter.serial_number }} + +TEMPLATE_VERSION = 0.1.0 +PACKAGE_DIR = .typst-packages/preview/rubin-technote/$(TEMPLATE_VERSION) +LSST_TEXMF_REF ?= main +BIB_FILES = lsst.bib lsst-dm.bib refs.bib refs_ads.bib books.bib + +# The git state is stamped into the document's front matter. +GITVERSION := $(shell git log -1 --date=short --pretty=%h) +GITSTATUS := $(shell git status --porcelain) +ifneq "$(GITSTATUS)" "" + GITDIRTY = -dirty +endif + +# Enforced PDF standards: archival (PDF/A-2a) and accessible (PDF/UA-1) +# output, making missing alt text a compilation failure. Set PDF_STANDARD +# to empty to explicitly opt out of the enforcement. +PDF_STANDARD ?= a-2a,ua-1 + +.PHONY: +init: + pip install tox pre-commit + pre-commit install + +.PHONY: +pdf: $(PACKAGE_DIR) lsstbib + typst compile --root . \ + --package-path .typst-packages \ + --font-path $(PACKAGE_DIR)/fonts \ + --input source-version=$(GITVERSION)$(GITDIRTY) \ + $(if $(PDF_STANDARD),--pdf-standard $(PDF_STANDARD)) \ + index.typ $(DOCNAME).pdf + +# Fetch the rubin-technote Typst template as a vendored package. Set +# LSST_TEXMF_DIR to copy it from a local lsst-texmf checkout instead of +# downloading it from GitHub. +$(PACKAGE_DIR): + mkdir -p $(PACKAGE_DIR) +ifdef LSST_TEXMF_DIR + cp -R $(LSST_TEXMF_DIR)/typst-lsstdoc/. $(PACKAGE_DIR) +else + mkdir -p .typst-tmp + curl -fsSL https://github.com/lsst/lsst-texmf/archive/refs/heads/$(LSST_TEXMF_REF).tar.gz \ + | tar -xz -C .typst-tmp + cp -R .typst-tmp/*/typst-lsstdoc/. $(PACKAGE_DIR) + rm -rf .typst-tmp +endif + +.PHONY: +template: $(PACKAGE_DIR) + +lsstbib: + mkdir -p lsstbib + for bib in $(BIB_FILES); do \ + curl -fsSL -o lsstbib/$$bib \ + https://raw.githubusercontent.com/lsst/lsst-texmf/main/texmf/bibtex/bib/$$bib; \ + done + +.PHONY: +sync-bibs: + rm -rf lsstbib + $(MAKE) lsstbib + +.PHONY: +add-author: + tox run -e add-author + +.PHONY: +sync-authors: + tox run -e sync-authors + +.PHONY: +lint: + tox run -e lint + +.PHONY: +clean: + rm -rf $(DOCNAME).pdf lsstbib .typst-packages .typst-tmp .tox diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/README.md b/project_templates/technote_typst/{{cookiecutter.repo_name}}/README.md new file mode 100644 index 00000000..2c854ef7 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/README.md @@ -0,0 +1,45 @@ +[![Website](https://img.shields.io/badge/{{ cookiecutter.repo_name|replace("-", "--") }}-lsst.io-brightgreen.svg)]({{ cookiecutter.url }}) +[![CI](https://github.com/{{ cookiecutter.github_namespace }}/actions/workflows/ci.yaml/badge.svg)](https://github.com/{{ cookiecutter.github_namespace }}/actions/workflows/ci.yaml) + +# {{ cookiecutter.title }} + +## {{ cookiecutter.series }}-{{ cookiecutter.serial_number }} + +{{ cookiecutter.description }} + +**Links:** + +- Publication URL: {{ cookiecutter.url }} +- GitHub repository: https://github.com/{{ cookiecutter.github_namespace }} +- Build system: https://github.com/{{ cookiecutter.github_namespace }}/actions/ +{% if cookiecutter.docushare_url|length > 0 %} +- LSST Docushare: {{ cookiecutter.docushare_url }}. +{% endif %} + +## Build this technical note + +You can clone this repository and build the technote locally if your system has [Typst](https://typst.app) 0.15 or later and Python 3.11 or later: + +```sh +git clone https://github.com/{{ cookiecutter.github_namespace }} +cd {{ cookiecutter.series.lower() }}-{{ cookiecutter.serial_number }} +make init +make pdf +``` + +The first `make pdf` downloads the `rubin-technote` Typst template and the shared Rubin bibliographies; set `LSST_TEXMF_DIR` to a local [lsst-texmf](https://github.com/lsst/lsst-texmf) checkout to copy the template from there instead. +Repeat the `make pdf` command to rebuild the technote after making changes. +If you need to delete any intermediate files for a clean build, run `make clean`. + +The built technote is located at `{{ cookiecutter.series }}-{{ cookiecutter.serial_number }}.pdf`. + +## Publishing changes to the web + +This technote is published to {{ cookiecutter.url }} whenever you push changes to the `main` branch on GitHub. +When you push changes to another branch, a preview of the technote is published to {{ cookiecutter.url }}/v. + +## Editing this technical note + +The main content of this technote is in `index.typ` (a [Typst](https://typst.app/docs) file). +Metadata, authors, and the document status are in the `technote.toml` file; run `make add-author` to add an author from the central author database and `make sync-authors` to refresh existing author entries. +Run `make sync-bibs` to refresh the shared Rubin bibliographies in `lsstbib/`. diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/index.typ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/index.typ new file mode 100644 index 00000000..78ee3fdd --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/index.typ @@ -0,0 +1,30 @@ +#import "@preview/rubin-technote:0.1.0": citeds, citedsp, lsstdoc, note, technote-args, warning + +// Shared Rubin bibliographies are materialized into lsstbib/ by +// `make sync-bibs` (run automatically by `make pdf`). +#let bibliographies = ( + read("local.bib", encoding: none), + read("lsstbib/lsst.bib", encoding: none), + read("lsstbib/lsst-dm.bib", encoding: none), + read("lsstbib/refs.bib", encoding: none), + read("lsstbib/refs_ads.bib", encoding: none), + read("lsstbib/books.bib", encoding: none), +) + +// Metadata, authors, and document status come from technote.toml, which +// `make add-author` and `make sync-authors` keep up to date. +#show: lsstdoc.with( + ..technote-args(toml("technote.toml")), + title: "{{ cookiecutter.title }}", + abstract: [ + {{ cookiecutter.description }} + ], + bibliography: bibliographies, +) + += Introduction + +Add content here. +Other Rubin documents can be referenced by their handles, for example +the science requirements #citeds("LPM-17"), and ordinary citations use +Typst's `@` syntax against the shared bibliographies or `local.bib`. diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/local.bib b/project_templates/technote_typst/{{cookiecutter.repo_name}}/local.bib new file mode 100644 index 00000000..e69de29b diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/requirements.txt b/project_templates/technote_typst/{{cookiecutter.repo_name}}/requirements.txt new file mode 100644 index 00000000..470a7ae8 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/requirements.txt @@ -0,0 +1 @@ +documenteer[technote]>=2.0.0,<3 diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/technote.toml b/project_templates/technote_typst/{{cookiecutter.repo_name}}/technote.toml new file mode 100644 index 00000000..8ec67074 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/technote.toml @@ -0,0 +1,23 @@ +[technote] +id = "{{ cookiecutter.series | escape_yaml_doublequoted }}-{{ cookiecutter.serial_number | escape_yaml_doublequoted }}" +series_id = "{{ cookiecutter.series | escape_yaml_doublequoted }}" +canonical_url = "{{ cookiecutter.url | escape_yaml_doublequoted }}" +github_url = "https://github.com/{{ cookiecutter.github_namespace | escape_yaml_doublequoted }}" +github_default_branch = "main" +date_created = {% now 'utc', '%Y-%m-%dT%H:%M:%SZ' %} +organization.name = "NSF-DOE Vera C. Rubin Observatory" +organization.ror = "https://ror.org/048g3cy84" +license.id = "CC-BY-4.0" + +[technote.status] +state = "draft" + +[[technote.authors]] +name.given = "{{ cookiecutter.first_author_given }}" +name.family = "{{ cookiecutter.first_author_family }}" +internal_id = "{{ cookiecutter.author_id }}" +{% if cookiecutter.first_author_orcid %}orcid = "{{ cookiecutter.first_author_orcid }}"{% endif %} +[[technote.authors.affiliations]] +name = "{{ cookiecutter.first_author_affil_name }}" +internal_id = "{{ cookiecutter.first_author_affil_internal_id }}" +address = "{{ cookiecutter.first_author_affil_address }}" diff --git a/project_templates/technote_typst/{{cookiecutter.repo_name}}/tox.ini b/project_templates/technote_typst/{{cookiecutter.repo_name}}/tox.ini new file mode 100644 index 00000000..d5f7b6f9 --- /dev/null +++ b/project_templates/technote_typst/{{cookiecutter.repo_name}}/tox.ini @@ -0,0 +1,21 @@ +[tox] +environments = lint +isolated_build = True + +[testenv] +skip_install = true +deps = + -rrequirements.txt + +[testenv:lint] +deps = pre-commit +commands = + pre-commit run --all-files + +[testenv:add-author] +commands = + documenteer technote add-author + +[testenv:sync-authors] +commands = + documenteer technote sync-authors