diff --git a/packages/preview/ori/0.2.0/LICENSE b/packages/preview/ori/0.2.0/LICENSE new file mode 100644 index 000000000..148b340d7 --- /dev/null +++ b/packages/preview/ori/0.2.0/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2025 OrangeX4 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/preview/ori/0.2.0/README.md b/packages/preview/ori/0.2.0/README.md new file mode 100644 index 000000000..17d48694a --- /dev/null +++ b/packages/preview/ori/0.2.0/README.md @@ -0,0 +1,89 @@ +# 🌠Ori + +[Ori](https://github.com/OrangeX4/typst-ori) 是一个简单但富有表现力的自用 Typst 文档模板,适用于笔记(支持夜间模式)、报告和各类文档。同时也是我个人 Typst 中文写作的最佳实践。 + +## 快速开始 + +要使用此模板,您需要: + +1. 安装必需的字体: + - [IBM Plex Sans, Mono](https://github.com/IBM/plex) + - [Noto Serif CJK SC](https://github.com/notofonts/noto-cjk) + +2. 导入模板,并在文档开头设置参数,包括标题、作者、课程或主题、学期、时间; + ```typ + #import "@preview/ori:0.2.0": * + + #set heading(numbering: numbly("{1:一}、", default: "1.1 ")) + + #show: ori.with( + title: "文档标题", + author: "张三", + subject: "Ori in Typst", + semester: "2025 春", + date: datetime.today(), + // maketitle: true, + // makeoutline: true, + // theme: "dark", + // media: "screen", + ) + ``` + +## 特性 + +### 可配置参数 + +- `size`: 字体大小(默认 `11pt`) +- `screen-size`: 屏幕显示字体大小(默认 `11pt`) +- `maketitle`: 是否生成标题页(默认 `false`) +- `makeoutline`: 是否生成目录(默认 `false`) +- `outline-depth`: 目录深度(默认 `2`) +- `first-line-indent`: 首行缩进(设置为 `auto` 则为 `2em`) +- `media`: 媒体类型(`"screen"` 或 `"print"`) +- `lang`: 语言(默认 `"zh"`) +- `region`: 地区(默认 `"cn"`) + +### 主要功能 + +1. **三线表支持**:基于 [Tablem 包](https://github.com/OrangeX4/typst-tablem),提供简单的三线表功能 +2. **Markdown 渲染**:基于 [Cmarker 包](https://github.com/SabrinaJewson/cmarker.typ),支持 Markdown 语法,包括加粗、斜体、删除线等 +3. **数学公式**:基于 [MiTeX 包](https://github.com/mitex-rs/mitex) 支持 LaTeX 风格的数学公式 +4. **定理环境**:基于 [Theorion 包](https://github.com/OrangeX4/typst-theorion),提供多种定理环境(定义、定理、引理、命题等) +5. **提示框**:包含多种样式的提示框(强调、引用、注意、提示、重要、警告、小心) + +### 自定义 + +#### 标题编号 + +可以使用 `numbly` 包自定义标题编号样式: + +```typst +#set heading(numbering: numbly("{1:一}、", default: "1.1 ")) +``` + +#### 字体设置 + +可以通过设置 `font` 参数自定义字体: + +```typst +#let font = ( + main: "IBM Plex Sans", + mono: "IBM Plex Mono", + cjk: "Noto Serif SC", + emph-cjk: "KaiTi", + math: "New Computer Modern Math", + math-cjk: "Noto Serif SC", +) +``` + +## 需要定制? + +源码仅有两百行左右,可以复制下来轻松定制。 + +## 致谢 + +- 感谢 [hongjr03](https://github.com/hongjr03) 的 [typst-assignment-template](https://github.com/hongjr03/typst-assignment-template) + +## 许可证 + +MIT License diff --git a/packages/preview/ori/0.2.0/lib.typ b/packages/preview/ori/0.2.0/lib.typ new file mode 100644 index 000000000..b7f4c9e0f --- /dev/null +++ b/packages/preview/ori/0.2.0/lib.typ @@ -0,0 +1,202 @@ +#import "@preview/numbly:0.1.0": numbly +#import "@preview/tablem:0.2.0": tablem, three-line-table +#import "@preview/mitex:0.2.5": * +#import "@preview/cmarker:0.1.2": render as cmarker-render +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +#let md = cmarker-render.with(math: mitex) + +#let default-font = ( + main: "IBM Plex Sans", + mono: "IBM Plex Mono", + cjk: "Noto Serif SC", + emph-cjk: "KaiTi", + math: "New Computer Modern Math", + math-cjk: "Noto Serif SC", +) + +// Definitions for math +#let prox = math.op("prox") +#let proj = math.op("proj") +#let argmax = math.op("argmax", limits: true) +#let argmin = math.op("argmin", limits: true) + + +/// 模板的核心类,规范了文档的格式。 +/// - media (string): 媒体类型,可选值为 `"screen"` 和 `"print"`。默认为 `"print"`。 +/// - theme (string): 主题,可选值为 `"light"` 和 `"dark"`。默认为 `"light"`。 +/// - size (length): 字体大小。默认为 `11pt`。 +/// - screen-size (length): 屏幕字体大小。默认为 `11pt`。 +/// - title (string): 文档的标题。 +/// - author (string): 作者。 +/// - subject (string): 课程名。 +/// - semester (string): 学期。 +/// - date (datetime): 时间。 +/// - font (object): 字体。默认为 `default-font`。如果你想使用不同的字体,可以传入一个字典,包含 `main`、`mono`、`cjk`、`math` 和 `math-cjk` 字段。 +/// - lang (string): 语言。默认为 `zh`。 +/// - region (string): 地区。默认为 `cn`。 +/// - body (content): 文档的内容。 +/// -> content +#let ori( + media: "print", + theme: "light", + size: 11pt, + screen-size: 11pt, + title: none, + author: none, + subject: none, + semester: none, + date: none, + font: default-font, + lang: "zh", + region: "cn", + first-line-indent: (amount: 0pt, all: false), + maketitle: false, + makeoutline: false, + outline-depth: 2, + body, +) = { + assert(media == "screen" or media == "print", message: "media must be 'screen' or 'print'") + assert(theme == "light" or theme == "dark", message: "theme must be 'light' or 'dark'") + let page-margin = if media == "screen" { (x: 35pt, y: 35pt) } else { auto } + let text-size = if media == "screen" { screen-size } else { size } + let bg-color = if theme == "dark" { rgb("#1f1f1f") } else { rgb("#ffffff") } + let text-color = if theme == "dark" { rgb("#ffffff") } else { rgb("#000000") } + let raw-color = if theme == "dark" { rgb("#27292c") } else { rgb("#f0f0f0") } + let font = default-font + font + + /// 设置字体。 + set text( + font: ((name: font.main, covers: "latin-in-cjk"), font.cjk), + size: text-size, + fill: text-color, + lang: lang, + region: region, + ) + show emph: text.with(font: ((name: font.main, covers: "latin-in-cjk"), font.emph-cjk)) + show raw: set text(font: ((name: font.mono, covers: "latin-in-cjk"), font.cjk)) + show math.equation: it => { + set text(font: font.math) + show regex("\p{script=Han}"): set text(font: font.math-cjk) + it + } + + /// 设置段落样式。 + set par( + justify: true, + first-line-indent: if first-line-indent == auto { + (amount: 2em, all: true) + } else { + first-line-indent + }, + ) + + /// 设置标题样式。 + show heading: it => { + show h.where(amount: 0.3em): none + it + } + show heading: set block(spacing: 1.2em) + + /// 设置代码块样式。 + show raw.where(block: false): body => box( + fill: raw-color, + inset: (x: 3pt, y: 0pt), + outset: (x: 0pt, y: 3pt), + radius: 2pt, + { + set par(justify: false) + body + }, + ) + show raw.where(block: true): body => block( + width: 100%, + fill: raw-color, + outset: (x: 0pt, y: 4pt), + inset: (x: 8pt, y: 4pt), + radius: 4pt, + { + set par(justify: false) + body + }, + ) + + /// 设置链接样式。 + show link: it => { + if type(it.dest) == str { + set text(fill: blue) + it + } else { + it + } + } + + /// 设置 figure 样式。 + show figure.where(kind: table): set figure.caption(position: top) + + /// 设置列表样式。 + set list(indent: 6pt) + set enum(indent: 6pt) + set enum(numbering: numbly("{1:1}.", "{2:1})", "{3:a}."), full: true) + + /// 设置引用样式。 + set bibliography(style: "ieee") + + /// 基础设置。 + set document(title: title, author: if type(author) == str { author } else { () }, date: date) + + /// 标题页。 + if maketitle { + // Title page + align(center + top)[ + #v(20%) + #text(2em, weight: 500, subject) + #v(2em, weak: true) + #text(2em, weight: 500, title) + #v(2em, weak: true) + #author + ] + pagebreak(weak: true) + } + + /// 目录。 + if makeoutline { + show heading: align.with(center) + show outline.entry: set block(spacing: 1.2em) + + outline(depth: outline-depth, indent: 2em) + pagebreak(weak: true) + } + + /// 重置页面计数器。 + counter(page).update(1) + + /// 设置页面。 + set page( + paper: "a4", + header: { + set text(0.9em) + stack( + spacing: 0.2em, + grid( + columns: (1fr, auto, 1fr), + align(left, semester), align(center, subject), align(right, title), + ), + v(0.3em), + line(length: 100%, stroke: 1pt + text-color), + v(.15em), + line(length: 100%, stroke: .5pt + text-color), + ) + // reset footnote counter + counter(footnote).update(0) + }, + fill: bg-color, + numbering: "1", + margin: page-margin, + ) + + /// 设置定理环境。 + show: show-theorion + + body +} diff --git a/packages/preview/ori/0.2.0/template/main.typ b/packages/preview/ori/0.2.0/template/main.typ new file mode 100644 index 000000000..04bcba86f --- /dev/null +++ b/packages/preview/ori/0.2.0/template/main.typ @@ -0,0 +1,181 @@ +#import "@preview/ori:0.2.0": * + +#set heading(numbering: numbly("{1:一}、", default: "1.1 ")) + +#show: ori.with( + title: "文档标题", + author: "作者", + subject: "Ori in Typst", + semester: "2025 春", + date: datetime.today(), + // maketitle: true, + // makeoutline: true, + // theme: "dark", + // media: "screen", +) + += 快速开始 + +要开始使用此模板,你需要 + ++ 安装必须的字体包,包括: + - #link("https://github.com/IBM/plex")[*IBM Plex Sans, Mono*] + - #link("https://github.com/notofonts/noto-cjk")[*Noto Serif CJK SC*] + ++ 导入模板,并在文档开头设置参数,包括标题、作者、课程或主题、学期、时间; + ```typ + #import "@preview/ori:0.2.0": * + + #show: ori.with( + title: "文档标题", + author: "张三", + subject: "Ori in Typst", + semester: "2025 春", + date: datetime.today(), + ) + ``` + += 使用 + +== 特殊参数 + +- `size`:字体大小,默认为 `11pt`; +- `screen-size`:屏幕字体大小,默认为 `11pt`; +- `maketitle`:是否生成标题页,默认为 `false`; +- `makeoutline`:是否生成目录,默认为 `false`; +- `outline-depth`:目录的深度,默认为 `2`; +- `first-line-indent`:首行缩进,如果设置为 `auto`,则会开启自动缩进,缩进量为 `2em`; +- `media`:媒体类型,可选值为 `"screen"` 和 `"print"`,前者边距较小,适合屏幕显示;后者边距较大,适合打印。默认值为 `"print"`; +- `lang`:语言,默认为 `"zh"`; +- `region`:地区,默认为 `"cn"`。 + +== 三线表 + +基于 #link("https://github.com/OrangeX4/typst-tablem")[*Tablem 包*],提供了简单好用的三线表功能,如@three-line-table。 + +```typ +#figure( + three-line-table[ + | Substance | Subcritical °C | Supercritical °C | + | --------------------- | -------------- | ---------------- | + | Hydrochloric Acid | 12.0 | 92.1 | + | Sodium Myreth Sulfate | 16.6 | 104 | + | Potassium Hydroxide | 24.7 | < | + ], + caption: "三线表示例" +) +``` + +#figure( + three-line-table[ + | Substance | Subcritical °C | Supercritical °C | + | --------------------- | -------------- | ---------------- | + | Hydrochloric Acid | 12.0 | 92.1 | + | Sodium Myreth Sulfate | 16.6 | 104 | + | Potassium Hydroxide | 24.7 | < | + ], + caption: "三线表示例" +) + +== Markdown 渲染 + +基于 #link("https://github.com/SabrinaJewson/cmarker.typ")[*Cmarker 包*] 和 #link("https://github.com/mitex-rs/mitex")[*MiTeX 包*],支持 Markdown 渲染,包括数学公式,如: + +`````typ +#md(````markdown + 支持 **加粗**、*斜体*、~~删除线~~、[链接](https://typst.com)、LaTeX 数学公式 $\max_{x \in X} f(x)$ 等 Markdown 语法。 +````) +````` + +#rect( + width: 100%, + md(````markdown + 支持 **加粗**、*斜体*、~~删除线~~、[链接](https://typst.com)、LaTeX 数学公式 $\max_{x \in X} f(x)$ 等 Markdown 语法。 + ````) +) + +== 定理环境 + +基于 #link("https://github.com/OrangeX4/typst-theorion")[*Theorion 包*],我们可以创建@definition、@theorem、@lemma 和@proposition 等定理环境。 + +#definition(title: "Typst 定义")[ + 定义内容。 +] + +#theorem(title: "Typst 定理")[ + 定理内容。 +] + +#lemma[ + 引理内容。 +] + +#proposition[ + 命题内容。 +] + +#emph-box[ + 强调内容。 +] + +#quote-box[ + 引用内容。 +] + +#remark[ + 注解内容。 +] + +#note-box[ + 在快速浏览时也应该注意的重要信息。 +] + +#tip-box[ + 帮助更好使用的可选建议信息。 +] + +#important-box[ + 为了成功使用必须了解的关键信息。 +] + +#warning-box[ + 可能存在风险,需要立即注意的关键信息。 +] + +#caution-box[ + 可能带来负面后果的提醒信息。 +] + += 自定义 + +== 标题编号 + +可以使用 `numbly` 包设置标题编号样式: + +```typ +#set heading(numbering: numbly("{1:一}、", default: "1.1 ")) +``` + +参数中,`{*:1}` 的 `*` 代表标题的级别,`1` 代表标题的格式。`{1:一}、` 代表一级标题的格式为 `一、`,并且设置了默认格式 `1.1 `。 + +*注意*,本模板默认去除了标题 numbering 后的空格,所以在设置标题编号时请注意空格的使用。如 `"1.1 "` 的末尾有两个空格,这样在标题编号后会有两个空格。 + +== 字体 + +先在终端 / 命令行输入 ```bash typst fonts``` 查看当前可用的字体,以在文档开头加入 `font` 参数修改字体设置以及使用的字体: + +```typ +#let font = ( + main: "IBM Plex Sans", + mono: "IBM Plex Mono", + cjk: "Noto Serif SC", + emph-cjk: "KaiTi", + math: "New Computer Modern Math", + math-cjk: "Noto Serif SC", +) + +#show: ori.with( + // ... 保持原有的参数 + font: font, +) +``` diff --git a/packages/preview/ori/0.2.0/thumbnail.png b/packages/preview/ori/0.2.0/thumbnail.png new file mode 100644 index 000000000..ec6f14e09 Binary files /dev/null and b/packages/preview/ori/0.2.0/thumbnail.png differ diff --git a/packages/preview/ori/0.2.0/typst.toml b/packages/preview/ori/0.2.0/typst.toml new file mode 100644 index 000000000..25625a091 --- /dev/null +++ b/packages/preview/ori/0.2.0/typst.toml @@ -0,0 +1,16 @@ +[package] +name = "ori" +version = "0.2.0" +compiler = "0.13.0" +entrypoint = "lib.typ" +repository = "https://github.com/OrangeX4/typst-ori" +authors = ["OrangeX4"] +license = "MIT" +description = "Simple enough but expressive template for notes, reports, and documents" +keywords = ["notes", "script", "report", "documents", "class", "lecture"] +categories = ["report"] + +[template] +path = "template" +entrypoint = "main.typ" +thumbnail = "thumbnail.png" \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/LICENSE b/packages/preview/theorion/0.3.0/LICENSE new file mode 100644 index 000000000..148b340d7 --- /dev/null +++ b/packages/preview/theorion/0.3.0/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2025 OrangeX4 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/preview/theorion/0.3.0/README.md b/packages/preview/theorion/0.3.0/README.md new file mode 100644 index 000000000..fc461ef72 --- /dev/null +++ b/packages/preview/theorion/0.3.0/README.md @@ -0,0 +1,423 @@ +# 🌌Theorion + +[Theorion](https://github.com/OrangeX4/typst-theorion) (The Orion) is an out-of-the-box, customizable and multilingual **theorem** environment package for [Typst](https://typst.app/docs/). + +[![Typst Universe](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Ftypst.app%2Funiverse%2Fpackage%2Ftheorion&query=%2Fhtml%2Fbody%2Fdiv%2Fmain%2Fdiv%5B2%5D%2Faside%2Fsection%5B2%5D%2Fdl%2Fdd%5B3%5D&logo=typst&label=universe&color=%2339cccc)](https://typst.app/universe/package/theorion) +![GitHub](https://img.shields.io/github/license/OrangeX4/typst-theorion) +![GitHub Repo stars](https://img.shields.io/github/stars/OrangeX4/typst-theorion) +![Cosmos badge](https://img.shields.io/badge/cosmos-4-aqua) + +## Quick Start + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] + +#theorem-box(title: "Theorem without numbering")[ + This theorem is not numbered. +] +``` + +## Customization + +```typst +// 1. Change the counters and numbering: +#set-inherited-levels(1) +#set-zero-fill(true) +#set-leading-zero(true) +#set-theorion-numbering("1.1") + +// 2. Other options: +#set-result("noanswer") +#set-qed-symbol[#math.qed] + +// 3. Custom theorem environment for yourself +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + "Theorem", // supplement, string or dictionary like `(en: "Theorem")`, or `theorion-i18n-map.at("theorem")` for built-in i18n support + counter: theorem-counter, // inherit the old counter, `none` by default + inherited-levels: 2, // useful when you need a new counter + inherited-from: heading, // heading or just another counter + render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +) +#show: show-theorem + +// 4. Just use it. +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] +#theorem-box(title: "Theorem without numbering")[ + This theorem is not numbered. +] + +// 5. Example of appendix +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + +// 6. Table of contents +#outline(title: none, target: figure.where(kind: "theorem")) +``` + +## Restate Theorems + +```typst +// 1. Restate all theorems +#theorion-restate(filter: it => it.identifier == "theorem", render: it => it.render) +// 2. Restate all theorems with custom render function +#theorion-restate( + filter: it => it.identifier == "theorem", + render: it => (prefix: none, title: "", full-title: auto, body) => block[#strong[#full-title.]#sym.space#emph(body)], +) +// 3. Restate a specific theorem +#theorion-restate(filter: it => it.label == ) +``` + +## Example + +[Source code](examples/example.typ) + +![example](examples/example.png) + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#set page(height: auto) +#set heading(numbering: "1.1") +#set text(lang: "en") + +/// 1. Change the color scheme (only for `fancy` cosmos): +// #set-primary-border-color(red) +// #set-primary-body-color(red.lighten(95%)) +// #set-primary-symbol[#sym.suit.diamond.filled] + +/// 2. Change the counters and numbering: +// #set-inherited-levels(1) +// #set-zero-fill(true) +// #set-leading-zero(true) +// #set-theorion-numbering("1.1") + +/// 3. Other options: +// #set-result("noanswer") +// #set-qed-symbol[#math.qed] + +/// 4. Custom theorem environment for yourself +// #let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( +// "theorem", +// "Theorem", // supplement, string or dictionary like `(en: "Theorem")`, or `theorion-i18n-map.at("theorem")` for built-in i18n support +// counter: theorem-counter, // inherit the counter, `none` by default +// inherited-levels: 2, // useful when you need a new counter +// inherited-from: heading, // heading or another counter +// render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +// ) +// #show: show-theorem + +/// 5. Just use it. +// #theorem(title: "Euclid's Theorem")[ +// There are infinitely many prime numbers. +// ] +// #theorem-box(title: "Theorem without numbering")[ +// This theorem is not numbered. +// ] + +/// 6. Example of appendix +// #counter(heading).update(0) +// #set heading(numbering: "A.1") +// #set-theorion-numbering("A.1") + +/// 7. Table of contents +// #outline(title: none, target: figure.where(kind: "theorem")) + += Theorion Environments + +== Table of Theorems + +#outline(title: none, target: figure.where(kind: "theorem")) + +== Basic Theorem Environments + +Let's start with the most fundamental definition. + +#definition[ + A natural number is called a #highlight[_prime number_] if it is greater than 1 + and cannot be written as the product of two smaller natural numbers. +] + +#example[ + The numbers $2$, $3$, and $17$ are prime. As proven in @cor:infinite-prime, + this list is far from complete! See @thm:euclid for the full proof. +] + +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] + +#proof[ + By contradiction: Suppose $p_1, p_2, dots, p_n$ is a finite enumeration of all primes. + Let $P = p_1 p_2 dots p_n$. Since $P + 1$ is not in our list, + it cannot be prime. Thus, some prime $p_j$ divides $P + 1$. + Since $p_j$ also divides $P$, it must divide their difference $(P + 1) - P = 1$, + a contradiction. +] + +#corollary[ + There is no largest prime number. +] + +#lemma[ + There are infinitely many composite numbers. +] + +== Functions and Continuity + +#theorem(title: "Continuity Theorem")[ + If a function $f$ is differentiable at every point, then $f$ is continuous. +] + +#tip-box[ + @thm:continuous tells us that differentiability implies continuity, + but not vice versa. For example, $f(x) = |x|$ is continuous but not differentiable at $x = 0$. + For a deeper understanding of continuous functions, see @thm:max-value in the appendix. +] + +== Geometric Theorems + +#theorem(title: "Pythagorean Theorem")[ + In a right triangle, the square of the hypotenuse equals the sum of squares of the other two sides: + $x^2 + y^2 = z^2$ +] + +#important-box[ + @thm:pythagoras is one of the most fundamental and important theorems in plane geometry, + bridging geometry and algebra. +] + +#corollary[ + There exists no right triangle with sides measuring 3cm, 4cm, and 6cm. + This directly follows from @thm:pythagoras. +] + +#lemma[ + Given two line segments of lengths $a$ and $b$, there exists a real number $r$ + such that $b = r a$. +] + +== Algebraic Structures + +#definition(title: "Ring")[ + Let $R$ be a non-empty set with two binary operations $+$ and $dot$, satisfying: + 1. $(R, +)$ is an abelian group + 2. $(R, dot)$ is a semigroup + 3. The distributive laws hold + Then $(R, +, dot)$ is called a ring. +] + +#proposition[ + Every field is a ring, but not every ring is a field. This concept builds upon @def:ring. +] + +#example[ + Consider @def:ring. The ring of integers $ZZ$ is not a field, as no elements except $plus.minus 1$ + have multiplicative inverses. +] + +/// Appendix +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + += Theorion Appendices + +== Advanced Analysis + +#theorem(title: "Maximum Value Theorem")[ + A continuous function on a closed interval must attain both a maximum and a minimum value. +] + +#warning-box[ + Both conditions of this theorem are essential: + - The function must be continuous + - The domain must be a closed interval +] + +== Advanced Algebra Supplements + +#axiom(title: "Group Axioms")[ + A group $(G, \cdot)$ must satisfy: + 1. Closure + 2. Associativity + 3. Identity element exists + 4. Inverse elements exist +] + +#postulate(title: "Fundamental Theorem of Algebra")[ + Every non-zero polynomial with complex coefficients has a complex root. +] + +#remark[ + This theorem is also known as Gauss's theorem, as it was first rigorously proved by Gauss. +] + +== Common Problems and Solutions + +#problem[ + Prove: For any integer $n > 1$, there exists a sequence of $n$ consecutive composite numbers. +] + +#solution[ + Consider the sequence: $n! + 2, n! + 3, ..., n! + n$ + + For any $2 <= k <= n$, $n! + k$ is divisible by $k$ because: + $n! + k = k(n! / k + 1)$ + + Thus, this forms a sequence of $n-1$ consecutive composite numbers. +] + +#exercise[ + 1. Prove: The twin prime conjecture remains unproven. + 2. Try to explain why this problem is so difficult. +] + +#conclusion[ + Number theory contains many unsolved problems that appear deceptively simple + yet are profoundly complex. +] + +== Important Notes + +#note-box[ + Remember that mathematical proofs should be both rigorous and clear. + Clarity without rigor is insufficient, and rigor without clarity is ineffective. +] + +#caution-box[ + When dealing with infinite series, always verify convergence before discussing other properties. +] + +#quote-box[ + Mathematics is the queen of sciences, and number theory is the queen of mathematics. + — Gauss +] + +#emph-box[ + Chapter Summary: + - We introduced basic number theory concepts + - Proved several important theorems + - Demonstrated different types of mathematical environments +] + +== Restated Theorems + +// 1. Restate all theorems +#theorion-restate(filter: it => it.identifier == "theorem", render: it => it.render) +// 2. Restate all theorems with custom render function +// #theorion-restate( +// filter: it => it.identifier == "theorem", +// render: it => (prefix: none, title: "", full-title: auto, body) => block[#strong[#full-title.]#sym.space#emph(body)], +// ) +// 3. Restate a specific theorem +// #theorion-restate(filter: it => it.label == ) +``` + +## All Cosmos + +### 📄Simple + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.simple: * +#show: show-theorion +``` + +[Customize from source code](cosmos/simple.typ) + +![image](https://github.com/user-attachments/assets/f1876cfb-1bc9-4edb-a19a-a1922a8babc0) + +### 🌈Rainbow + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.rainbow: * +#show: show-theorion +``` + +[Customize from source code](cosmos/rainbow.typ) + +```typst +/// Custom color +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + counter: theorem-counter, + render: render-fn.with(fill: blue.darken(10%)), +) +#show: show-theorem +``` + +![image](https://github.com/user-attachments/assets/5e6e29f9-c493-4e21-b14a-347f3ca83b99) + +### ☁️Clouds + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.clouds: * +#show: show-theorion +``` + +[Customize from source code](cosmos/clouds.typ) + +```typst +/// Custom color +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + counter: theorem-counter, + render: render-fn.with(fill: blue.lighten(85%)), +) +#show: show-theorem +``` + +![image](https://github.com/user-attachments/assets/1f0f280b-94f5-43b7-b685-d2998d867b58) + +### ✨Fancy + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +#show: show-theorion +``` + +[Customize from source code](cosmos/fancy.typ) + +```typst +/// Custom color +#set-primary-border-color(red) +#set-primary-body-color(red.lighten(95%)) +#set-primary-symbol[#sym.suit.diamond.filled] +``` + +![image](https://github.com/user-attachments/assets/a8938339-9510-4371-ae23-7f73a828c17d) + +### Contributing your cosmos + +Welcome to [open a pull request](htps://github.com/OrangeX4/typst-theorion/pulls) and contribute your beautiful cosmos to Theorion! + + +## Acknowledgements + +- Thanks [Johann Birnick](https://github.com/jbirnick) for [rich-counters](https://github.com/jbirnick/typst-rich-counters) +- Thanks [Satvik Saha](https://github.com/sahasatvik) for [ctheorems](https://github.com/sahasatvik/typst-theorems) +- Thanks [s15n](https://github.com/s15n) for [typst-thmbox](https://github.com/s15n/typst-thmbox) +- Thanks [0x6b](https://github.com/0x6b) for [octique](https://github.com/0x6b/typst-octique) +- Thanks [Pablo González Calderón](https://github.com/Pablo-Gonzalez-Calderon) for [showybox](https://github.com/Pablo-Gonzalez-Calderon/showybox-package) diff --git a/packages/preview/theorion/0.3.0/core.typ b/packages/preview/theorion/0.3.0/core.typ new file mode 100644 index 000000000..d40a2df28 --- /dev/null +++ b/packages/preview/theorion/0.3.0/core.typ @@ -0,0 +1,399 @@ +#import "i18n.typ": theorion-i18n, theorion-i18n-map + +/// A simple wrapper for the `state` function, inspired by React Hook. +#let use-state(key, init) = { + let used-state = state(key, init) + return ( + (..args) => { + let arg = args.pos().at(0, default: none) + if arg == none { + used-state.final() + } else if type(arg) == function { + used-state.at(arg()) + } else { + used-state.at(arg) + } + }, + value => used-state.update(value), + ) +} + +/// Global theorion numbering +#let (get-theorion-numbering, set-theorion-numbering) = use-state("theorion-numbering", "1.1") + +/// Code from: [jbirnick](https://github.com/jbirnick/typst-rich-counters) +/// Modified by: [OrangeX4](https://github.com/OrangeX4) +/// License: MIT +/// I need a patched version of `rich-counter` to support the `zero-fill` and `leading-zero` options. And we can update the arguments by set-inherited-levels, set-inherited-from, set-zero-fill, and set-leading-zero functions. + +/// Create a richer counter that can inherit from other counters and display the counter value. Returns a dictionary of functions to interact with the counter like `at`, `get-inherited-levels` and `set-inherited-levels`. +/// +/// - identifier (string): Unique identifier for the counter. +/// - inherited-levels (integer): Number of heading levels to inherit from. Default is 0, which will inherit from the inherited-from counter if it is a dictionary. +/// - inherited-from (counter): Counter to inherit from. Default is heading. +/// - zero-fill (boolean): Whether to zero-fill the numbering. Default is false. +/// - leading-zero (boolean): Whether to remove the leading zero. Default is false. +#let richer-counter( + identifier: none, + inherited-levels: 0, + inherited-from: heading, + zero-fill: false, + leading-zero: false, +) = { + // this can equip `headings` and similar objects with the richer-counter functions + // that are needed for recursive evaluation + let richer-wrapper(key) = { + let at(loc) = { + let cntr = counter(key) + if loc == none { cntr.final() } else { cntr.at(loc) } + } + let last-update-location(level, before-key) = { + if key == heading { + let occurrences = if before-key == none { query(selector(key)) } else { + query(selector(key).before(before-key)) + } + for occurrence in occurrences.rev() { + if occurrence.level <= level { + return occurrence.location() + } + } + } else { + // best guess: just take the last occurrence of the element + // WARNING: this can be wrong for certain elements, especially if Typst introduces more queryable/locatable elements + let occurrences = if before-key == none { query(selector(key)) } else { + query(selector(key).before(before-key)) + } + if occurrences.len() == 0 { + return none + } else { + return occurrences.last().location() + } + } + } + + return (at: at, get-inherited-levels: () => 0, last-update-location: last-update-location) + } + + // oop-style state management + let (get-inherited-from, set-inherited-from) = use-state("richer-inherited-from:" + identifier, inherited-from) + let richer-inherited-levels = state("richer-inherited-levels:" + identifier, inherited-levels) + let get-inherited-levels(..args) = { + // small hack to allow for inheritance of richer-counter + let arg = args.pos().at(0, default: none) + let value = if arg == none { + richer-inherited-levels.final() + } else { + richer-inherited-levels.at(arg) + } + if type(get-inherited-from()) == dictionary and value == 0 { + return (get-inherited-from().get-inherited-levels)() + 1 + } + return value + } + let set-inherited-levels(value) = richer-inherited-levels.update(value) + let (get-zero-fill, set-zero-fill) = use-state("richer-zero-fill:" + identifier, zero-fill) + let (get-leading-zero, set-leading-zero) = use-state("richer-leading-zero:" + identifier, leading-zero) + + // get the parent richer-counter + let parent-richer-counter() = if type(get-inherited-from(here())) == dictionary { + get-inherited-from(here()) + } else { + richer-wrapper(get-inherited-from(here())) + } + + // `step` method for this richer-counter + let step(depth: 1) = [ + #metadata(( + kind: "richer-counter:step", + identifier: identifier, + value: depth, + )) + #label("richer-counter:step:" + identifier) + ] + + // `update` method for this richer-counter + // only support array of integers as counter value + let update(counter-value) = [ + #metadata(( + kind: "richer-counter:update", + identifier: identifier, + value: counter-value, + )) + #label("richer-counter:update:" + identifier) + ] + + // find updates of own partial (!) counter in certain range + let updates-during(after-key, before-key) = { + let query-for = selector(label("richer-counter:step:" + identifier)).or( + selector(label("richer-counter:update:" + identifier)), + ) + + if after-key == none and before-key == none { + return query(query-for) + } else if after-key == none { + return query(query-for.before(before-key)) + } else if before-key == none { + return query(query-for.after(after-key)) + } else { + return query(query-for.after(after-key).before(before-key)) + } + } + + // find last update of this total (!) counter up to a certain level and before a certain location + let last-update-location(level, before-key) = { + let parent-last-update-location = (parent-richer-counter().last-update-location)( + get-inherited-levels(here()), + before-key, + ) + let updates = updates-during(parent-last-update-location, before-key) + + for update in updates.rev() { + let kind = update.value.kind + if kind == "richer-counter:step" { + if update.value.value <= level - get-inherited-levels(here()) { + return update.location() + } + } else if kind == "richer-counter:update" { + if update.value.value.len() < level { + return update.location() + } + } + } + + return parent-last-update-location + } + + // compute value of the counter after the given updates, starting from 0 + let compute-counter(updates) = { + let value = (0,) + for update in updates { + let kind = update.value.kind + if kind == "richer-counter:step" { + let level = update.value.value + while value.len() < level { value.push(0) } + while value.len() > level { let _ = value.pop() } + value.at(level - 1) += 1 + } else if kind == "richer-counter:update" { + let inherited-levels = get-inherited-levels(here()) + let counter-value = update.value.value + counter-value = counter-value.slice(calc.min(inherited-levels, counter-value.len())) + value = if counter-value.len() == 0 { + (0,) + } else { + counter-value + } + } + } + + return value + } + + // `at` method for this richer-counter + let at(key) = { + // get inherited numbers + let num-parent = (parent-richer-counter().at)(key) + let inherited-levels = get-inherited-levels(here()) + while get-zero-fill(here()) and num-parent.len() < inherited-levels { num-parent.push(0) } + while num-parent.len() > inherited-levels { let _ = num-parent.pop() } + if not get-leading-zero(here()) and num-parent.at(0, default: none) == 0 { + num-parent = num-parent.slice(1) + } + + // get numbers of own partial counter + let updates = updates-during((parent-richer-counter().last-update-location)(inherited-levels, key), key) + let num-self = compute-counter(updates) + + return num-parent + num-self + } + + // `get` method for this richer-counter + let get() = { at(here()) } + + // `final` method for this richer-counter + let final() = { at(none) } + + // `display` method for this richer-counter + let display(..args) = { + if args.pos().len() == 0 { + numbering("1.1", ..get()) + } else { + numbering(args.pos().first(), ..get()) + } + } + + return ( + step: step, + update: update, + at: at, + get: get, + final: final, + display: display, + get-inherited-levels: get-inherited-levels, + set-inherited-levels: set-inherited-levels, + get-inherited-from: get-inherited-from, + set-inherited-from: set-inherited-from, + get-zero-fill: get-zero-fill, + set-zero-fill: set-zero-fill, + get-leading-zero: get-leading-zero, + set-leading-zero: set-leading-zero, + last-update-location: last-update-location, + ) +} + + +/// Display the numbering of a theorem environment +/// +/// - el (content): Figure element to display the numbering +#let display-theorion-number(el) = { + assert(type(el) == content and el.func() == figure, message: "The element must be a figure.") + // some magic to get the correct numbering + std.numbering(el.numbering.with(get-loc: () => el.location())) +} + + +/// Create a theorem environment based on richer-counter +/// +/// - identifier (string): Unique identifier for the counter +/// - supplement (string|dict): Label text or dictionary of labels for different languages +/// - kind (string): Kind of the theorem environment. Default is auto, which uses the identifier +/// - counter (counter): Counter to use. Default is none, which creates a new counter based on the identifier +/// - inherited-levels (integer): Number of heading levels to inherit from. Default is 0 +/// - inherited-from (counter): Counter to inherit from. Default is heading +/// - numbering (string): Numbering format. Default is get-theorion-numbering +/// - render (function): Custom rendering function +/// -> (counter, render-fn, frame-fn, show-fn) +#let make-frame( + identifier, + supplement, + kind: auto, + counter: none, + inherited-levels: 0, + inherited-from: heading, + numbering: get-theorion-numbering, + render: (prefix: none, title: "", full-title: "", body) => block[*#full-title*: #body], +) = { + let get-numbering = if type(numbering) != function { (..args) => numbering } else { numbering } + let current-kind = if kind == auto { identifier } else { kind } + /// Counter for the frame. + let frame-counter = if counter != none { counter } else { + richer-counter( + identifier: identifier, + inherited-levels: inherited-levels, + inherited-from: inherited-from, + ) + } + let supplement-i18n = theorion-i18n(supplement) + let display-number(get-loc: here, counter: frame-counter, ..args) = context { + let loc = get-loc() + // We need to add 1 to the counter value. + let counter-value = if type(counter) == dictionary { + (counter.at)(loc) + } else { + counter.at(loc) + } + counter-value = counter-value.slice(0, -1) + (counter-value.at(-1) + 1,) + std.numbering(get-numbering(get-loc()), ..counter-value) + } + /// Frame with the counter. + let frame(title: "", body) = figure( + kind: current-kind, + supplement: supplement-i18n, + caption: title, + numbering: display-number, + { + let get-prefix(get-loc) = [#supplement-i18n #display-number(get-loc: get-loc)] + let get-full-title(get-loc) = [#get-prefix(get-loc)#{ if title != "" [ (#title)] }] + [#metadata(( + identifier: identifier, + supplement: supplement, + supplement-i18n: supplement-i18n, + get-prefix: get-prefix, + kind: current-kind, + counter: frame-counter, + title: title, + get-full-title: get-full-title, + render: render, + body: body, + )) ] + render( + prefix: get-prefix(here), + title: title, + full-title: get-full-title(here), + body, + ) + // Update the counter. + (frame-counter.step)() + }, + ) + /// Show rule for the frame. + let show-frame(body) = { + // skip the default figure style. + show figure.where(kind: current-kind): set align(left) + show figure.where(kind: current-kind): set block(breakable: true) + show figure.where(kind: current-kind): it => it.body + // Custom outline for the theorem environment. + show outline.where(target: figure.where(kind: current-kind)): it => { + show outline.entry: entry => { + let el = entry.element + block( + link( + el.location(), + entry.indented( + [#el.supplement #context display-theorion-number(el)], + { + entry.body() + box(width: 1fr, inset: (x: .25em), entry.fill) + entry.page() + }, + gap: .5em, + ), + ), + ) + } + it + } + // Custom reference for the theorem environment. + show ref: it => { + let el = it.element + if el != none and el.func() == figure and el.kind == kind { + link( + el.location(), + { + if it.supplement == auto { el.supplement } else { it.supplement } + " " + context display-theorion-number(el) + }, + ) + } else { + it + } + } + body + } + return (frame-counter, render, frame, show-frame) +} + + +/// Restate the theorion frame with a custom filter and render function. +/// +/// - filter (function): Filter function to select the frames to restate, such as `it => it.identifier == "theorem"` +/// - render (function): Custom rendering function for the frames, such as `it => it.render` or `it => (prefix: none, title: "", full-title: auto, body) => block[#strong[#full-title.]#sym.space#emph(body)]` +#let theorion-restate(filter: it => true, render: it => it.render) = context { + for el in query() { + let figure-el = query(selector(figure).before(el.location())).last() + let get-loc = () => el.location() + let it = el.value + assert(type(it) == dictionary, message: "The metadata must be a dictionary.") + it.get-loc = get-loc + it.el = figure-el + it.label = if figure-el.has("label") { figure-el.label } else { none } + if filter(it) { + (render(it))( + prefix: (it.get-prefix)(get-loc), + title: it.title, + full-title: (it.get-full-title)(get-loc), + it.body, + ) + } + } +} diff --git a/packages/preview/theorion/0.3.0/cosmos/clouds.typ b/packages/preview/theorion/0.3.0/cosmos/clouds.typ new file mode 100644 index 000000000..5cd19f1d2 --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/clouds.typ @@ -0,0 +1,93 @@ +#import "../core.typ": * + +/// A simple render function with a colored left border +#let render-fn( + fill: red, + prefix: none, + title: "", + full-title: auto, + body, +) = block(inset: 1em, fill: fill, radius: .4em, width: 100%)[#strong(full-title)#sym.space#body] + +// Core theorems +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + inherited-levels: 2, + render: render-fn.with(fill: red.lighten(85%)), +) + +#let (lemma-counter, lemma-box, lemma, show-lemma) = make-frame( + "lemma", + theorion-i18n-map.at("lemma"), + counter: theorem-counter, + render: render-fn.with(fill: teal.lighten(85%)), +) + +#let (corollary-counter, corollary-box, corollary, show-corollary) = make-frame( + "corollary", + theorion-i18n-map.at("corollary"), + counter: theorem-counter, + render: render-fn.with(fill: navy.lighten(90%)), +) + +// Definitions and foundations +#let (definition-counter, definition-box, definition, show-definition) = make-frame( + "definition", + theorion-i18n-map.at("definition"), + counter: theorem-counter, + render: render-fn.with(fill: olive.lighten(85%)), +) + +#let (axiom-counter, axiom-box, axiom, show-axiom) = make-frame( + "axiom", + theorion-i18n-map.at("axiom"), + counter: theorem-counter, + render: render-fn.with(fill: green.lighten(85%)), +) + +#let (postulate-counter, postulate-box, postulate, show-postulate) = make-frame( + "postulate", + theorion-i18n-map.at("postulate"), + counter: theorem-counter, + render: render-fn.with(fill: maroon.lighten(85%)), +) + +// Important results +#let (proposition-counter, proposition-box, proposition, show-proposition) = make-frame( + "proposition", + theorion-i18n-map.at("proposition"), + counter: theorem-counter, + render: render-fn.with(fill: blue.lighten(85%)), +) + +/// Collection of show rules for all theorem environments +/// Applies all theorion-related show rules to the document +/// +/// - body (content): Content to apply the rules to +/// -> content +#let show-theorion(body) = { + show: show-theorem + show: show-lemma + show: show-corollary + show: show-axiom + show: show-postulate + show: show-definition + show: show-proposition + body +} + +/// Set the number of inherited levels for theorem environments +/// +/// - value (integer): Number of levels to inherit +#let set-inherited-levels(value) = (theorem-counter.set-inherited-levels)(value) + +/// Set the zero-fill option for theorem environments +/// +/// - value (boolean): Whether to zero-fill the numbering +#let set-zero-fill(value) = (theorem-counter.set-zero-fill)(value) + +/// Set the leading-zero option for theorem environments +/// +/// - value (boolean): Whether to include leading zeros in the numbering +#let set-leading-zero(value) = (theorem-counter.set-leading-zero)(value) diff --git a/packages/preview/theorion/0.3.0/cosmos/cosmos.typ b/packages/preview/theorion/0.3.0/cosmos/cosmos.typ new file mode 100644 index 000000000..d1b95fad6 --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/cosmos.typ @@ -0,0 +1,5 @@ +#import "default.typ" +#import "simple.typ" +#import "fancy.typ" +#import "rainbow.typ" +#import "clouds.typ" \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/cosmos/default.typ b/packages/preview/theorion/0.3.0/cosmos/default.typ new file mode 100644 index 000000000..6a2a43c91 --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/default.typ @@ -0,0 +1,190 @@ +#import "../core.typ": * +#import "../deps.typ": showybox, octique-inline + +/// Global result configuration to control visibility of proofs and solutions +/// Modified by `#set-result("noanswer")` +/// - "answer": Show proofs and solutions (default) +/// - "noanswer": Hide proofs and solutions +#let (get-result, set-result) = use-state("theorion-result", "answer") + +/// Global QED symbol configuration +/// Modified by `#set-qed-symbol(sym.square.stroked)` +/// Default is `sym.square` +#let (get-qed-symbol, set-qed-symbol) = use-state("theorion-qed-symbol", sym.square) + +/// Create an example environment with italic title +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Example" +/// - body (content): Content of the example +/// -> content +#let example( + title: theorion-i18n-map.at("example"), + body, +) = [#emph(theorion-i18n(title)).#sym.space#body] + + +/// Create a problem environment with italic title +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Problem" +/// - body (content): Content of the problem +/// -> content +#let problem( + title: theorion-i18n-map.at("problem"), + body, +) = [#emph(theorion-i18n(title)).#sym.space#body] + +/// Create a solution environment with italic title +/// Can be hidden using #set-result("noanswer") +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Solution" +/// - body (content): Content of the solution +/// -> content +#let solution( + title: theorion-i18n-map.at("solution"), + body, +) = context if get-result(here()) == "noanswer" { none } else [#emph(theorion-i18n(title)).#sym.space#body] + +/// Create a conclusion environment with italic title +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Conclusion" +/// - body (content): Content of the conclusion +/// -> content +#let conclusion( + title: theorion-i18n-map.at("conclusion"), + body, +) = [#emph(theorion-i18n(title)).#sym.space#body] + +/// Create an exercise environment with italic title +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Exercise" +/// - body (content): Content of the exercise +/// -> content +#let exercise( + title: theorion-i18n-map.at("exercise"), + body, +) = [#emph(theorion-i18n(title)).#sym.space#body] + +/// Create a proof environment with italic title and QED symbol +/// Can be hidden using #set-result("noanswer") +/// Uses global QED symbol set by #set-qed-symbol() +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Proof" +/// - qed (symbol): Symbol to use for end of proof. Default is from global setting +/// - body (content): Content of the proof +/// -> content +#let proof( + title: theorion-i18n-map.at("proof"), + qed: auto, + body, +) = context if get-result(here()) == "noanswer" { none } else { + let qed-symbol = if qed == auto { get-qed-symbol(here()) } else { qed } + [#emph(theorion-i18n(title)).#sym.space#body#box(width: 0em)#h(1fr)#sym.wj#sym.space.nobreak$#qed-symbol$] +} + +/// Create an emphasized box with yellow styling and dashed border +/// +/// - body (content): Content of the box +/// -> content +#let emph-box(body) = { + showybox( + frame: ( + dash: "dashed", + border-color: yellow.darken(30%), + body-color: yellow.lighten(90%), + ), + sep: (dash: "dashed"), + breakable: true, + body, + ) +} + +/// Create a quote box with left border styling in gray +/// +/// - body (content): Content to be quoted +/// -> content +#let quote-box(body) = block( + stroke: (left: .25em + luma(200)), + inset: (left: 1em, y: .75em), + text(luma(100), body), +) + +/// Create a note box with customizable styling and icon +/// Base template for tip-box, important-box, warning-box, and caution-box +/// +/// - fill (color): Color of the border and icon. Default is `rgb("#0969DA")` +/// - title (string|dict): Title text or dictionary for i18n. Default is "Note" +/// - icon-name (string): Name of the icon to display from octicons set +/// - body (content): Content of the note +/// -> content +#let note-box( + fill: rgb("#0969DA"), + title: theorion-i18n-map.at("note"), + icon-name: "info", + body, +) = block( + stroke: (left: .25em + fill), + inset: (left: 1em, top: .5em, bottom: .75em), + { + let title-i18n = theorion-i18n(title) + stack( + spacing: 1.5em, + text( + fill: fill, + weight: "semibold", + octique-inline( + height: 1.2em, + width: 1.2em, + color: fill, + baseline: .2em, + icon-name, + ) + + h(.5em) + + title-i18n, + ), + body, + ) + }, +) + +/// Create a tip box with green styling and light bulb icon +/// Useful for helpful suggestions and tips +#let tip-box = note-box.with( + fill: rgb("#1A7F37"), + title: theorion-i18n-map.at("tip"), + icon-name: "light-bulb", +) + +/// Create an important box with purple styling and report icon +/// Useful for highlighting key information +#let important-box = note-box.with( + fill: rgb("#8250DF"), + title: theorion-i18n-map.at("important"), + icon-name: "report", +) + +/// Create a warning box with amber styling and alert icon +/// Useful for potential issues or warnings +#let warning-box = note-box.with( + fill: rgb("#9A6700"), + title: theorion-i18n-map.at("warning"), + icon-name: "alert", +) + +/// Create a caution box with red styling and stop icon +/// Useful for serious warnings or dangerous situations +#let caution-box = note-box.with( + fill: rgb("#CF222E"), + title: theorion-i18n-map.at("caution"), + icon-name: "stop", +) + +/// Create a remark environment +/// +/// - title (string|dict): Title text or dictionary for i18n. Default is "Remark" +/// - body (content): Content of the remark +/// -> content +#let remark = note-box.with( + fill: rgb("#118D8D"), + title: theorion-i18n-map.at("remark"), + icon-name: "comment", +) \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/cosmos/fancy.typ b/packages/preview/theorion/0.3.0/cosmos/fancy.typ new file mode 100644 index 000000000..2349f4f0b --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/fancy.typ @@ -0,0 +1,215 @@ +#import "../core.typ": * +#import "../deps.typ": showybox + +/// A fancy box design inspired by elegantbook style. +/// +/// - border-color (color): Color of the box border. Default is `orange.darken(0%)`. +/// - body-color (color): Color of the box background. Default is `orange.lighten(95%)`. +/// - symbol (symbol): Symbol to display at bottom right. Default is `sym.suit.heart.stroked`. +/// - prefix (content): Prefix text before the title. Default is `none`. +/// - title (string): Title of the box. Default is empty string. +/// - full-title (auto|content): Complete title including prefix. Default is `auto`. +/// - body (content): Content of the box. +/// -> content +#let fancy-box( + get-border-color: () => orange.darken(0%), + get-body-color: () => orange.lighten(95%), + get-symbol: () => sym.suit.heart.stroked, + prefix: none, + title: "", + full-title: auto, + body, +) = context showybox( + frame: ( + thickness: .05em, + radius: .3em, + inset: (x: 1.2em, top: .7em, bottom: 1.2em), + border-color: get-border-color(here()), + title-color: get-border-color(here()), + body-color: get-body-color(here()), + title-inset: (x: 1em, y: .5em), + ), + title-style: ( + boxed-style: ( + anchor: (x: left, y: horizon), + radius: 0em, + ), + color: white, + weight: "semibold", + ), + breakable: true, + title: { + if full-title == auto { + if prefix != none { + [#prefix (#title)] + } else { + title + } + } else { + full-title + } + }, + { + body + if get-symbol(here()) != none { + place( + right + bottom, + dy: .8em, + dx: .9em, + text(size: .6em, fill: get-border-color(here()), get-symbol(here())), + ) + } + }, +) + +/// Register global colors. +#let (get-primary-border-color, set-primary-border-color) = use-state( + "fancy-primary-border-color", + green.darken(30%), +) +#let (get-primary-body-color, set-primary-body-color) = use-state( + "fancy-primary-body-color", + green.lighten(95%), +) +#let (get-secondary-border-color, set-secondary-border-color) = use-state( + "fancy-secondary-border-color", + orange.darken(0%), +) +#let (get-secondary-body-color, set-secondary-body-color) = use-state( + "fancy-secondary-body-color", + orange.lighten(95%), +) +#let (get-tertiary-border-color, set-tertiary-border-color) = use-state( + "fancy-tertiary-border-color", + blue.darken(30%), +) +#let (get-tertiary-body-color, set-tertiary-body-color) = use-state( + "fancy-tertiary-body-color", + blue.lighten(95%), +) + +/// Register global symbols. +#let (get-primary-symbol, set-primary-symbol) = use-state( + "fancy-primary-symbol", + sym.suit.club.filled, +) +#let (get-secondary-symbol, set-secondary-symbol) = use-state( + "fancy-secondary-symbol", + sym.suit.heart.stroked, +) +#let (get-tertiary-symbol, set-tertiary-symbol) = use-state( + "fancy-tertiary-symbol", + sym.suit.spade.filled, +) + + +/// Create corresponding theorem box. +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + inherited-levels: 2, + render: fancy-box.with( + get-border-color: get-secondary-border-color, + get-body-color: get-secondary-body-color, + get-symbol: get-secondary-symbol, + ), +) + +#let (lemma-counter, lemma-box, lemma, show-lemma) = make-frame( + "lemma", + theorion-i18n-map.at("lemma"), + counter: theorem-counter, + render: fancy-box.with( + get-border-color: get-secondary-border-color, + get-body-color: get-secondary-body-color, + get-symbol: get-secondary-symbol, + ), +) + +#let (corollary-counter, corollary-box, corollary, show-corollary) = make-frame( + "corollary", + theorion-i18n-map.at("corollary"), + inherited-from: theorem-counter, + render: fancy-box.with( + get-border-color: get-secondary-border-color, + get-symbol: get-secondary-symbol, + get-body-color: get-secondary-body-color, + ), +) + +#let (axiom-counter, axiom-box, axiom, show-axiom) = make-frame( + "axiom", + theorion-i18n-map.at("axiom"), + counter: theorem-counter, + render: fancy-box.with( + get-border-color: get-secondary-border-color, + get-body-color: get-secondary-body-color, + get-symbol: get-secondary-symbol, + ), +) + +#let (postulate-counter, postulate-box, postulate, show-postulate) = make-frame( + "postulate", + theorion-i18n-map.at("postulate"), + counter: theorem-counter, + render: fancy-box.with( + get-border-color: get-secondary-border-color, + get-body-color: get-secondary-body-color, + get-symbol: get-secondary-symbol, + ), +) + +#let (definition-counter, definition-box, definition, show-definition) = make-frame( + "definition", + theorion-i18n-map.at("definition"), + counter: theorem-counter, + render: fancy-box.with( + get-border-color: get-primary-border-color, + get-body-color: get-primary-body-color, + get-symbol: get-primary-symbol, + ), +) + +#let (proposition-counter, proposition-box, proposition, show-proposition) = make-frame( + "proposition", + theorion-i18n-map.at("proposition"), + counter: theorem-counter, + render: fancy-box.with( + get-border-color: get-tertiary-border-color, + get-body-color: get-tertiary-body-color, + get-symbol: get-tertiary-symbol, + ), +) + +/// Collection of show rules for all theorem environments +/// Applies all theorion-related show rules to the document +/// +/// - body (content): Content to apply the rules to +/// -> content +#let show-theorion(body) = { + show: show-theorem + show: show-lemma + show: show-corollary + show: show-axiom + show: show-postulate + show: show-definition + show: show-proposition + body +} + + +/// Set the number of inherited levels for theorem environments +/// +/// - value (integer): Number of levels to inherit +#let set-inherited-levels(value) = (theorem-counter.set-inherited-levels)(value) + + +/// Set the zero-fill option for theorem environments +/// +/// - value (boolean): Whether to zero-fill the numbering +#let set-zero-fill(value) = (theorem-counter.set-zero-fill)(value) + +/// Set the leading-zero option for theorem environments +/// +/// - value (boolean): Whether to include leading zeros in the numbering +#let set-leading-zero(value) = (theorem-counter.set-leading-zero)(value) \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/cosmos/rainbow.typ b/packages/preview/theorion/0.3.0/cosmos/rainbow.typ new file mode 100644 index 000000000..7e79f2612 --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/rainbow.typ @@ -0,0 +1,101 @@ +#import "../core.typ": * + +/// A simple render function with a colored left border +#let render-fn( + fill: red, + prefix: none, + title: "", + full-title: auto, + body, +) = block( + stroke: (left: .25em + fill), + inset: (left: 1em, y: .75em), + [ + #strong(text(fill: fill, full-title)) + + #body + ] +) + +// Core theorems +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + inherited-levels: 2, + render: render-fn.with(fill: red.darken(20%)), +) + +#let (lemma-counter, lemma-box, lemma, show-lemma) = make-frame( + "lemma", + theorion-i18n-map.at("lemma"), + counter: theorem-counter, + render: render-fn.with(fill: teal.darken(10%)), +) + +#let (corollary-counter, corollary-box, corollary, show-corollary) = make-frame( + "corollary", + theorion-i18n-map.at("corollary"), + counter: theorem-counter, + render: render-fn.with(fill: fuchsia.darken(10%)), +) + +// Definitions and foundations +#let (definition-counter, definition-box, definition, show-definition) = make-frame( + "definition", + theorion-i18n-map.at("definition"), + counter: theorem-counter, + render: render-fn.with(fill: orange), +) + +#let (axiom-counter, axiom-box, axiom, show-axiom) = make-frame( + "axiom", + theorion-i18n-map.at("axiom"), + counter: theorem-counter, + render: render-fn.with(fill: green.darken(20%)), +) + +#let (postulate-counter, postulate-box, postulate, show-postulate) = make-frame( + "postulate", + theorion-i18n-map.at("postulate"), + counter: theorem-counter, + render: render-fn.with(fill: maroon), +) + +// Important results +#let (proposition-counter, proposition-box, proposition, show-proposition) = make-frame( + "proposition", + theorion-i18n-map.at("proposition"), + counter: theorem-counter, + render: render-fn.with(fill: blue.darken(10%)), +) + +/// Collection of show rules for all theorem environments +/// Applies all theorion-related show rules to the document +/// +/// - body (content): Content to apply the rules to +/// -> content +#let show-theorion(body) = { + show: show-theorem + show: show-lemma + show: show-corollary + show: show-axiom + show: show-postulate + show: show-definition + show: show-proposition + body +} + +/// Set the number of inherited levels for theorem environments +/// +/// - value (integer): Number of levels to inherit +#let set-inherited-levels(value) = (theorem-counter.set-inherited-levels)(value) + +/// Set the zero-fill option for theorem environments +/// +/// - value (boolean): Whether to zero-fill the numbering +#let set-zero-fill(value) = (theorem-counter.set-zero-fill)(value) + +/// Set the leading-zero option for theorem environments +/// +/// - value (boolean): Whether to include leading zeros in the numbering +#let set-leading-zero(value) = (theorem-counter.set-leading-zero)(value) diff --git a/packages/preview/theorion/0.3.0/cosmos/simple.typ b/packages/preview/theorion/0.3.0/cosmos/simple.typ new file mode 100644 index 000000000..92b9defa5 --- /dev/null +++ b/packages/preview/theorion/0.3.0/cosmos/simple.typ @@ -0,0 +1,92 @@ +#import "../core.typ": * + +/// A simple render function +#let render-fn( + prefix: none, + title: "", + full-title: auto, + body, +) = [#strong[#full-title.]#sym.space#emph(body)] + +/// Create corresponding theorem box. +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + inherited-levels: 2, + render: render-fn, +) + +#let (lemma-counter, lemma-box, lemma, show-lemma) = make-frame( + "lemma", + theorion-i18n-map.at("lemma"), + counter: theorem-counter, + render: render-fn, +) + +#let (corollary-counter, corollary-box, corollary, show-corollary) = make-frame( + "corollary", + theorion-i18n-map.at("corollary"), + inherited-from: theorem-counter, + render: render-fn, +) + +#let (axiom-counter, axiom-box, axiom, show-axiom) = make-frame( + "axiom", + theorion-i18n-map.at("axiom"), + counter: theorem-counter, + render: render-fn, +) + +#let (postulate-counter, postulate-box, postulate, show-postulate) = make-frame( + "postulate", + theorion-i18n-map.at("postulate"), + counter: theorem-counter, + render: render-fn, +) + +#let (definition-counter, definition-box, definition, show-definition) = make-frame( + "definition", + theorion-i18n-map.at("definition"), + counter: theorem-counter, + render: render-fn, +) + +#let (proposition-counter, proposition-box, proposition, show-proposition) = make-frame( + "proposition", + theorion-i18n-map.at("proposition"), + counter: theorem-counter, + render: render-fn, +) + +/// Collection of show rules for all theorem environments +/// Applies all theorion-related show rules to the document +/// +/// - body (content): Content to apply the rules to +/// -> content +#let show-theorion(body) = { + show: show-theorem + show: show-lemma + show: show-corollary + show: show-axiom + show: show-postulate + show: show-definition + show: show-proposition + body +} + + +/// Set the number of inherited levels for theorem environments +/// +/// - value (integer): Number of levels to inherit +#let set-inherited-levels(value) = (theorem-counter.set-inherited-levels)(value) + + +/// Set the zero-fill option for theorem environments +/// +/// - value (boolean): Whether to zero-fill the numbering +#let set-zero-fill(value) = (theorem-counter.set-zero-fill)(value) + +/// Set the leading-zero option for theorem environments +/// +/// - value (boolean): Whether to include leading zeros in the numbering +#let set-leading-zero(value) = (theorem-counter.set-leading-zero)(value) diff --git a/packages/preview/theorion/0.3.0/deps.typ b/packages/preview/theorion/0.3.0/deps.typ new file mode 100644 index 000000000..0b16b1129 --- /dev/null +++ b/packages/preview/theorion/0.3.0/deps.typ @@ -0,0 +1,359 @@ +#import "@preview/showybox:2.0.4": showybox + +// ------------------------------------------------------------------------ +// Octique Package +// Author: @0x6b +// License: MIT +// ------------------------------------------------------------------------ +// Copied from the `octique` package, and I will replace it in the future. +// ------------------------------------------------------------------------ +#let _data = ( + accessibility-inset: "", + accessibility: "", + alert-fill: "", + alert: "", + apps: "", + archive: "", + arrow-both: "", + arrow-down-left: "", + arrow-down-right: "", + arrow-down: "", + arrow-left: "", + arrow-right: "", + arrow-switch: "", + arrow-up-left: "", + arrow-up-right: "", + arrow-up: "", + beaker: "", + bell-fill: "", + bell-slash: "", + bell: "", + blocked: "", + bold: "", + book: "", + bookmark-slash: "", + bookmark: "", + briefcase: "", + broadcast: "", + browser: "", + bug: "", + cache: "", + calendar: "", + check-circle-fill: "", + check-circle: "", + check: "", + checkbox: "", + checklist: "", + chevron-down: "", + chevron-left: "", + chevron-right: "", + chevron-up: "", + circle-slash: "", + circle: "", + clock-fill: "", + clock: "", + cloud-offline: "", + cloud: "", + code-of-conduct: "", + code-review: "", + code: "", + code-square: "", + codescan-checkmark: "", + codescan: "", + codespaces: "", + columns: "", + command-palette: "", + comment-discussion: "", + comment: "", + container: "", + copilot-error: "", + copilot: "", + copilot-warning: "", + copy: "", + cpu: "", + credit-card: "", + cross-reference: "", + dash: "", + database: "", + dependabot: "", + desktop-download: "", + device-camera: "", + device-camera-video: "", + device-desktop: "", + device-mobile: "", + devices: "", + diamond: "", + diff-added: "", + diff-ignored: "", + diff-modified: "", + diff-removed: "", + diff-renamed: "", + diff: "", + discussion-closed: "", + discussion-duplicate: "", + discussion-outdated: "", + dot-fill: "", + dot: "", + download: "", + duplicate: "", + ellipsis: "", + eye-closed: "", + eye: "", + feed-discussion: "", + feed-forked: "", + feed-heart: "", + feed-issue-closed: "", + feed-issue-draft: "", + feed-issue-open: "", + feed-issue-reopen: "", + feed-merged: "", + feed-person: "", + feed-plus: "", + feed-public: "", + feed-pull-request-closed: "", + feed-pull-request-draft: "", + feed-pull-request-open: "", + feed-repo: "", + feed-rocket: "", + feed-star: "", + feed-tag: "", + feed-trophy: "", + file-added: "", + file-badge: "", + file-binary: "", + file-code: "", + file-diff: "", + file-directory-fill: "", + file-directory-open-fill: "", + file-directory: "", + file-directory-symlink: "", + file-moved: "", + file-removed: "", + file: "", + file-submodule: "", + file-symlink-file: "", + file-zip: "", + filter: "", + fiscal-host: "", + flame: "", + fold-down: "", + fold: "", + fold-up: "", + gear: "", + gift: "", + git-branch: "", + git-commit: "", + git-compare: "", + git-merge-queue: "", + git-merge: "", + git-pull-request-closed: "", + git-pull-request-draft: "", + git-pull-request: "", + globe: "", + goal: "", + grabber: "", + graph: "", + hash: "", + heading: "", + heart-fill: "", + heart: "", + history: "", + home: "", + horizontal-rule: "", + hourglass: "", + hubot: "", + id-badge: "", + image: "", + inbox: "", + infinity: "", + info: "", + issue-closed: "", + issue-draft: "", + issue-opened: "", + issue-reopened: "", + issue-tracked-by: "", + issue-tracks: "", + italic: "", + iterations: "", + kebab-horizontal: "", + key-asterisk: "", + key: "", + law: "", + light-bulb: "", + link-external: "", + link: "", + list-ordered: "", + list-unordered: "", + location: "", + lock: "", + log: "", + logo-gist: "", + logo-github: "", + mail: "", + mark-github: "", + markdown: "", + megaphone: "", + mention: "", + meter: "", + milestone: "", + mirror: "", + moon: "", + mortar-board: "", + move-to-bottom: "", + move-to-end: "", + move-to-start: "", + move-to-top: "", + multi-select: "", + mute: "", + no-entry: "", + north-star: "", + note: "", + number: "", + organization: "", + package-dependencies: "", + package-dependents: "", + package: "", + paintbrush: "", + paper-airplane: "", + paperclip: "", + passkey-fill: "", + paste: "", + pencil: "", + people: "", + person-add: "", + person-fill: "", + person: "", + pin-slash: "", + pin: "", + pivot-column: "", + play: "", + plug: "", + plus-circle: "", + plus: "", + project-roadmap: "", + project: "", + project-symlink: "", + project-template: "", + pulse: "", + question: "", + quote: "", + read: "", + redo: "", + rel-file-path: "", + reply: "", + repo-clone: "", + repo-deleted: "", + repo-forked: "", + repo-locked: "", + repo-pull: "", + repo-push: "", + repo: "", + repo-template: "", + report: "", + rocket: "", + rows: "", + rss: "", + ruby: "", + screen-full: "", + screen-normal: "", + search: "", + server: "", + share-android: "", + share: "", + shield-check: "", + shield-lock: "", + shield-slash: "", + shield: "", + shield-x: "", + sidebar-collapse: "", + sidebar-expand: "", + sign-in: "", + sign-out: "", + single-select: "", + skip-fill: "", + skip: "", + sliders: "", + smiley: "", + sort-asc: "", + sort-desc: "", + sparkle-fill: "", + sponsor-tiers: "", + square-fill: "", + square: "", + squirrel: "", + stack: "", + star-fill: "", + star: "", + stop: "", + stopwatch: "", + strikethrough: "", + sun: "", + sync: "", + tab-external: "", + table: "", + tag: "", + tasklist: "", + telescope-fill: "", + telescope: "", + terminal: "", + three-bars: "", + thumbsdown: "", + thumbsup: "", + tools: "", + tracked-by-closed-completed: "", + tracked-by-closed-not-planned: "", + trash: "", + triangle-down: "", + triangle-left: "", + triangle-right: "", + triangle-up: "", + trophy: "", + typography: "", + undo: "", + unfold: "", + unlink: "", + unlock: "", + unmute: "", + unread: "", + unverified: "", + upload: "", + verified: "", + versions: "", + video: "", + webhook: "", + workflow: "", + x-circle-fill: "", + x-circle: "", + x: "", + zap: "", + zoom-in: "", + zoom-out: "", +) + +// Wrap path data into SVG +#let _octique-svg(name) = { + "" + _data.at(name) + "" +} + +// Returns decoded image for name +#let _octique-image(name, color: rgb("#000000"), width: 1em, height: 1em) = { + image( + bytes(_octique-svg(name).replace("#000000", color.to-hex())), + width: width, + height: height, + alt: name, + format: "svg", + ) +} + + +// Returns an image for the given name. +#let octique(name, color: rgb("#000000"), width: 1em, height: 1em) = _octique-image(name, color: color, width: width, height: width) + +// Returns a boxed image for the given name. +#let octique-inline(name, color: rgb("#000000"), width: 1em, height: 1em, baseline: 25%) = { + box(baseline: baseline, octique(name, color: color, width: width, height: height)) +} + +// Returns an SVG text for the given name. +#let octique-svg(name) = _octique-svg(name) diff --git a/packages/preview/theorion/0.3.0/examples/example-zh.typ b/packages/preview/theorion/0.3.0/examples/example-zh.typ new file mode 100644 index 000000000..59af9b439 --- /dev/null +++ b/packages/preview/theorion/0.3.0/examples/example-zh.typ @@ -0,0 +1,287 @@ +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#set page(height: auto) +#set heading(numbering: "1.1") +#set text(lang: "zh", region: "cn") + +/// 1. 更改计数器和编号: +// #set-inherited-levels(1) +// #set-zero-fill(true) +// #set-leading-zero(true) +// #set-theorion-numbering("1.1") + +/// 2. 其他选项: +// #set-result("noanswer") +// #set-qed-symbol[#math.qed] + +/// 3. 自定义定理环境 +// #let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( +// "theorem", +// theorion-i18n-map.at("theorem"), +// counter: theorem-counter, // 继承已有计数器,默认为 none +// inherited-levels: 2, // 需要新计数器时有用 +// inherited-from: heading, // 从标题或其他计数器继承 +// render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +// ) +// #show: show-theorem + +/// 4. 开始使用 +// #theorem(title: "欧几里得定理")[ +// 素数有无穷多个。 +// ] +// #theorem-box(title: "无编号定理")[ +// 这个定理没有编号。 +// ] + +/// 5. 附录示例 +// #counter(heading).update(0) +// #set heading(numbering: "A.1") +// #set-theorion-numbering("A.1") + +/// 6. 目录 +// #outline(title: none, target: figure.where(kind: "theorem")) + + += Theorion 环境示例 + +== 目录 + +#outline(title: none, target: figure.where(kind: "theorem")) + +== 开箱即用 + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#theorem(title: "欧几里得定理")[ + 素数有无穷多个。 +] + +#theorem-box(title: "无编号定理")[ + 这个定理没有编号。 +] +``` + +== 自定义 + +```typst +// 1. 更改计数器和编号: +#set-inherited-levels(1) +#set-zero-fill(true) +#set-leading-zero(true) +#set-theorion-numbering("1.1") + +// 2. 其他选项: +#set-result("noanswer") +#set-qed-symbol[#math.qed] + +// 3. 自定义定理环境 +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + theorion-i18n-map.at("theorem"), + counter: theorem-counter, // inherit the old counter, `none` by default + inherited-levels: 2, // useful when you need a new counter + inherited-from: heading, // heading or just another counter + render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +) +#show: show-theorem + +// 4. 开始使用 +#theorem(title: "欧几里得定理")[ + 素数有无穷多个。 +] +#theorem-box(title: "无编号定理")[ + 这个定理没有编号。 +] + +// 5. 附录示例 +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + +// 6. 目录 +#outline(title: none, target: figure.where(kind: "theorem")) +``` + +== 基础定理环境 + +让我们从最基本的定义开始。 + +#definition[ + 若一个大于1的自然数不能写成两个更小自然数的乘积,则称其为#highlight[_素数_](或_质数_)。 +] + +#example[ + 数 $2$、$3$ 和 $17$ 都是素数。正如@cor:infinite-prime 所证,这个列表远未完整!详细证明见@thm:euclid。 +] + +#theorem(title: "欧几里得定理")[ + 素数有无穷多个。 +] + +#proof[ + 反证法:假设 $p_1, p_2, dots, p_n$ 是所有素数的有限列举。 + 记 $P = p_1 p_2 dots p_n$。因为 $P + 1$ 不在我们的列表中, + 它不可能是素数。因此,一定存在某个素数 $p_j$ 整除 $P + 1$。 + 又因为 $p_j$ 也整除 $P$,所以它必须整除差 $(P + 1) - P = 1$,矛盾。 +] + +#corollary[ + 不存在最大的素数。 +] + +#corollary[ + 合数有无穷多个。 +] + +== 函数与连续性 + +#theorem(title: "连续性定理")[ + 设函数 $f$ 在每一点都可导,则 $f$ 是连续函数。 +] + +#tip-box[ + @thm:continuous 告诉我们可导性蕴含连续性,但反之不成立。比如 $f(x) = |x|$ 在 $x = 0$ 处连续但不可导。 + 更深入理解连续函数,请参见附录中的@thm:max-value。 +] + +== 几何定理 + +#theorem(title: "勾股定理")[ + 直角三角形的两条直角边的平方和等于斜边的平方: + $x^2 + y^2 = z^2$ +] + +#important-box[ + @thm:pythagoras 是平面几何中最基本也是最重要的定理之一,它连接了几何与代数。 +] + +#corollary[ + 不存在边长为3厘米、4厘米和6厘米的直角三角形。这是@thm:pythagoras 的直接推论。 +] + +#lemma[ + 给定两条线段,其长度分别为 $a$ 和 $b$,则存在实数 $r$ 使得 $b = r a$。 +] + +== 代数结构 + +#definition(title: "环")[ + 设 $R$ 是一个非空集合,如果 $R$ 上定义了两个二元运算 $+$ 和 $dot$,满足: + 1. $(R, +)$ 是阿贝尔群 + 2. $(R, dot)$ 是半群 + 3. 分配律成立 + 则称 $(R, +, dot)$ 为一个环。 +] + +#proposition[ + 每个域都是环,但不是每个环都是域。这个概念基于@def:ring。 +] + +#example[ + 参考@def:ring,整数环 $ZZ$ 不是域,因为除了 $plus.minus 1$,其他元素都没有乘法逆元。 +] + +/// 附录示例 +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + += Theorion 附录 + +== 进阶分析 + +#theorem(title: "最大值定理")[ + 闭区间上的连续函数必有最大值和最小值。 +] + +#warning-box[ + 这个定理的两个条件缺一不可: + - 函数必须是连续的 + - 定义域必须是闭区间 +] + +== 高等代数补充 + +#axiom(title: "群公理")[ + 群 $(G, \cdot)$ 需满足: + 1. 封闭性 + 2. 结合律 + 3. 存在单位元 + 4. 存在逆元 +] + +#postulate(title: "代数基本定理")[ + 任意一个非零复系数多项式一定有复数根。 +] + +#remark[ + 这个定理也被称为高斯基本定理,因为它是由高斯首次严格证明的。 +] + +== 常见问题与解答 + +#problem[ + 证明:如果 $n$ 是大于1的整数,则存在长度为 $n$ 的连续合数序列。 +] + +#solution[ + 考虑序列:$n! + 2, n! + 3, ..., n! + n$。 + + 对于任意 $2 <= k <= n$,$n! + k$ 能被 $k$ 整除,因为: + $n! + k = k(n!/k + 1)$ + + 所以这是一个长度为 $n-1$ 的连续合数序列。 +] + +#exercise[ + 1. 证明:存在无限多对孪生素数的猜想至今未被证明。 + 2. 尝试说明为什么这个问题如此困难。 +] + +#conclusion[ + 数论中还有许多未解决的问题,它们往往看似简单,实则深奥。 +] + +== 注意事项 + +#note-box[ + 请记住数学证明既要严谨又要清晰。 + 没有严谨性的清晰是不充分的,没有清晰性的严谨也是无效的。 +] + +#caution-box[ + 在处理无穷级数时,一定要先检验其收敛性,再讨论其他性质。 +] + +#quote-box[ + 数学是科学的女王,而数论是数学的女王。 + — 高斯 +] + +#emph-box[ + 本章总结: + - 我们介绍了基本的数论概念 + - 证明了几个重要定理 + - 展示了不同类型的数学环境 +] + +== 重述定理 + +// 1. 重述所有定理 +#theorion-restate(filter: it => it.identifier == "theorem", render: it => it.render) +// 2. 重述所有定理(自定义格式) +// #theorion-restate( +// filter: it => it.identifier == "theorem", +// render: it => (prefix: none, title: "", full-title: auto, body) => block[#strong[#full-title.]#sym.space#emph(body)], +// ) +// 3. 重述特定定理 +// #theorion-restate(filter: it => it.label == ) \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/examples/example.png b/packages/preview/theorion/0.3.0/examples/example.png new file mode 100644 index 000000000..c9ebff0d9 Binary files /dev/null and b/packages/preview/theorion/0.3.0/examples/example.png differ diff --git a/packages/preview/theorion/0.3.0/examples/example.typ b/packages/preview/theorion/0.3.0/examples/example.typ new file mode 100644 index 000000000..08903030d --- /dev/null +++ b/packages/preview/theorion/0.3.0/examples/example.typ @@ -0,0 +1,295 @@ +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#set page(height: auto) +#set heading(numbering: "1.1") +#set text(lang: "en") + +/// 1. Change the counters and numbering: +// #set-inherited-levels(1) +// #set-zero-fill(true) +// #set-leading-zero(true) +// #set-theorion-numbering("1.1") + +/// 2. Other options: +// #set-result("noanswer") +// #set-qed-symbol[#math.qed] + +/// 3. Custom theorem environment for yourself +// #let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( +// "theorem", +// "Theorem", // supplement, string or dictionary like `(en: "Theorem")`, or `theorion-i18n-map.at("theorem")` for built-in i18n support +// counter: theorem-counter, // inherit the counter, `none` by default +// inherited-levels: 2, // useful when you need a new counter +// inherited-from: heading, // heading or another counter +// render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +// ) +// #show: show-theorem + +/// 4. Just use it. +// #theorem(title: "Euclid's Theorem")[ +// There are infinitely many prime numbers. +// ] +// #theorem-box(title: "Theorem without numbering")[ +// This theorem is not numbered. +// ] + +/// 5. Example of appendix +// #counter(heading).update(0) +// #set heading(numbering: "A.1") +// #set-theorion-numbering("A.1") + +/// 6. Table of contents +// #outline(title: none, target: figure.where(kind: "theorem")) + += Theorion Environments + +== Quick Start + +```typst +#import "@preview/theorion:0.3.0": * +#import cosmos.fancy: * +// #import cosmos.rainbow: * +// #import cosmos.clouds: * +#show: show-theorion + +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] + +#theorem-box(title: "Theorem without numbering")[ + This theorem is not numbered. +] +``` + +== Customization + +```typst +// 1. Change the counters and numbering: +#set-inherited-levels(1) +#set-zero-fill(true) +#set-leading-zero(true) +#set-theorion-numbering("1.1") + +// 2. Other options: +#set-result("noanswer") +#set-qed-symbol[#math.qed] + +// 3. Custom theorem environment for yourself +#let (theorem-counter, theorem-box, theorem, show-theorem) = make-frame( + "theorem", + "Theorem", // supplement, string or dictionary like `(en: "Theorem")`, or `theorion-i18n-map.at("theorem")` for built-in i18n support + counter: theorem-counter, // inherit the old counter, `none` by default + inherited-levels: 2, // useful when you need a new counter + inherited-from: heading, // heading or just another counter + render: (prefix: none, title: "", full-title: auto, body) => [#strong[#full-title.]#sym.space#emph(body)], +) +#show: show-theorem + +// 4. Just use it. +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] +#theorem-box(title: "Theorem without numbering")[ + This theorem is not numbered. +] + +// 5. Example of appendix +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + +// 6. Table of contents +#outline(title: none, target: figure.where(kind: "theorem")) +``` + +== Table of Theorems + +#outline(title: none, target: figure.where(kind: "theorem")) + +== Basic Theorem Environments + +Let's start with the most fundamental definition. + +#definition[ + A natural number is called a #highlight[_prime number_] if it is greater than 1 + and cannot be written as the product of two smaller natural numbers. +] + +#example[ + The numbers $2$, $3$, and $17$ are prime. As proven in @cor:infinite-prime, + this list is far from complete! See @thm:euclid for the full proof. +] + +#theorem(title: "Euclid's Theorem")[ + There are infinitely many prime numbers. +] + +#proof[ + By contradiction: Suppose $p_1, p_2, dots, p_n$ is a finite enumeration of all primes. + Let $P = p_1 p_2 dots p_n$. Since $P + 1$ is not in our list, + it cannot be prime. Thus, some prime $p_j$ divides $P + 1$. + Since $p_j$ also divides $P$, it must divide their difference $(P + 1) - P = 1$, + a contradiction. +] + +#corollary[ + There is no largest prime number. +] + +#lemma[ + There are infinitely many composite numbers. +] + +== Functions and Continuity + +#theorem(title: "Continuity Theorem")[ + If a function $f$ is differentiable at every point, then $f$ is continuous. +] + +#tip-box[ + @thm:continuous tells us that differentiability implies continuity, + but not vice versa. For example, $f(x) = |x|$ is continuous but not differentiable at $x = 0$. + For a deeper understanding of continuous functions, see @thm:max-value in the appendix. +] + +== Geometric Theorems + +#theorem(title: "Pythagorean Theorem")[ + In a right triangle, the square of the hypotenuse equals the sum of squares of the other two sides: + $x^2 + y^2 = z^2$ +] + +#important-box[ + @thm:pythagoras is one of the most fundamental and important theorems in plane geometry, + bridging geometry and algebra. +] + +#corollary[ + There exists no right triangle with sides measuring 3cm, 4cm, and 6cm. + This directly follows from @thm:pythagoras. +] + +#lemma[ + Given two line segments of lengths $a$ and $b$, there exists a real number $r$ + such that $b = r a$. +] + +== Algebraic Structures + +#definition(title: "Ring")[ + Let $R$ be a non-empty set with two binary operations $+$ and $dot$, satisfying: + 1. $(R, +)$ is an abelian group + 2. $(R, dot)$ is a semigroup + 3. The distributive laws hold + Then $(R, +, dot)$ is called a ring. +] + +#proposition[ + Every field is a ring, but not every ring is a field. This concept builds upon @def:ring. +] + +#example[ + Consider @def:ring. The ring of integers $ZZ$ is not a field, as no elements except $plus.minus 1$ + have multiplicative inverses. +] + +/// Appendix +#counter(heading).update(0) +#set heading(numbering: "A.1") +#set-theorion-numbering("A.1") + += Theorion Appendices + +== Advanced Analysis + +#theorem(title: "Maximum Value Theorem")[ + A continuous function on a closed interval must attain both a maximum and a minimum value. +] + +#warning-box[ + Both conditions of this theorem are essential: + - The function must be continuous + - The domain must be a closed interval +] + +== Advanced Algebra Supplements + +#axiom(title: "Group Axioms")[ + A group $(G, \cdot)$ must satisfy: + 1. Closure + 2. Associativity + 3. Identity element exists + 4. Inverse elements exist +] + +#postulate(title: "Fundamental Theorem of Algebra")[ + Every non-zero polynomial with complex coefficients has a complex root. +] + +#remark[ + This theorem is also known as Gauss's theorem, as it was first rigorously proved by Gauss. +] + +== Common Problems and Solutions + +#problem[ + Prove: For any integer $n > 1$, there exists a sequence of $n$ consecutive composite numbers. +] + +#solution[ + Consider the sequence: $n! + 2, n! + 3, ..., n! + n$ + + For any $2 <= k <= n$, $n! + k$ is divisible by $k$ because: + $n! + k = k(n! / k + 1)$ + + Thus, this forms a sequence of $n-1$ consecutive composite numbers. +] + +#exercise[ + 1. Prove: The twin prime conjecture remains unproven. + 2. Try to explain why this problem is so difficult. +] + +#conclusion[ + Number theory contains many unsolved problems that appear deceptively simple + yet are profoundly complex. +] + +== Important Notes + +#note-box[ + Remember that mathematical proofs should be both rigorous and clear. + Clarity without rigor is insufficient, and rigor without clarity is ineffective. +] + +#caution-box[ + When dealing with infinite series, always verify convergence before discussing other properties. +] + +#quote-box[ + Mathematics is the queen of sciences, and number theory is the queen of mathematics. + — Gauss +] + +#emph-box[ + Chapter Summary: + - We introduced basic number theory concepts + - Proved several important theorems + - Demonstrated different types of mathematical environments +] + +== Restated Theorems + +// 1. Restate all theorems +#theorion-restate(filter: it => it.identifier == "theorem", render: it => it.render) +// 2. Restate all theorems with custom render function +// #theorion-restate( +// filter: it => it.identifier == "theorem", +// render: it => (prefix: none, title: "", full-title: auto, body) => block[#strong[#full-title.]#sym.space#emph(body)], +// ) +// 3. Restate a specific theorem +// #theorion-restate(filter: it => it.label == ) \ No newline at end of file diff --git a/packages/preview/theorion/0.3.0/i18n.typ b/packages/preview/theorion/0.3.0/i18n.typ new file mode 100644 index 000000000..8fbd50357 --- /dev/null +++ b/packages/preview/theorion/0.3.0/i18n.typ @@ -0,0 +1,264 @@ +#let theorion-i18n(map) = { + if type(map) != dictionary { + return map + } + return context { + let value = map + if "en" in map { + if type(map.at("en")) != dictionary { + value = map.at("en") + } else { + value = map.at("en").values().at(0, default: value) + } + } + if text.lang == none { + return value + } + if text.lang in map { + if type(map.at(text.lang)) != dictionary { + value = map.at(text.lang) + } else { + if text.region != none and text.region in map.at(text.lang) { + value = map.at(text.lang).at(text.region) + } else { + value = map.at(text.lang).values().at(0, default: value) + } + } + } + return value + } +} + +#let theorion-i18n-map = ( + theorem: ( + en: (us: "Theorem", gb: "Theorem"), + zh: (cn: "定理", hk: "定理", tw: "定理"), + de: (de: "Satz", at: "Satz", ch: "Satz"), + fr: (fr: "Théorème", ca: "Théorème", ch: "Théorème"), + es: (es: "Teorema", mx: "Teorema"), + pt: (pt: "Teorema", br: "Teorema"), + ja: "定理", + ko: "정리", + ru: "Теорема", + ), + lemma: ( + en: (us: "Lemma", gb: "Lemma"), + zh: (cn: "引理", hk: "引理", tw: "引理"), + de: (de: "Lemma", at: "Lemma", ch: "Lemma"), + fr: (fr: "Lemme", ca: "Lemme", ch: "Lemme"), + es: (es: "Lema", mx: "Lema"), + pt: (pt: "Lema", br: "Lema"), + ja: "補助定理", + ko: "보조정리", + ru: "Лемма", + ), + corollary: ( + en: (us: "Corollary", gb: "Corollary"), + zh: (cn: "推论", hk: "推論", tw: "推論"), + de: (de: "Korollar", at: "Korollar", ch: "Korollar"), + fr: (fr: "Corollaire", ca: "Corollaire", ch: "Corollaire"), + es: (es: "Corolario", mx: "Corolario"), + pt: (pt: "Corolário", br: "Corolário"), + ja: "系", + ko: "따름정리", + ru: "Следствие", + ), + note: ( + en: (us: "Note", gb: "Note"), + zh: (cn: "注意", hk: "注意", tw: "注意"), + de: (de: "Hinweis", at: "Hinweis", ch: "Hinweis"), + fr: (fr: "Note", ca: "Note", ch: "Note"), + es: (es: "Nota", mx: "Nota"), + pt: (pt: "Nota", br: "Nota"), + ja: "注意", + ko: "주의", + ru: "Примечание", + ), + warning: ( + en: (us: "Warning", gb: "Warning"), + zh: (cn: "警告", hk: "警告", tw: "警告"), + de: (de: "Warnung", at: "Warnung", ch: "Warnung"), + fr: (fr: "Avertissement", ca: "Avertissement", ch: "Avertissement"), + es: (es: "Advertencia", mx: "Advertencia"), + pt: (pt: "Aviso", br: "Aviso"), + ja: "警告", + ko: "경고", + ru: "Предупреждение", + ), + definition: ( + en: (us: "Definition", gb: "Definition"), + zh: (cn: "定义", hk: "定義", tw: "定義"), + de: (de: "Definition", at: "Definition", ch: "Definition"), + fr: (fr: "Définition", ca: "Définition", ch: "Définition"), + es: (es: "Definición", mx: "Definición"), + pt: (pt: "Definição", br: "Definição"), + ja: "定義", + ko: "정의", + ru: "Определение", + ), + axiom: ( + en: (us: "Axiom", gb: "Axiom"), + zh: (cn: "公理", hk: "公理", tw: "公理"), + de: (de: "Axiom", at: "Axiom", ch: "Axiom"), + fr: (fr: "Axiome", ca: "Axiome", ch: "Axiome"), + es: (es: "Axioma", mx: "Axioma"), + pt: (pt: "Axioma", br: "Axioma"), + ja: "公理", + ko: "공리", + ru: "Аксиома", + ), + postulate: ( + en: (us: "Postulate", gb: "Postulate"), + zh: (cn: "设准", hk: "設準", tw: "設準"), + de: (de: "Postulat", at: "Postulat", ch: "Postulat"), + fr: (fr: "Postulat", ca: "Postulat", ch: "Postulat"), + es: (es: "Postulado", mx: "Postulado"), + pt: (pt: "Postulado", br: "Postulado"), + ja: "要請", + ko: "공준", + ru: "Постулат", + ), + proposition: ( + en: (us: "Proposition", gb: "Proposition"), + zh: (cn: "命题", hk: "命題", tw: "命題"), + de: (de: "Satz", at: "Satz", ch: "Satz"), + fr: (fr: "Proposition", ca: "Proposition", ch: "Proposition"), + es: (es: "Proposición", mx: "Proposición"), + pt: (pt: "Proposição", br: "Proposição"), + ja: "命題", + ko: "명제", + ru: "Предложение", + ), + example: ( + en: (us: "Example", gb: "Example"), + zh: (cn: "例", hk: "例", tw: "例"), + de: (de: "Beispiel", at: "Beispiel", ch: "Beispiel"), + fr: (fr: "Exemple", ca: "Exemple", ch: "Exemple"), + es: (es: "Ejemplo", mx: "Ejemplo"), + pt: (pt: "Exemplo", br: "Exemplo"), + ja: "例", + ko: "예", + ru: "Пример", + ), + problem: ( + en: (us: "Problem", gb: "Problem"), + zh: (cn: "问题", hk: "問題", tw: "問題"), + de: (de: "Problem", at: "Problem", ch: "Problem"), + fr: (fr: "Problème", ca: "Problème", ch: "Problème"), + es: (es: "Problema", mx: "Problema"), + pt: (pt: "Problema", br: "Problema"), + ja: "問題", + ko: "문제", + ru: "Задача", + ), + exercise: ( + en: (us: "Exercise", gb: "Exercise"), + zh: (cn: "练习", hk: "練習", tw: "練習"), + de: (de: "Übung", at: "Übung", ch: "Übung"), + fr: (fr: "Exercice", ca: "Exercice", ch: "Exercice"), + es: (es: "Ejercicio", mx: "Ejercicio"), + pt: (pt: "Exercício", br: "Exercício"), + ja: "練習", + ko: "연습", + ru: "Упражнение", + ), + conclusion: ( + en: (us: "Conclusion", gb: "Conclusion"), + zh: (cn: "结论", hk: "結論", tw: "結論"), + de: (de: "Schlussfolgerung", at: "Schlussfolgerung", ch: "Schlussfolgerung"), + fr: (fr: "Conclusion", ca: "Conclusion", ch: "Conclusion"), + es: (es: "Conclusión", mx: "Conclusión"), + pt: (pt: "Conclusão", br: "Conclusão"), + ja: "結論", + ko: "결론", + ru: "Вывод", + ), + assumption: ( + en: (us: "Assumption", gb: "Assumption"), + zh: (cn: "假设", hk: "假設", tw: "假設"), + de: (de: "Annahme", at: "Annahme", ch: "Annahme"), + fr: (fr: "Hypothèse", ca: "Hypothèse", ch: "Hypothèse"), + es: (es: "Suposición", mx: "Suposición"), + pt: (pt: "Suposição", br: "Suposição"), + ja: "仮定", + ko: "가정", + ru: "Предположение", + ), + property: ( + en: (us: "Property", gb: "Property"), + zh: (cn: "性质", hk: "性質", tw: "性質"), + de: (de: "Eigenschaft", at: "Eigenschaft", ch: "Eigenschaft"), + fr: (fr: "Propriété", ca: "Propriété", ch: "Propriété"), + es: (es: "Propiedad", mx: "Propiedad"), + pt: (pt: "Propriedade", br: "Propriedade"), + ja: "性質", + ko: "성질", + ru: "Свойство", + ), + remark: ( + en: (us: "Remark", gb: "Remark"), + zh: (cn: "注解", hk: "注解", tw: "注解"), + de: (de: "Bemerkung", at: "Bemerkung", ch: "Bemerkung"), + fr: (fr: "Remarque", ca: "Remarque", ch: "Remarque"), + es: (es: "Observación", mx: "Observación"), + pt: (pt: "Observação", br: "Observação"), + ja: "注解", + ko: "비고", + ru: "Замечание", + ), + solution: ( + en: (us: "Solution", gb: "Solution"), + zh: (cn: "解", hk: "解", tw: "解"), + de: (de: "Lösung", at: "Lösung", ch: "Lösung"), + fr: (fr: "Solution", ca: "Solution", ch: "Solution"), + es: (es: "Solución", mx: "Solución"), + pt: (pt: "Solução", br: "Solução"), + ja: "解", + ko: "풀이", + ru: "Решение", + ), + proof: ( + en: (us: "Proof", gb: "Proof"), + zh: (cn: "证明", hk: "證明", tw: "證明"), + de: (de: "Beweis", at: "Beweis", ch: "Beweis"), + fr: (fr: "Démonstration", ca: "Démonstration", ch: "Démonstration"), + es: (es: "Demostración", mx: "Demostración"), + pt: (pt: "Demonstração", br: "Demonstração"), + ja: "証明", + ko: "증명", + ru: "Доказательство", + ), + tip: ( + en: (us: "Tip", gb: "Tip"), + zh: (cn: "提示", hk: "提示", tw: "提示"), + de: (de: "Tipp", at: "Tipp", ch: "Tipp"), + fr: (fr: "Conseil", ca: "Conseil", ch: "Conseil"), + es: (es: "Consejo", mx: "Consejo"), + pt: (pt: "Dica", br: "Dica"), + ja: "ヒント", + ko: "팁", + ru: "Подсказка", + ), + important: ( + en: (us: "Important", gb: "Important"), + zh: (cn: "重要", hk: "重要", tw: "重要"), + de: (de: "Wichtig", at: "Wichtig", ch: "Wichtig"), + fr: (fr: "Important", ca: "Important", ch: "Important"), + es: (es: "Importante", mx: "Importante"), + pt: (pt: "Importante", br: "Importante"), + ja: "重要", + ko: "중요", + ru: "Важно", + ), + caution: ( + en: (us: "Caution", gb: "Caution"), + zh: (cn: "小心", hk: "小心", tw: "小心"), + de: (de: "Vorsicht", at: "Vorsicht", ch: "Vorsicht"), + fr: (fr: "Attention", ca: "Attention", ch: "Attention"), + es: (es: "Precaución", mx: "Precaución"), + pt: (pt: "Cuidado", br: "Cuidado"), + ja: "注意", + ko: "주의", + ru: "Осторожно", + ), +) diff --git a/packages/preview/theorion/0.3.0/lib.typ b/packages/preview/theorion/0.3.0/lib.typ new file mode 100644 index 000000000..42e5be0d6 --- /dev/null +++ b/packages/preview/theorion/0.3.0/lib.typ @@ -0,0 +1,4 @@ +#import "core.typ": richer-counter, make-frame, theorion-i18n, theorion-i18n-map +#import "cosmos/cosmos.typ" +#import cosmos.default: * +#import cosmos.simple: * diff --git a/packages/preview/theorion/0.3.0/typst.toml b/packages/preview/theorion/0.3.0/typst.toml new file mode 100644 index 000000000..9bffa54d1 --- /dev/null +++ b/packages/preview/theorion/0.3.0/typst.toml @@ -0,0 +1,13 @@ +[package] +name = "theorion" +version = "0.3.0" +entrypoint = "lib.typ" +authors = ["OrangeX4"] +license = "MIT" +description = "Out-of-the-box, customizable and multilingual theorem environment package." +repository = "https://github.com/OrangeX4/typst-theorion" +keywords = ["theorem", "corollary", "lemma", "environment", "math", "box", "multilingual", "boxes", "colorful"] +disciplines = ["computer-science", "engineering", "mathematics", "physics", "education"] +categories = ["components"] +compiler = "0.12.0" +exclude = ["examples"] \ No newline at end of file diff --git a/packages/preview/touying/0.6.1/.gitignore b/packages/preview/touying/0.6.1/.gitignore new file mode 100644 index 000000000..5e56ef32e --- /dev/null +++ b/packages/preview/touying/0.6.1/.gitignore @@ -0,0 +1,4 @@ +/local + +*.pdf +*.pdfpc \ No newline at end of file diff --git a/packages/preview/touying/0.6.1/LICENSE b/packages/preview/touying/0.6.1/LICENSE new file mode 100644 index 000000000..c8023939f --- /dev/null +++ b/packages/preview/touying/0.6.1/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2024 OrangeX4 +Copyright (c) 2024 Andreas Kröpelin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/preview/touying/0.6.1/README.md b/packages/preview/touying/0.6.1/README.md new file mode 100644 index 000000000..a40706b30 --- /dev/null +++ b/packages/preview/touying/0.6.1/README.md @@ -0,0 +1,376 @@ +# ![logo](https://github.com/user-attachments/assets/58a91b14-ae1a-49e2-a3e7-5e3a148e2ba5) + +[Touying](https://github.com/touying-typ/touying) (投影 in chinese, /tóuyǐng/, meaning projection) is a user-friendly, powerful and efficient package for creating presentation slides in Typst. Partial code is inherited from [Polylux](https://github.com/andreasKroepelin/polylux) like `#only()` and `#uncover()`. + +Touying provides automatically injected global configurations, which is convenient for configuring themes. Besides, Touying does not rely on `counter` and `context` to implement `#pause`, resulting in better performance. + +If you like it, consider [giving a star on GitHub](https://github.com/touying-typ/touying). Touying is a community-driven project, feel free to suggest any ideas and contribute. + +[![Typst Universe](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Ftypst.app%2Funiverse%2Fpackage%2Ftouying&query=%2Fhtml%2Fbody%2Fdiv%2Fmain%2Fdiv%5B2%5D%2Faside%2Fsection%5B2%5D%2Fdl%2Fdd%5B3%5D&logo=typst&label=universe&color=%2339cccc)](https://typst.app/universe/package/touying) +[![Book badge](https://img.shields.io/badge/docs-book-green)](https://touying-typ.github.io/) +[![Gallery badge](https://img.shields.io/badge/docs-gallery-orange)](https://github.com/touying-typ/touying/wiki) +![GitHub](https://img.shields.io/github/license/touying-typ/touying) +![GitHub release (latest by date)](https://img.shields.io/github/v/release/touying-typ/touying) +![GitHub Repo stars](https://img.shields.io/github/stars/touying-typ/touying) +![Themes badge](https://img.shields.io/badge/themes-6-aqua) + +## Document + +Read [the document](https://touying-typ.github.io/) to learn all about Touying. + +We will maintain **English** and **Chinese** versions of the documentation for Touying, and for each major version, we will maintain a documentation copy. This allows you to easily refer to old versions of the Touying documentation and migrate to new versions. + +**Note that the documentation may be outdated, and you can also use Tinymist to view Touying's annotated documentation by hovering over the code.** + +## Gallery + +Touying offers [a gallery page](https://github.com/touying-typ/touying/wiki) via wiki, where you can browse elegant slides created by Touying users. You're also encouraged to contribute your own beautiful slides here! + +## Special Features + +1. Split slides by headings [document](https://touying-typ.github.io/docs/sections) + +```typst += Section + +== Subsection + +=== First Slide + +Hello, Touying! + +=== Second Slide + +Hello, Typst! +``` + +2. `#pause` and `#meanwhile` animations [document](https://touying-typ.github.io/docs/dynamic/simple) + +```typst +#slide[ + First + + #pause + + Second + + #meanwhile + + Third + + #pause + + Fourth +] +``` + +![image](https://github.com/touying-typ/touying/assets/34951714/24ca19a3-b27c-4d31-ab75-09c37911e6ac) + +3. Math Equation Animation [document](https://touying-typ.github.io/docs/dynamic/equation) + +![image](https://github.com/touying-typ/touying/assets/34951714/8640fe0a-95e4-46ac-b570-c8c79f993de4) + +4. `touying-reducer` Cetz and Fletcher Animations [document](https://touying-typ.github.io/docs/dynamic/other) + +![image](https://github.com/touying-typ/touying/assets/34951714/9ba71f54-2a5d-4144-996c-4a42833cc5cc) + +5. Correct outline and bookmark (no duplicate and correct page number) + +![image](https://github.com/touying-typ/touying/assets/34951714/7b62fcaf-6342-4dba-901b-818c16682529) + +6. Dewdrop Theme Navigation Bar [document](https://touying-typ.github.io/docs/themes/dewdrop) + +![image](https://github.com/touying-typ/touying/assets/34951714/0426516d-aa3c-4b7a-b7b6-2d5d276fb971) + +7. Semi-transparent cover mode [document](https://touying-typ.github.io/docs/dynamic/cover) + +![image](https://github.com/touying-typ/touying/assets/34951714/22a9ea66-c8b5-431e-a52c-2c8ca3f18e49) + +8. Speaker notes for dual-screen [document](https://touying-typ.github.io/docs/external/pympress) + +![image](https://github.com/touying-typ/touying/assets/34951714/afbe17cb-46d4-4507-90e8-959c53de95d5) + +9. Export slides to PPTX and HTML formats and show presentation online. [touying-exporter](https://github.com/touying-typ/touying-exporter) [touying-template](https://github.com/touying-typ/touying-template) [online](https://touying-typ.github.io/touying-template/) + +![image](https://github.com/touying-typ/touying-exporter/assets/34951714/207ddffc-87c8-4976-9bf4-4c6c5e2573ea) + + +## Quick start + +Before you begin, make sure you have installed the Typst environment. If not, you can use the [Web App](https://typst.app/) or the [Tinymist LSP](https://marketplace.visualstudio.com/items?itemName=myriad-dreamin.tinymist) extensions for VS Code. + +To use Touying, you only need to include the following code in your document: + +```typst +#import "@preview/touying:0.6.1": * +#import themes.simple: * + +#show: simple-theme.with(aspect-ratio: "16-9") + += Title + +== First Slide + +Hello, Touying! + +#pause + +Hello, Typst! +``` + +![image](https://github.com/touying-typ/touying/assets/34951714/f5bdbf8f-7bf9-45fd-9923-0fa5d66450b2) + +It's simple. Congratulations on creating your first Touying slide! 🎉 + +**Tip:** You can use Typst syntax like `#import "config.typ": *` or `#include "content.typ"` to implement Touying's multi-file architecture. + + +## More Complex Examples + +In fact, Touying provides various styles for writing slides. For example, the above example uses first-level and second-level titles to create new slides. However, you can also use the `#slide[..]` format to access more powerful features provided by Touying. + +```typst +#import "@preview/touying:0.6.1": * +#import themes.university: * +#import "@preview/cetz:0.3.2" +#import "@preview/fletcher:0.5.4" as fletcher: node, edge +#import "@preview/numbly:0.1.0": numbly +#import "@preview/theorion:0.3.0": * +#import cosmos.clouds: * +#show: show-theorion + +// cetz and fletcher bindings for touying +#let cetz-canvas = touying-reducer.with(reduce: cetz.canvas, cover: cetz.draw.hide.with(bounds: true)) +#let fletcher-diagram = touying-reducer.with(reduce: fletcher.diagram, cover: fletcher.hide) + +#show: university-theme.with( + aspect-ratio: "16-9", + // align: horizon, + // config-common(handout: true), + config-common(frozen-counters: (theorem-counter,)), // freeze theorem counter for animation + config-info( + title: [Title], + subtitle: [Subtitle], + author: [Authors], + date: datetime.today(), + institution: [Institution], + logo: emoji.school, + ), +) + +#set heading(numbering: numbly("{1}.", default: "1.1")) + +#title-slide() + +== Outline + +#components.adaptive-columns(outline(title: none, indent: 1em)) + += Animation + +== Simple Animation + +We can use `#pause` to #pause display something later. + +#pause + +Just like this. + +#meanwhile + +Meanwhile, #pause we can also use `#meanwhile` to #pause display other content synchronously. + +#speaker-note[ + + This is a speaker note. + + You won't see it unless you use `config-common(show-notes-on-second-screen: right)` +] + + +== Complex Animation + +At subslide #touying-fn-wrapper((self: none) => str(self.subslide)), we can + +use #uncover("2-")[`#uncover` function] for reserving space, + +use #only("2-")[`#only` function] for not reserving space, + +#alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives. + + +== Callback Style Animation + +#slide( + repeat: 3, + self => [ + #let (uncover, only, alternatives) = utils.methods(self) + + At subslide #self.subslide, we can + + use #uncover("2-")[`#uncover` function] for reserving space, + + use #only("2-")[`#only` function] for not reserving space, + + #alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives. + ], +) + + +== Math Equation Animation + +Equation with `pause`: + +$ + f(x) &= pause x^2 + 2x + 1 \ + &= pause (x + 1)^2 \ +$ + +#meanwhile + +Here, #pause we have the expression of $f(x)$. + +#pause + +By factorizing, we can obtain this result. + + +== CeTZ Animation + +CeTZ Animation in Touying: + +#cetz-canvas({ + import cetz.draw: * + + rect((0, 0), (5, 5)) + + (pause,) + + rect((0, 0), (1, 1)) + rect((1, 1), (2, 2)) + rect((2, 2), (3, 3)) + + (pause,) + + line((0, 0), (2.5, 2.5), name: "line") +}) + + +== Fletcher Animation + +Fletcher Animation in Touying: + +#fletcher-diagram( + node-stroke: .1em, + node-fill: gradient.radial(blue.lighten(80%), blue, center: (30%, 20%), radius: 80%), + spacing: 4em, + edge((-1, 0), "r", "-|>", `open(path)`, label-pos: 0, label-side: center), + node((0, 0), `reading`, radius: 2em), + edge((0, 0), (0, 0), `read()`, "--|>", bend: 130deg), + pause, + edge(`read()`, "-|>"), + node((1, 0), `eof`, radius: 2em), + pause, + edge(`close()`, "-|>"), + node((2, 0), `closed`, radius: 2em, extrude: (-2.5, 0)), + edge((0, 0), (2, 0), `close()`, "-|>", bend: -40deg), +) + + += Theorems + +== Prime numbers + +#definition[ + A natural number is called a #highlight[_prime number_] if it is greater + than 1 and cannot be written as the product of two smaller natural numbers. +] +#example[ + The numbers $2$, $3$, and $17$ are prime. + @cor_largest_prime shows that this list is not exhaustive! +] + +#theorem(title: "Euclid")[ + There are infinitely many primes. +] +#pagebreak(weak: true) +#proof[ + Suppose to the contrary that $p_1, p_2, dots, p_n$ is a finite enumeration + of all primes. Set $P = p_1 p_2 dots p_n$. Since $P + 1$ is not in our list, + it cannot be prime. Thus, some prime factor $p_j$ divides $P + 1$. Since + $p_j$ also divides $P$, it must divide the difference $(P + 1) - P = 1$, a + contradiction. +] + +#corollary[ + There is no largest prime number. +] +#corollary[ + There are infinitely many composite numbers. +] + +#theorem[ + There are arbitrarily long stretches of composite numbers. +] + +#proof[ + For any $n > 2$, consider $ + n! + 2, quad n! + 3, quad ..., quad n! + n #qedhere + $ +] + + += Others + +== Side-by-side + +#slide(composer: (1fr, 1fr))[ + First column. +][ + Second column. +] + + +== Multiple Pages + +#lorem(200) + + +#show: appendix + += Appendix + +== Appendix + +Please pay attention to the current slide number. +``` + +![image](https://github.com/user-attachments/assets/b1dfc4d9-e263-46ff-8588-a0635870e370) + + +## Acknowledgements + +Thanks to... + +- [@andreasKroepelin](https://github.com/andreasKroepelin) for the `polylux` package +- [@enklht](https://github.com/enklht) for many fixes and improvements +- [@Enivex](https://github.com/Enivex) for the `metropolis` theme +- [@drupol](https://github.com/drupol) for the `university` theme +- [@pride7](https://github.com/pride7) for the `aqua` theme +- [@Coekjan](https://github.com/Coekjan) and [@QuadnucYard](https://github.com/QuadnucYard) for the `stargazer` theme +- [@ntjess](https://github.com/ntjess) for contributing to `fit-to-height`, `fit-to-width` and `cover-with-rect` + +## Poster + +![poster](https://github.com/user-attachments/assets/e1ddb672-8e8f-472d-b364-b8caed1da16b) + + +[View Code](https://github.com/touying-typ/touying-poster) + +## Star History + + + + + + Star History Chart + + \ No newline at end of file diff --git a/packages/preview/touying/0.6.1/changelog.md b/packages/preview/touying/0.6.1/changelog.md new file mode 100644 index 000000000..3d4598b55 --- /dev/null +++ b/packages/preview/touying/0.6.1/changelog.md @@ -0,0 +1,316 @@ +# Changelog + +## v0.6.1 + +Added support for the [theorion](https://github.com/OrangeX4/typst-theorion) package, and used it as the default math theorem environment. + +## v0.6.0 + +It's not a big update, but it's the first touying release since typst 0.13 was released. + +### Features + +- feat: add auto style for display-current-heading. + - For users, you can use `show heading: set text(blue)` to change color for heading in some themes like `dewdrop`. + - For theme creator, you can use syntax like `utils.display-current-heading(level: 1, style: auto)` to achieve the same result. +- feat: apply config-info information to `set document`. +- feat: set `stretch: false` by default for `alternatives` functions. This is **a minor breaking change**, but I think it would be more intuitive: no auto empty space. + +### Fixes + +- fix: fix error with uncover using semi-transparent-cover +- fix: fix type string comparison https://github.com/touying-typ/touying/pull/153 +- fix: fix horizontal-line bug in typst 0.13.0 +- refactor: fix display-current-short-heading + + +## v0.5.4 & v0.5.5 + +### Features + +- docs: improve param documentation and we have better hints for tinymist https://github.com/touying-typ/touying/pull/98 +- feat: fake frozon states support for `heading` https://github.com/touying-typ/touying/pull/124 +- feat: add alpha-changing-cover and color-changing-cover https://github.com/touying-typ/touying/pull/129 +- feat: add effect function https://github.com/touying-typ/touying/issues/111 + - Example: `#effect(text.with(fill: red), "2-")[Something]` will display `[Something]` if the current slide is 2 or later. +- feat: add argument `config: (..)` for `xxx-slide` functions +- feat: add `align` argument for university theme + +### Fixes + +- fix: also hide enum numbers with show-hide-set-list-marker-none https://github.com/touying-typ/touying/pull/114 +- fix: fixed progress bar not to break apart when global figure gutter is set nonzero https://github.com/touying-typ/touying/pull/120 +- fix: fixed frozen-counters bug with multiple #pause commands https://github.com/touying-typ/touying/pull/124 +- fix: fixed incorrect page num when draft is true https://github.com/touying-typ/touying/pull/125 +- fix: fix behaviors of fit-to-height and fit-to-width partially https://github.com/touying-typ/touying/pull/131 +- fix: duplicated footnotes in headings https://github.com/touying-typ/touying/pull/132 +- fix: do not hardcode page sizes https://github.com/touying-typ/touying/pull/134 +- fix: add default numbering for page https://github.com/touying-typ/touying/issues/100 +- refactor: move show-strong-with-alert to per-slide level https://github.com/touying-typ/touying/issues/123 +- refactor: remove unnecessary `config-page(fill: ...)` +- theme(metropolis): fix color of title page and fix https://github.com/touying-typ/touying/issues/103 +- theme(metropolis): fixed metropolis slide's header to return content if title is specified https://github.com/touying-typ/touying/pull/126 +- theme(metropolis): respect colors dict in metropolis theme https://github.com/touying-typ/touying/pull/133 +- fix: fix bug of `#effect` function + +Thanks for the contributions from [@enklht](https://github.com/enklht). + + +## v0.5.3 + +### Features + +- feat: add `stretch` parameter for `#alternatives[]` function class. This allows us to handle cases where the internal element is a context expression. +- feat: add `config-common(align-enum-marker-with-baseline: true)` for aligning the enum marker with the baseline. +- feat: add `linebreaks` option to `components.mini-slides`. https://github.com/touying-typ/touying/pull/96 +- feat: add `` label to skip a new-section-slide. +- feat: add `config-common(show-hide-set-list-marker-none: true)` to make the markers of `list` and `enum` invisible after `#pause`. +- feat: add `config-common(bibliography-as-footnote: bibliography(title: none, "ref.bib"))` to display the bibliography in footnotes. +- refactor: add `config-common(show-strong-with-alert: true)` configuration to display strong text with an alert. (small breaking change for some themes) +- refactor: refactor `display-current-heading` for preserving heading style in title and subtitle. https://github.com/touying-typ/touying/issues/71 +- refactor: make `new-section-slide-fn` function class can receive `body` parameter. We can use `receive-body-for-new-section-slide-fn` to control it. **(Breaking change)** + - For example, you can add `#speaker-note[]` for a new section slide, like `= Section Title \ #speaker-note[]`. + - If you don't want to append content to the body of the new section slide, you can use `---` after the section title. + +### Fixes + +- fix outdated documentation. +- fix bug of `enable-frozen-states-and-counters` in handout mode. +- fix unusable `square()` function. https://github.com/touying-typ/touying/issues/73 +- fix hidden footer for `show-notes-on-second-screen: bottom`. https://github.com/touying-typ/touying/issues/89 +- fix metadata element in table cells. https://github.com/touying-typ/touying/issues/77 https://github.com/touying-typ/touying/issues/95 +- fix `auto-offset-for-heading` to `false` by default. +- fix uncover/only hides more content than it should. https://github.com/touying-typ/touying/issues/85 +- theme(simple): fix wrong title and subtitle. https://github.com/touying-typ/touying/issues/70 + + +## v0.5.1 & v0.5.2 + +- Fix somg bugs. + + +## v0.5.0 + +This is a significant disruptive version update. Touying has removed many mistakes that resulted from incorrect decisions. We have redesigned numerous features. The goal of this version is to make Touying more user-friendly, more flexible, and more powerful. + +**Major changes include:** + +- Avoiding closures and OOP syntax, which makes Touying's configuration simpler and allows for the use of document comments to provide more auto-completion information for the slide function. + - The existing `#let slide(self: none, ..args) = { .. }` is now `#let slide(..args) = touying-slide-wrapper(self => { .. })`, where `self` is automatically injected. + - We can use `config-xxx` syntax to configure Touying, for example, `#show: university-theme.with(aspect-ratio: "16-9", config-colors(primary: blue))`. +- The `touying-slide` function no longer includes parameters like `section`, `subsection`, and `title`. These will be automatically inserted into the slide as invisible level 1, 2, or 3 headings via `self.headings` (controlled by the `slide-level` configuration). + - We can leverage the powerful headings provided by Typst to support numbering, outlines, and bookmarks. + - Headings within the `#slide[= XXX]` function will be adjusted to level `slide-level + 1` using the `offset` parameter. + - We can use labels on headings to control many aspects, such as supporting the `` and other special labels, implementing short headings, or recalling a slide with `#touying-recall()`. +- Touying now supports the normal use of `set` and `show` rules at any position, without requiring them to be in specific locations. + +A simple usage example is shown below, and more examples can be found in the `examples` directory: + +```typst +#import "@preview/touying:0.5.0": * +#import themes.university: * + +#show: university-theme.with( + aspect-ratio: "16-9", + config-info( + title: [Title], + subtitle: [Subtitle], + author: [Authors], + date: datetime.today(), + institution: [Institution], + logo: emoji.school, + ), +) + +#set heading(numbering: "1.1") + +#title-slide() + += The Section + +== Slide Title + +#lorem(40) +``` + +**Theme Migration Guide:** + +For detailed changes to specific themes, you can refer to the `themes` directory. Generally, if you want to migrate an existing theme, you should: + +1. Rename the `register` function to `xxx-theme` and remove the `self` parameter. +2. Add a `show: touying-slides.with(..)` configuration. + - Change `self.methods.colors` to `config-colors(primary: rgb("#xxxxxx"))`. + - Change `self.page-args` to `config-page()`. + - Change `self.methods.slide = slide` to `config-methods(slide: slide)`. + - Change `self.methods.new-section-slide = new-section-slide` to `config-methods(new-section-slide: new-section-slide)`. + - Change private theme variables like `self.xxx-footer` to `config-store(footer: [..])`, which you can access through `self.store.footer`. + - Move the configuration of headers and footers into the `slide` function rather than in the `xxx-theme` function. + - You can directly use `set` or `show` rules in `xxx-theme` or configure them through `config-methods(init: (self: none, body) => { .. })` to fully utilize the `self` parameter. +3. For `states.current-section-with-numbering`, you can use `utils.display-current-heading(level: 1)` instead. + - If you only need the previous heading regardless of whether it is a section or a subsection, use `self => utils.display-current-heading(depth: self.slide-level)`. +4. The `alert` function can be replaced with `config-methods(alert: utils.alert-with-primary-color)`. +5. The `touying-outline()` function is no longer needed; you can use `components.adaptive-columns(outline())` instead. Consider using `components.progressive-outline()` or `components.custom-progressive-outline()`. +6. Replace `states.slide-counter.display() + " / " + states.last-slide-number` with `context utils.slide-counter.display() + " / " + utils.last-slide-number`. That is, we no longer use `states` but `utils`. +7. Remove the `slides` function; we no longer need this function. Instead of implicitly injecting `title-slide()`, explicitly use `#title-slide()`. If necessary, consider adding it in the `xxx-theme` function. +8. Change `#let slide(self: none, ..args) = { .. }` to `#let slide(..args) = touying-slide-wrapper(self => { .. })`, where `self` is automatically injected. + - Change specific parameter configurations to `self = utils.merge-dicts(self, config-page(fill: self.colors.neutral-lightest))`. + - Remove `self = utils.empty-page(self)` and use `config-common(freeze-slide-counter: true)` and `config-page(margin: 0em)` instead. + - Change `(self.methods.touying-slide)()` to `touying-slide()`. +9. You can insert visible headings into slides by configuring `config-common(subslide-preamble: self => text(1.2em, weight: "bold", utils.display-current-heading(depth: self.slide-level)))`. +10. Finally, don't forget to add document comments to your functions so your users can get better auto-completion hints, especially when using the Tinymist plugin. + +**Other Changes:** + +- theme(stargazer): new stargazer theme modified from [Coekjan/touying-buaa](https://github.com/Coekjan/touying-buaa). +- feat: implemented fake frozen states support, allowing you to use numbering and `#pause` normally. This behavior can be controlled with `enable-frozen-states-and-counters`, `frozen-states`, and `frozen-counters` in `config-common()`. +- feat: implemented `label-only-on-last-subslide` functionality to prevent non-unique label warnings when working with `@equation` and `@figure` in conjunction with `#pause` animations. +- feat: added the `touying-recall(