Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/brand-sync.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Keep _brand/ and the generated reference.docx in step with
# openwashdata/brand. Runs weekly and on request; opens a pull request
# into dev when anything changed, none otherwise.
name: brand-sync

on:
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:

permissions:
contents: write
pull-requests: write

jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: dev

- uses: quarto-dev/quarto-actions/setup@v2
with:
version: 1.9.38

- name: Refresh _brand/ from openwashdata/brand
run: quarto use brand openwashdata/brand --force

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
packages: any::xml2, any::zip, any::yaml, any::brand.yml

- name: Regenerate reference.docx
run: Rscript tools/make-reference-docx.R

# A pull request opened with GITHUB_TOKEN does not trigger render.yaml,
# so the render gate runs here before the PR exists.
- name: Render both formats as a gate
run: quarto render template.qmd --to owd-typst,owd-docx

- name: Summarise changes
id: changes
run: |
{
echo "files<<EOF"
git status --porcelain -- _brand _extensions/owd/reference.docx | sed 's/^/- /'
echo "EOF"
} >> "$GITHUB_OUTPUT"

# The openwashdata org does not let GITHUB_TOKEN open pull requests.
# Until that setting changes, a fine-grained PAT with contents and
# pull-requests write on this repo goes into the BRAND_SYNC_TOKEN
# secret; a PR opened with it also triggers render.yaml.
- uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.BRAND_SYNC_TOKEN || github.token }}
base: dev
branch: brand-sync
add-paths: |
_brand
_extensions/owd/reference.docx
commit-message: "chore: sync the brand from openwashdata/brand"
title: "chore: sync the brand from openwashdata/brand"
labels: brand
body: |
Automated refresh of `_brand/` from openwashdata/brand and of the
generated `reference.docx`. Both formats rendered in this run.

Changed files:

${{ steps.changes.outputs.files }}
62 changes: 62 additions & 0 deletions .github/workflows/render.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Smoke test on every push and pull request: render template.qmd in both
# formats, and check that the committed reference.docx matches what the
# generator produces from the current brand.
name: render

on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch:

jobs:
render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: quarto-dev/quarto-actions/setup@v2
with:
version: 1.9.38

# Quarto downloads the brand fonts from Google Fonts on the first
# Typst render; keep them between runs until the brand changes.
- uses: actions/cache@v4
with:
path: .quarto/typst/fonts
key: typst-fonts-${{ hashFiles('_brand/_brand.yml') }}

- name: Render template.qmd to owd-typst and owd-docx
run: quarto render template.qmd --to owd-typst,owd-docx

- uses: actions/upload-artifact@v4
with:
name: template
path: |
template.pdf
template.docx
if-no-files-found: error

reference-docx:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
packages: any::xml2, any::zip, any::yaml, any::brand.yml

- name: Regenerate reference.docx from _brand/_brand.yml
run: Rscript tools/make-reference-docx.R

- name: Fail when the committed reference.docx is stale
run: |
git diff --stat --exit-code -- _extensions/owd/reference.docx || {
echo "::error::_extensions/owd/reference.docx does not match _brand/_brand.yml. Run Rscript tools/make-reference-docx.R and commit."
exit 1
}
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Quarto render artefacts
.quarto/
/.quarto/
template.pdf
template.docx
template.typ
template_files/
*_files/

# OS and editors
.DS_Store
.Rproj.user/
*.Rproj
.Rhistory
10 changes: 10 additions & 0 deletions .quartoignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Not copied into a new project by `quarto use template openwashdata/quarto-owd`.
# The extension, the brand mirror and template.qmd are what a new document needs.
.github/
tools/
images/
README.md
NEWS.md
LICENSE
.gitignore
.quartoignore
18 changes: 18 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# quarto-owd 0.1.0

First release.

- `owd-typst`: PDF through Typst. Reads the brand at render time: brand
fonts, headings and the title rule in the primary colour, links in the
link colour, code blocks tinted from the primary colour, the medium logo
once in the title block, white pages, A4 with 25 mm margins, a footer
with `footer-text` and page numbers.
- `owd-docx`: Word through a `reference.docx` whose styles are generated
from the brand by `tools/make-reference-docx.R`. A4 with 20 mm margins,
1.15 line height, data tables with all borders and a tinted header row
(style `OwdTable`, assigned by a filter), brand fonts with Arial and
Courier New as substitutes when they are not installed.
- `_brand/` mirrors openwashdata/brand; `template.qmd` is the starter
document and the CI smoke test.
- Works on Quarto 1.8 with an explicit `brand:` key and on Quarto 1.9
without one.
162 changes: 161 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,162 @@
# quarto-owd
Quarto extension: openwashdata brand for Typst (PDF) and DOCX documents (formats owd-typst, owd-docx)

[![render](https://github.com/openwashdata/quarto-owd/actions/workflows/render.yaml/badge.svg)](https://github.com/openwashdata/quarto-owd/actions/workflows/render.yaml)

A Quarto extension that renders documents in the openwashdata brand. It
provides two formats:

- `owd-typst`: PDF, through Typst
- `owd-docx`: Word

Both take their colours, fonts and logo from the brand definition in
[openwashdata/brand](https://github.com/openwashdata/brand). The Typst
format reads the brand file at render time. The Word format uses a
reference document whose styles are generated from the same file.

![First page of the sample document rendered with owd-typst](images/template-page-1.png)

## Requirements

- Quarto 1.9 or later. RStudio and Positron bundle it; check with
`quarto --version`. Quarto 1.8 works too, with one extra line in the
document header (see [Quarto 1.8](#quarto-18)).
- Nothing else for rendering. R is only needed to regenerate the Word
reference document (see [Maintaining](#maintaining)).

## Install

For a new document, in an empty directory:

```sh
quarto use template openwashdata/quarto-owd
```

This copies the extension, the brand mirror in `_brand/` and a starter
document named after the directory. Render it with:

```sh
quarto render mydoc.qmd --to owd-typst
```

For an existing project:

```sh
quarto add openwashdata/quarto-owd
quarto use brand openwashdata/brand
```

Then list the formats in the document header:

```yaml
format:
owd-typst: default
owd-docx: default
```

## Options

Everything Quarto offers for `typst` and `docx` works as usual, for
example `toc`, `number-sections`, `fontsize`, `papersize` and `margin`.
The Typst format adds two options:

```yaml
format:
owd-typst:
footer-text: openwashdata.org # left side of the footer
logo-width: 40mm # width of the logo in the title block
```

## Update

```sh
quarto update openwashdata/quarto-owd
quarto use brand openwashdata/brand
```

The two commands do different things. `quarto use brand` refreshes
`_brand/`, and the Typst format picks the change up at the next render.
The Word styles are baked into the extension's `reference.docx`, so a
brand change reaches Word documents only through `quarto update`, once
this repository has regenerated the file.

## Fonts

The brand uses Atkinson Hyperlegible for text and Source Code Pro for
code.

- Typst: Quarto downloads both from Google Fonts into
`.quarto/typst/fonts` on the first render. That first render needs a
network connection.
- Word: the fonts have to be installed on the machine that opens the
document. Without them Word falls back to Arial and Courier New, which
the reference document names as alternates. Both brand fonts are free:
[Atkinson Hyperlegible](https://fonts.google.com/specimen/Atkinson+Hyperlegible)
and [Source Code Pro](https://fonts.google.com/specimen/Source+Code+Pro).
Word reads the font list when it starts, so restart it after installing.

## Table of contents

Neither format adds one on its own. Set `toc: true` in the document
header (with `toc-depth` and `toc-title` as usual). The Typst format
computes it at render time. In Word the table of contents is a field:
Word asks whether to update fields when the document opens, and answering
Yes fills it in. Otherwise right-click the heading and choose Update
Field.

## Quarto 1.8

Quarto 1.8 does not look for `_brand/` on its own and has no
`quarto use brand` command. Copy `_brand.yml` and `logos/` from
openwashdata/brand into `_brand/` by hand and name the file in the
document header:

```yaml
brand: _brand/_brand.yml
```

## For washr data package authors

After `washr::use_brand()`, a data package already has `_brand.yml` and
`logos/` at its root. In the package root:

```sh
quarto add openwashdata/quarto-owd
```

Do not run `quarto use brand` as well; two brand copies in one project
are one too many. Add `^_extensions$` to `.Rbuildignore`. A `.qmd` in the
package root finds `_brand.yml` on its own with Quarto 1.9; a document in
a subfolder needs `brand: ../_brand.yml` in its header.

## How the brand flows

Values change in openwashdata/brand first. A weekly workflow in this
repository copies the brand into `_brand/`, regenerates `reference.docx`
and opens a pull request when anything changed. After the next release,
`quarto update` brings the Word styles to your project, and
`quarto use brand` brings the brand file itself.

## Maintaining

The Word reference document lives at `_extensions/owd/reference.docx`.
Regenerate its styles from the brand with R (packages xml2, zip, yaml and
brand.yml):

```sh
quarto use brand openwashdata/brand --force
Rscript tools/make-reference-docx.R
```

The script rewrites `word/styles.xml` and `word/theme/theme1.xml` and
nothing else, so a header or footer added in Word survives. Running it
twice gives identical bytes; CI checks that the committed file matches
the current brand.

`tools/bootstrap-reference-docx.R --force` starts over from pandoc's
default document on A4. It discards any edits made in Word.

## License

MIT for the extension code (see `LICENSE`). The brand assets in `_brand/`
belong to openwashdata; their license is tracked in
[openwashdata/brand#2](https://github.com/openwashdata/brand/issues/2).
Loading
Loading