diff --git a/packages/preview/texst/0.1.0/CHANGELOG.md b/packages/preview/texst/0.1.0/CHANGELOG.md new file mode 100644 index 0000000000..950ffeb901 --- /dev/null +++ b/packages/preview/texst/0.1.0/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## 0.1.0 - 2026-02-11 + +- Initial public release. +- Added `paper(...)` document wrapper with a LaTeX-like layout. +- Added theorem/proof environments via `ctheorems`. +- Added caption and equation helper utilities. +- Added package template and minimal example. diff --git a/packages/preview/texst/0.1.0/LICENSE b/packages/preview/texst/0.1.0/LICENSE new file mode 100644 index 0000000000..0256c5aed7 --- /dev/null +++ b/packages/preview/texst/0.1.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Shusuke Ioku + +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/texst/0.1.0/README.md b/packages/preview/texst/0.1.0/README.md new file mode 100644 index 0000000000..088b419e7a --- /dev/null +++ b/packages/preview/texst/0.1.0/README.md @@ -0,0 +1,106 @@ +# texst + +`texst` is a Typst package for LaTeX-like academic paper formatting. + +## Start Here + +Use one of these two paths: + +1. Published package (Typst Universe): + +```typst +#import "@preview/texst:0.1.0": paper +``` + +2. Local repository checkout (before/without publication): + +```typst +#import "./src/lib.typ": paper +``` + +## Fastest Way to Use It + +Copy this into your `main.typ`: + +```typst +#import "@preview/texst:0.1.0": paper + +#show: doc => paper( + title: [Paper Title], + subtitle: [Optional Subtitle], + authors: ( + (name: [Author One]), + (name: [Author Two]), + ), + date: datetime.today().display("[month repr:long] [day], [year]"), + abstract: [Write a concise abstract here.], + doc, +) + +#heading(level: 1, outlined: false)[Introduction] + +Start writing your paper. +``` + +## Initialize a Template Project + +```bash +typst init @preview/texst:0.1.0 +``` + +This generates a starter project from `template/main.typ`. + +## What `paper(...)` Does + +`paper(...)` applies: +- page layout and numbering +- typography defaults +- heading style and spacing +- table/figure alignment and numbering +- equation and reference behavior +- title block and abstract formatting + +Your document content is passed through `doc`. + +## Public API + +- `paper(title:, subtitle:, authors:, date:, abstract:, style:, doc)` +- `nneq(eq)` (unnumbered display equation) +- `caption_note(body)` +- `caption_with_note(title, note)` +- `table_note(body)` +- `theorem`, `proof`, `prop`, `lem`, `rem`, `asp` + +## Style Overrides + +Pass a `style` dictionary to override defaults: + +```typst +#show: doc => paper( + title: [Styled Paper], + style: ( + body_font: "Libertinus Serif", + page_margin: (x: 1in, y: 1in), + heading_numbering: "1.", + accent_main: rgb(20, 40, 120), + ), + doc, +) +``` + +Common keys include: +- `page_margin`, `page_numbering` +- `body_font`, `body_size` +- `paragraph_leading`, `paragraph_indent` +- `heading_numbering`, `heading_size`, `heading_weight` +- `footnote_numbering`, `accent_main` + +## Local Development + +- `examples/minimal.typ` is the local smoke test. +- `template/main.typ` is the package template entrypoint. +- Compile locally: + +```bash +typst compile --root . examples/minimal.typ /tmp/minimal.pdf +``` diff --git a/packages/preview/texst/0.1.0/aesthetics.typ b/packages/preview/texst/0.1.0/aesthetics.typ new file mode 100644 index 0000000000..2ebb2cea1d --- /dev/null +++ b/packages/preview/texst/0.1.0/aesthetics.typ @@ -0,0 +1 @@ +#import "./src/lib.typ": * diff --git a/packages/preview/texst/0.1.0/examples/minimal.typ b/packages/preview/texst/0.1.0/examples/minimal.typ new file mode 100644 index 0000000000..74a02f1c1f --- /dev/null +++ b/packages/preview/texst/0.1.0/examples/minimal.typ @@ -0,0 +1,32 @@ +#import "../src/lib.typ": paper, theorem, proof, nneq + +#show: doc => paper( + title: [A Minimal Academic Paper], + subtitle: [Demonstration of the texst Package], + authors: ( + (name: [First Author]), + (name: [Second Author]), + ), + date: datetime.today().display("[month repr:long] [day], [year]"), + abstract: [ + This is a minimal, generic example that demonstrates the package layout and + theorem environments. + ], + doc, +) + +#heading(level: 1, outlined: false)[Introduction] + +This sample keeps content intentionally generic. + +#heading(level: 1, outlined: false)[A Theorem] + +#theorem[ +For any real numbers $a$ and $b$, if $a = b$, then $a + 1 = b + 1$. +] + +#proof[ +Add 1 to both sides. +] + +#nneq($x^2 + y^2 = z^2$) diff --git a/packages/preview/texst/0.1.0/paper.typ b/packages/preview/texst/0.1.0/paper.typ new file mode 100644 index 0000000000..b02c658083 --- /dev/null +++ b/packages/preview/texst/0.1.0/paper.typ @@ -0,0 +1,49 @@ +#import "./src/lib.typ": paper, theorem, proof, caption_with_note, nneq + +#show: doc => paper( + title: [A Generic Research Paper], + subtitle: [A LaTeX-Like Typst Template Demo], + authors: ( + (name: [First Author]), + (name: [Second Author]), + ), + date: datetime.today().display("[month repr:long] [day], [year]"), + abstract: [ + This document demonstrates the texst package with neutral placeholder content. + It is intentionally free of project-specific or personal information. + ], + doc, +) + +#heading(level: 1, outlined: false)[Introduction] + +This sample illustrates how to structure an academic manuscript. + +#heading(level: 2, outlined: false)[Equation Example] + +#nneq($ +f(x) = alpha + beta x + epsilon +$) + +#heading(level: 2, outlined: false)[Theorem Example] + +#theorem[ +If two quantities are equal, adding the same constant to each preserves equality. +] + +#proof[ +Suppose $a=b$. For any constant $c$, adding $c$ to both sides gives $a+c=b+c$. +] + +#figure( + table( + columns: 3, + [Variable], [Estimate], [Std. Error], + [Intercept], [0.42], [0.11], + [Treatment], [0.18], [0.07], + ), + caption: caption_with_note( + [Illustrative Regression Output], + [Values are placeholders for demonstration only.], + ), +) diff --git a/packages/preview/texst/0.1.0/src/lib.typ b/packages/preview/texst/0.1.0/src/lib.typ new file mode 100644 index 0000000000..1eaec3ef1b --- /dev/null +++ b/packages/preview/texst/0.1.0/src/lib.typ @@ -0,0 +1,194 @@ +#import "@preview/ctheorems:1.1.3": * + +#let default_style = ( + page_margin: (x: 1.2in, y: 1.2in), + page_numbering: "1", + body_font: "New Computer Modern", + body_size: 11pt, + body_top_edge: 0.7em, + body_bottom_edge: -0.3em, + paragraph_leading: 1em, + paragraph_indent: 1.8em, + heading_numbering: "1.", + heading_size: 1em, + heading_weight: "bold", + heading_level1_size: 0.9em, + table_text_size: 0.8em, + table_leading: 0.65em, + table_top_edge: 0.35em, + table_bottom_edge: -0.3em, + block_above: 1.5em, + block_below: 1.5em, + footnote_numbering: "[1]", + accent_main: rgb(0, 0, 100), +) + +#let nneq(eq) = math.equation(block: true, numbering: none, eq) + +#let caption_note(body) = align(left)[ + #pad(x: 2em, y: 0em)[ + #par(leading: 0.2em)[ + #text(size: 0.9em)[*Note:* #body] + ] + ] +] + +#let caption_with_note(title, note) = [#title #caption_note(note)] + +#let table_note(body) = align(left)[ + #text(size: 0.9em)[#emph(body)] +] + +#show: thmrules.with(qed-symbol: $square$) +#let theorem = thmbox("theorem", "Theorem") +#let proof = thmproof("proof", "Proof") +#let prop = thmbox( + "prop", + "Proposition", + inset: (x: 2em, y: .5em), + base_level: 0, + base: "prop", + titlefmt: smallcaps, + bodyfmt: body => [#body], +).with(numbering: "1") + +#let lem = thmbox( + "lem", + "Lemma", + inset: (x: 2em, y: .5em), + base_level: 0, + base: "lem", + titlefmt: smallcaps, + bodyfmt: body => [#body], +).with(numbering: "1") + +#let rem = thmbox( + "rem", + "Remark", + inset: (x: 2em, y: .5em), + base_level: 0, + base: "rem", + titlefmt: smallcaps, + bodyfmt: body => [#body], +).with(numbering: "1") + +#let asp = thmbox( + "asp", + "Assumption", + inset: (x: 2em, y: .5em), + base_level: 0, + base: "asp", + titlefmt: smallcaps, + bodyfmt: body => [#body], +).with(numbering: "1") + +#let paper( + title: none, + subtitle: none, + authors: (), + date: none, + abstract: none, + style: none, + doc, +) = { + let s = if style == none { + default_style + } else { + default_style + style + } + + set page(margin: s.page_margin, numbering: s.page_numbering) + set par( + leading: s.paragraph_leading, + first-line-indent: s.paragraph_indent, + justify: true, + ) + set text( + font: s.body_font, + size: s.body_size, + top-edge: s.body_top_edge, + bottom-edge: s.body_bottom_edge, + ) + + set math.equation(numbering: "(1)") + set table(align: (x, _) => if x == 0 { left } else { center }) + set figure(numbering: "1", placement: auto) + + show ref: it => { + let eq = math.equation + let el = it.element + if el != none and el.func() == eq { + numbering(el.numbering, ..counter(eq).at(el.location())) + } else { + it + } + } + + set quote(block: true) + + set heading(numbering: s.heading_numbering) + show heading: set block(above: 2em, below: 1em) + show heading: set par(leading: 0.3em) + show heading: set text(size: s.heading_size, weight: s.heading_weight) + show heading: it => { + if it.level == 1 { + smallcaps(align(center, text(size: s.heading_level1_size, it))) + } else { + it + } + } + + set enum(indent: 1.8em) + show enum: set block(above: 1em, below: 1em) + + show table: set text(size: s.table_text_size) + show table: set par(leading: s.table_leading) + show table: set text(top-edge: s.table_top_edge, bottom-edge: s.table_bottom_edge) + show figure: set block(below: 0em) + set block(above: s.block_above, below: s.block_below) + show figure: set align(center) + show table: set align(center) + show figure.where(kind: table): set align(center) + show figure.where(body: it => if it.func() == table { true } else { false }): set align(center) + + show link: set text(s.accent_main) + show ref: set text(s.accent_main) + show cite: set text(s.accent_main) + show footnote: set text(s.accent_main) + show footnote: set text(weight: "bold") + set footnote(numbering: s.footnote_numbering) + + v(4em) + set align(center) + par(leading: .5em)[ + #text(1.2em)[#title]\\ + #if subtitle != none { text(1em)[#subtitle] } + ] + + let count = authors.len() + if count > 0 { + let ncols = calc.min(count, 3) + grid( + columns: (1fr,) * ncols, + row-gutter: 24pt, + ..authors.map(author => [#text(author.name)]), + ) + } + + if date != none { + text(date) + } + + set align(left) + if abstract != none { + pad( + x: 3em, + par( + leading: 0.4em, + text(0.9em, [#smallcaps("Abstract.") #abstract]), + ), + ) + } + + doc +} diff --git a/packages/preview/texst/0.1.0/template/main.typ b/packages/preview/texst/0.1.0/template/main.typ new file mode 100644 index 0000000000..2085b4feef --- /dev/null +++ b/packages/preview/texst/0.1.0/template/main.typ @@ -0,0 +1,29 @@ +#import "@preview/texst:0.1.0": paper, theorem, proof + +#show: doc => paper( + title: [Paper Title], + subtitle: [Optional Subtitle], + authors: ( + (name: [Author One]), + (name: [Author Two]), + ), + date: datetime.today().display("[month repr:long] [day], [year]"), + abstract: [ + Write a concise abstract summarizing your research question, method, and findings. + ], + doc, +) + +#heading(level: 1, outlined: false)[Introduction] + +Start your paper here. + +#heading(level: 1, outlined: false)[Main Result] + +#theorem[ +State your main theorem or proposition. +] + +#proof[ +Add your proof or argument. +] diff --git a/packages/preview/texst/0.1.0/typst.toml b/packages/preview/texst/0.1.0/typst.toml new file mode 100644 index 0000000000..54445b63fa --- /dev/null +++ b/packages/preview/texst/0.1.0/typst.toml @@ -0,0 +1,15 @@ +[package] +name = "texst" +version = "0.1.0" +entrypoint = "src/lib.typ" +authors = ["Shusuke Ioku"] +license = "MIT" +description = "LaTeX-like academic paper styling and theorem helpers for Typst." +repository = "https://github.com/shusuke-ioku/texst" +homepage = "https://github.com/shusuke-ioku/texst" +keywords = ["academic", "paper", "latex", "theorem"] +categories = ["model", "layout"] + +[template] +path = "template" +entrypoint = "main.typ"