Skip to content

Commit a3ec44e

Browse files
Squashed 'src/resources/extension-subtrees/orange-book/' content from commit d39d268a9
git-subtree-dir: src/resources/extension-subtrees/orange-book git-subtree-split: d39d268a93a8e14518b59a2be05893f0a8943aef
0 parents  commit a3ec44e

181 files changed

Lines changed: 4384 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Orange Book Format Extension for Quarto
2+
3+
A Quarto format extension that provides Typst book support using the [orange-book](https://typst.app/universe/package/orange-book) package.
4+
5+
## Installation
6+
7+
Orange-book will be bundled with Quarto 1.9 and will be the default extension for Typst book projects.
8+
9+
However, if you want to explicitly install and use this extension
10+
11+
```bash
12+
quarto add quarto-ext/orange-book
13+
```
14+
15+
## Usage
16+
17+
In your `_quarto.yml`:
18+
19+
```yaml
20+
project:
21+
type: book
22+
23+
format: orange-book-typst
24+
```
25+
26+
## Features
27+
28+
- Transforms book parts into `#part[...]` calls for proper orange-book formatting
29+
- Handles appendix sections with `#show: appendices.with(...)`
30+
- Chapter-based numbering for equations, callouts, and cross-references
31+
- Integrates with Quarto's brand system for colors and logos
32+
33+
## Requirements
34+
35+
- Quarto >= 1.9.17
36+
- The `orange-book` Typst package (automatically imported and bundled with [typst-gather](https://prerelease.quarto.org/docs/advanced/typst/typst-gather.html))
37+
38+
## How It Works
39+
40+
This extension:
41+
42+
1. Provides template partials (`typst-show.typ`, `numbering.typ`) that configure the orange-book package
43+
2. Includes a Lua filter (`orange-book.lua`) that transforms Quarto's book structure into orange-book-specific Typst commands
44+
3. Uses Quarto's `file_metadata` API to detect book item types (parts, chapters, appendices)
45+
46+
## License
47+
48+
MIT
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
title: Typst Orange Book Format
2+
author: Quarto
3+
version: 0.1.0
4+
quarto-required: ">=1.9.17"
5+
contributes:
6+
formats:
7+
typst:
8+
template-partials:
9+
- numbering.typ
10+
- page.typ
11+
- typst-show.typ
12+
filters:
13+
- path: orange-book.lua
14+
at: post-quarto
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Chapter-based numbering for books with appendix support
2+
#let equation-numbering = it => {
3+
let pattern = if state("appendix-state", none).get() != none { "(A.1)" } else { "(1.1)" }
4+
numbering(pattern, counter(heading).get().first(), it)
5+
}
6+
#let callout-numbering = it => {
7+
let pattern = if state("appendix-state", none).get() != none { "A.1" } else { "1.1" }
8+
numbering(pattern, counter(heading).get().first(), it)
9+
}
10+
#let subfloat-numbering(n-super, subfloat-idx) = {
11+
let chapter = counter(heading).get().first()
12+
let pattern = if state("appendix-state", none).get() != none { "A.1a" } else { "1.1a" }
13+
numbering(pattern, chapter, n-super, subfloat-idx)
14+
}
15+
// Theorem configuration for theorion
16+
// Chapter-based numbering (H1 = chapters)
17+
#let theorem-inherited-levels = 1
18+
19+
// Appendix-aware theorem numbering
20+
#let theorem-numbering(loc) = {
21+
if state("appendix-state", none).at(loc) != none { "A.1" } else { "1.1" }
22+
}
23+
24+
// Theorem render function
25+
// Note: brand-color is not available at this point in template processing
26+
#let theorem-render(prefix: none, title: "", full-title: auto, body) = {
27+
block(
28+
width: 100%,
29+
inset: (left: 1em),
30+
stroke: (left: 2pt + black),
31+
)[
32+
#if full-title != "" and full-title != auto and full-title != none {
33+
strong[#full-title]
34+
linebreak()
35+
}
36+
#body
37+
]
38+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- orange-book.lua
2+
-- Orange-book specific part and appendix handling for Typst books
3+
4+
local function is_typst_book()
5+
local file_state = quarto.doc.file_metadata()
6+
return quarto.doc.is_format("typst") and
7+
file_state ~= nil and
8+
file_state.file ~= nil
9+
end
10+
11+
local header_filter = {
12+
Header = function(el)
13+
local file_state = quarto.doc.file_metadata()
14+
15+
if not is_typst_book() then
16+
return nil
17+
end
18+
19+
if file_state == nil or file_state.file == nil then
20+
return nil
21+
end
22+
23+
local file = file_state.file
24+
local bookItemType = file.bookItemType
25+
26+
if el.level ~= 1 or bookItemType == nil then
27+
return nil
28+
end
29+
30+
-- Handle parts
31+
if bookItemType == "part" then
32+
return pandoc.RawBlock('typst', '#part[' .. pandoc.utils.stringify(el.content) .. ']')
33+
end
34+
35+
-- Handle appendices
36+
if bookItemType == "appendix" then
37+
-- First appendix triggers the show rule with localized "Appendices" title
38+
if file.bookItemNumber == 1 or file.bookItemNumber == nil then
39+
-- Get localized title from language settings
40+
local language = quarto.doc.language
41+
local appendicesTitle = (language and language["section-title-appendices"]) or "Appendices"
42+
43+
-- Use hide-parent: true to work around orange-book bug where unnumbered headings
44+
-- (like Bibliography) trigger duplicate "Appendices" TOC entries.
45+
local appendixStart = pandoc.RawBlock('typst',
46+
'#show: appendices.with("' .. appendicesTitle .. '", hide-parent: true)')
47+
48+
-- If this is the synthetic "Appendices" divider heading (has .unnumbered class),
49+
-- emit our own Appendices heading for TOC display
50+
if el.classes:includes("unnumbered") then
51+
local appendicesHeading = pandoc.RawBlock('typst',
52+
'#heading(level: 1, numbering: none)[' .. appendicesTitle .. ']')
53+
return {appendixStart, appendicesHeading}
54+
end
55+
56+
return {appendixStart, el}
57+
end
58+
end
59+
60+
return nil
61+
end
62+
}
63+
64+
-- Combine with file_metadata_filter so book metadata markers are parsed
65+
-- during this filter's document traversal (needed for bookItemType, etc.)
66+
return quarto.utils.combineFilters({
67+
quarto.utils.file_metadata_filter(),
68+
header_filter
69+
})

_extensions/orange-book/page.typ

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#set page(
2+
paper: $if(papersize)$"$papersize$"$else$"us-letter"$endif$,
3+
$if(margin-geometry)$
4+
// Margins handled by marginalia.setup in typst-show.typ AFTER book.with()
5+
$elseif(margin)$
6+
margin: ($for(margin/pairs)$$margin.key$: $margin.value$,$endfor$),
7+
$else$
8+
margin: (x: 1.25in, y: 1.25in),
9+
$endif$
10+
numbering: $if(page-numbering)$"$page-numbering$"$else$none$endif$,
11+
columns: $if(columns)$$columns$$else$1$endif$,
12+
)
13+
// Logo is handled by orange-book's cover page, not as a page background
14+
// NOTE: marginalia.setup is called in typst-show.typ AFTER book.with()
15+
// to ensure marginalia's margins override the book format's default margins
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# typst-gather configuration
2+
# Run: quarto call typst-gather
3+
4+
destination = "typst/packages"
5+
6+
discover = ["numbering.typ", "page.typ", "typst-show.typ"]
7+
8+
# Preview packages are auto-discovered from imports.
9+
# Uncomment to pin specific versions:
10+
# [preview]
11+
# cetz = "0.4.1"
12+
13+
# Local packages (@local namespace) must be configured manually.
14+
# Found @local imports:
15+
# @local/orange-book:0.7.1 (in typst-show.typ)
16+
[local]
17+
orange-book = "/Users/gordon/src/tb-work/templates/orange-book"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#import "@local/orange-book:0.7.1": book, part, chapter, appendices
2+
3+
#show: book.with(
4+
$if(title)$
5+
title: [$title$],
6+
$endif$
7+
$if(subtitle)$
8+
subtitle: [$subtitle$],
9+
$endif$
10+
$if(by-author)$
11+
author: "$for(by-author)$$it.name.literal$$sep$, $endfor$",
12+
$endif$
13+
$if(date)$
14+
date: "$date$",
15+
$endif$
16+
$if(lang)$
17+
lang: "$lang$",
18+
$endif$
19+
main-color: brand-color.at("primary", default: blue),
20+
logo: {
21+
let logo-info = brand-logo.at("medium", default: none)
22+
if logo-info != none { image(logo-info.path, alt: logo-info.at("alt", default: none)) }
23+
},
24+
$if(toc-depth)$
25+
outline-depth: $toc-depth$,
26+
$endif$
27+
$if(lof)$
28+
list-of-figure-title: "$if(crossref.lof-title)$$crossref.lof-title$$else$$crossref-lof-title$$endif$",
29+
$endif$
30+
$if(lot)$
31+
list-of-table-title: "$if(crossref.lot-title)$$crossref.lot-title$$else$$crossref-lot-title$$endif$",
32+
$endif$
33+
$if(margin-geometry)$
34+
padded-heading-number: false,
35+
$endif$
36+
)
37+
38+
$if(margin-geometry)$
39+
// Configure marginalia page geometry for book context
40+
// Geometry computed by Quarto's meta.lua filter (typstGeometryFromPaperWidth)
41+
// IMPORTANT: This must come AFTER book.with() to override the book format's margin settings
42+
#import "@preview/marginalia:0.3.1" as marginalia
43+
44+
#show: marginalia.setup.with(
45+
inner: (
46+
far: $margin-geometry.inner.far$,
47+
width: $margin-geometry.inner.width$,
48+
sep: $margin-geometry.inner.separation$,
49+
),
50+
outer: (
51+
far: $margin-geometry.outer.far$,
52+
width: $margin-geometry.outer.width$,
53+
sep: $margin-geometry.outer.separation$,
54+
),
55+
top: $if(margin.top)$$margin.top$$else$1.25in$endif$,
56+
bottom: $if(margin.bottom)$$margin.bottom$$else$1.25in$endif$,
57+
// CRITICAL: Enable book mode for recto/verso awareness
58+
book: true,
59+
clearance: $margin-geometry.clearance$,
60+
)
61+
$endif$
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
MIT No Attribution
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
software and associated documentation files (the "Software"), to deal in the Software
5+
without restriction, including without limitation the rights to use, copy, modify,
6+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7+
permit persons to whom the Software is furnished to do so.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
10+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
11+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
12+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
13+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
14+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# orange-book
2+
A book template inspired by The Legrand Orange Book of Mathias Legrand and Vel https://www.latextemplates.com/template/legrand-orange-book.
3+
4+
## Usage
5+
You can use this template in the Typst web app by clicking "Start from template"
6+
on the dashboard and searching for `orange-book`.
7+
8+
Alternatively, you can use the CLI to kick this project off using the command
9+
```
10+
typst init @preview/orange-book
11+
```
12+
13+
Typst will create a new directory with all the files needed to get you started.
14+
15+
## Configuration
16+
This template exports the `book` function with the following named arguments:
17+
18+
- `title`: The book's title as content.
19+
- `subtitle`: The book's subtitle as content.
20+
- `author`: Content or an array of content to specify the author.
21+
- `paper-size`: Defaults to `a4`. Specify a [paper size
22+
string](https://typst.app/docs/reference/layout/page/#parameters-paper) to
23+
change the page format.
24+
- `copyright`: Details about the copyright or
25+
`none`.
26+
- `lowercase-references`: True to have references in lowercase (Eg. table 1.1)
27+
28+
The function also accepts a single, positional argument for the body of the
29+
book.
30+
31+
The template will initialize your package with a sample call to the `book`
32+
function in a show rule. If you, however, want to change an existing project to
33+
use this template, you can add a show rule like this at the top of your file:
34+
35+
```typ
36+
#import "@preview/orange-book:0.7.0": book
37+
38+
#show: book.with(
39+
title: "Exploring the Physical Manifestation of Humanity’s Subconscious Desires",
40+
subtitle: "A Practical Guide",
41+
date: "Anno scolastico 2023-2024",
42+
author: "Goro Akechi",
43+
main-color: rgb("#F36619"),
44+
lang: "en",
45+
cover: image("./background.svg"),
46+
image-index: image("./orange1.jpg"),
47+
list-of-figure-title: "List of Figures",
48+
list-of-table-title: "List of Tables",
49+
supplement-chapter: "Chapter",
50+
supplement-part: "Part",
51+
part-style: 0,
52+
copyright: [
53+
Copyright © 2023 Flavio Barisi
54+
55+
PUBLISHED BY PUBLISHER
56+
57+
#link("https://github.com/flavio20002/typst-orange-template", "TEMPLATE-WEBSITE")
58+
59+
Licensed under the Apache 2.0 License (the “License”).
60+
You may not use this file except in compliance with the License. You may obtain a copy of
61+
the License at https://www.apache.org/licenses/LICENSE-2.0. Unless required by
62+
applicable law or agreed to in writing, software distributed under the License is distributed on an
63+
“AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64+
See the License for the specific language governing permissions and limitations under the License.
65+
66+
_First printing, July 2023_
67+
],
68+
lowercase-references: false
69+
)
70+
71+
// Your content goes below.
72+
```

0 commit comments

Comments
 (0)