Skip to content

Report#22

Open
maehr wants to merge 5 commits into
eth-library:mainfrom
maehr:report
Open

Report#22
maehr wants to merge 5 commits into
eth-library:mainfrom
maehr:report

Conversation

@maehr
Copy link
Copy Markdown
Collaborator

@maehr maehr commented Apr 24, 2026

Pull request overview

Adds a NAIF-branded Typst report template and exposes it as a Quarto extension so reports can be authored in Typst directly or rendered from Quarto to PDF.

Changes:

  • Introduces a reusable Typst report template package (documents/templates/typst) with an example document and compiled PDF.
  • Adds a Quarto extension (_extensions/naif-report) intended to provide a naif-report-typst output format using Typst template partials.
  • Adds a Quarto example report (documents/templates/quarto/naif-report-example.qmd) demonstrating the intended authoring workflow.

Copilot AI review requested due to automatic review settings April 24, 2026 12:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a NAIF-branded Typst report template and exposes it as a Quarto extension so reports can be authored in Typst directly or rendered from Quarto to PDF.

Changes:

  • Introduces a reusable Typst report template package (documents/templates/typst) with an example document and compiled PDF.
  • Adds a Quarto extension (_extensions/naif-report) intended to provide a naif-report-typst output format using Typst template partials.
  • Adds a Quarto example report (documents/templates/quarto/naif-report-example.qmd) demonstrating the intended authoring workflow.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
documents/templates/typst/typst.toml Defines Typst package metadata and the template entrypoint.
documents/templates/typst/lib.typ Implements the NAIF report layout, cover/title blocks, and helper components.
documents/templates/typst/example.typ Demonstrates how to use the Typst template directly.
documents/templates/typst/example.pdf Rendered sample output for the Typst example.
documents/templates/typst/README.md Documents usage and compilation instructions for the Typst template.
documents/templates/quarto/naif-report-example.qmd Demonstrates rendering a Quarto report using the NAIF Typst format.
_extensions/naif-report/typst-template.typ Typst implementation used by the Quarto extension (currently duplicates lib.typ).
_extensions/naif-report/typst-show.typ Quarto template glue that calls naif-report(...) with metadata mapped from YAML.
_extensions/naif-report/_extension.yml Registers the Quarto format contribution and template partials.
_extensions/naif-report/README.md Documents the intended custom Quarto format and supported metadata fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

(
name: [$it.name.literal$],
affiliation: [$for(it.affiliations)$$it.name$$sep$, $endfor$],
email: [$it.email$],
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

email is passed as Typst content (email: [$it.email$]), but the template later uses it in string concatenation ("mailto:" + email). In Typst, content is not a string, so this will likely error at render time. Pass email as a string value instead (e.g. email: "$it.email$") or adjust the template to convert content to a string before concatenation.

Suggested change
email: [$it.email$],
email: "$it.email$",

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +14
contributes:
formats:
typst:
doc-category: "NAIF report"
website: "https://eth-library.github.io/naif/"
toc: true
number-sections: true
template-partials:
- typst-template.typ
- typst-show.typ
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extension config contributes settings under formats.typst, but the documentation and example report use the custom format name naif-report-typst. As written, format: naif-report-typst: will not be registered by this extension (unless Quarto implicitly aliases it), so the example render will fail. Align these by either defining the format under formats.naif-report-typst (and inheriting from Typst) or updating the docs/examples to use format: typst:.

Copilot uses AI. Check for mistakes.
- metadata quality
- repositories
format:
naif-report-typst:
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format is set to naif-report-typst, but the extension currently contributes to the typst format name (see _extensions/naif-report/_extension.yml). Unless the extension actually registers naif-report-typst, this example file won’t render as-is. Update either the extension’s contributed format name or this YAML header to match.

Suggested change
naif-report-typst:
typst:

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +180
if not compact-mode {
counter(page).update(1)
_cover-page(doc-category, title, subtitle, authors, date, version, logo)
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

counter(page).update(1) is applied before generating the cover page, which means that when show-outline is false, the first numbered content page will be 2 (cover consumes page 1, but has no footer). Consider moving the page-counter reset to just before the main content starts (after cover/outline handling) so the first content page is consistently numbered 1 regardless of whether a TOC is shown.

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +180
if not compact-mode {
counter(page).update(1)
_cover-page(doc-category, title, subtitle, authors, date, version, logo)
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

counter(page).update(1) is applied before generating the cover page, which means that when show-outline is false, the first numbered content page will be 2 (cover consumes page 1, but has no footer). Consider moving the page-counter reset to just before the main content starts (after cover/outline handling) so the first content page is consistently numbered 1 regardless of whether a TOC is shown.

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +106
// Brand source: ../../../_brand.yml and ../../../base_colors.scss.

#let naif-primary = rgb("#A1AB71")
#let naif-secondary = rgb("#E8E1D0")
#let naif-dark = rgb("#181818")
#let naif-accent = rgb("#1F3A5F")
#let naif-accent-dark = rgb("#162A45")
#let naif-white = rgb("#FFFFFF")

#let naif-font-stack = ("Barlow", "Inter", "Arial", "Helvetica")
#let naif-barlow-font-stack = ("Barlow", "Inter", "Arial", "Helvetica")
#let naif-mono-font-stack = ("Menlo", "DejaVu Sans Mono")

#let _is-empty(value) = value == none or value == "" or value == []

#let _meta-line(date, version) = {
if date != none and version != none {
[#date | #version]
} else if date != none {
date
} else if version != none {
version
} else {
none
}
}

#let _author-card(author) = {
let name = author.at("name", default: [])
let affiliation = author.at("affiliation", default: none)
let email = author.at("email", default: none)

[
#text(weight: 700)[#name]
#if not _is-empty(affiliation) [
#v(2pt)
#text(size: 9pt)[#affiliation]
]
#if not _is-empty(email) [
#v(2pt)
#link("mailto:" + email)[#email]
]
]
}

#let _authors-block(authors) = {
if authors.len() > 0 {
let ncols = calc.min(authors.len(), 3)
grid(
columns: (1fr,) * ncols,
gutter: 10pt,
row-gutter: 12pt,
..authors.map(author => _author-card(author)),
)
}
}

#let _title-block(title, subtitle, authors, date, version, abstract, keywords) = {
let meta = _meta-line(date, version)

rect(width: 100%, fill: naif-secondary, radius: 8pt, inset: 20pt)[
#align(center)[
#text(size: 8pt, weight: 700, tracking: 0.08em, fill: naif-accent)[NAIF REPORT]
#v(9pt)
#text(size: 28pt, weight: 800, fill: naif-dark)[#title]
#v(5pt)
#line(length: 35%, stroke: 2pt + naif-primary)
#if subtitle != none [
#v(9pt)
#text(size: 14pt, weight: 500, fill: naif-accent-dark)[#subtitle]
]
#if meta != none [
#v(10pt)
#text(size: 9pt, weight: 500)[#meta]
]
]
]

if authors.len() > 0 {
v(14pt)
_authors-block(authors)
}

if abstract != none {
v(16pt)
rect(
width: 100%,
fill: naif-white,
stroke: 0.7pt + naif-secondary,
radius: 6pt,
inset: 12pt,
)[
#text(weight: 700, fill: naif-accent)[Abstract]
#v(4pt)
#abstract
#if keywords.len() > 0 [
#v(8pt)
#text(weight: 700)[Keywords.] #keywords.join(", ")
]
]
}

v(20pt)
}

Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file appears to duplicate documents/templates/typst/lib.typ (same constants + naif-report implementation). Maintaining two independent copies of the same Typst template increases the risk they drift over time. If possible, make one the single source of truth (e.g., have the extension reference/import the shared file, or generate/copy it as part of a build step).

Suggested change
// Brand source: ../../../_brand.yml and ../../../base_colors.scss.
#let naif-primary = rgb("#A1AB71")
#let naif-secondary = rgb("#E8E1D0")
#let naif-dark = rgb("#181818")
#let naif-accent = rgb("#1F3A5F")
#let naif-accent-dark = rgb("#162A45")
#let naif-white = rgb("#FFFFFF")
#let naif-font-stack = ("Barlow", "Inter", "Arial", "Helvetica")
#let naif-barlow-font-stack = ("Barlow", "Inter", "Arial", "Helvetica")
#let naif-mono-font-stack = ("Menlo", "DejaVu Sans Mono")
#let _is-empty(value) = value == none or value == "" or value == []
#let _meta-line(date, version) = {
if date != none and version != none {
[#date | #version]
} else if date != none {
date
} else if version != none {
version
} else {
none
}
}
#let _author-card(author) = {
let name = author.at("name", default: [])
let affiliation = author.at("affiliation", default: none)
let email = author.at("email", default: none)
[
#text(weight: 700)[#name]
#if not _is-empty(affiliation) [
#v(2pt)
#text(size: 9pt)[#affiliation]
]
#if not _is-empty(email) [
#v(2pt)
#link("mailto:" + email)[#email]
]
]
}
#let _authors-block(authors) = {
if authors.len() > 0 {
let ncols = calc.min(authors.len(), 3)
grid(
columns: (1fr,) * ncols,
gutter: 10pt,
row-gutter: 12pt,
..authors.map(author => _author-card(author)),
)
}
}
#let _title-block(title, subtitle, authors, date, version, abstract, keywords) = {
let meta = _meta-line(date, version)
rect(width: 100%, fill: naif-secondary, radius: 8pt, inset: 20pt)[
#align(center)[
#text(size: 8pt, weight: 700, tracking: 0.08em, fill: naif-accent)[NAIF REPORT]
#v(9pt)
#text(size: 28pt, weight: 800, fill: naif-dark)[#title]
#v(5pt)
#line(length: 35%, stroke: 2pt + naif-primary)
#if subtitle != none [
#v(9pt)
#text(size: 14pt, weight: 500, fill: naif-accent-dark)[#subtitle]
]
#if meta != none [
#v(10pt)
#text(size: 9pt, weight: 500)[#meta]
]
]
]
if authors.len() > 0 {
v(14pt)
_authors-block(authors)
}
if abstract != none {
v(16pt)
rect(
width: 100%,
fill: naif-white,
stroke: 0.7pt + naif-secondary,
radius: 6pt,
inset: 12pt,
)[
#text(weight: 700, fill: naif-accent)[Abstract]
#v(4pt)
#abstract
#if keywords.len() > 0 [
#v(8pt)
#text(weight: 700)[Keywords.] #keywords.join(", ")
]
]
}
v(20pt)
}
// Import the shared template library so this extension does not duplicate it.
#import "../../documents/templates/typst/lib.typ": *

Copilot uses AI. Check for mistakes.
keywords: ($for(keywords)$"$it$"$sep$, $endfor$),
$endif$
$if(lang)$
language: "$lang$",
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template passes Quarto’s project lang through to Typst (language: "$lang$"). In this repo _quarto.yml sets lang: en-UK, which is a non-standard BCP47 tag (typically en-GB). If Typst validates language tags, this can break rendering. Consider either omitting language unless explicitly set for the report, or normalising common values (e.g. mapping en-UKen-GB).

Suggested change
language: "$lang$",
language: if "$lang$" == "en-UK" { "en-GB" } else { "$lang$" },

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants