From 7ac46b2c93dcfc30e51f51f7362c6452b779b3c1 Mon Sep 17 00:00:00 2001 From: dhayer Date: Thu, 5 Mar 2026 11:37:39 -0600 Subject: [PATCH] homework-template:0.1.0 --- .../preview/homework-template/0.1.0/LICENSE | 21 ++ .../preview/homework-template/0.1.0/README.md | 47 +++++ .../homework-template/0.1.0/example.typ | 151 ++++++++++++++ .../preview/homework-template/0.1.0/lib.typ | 192 ++++++++++++++++++ .../homework-template/0.1.0/typst.toml | 11 + 5 files changed, 422 insertions(+) create mode 100644 packages/preview/homework-template/0.1.0/LICENSE create mode 100644 packages/preview/homework-template/0.1.0/README.md create mode 100644 packages/preview/homework-template/0.1.0/example.typ create mode 100644 packages/preview/homework-template/0.1.0/lib.typ create mode 100644 packages/preview/homework-template/0.1.0/typst.toml diff --git a/packages/preview/homework-template/0.1.0/LICENSE b/packages/preview/homework-template/0.1.0/LICENSE new file mode 100644 index 0000000000..009c3c5c23 --- /dev/null +++ b/packages/preview/homework-template/0.1.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 dhayer200 + +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/homework-template/0.1.0/README.md b/packages/preview/homework-template/0.1.0/README.md new file mode 100644 index 0000000000..27aa6ce0a9 --- /dev/null +++ b/packages/preview/homework-template/0.1.0/README.md @@ -0,0 +1,47 @@ +# homework-template + +A minimal Typst package for math homework with styled boxes for questions, parts, answers, proofs, definitions, and theorems. + +## Usage + +```typst +#import "@preview/homework-template:0.1.0": * + +#header( + name: "Your Name", + course: "Math 110 — Linear Algebra", + hw: "3", + date: "March 4, 2026", + professor: "Prof. Smith", // optional +) + +#qs(title: [Prove that the additive identity is unique.])[ + #pt(title: [Uniqueness of zero])[ + #prf[ + Suppose $0$ and $0'$ are both identities. Then $0 = 0 + 0' = 0'$. + ] + ] +] +``` + +See [`example.typ`](example.typ) for a full working document. + +## Functions + +| Function | Description | +|----------|-------------| +| `header(name, course, hw, date, professor?, topic?)` | Page header with rule | +| `qs(title?)[ ]` | Numbered question box | +| `pt(title?)[ ]` | Lettered part (a., b., …); nests to i., ii., … | +| `ans[ ]` | Answer/solution block | +| `prf[ ]` | Proof block with flush-right QED mark | +| `defn(title?)[ ]` | Definition box | +| `thm(title?)[ ]` | Theorem box | +| `eg(title?)[ ]` | Example box | +| `notn(title?)[ ]` | Notation box | +| `note[ ]` | Left-ruled remark | +| `vc(sym)` | Vector arrow shorthand: `vc(v)` → $\vec{v}$ | + +## License + +MIT diff --git a/packages/preview/homework-template/0.1.0/example.typ b/packages/preview/homework-template/0.1.0/example.typ new file mode 100644 index 0000000000..b11fc3d31b --- /dev/null +++ b/packages/preview/homework-template/0.1.0/example.typ @@ -0,0 +1,151 @@ +#import "@local/homework-template:0.1.0": * + +#header( + name: "Deep Hayer", + course: "Math 110 — Linear Algebra", + hw: "3", + date: "March 4, 2026", + professor: "Prof. Sheldon Axler", +) + +// ───────────────────────────────────────────────────────────────────────────── +// Background definitions the homework builds on +// ───────────────────────────────────────────────────────────────────────────── + +#defn(title: [vector space])[ + A _vector space_ over $FF$ is a set $V$ together with addition and scalar + multiplication satisfying commutativity, associativity, additive identity, + additive inverses, multiplicative identity, and distributive properties. +] + +#notn(title: [$FF^n$])[ + $FF^n$ denotes the set of all lists of length $n$ with entries in $FF$ + (either $RR$ or $CC$). +] + +// ───────────────────────────────────────────────────────────────────────────── +// Questions +// ───────────────────────────────────────────────────────────────────────────── + +#qs(title: [Let $V$ be a vector space over $FF$. Prove each of the following.])[ + #pt(title: [The additive identity $0 in V$ is unique.])[ + #prf[ + Suppose $0$ and $0'$ are both additive identities in $V$. Then + $ 0 = 0 + 0' = 0', $ + where the first equality uses the fact that $0'$ is an identity and + the second uses the fact that $0$ is an identity. Hence $0 = 0'$. + ] + ] + + #pt(title: [Every element of $V$ has a unique additive inverse.])[ + #prf[ + Let $v in V$ and suppose $w, w'$ are both additive inverses of $v$. Then + $ w = w + 0 = w + (v + w') = (w + v) + w' = 0 + w' = w'. $ + Hence the additive inverse is unique. + ] + ] + + #pt(title: [$0 v = 0$ for every $v in V$, where the left $0$ is the scalar and the right $0$ is the zero vector.])[ + #prf[ + For any $v in V$, + $ 0 v = (0 + 0) v = 0 v + 0 v. $ + Adding $-(0 v)$ to both sides gives $0 = 0 v$. + ] + ] +] +#v(10em) +#qs(title: [Let $U = {(x_1, x_2, x_3, x_4) in FF^4 : x_1 + 2 x_2 = 0 "and" x_3 = 5 x_4}$.])[ + #pt(title: [Show that $U$ is a subspace of $FF^4$.])[ + #ans[ + We verify the three subspace conditions. + + #pt(title: [Additive identity])[ + $(0,0,0,0)$ satisfies $0 + 2(0) = 0$ and $0 = 5(0)$, so $0 in U$. + ] + + #pt(title: [Closed under addition])[ + Let $(x_1,x_2,x_3,x_4),(y_1,y_2,y_3,y_4) in U$. Then + $ (x_1+y_1) + 2(x_2+y_2) = (x_1+2x_2) + (y_1+2y_2) = 0+0 = 0, $ + and $x_3+y_3 = 5x_4+5y_4 = 5(x_4+y_4)$. So the sum is in $U$. + ] + + #pt(title: [Closed under scalar multiplication])[ + Let $lambda in FF$ and $(x_1,x_2,x_3,x_4) in U$. Then + $ lambda x_1 + 2(lambda x_2) = lambda(x_1 + 2x_2) = 0, $ + and $lambda x_3 = lambda(5 x_4) = 5(lambda x_4)$. So $lambda (x_1,dots,x_4) in U$. + ] + + Hence $U$ is a subspace of $FF^4$. + ] + ] + + #pt(title: [Find a basis for $U$ and state $dim U$.])[ + #ans[ + The constraints $x_1 = -2x_2$ and $x_3 = 5x_4$ leave $x_2$ and $x_4$ + as free variables. Setting $(x_2, x_4) = (1,0)$ and $(0,1)$ gives + $ + e_1 = (-2, 1, 0, 0), quad e_2 = (0, 0, 5, 1). + $ + These two vectors span $U$ and are linearly independent, so + ${e_1, e_2}$ is a basis and $dim U = 2$. + ] + ] +] +#v(17em) +#qs(title: [Suppose $T : V -> W$ is a linear map. Using the theorem below, answer the following.])[ + #thm(title: [fundamental theorem of linear maps])[ + $ dim V = dim "null" T + dim "range" T. $ + ] + + #pt(title: [If $dim V = 7$ and $dim W = 3$, what are the possible values of $dim "null" T$?])[ + #ans[ + Since $dim "range" T <= dim W = 3$, we have $dim "range" T in {0,1,2,3}$. + By the fundamental theorem, + $ dim "null" T = 7 - dim "range" T in {4, 5, 6, 7}. $ + ] + ] + + #pt(title: [Can $T$ be injective if $dim V > dim W$?])[ + #ans[ + No. If $T$ is injective then $dim "null" T = 0$, so $dim "range" T = dim V > dim W$, + contradicting $dim "range" T <= dim W$. + ] + ] +] +#qs(title: [Let $v_1, dots, v_m in V$ and define the linear map $T : FF^m -> V$ by $T(c_1, dots, c_m) = c_1 v_1 + dots.c + c_m v_m$.])[ + #eg(title: [span as range])[ + The range of $T$ is exactly $"span"(v_1, dots, v_m)$. For instance, if + $v_1 = (1,0)$ and $v_2 = (0,1)$ in $FF^2$, then $T : FF^2 -> FF^2$ is + the identity and $"range" T = FF^2$. + ] + + #pt(title: [Show that $v_1, dots, v_m$ spans $V$ if and only if $T$ is surjective.])[ + #ans[ + $T$ is surjective $<==>$ $"range" T = V$ $<==>$ every $v in V$ is a linear + combination of $v_1, dots, v_m$ $<==>$ $"span"(v_1, dots, v_m) = V$. + ] + ] + + #pt(title: [Show that $v_1, dots, v_m$ is linearly independent if and only if $T$ is injective.])[ + #ans[ + $T$ is injective $<==>$ $"null" T = {0}$ $<==>$ the only solution to + $c_1 v_1 + dots.c + c_m v_m = 0$ is $c_1 = dots.c = c_m = 0$ + $<==>$ $v_1, dots, v_m$ is linearly independent. + ] + ] +] + +#qs(title: [Let $vc(u) = (1, 2, -1)$ and $vc(v) = (3, 0, 2)$ in $RR^3$. Compute $vc(u) + 2 vc(v)$ and verify it lies in $"span"{vc(u), vc(v)}$.])[ + #note[ + The notation $vc(w)$ denotes a vector $w$ with an arrow, used here to + distinguish vectors from scalars. + ] + + #ans[ + $ + vc(u) + 2 vc(v) = (1,2,-1) + (6,0,4) = (7, 2, 3). + $ + Since $(7,2,3) = 1 dot vc(u) + 2 dot vc(v)$, it is a linear combination + of $vc(u)$ and $vc(v)$, so it lies in $"span"{vc(u), vc(v)}$. + ] +] diff --git a/packages/preview/homework-template/0.1.0/lib.typ b/packages/preview/homework-template/0.1.0/lib.typ new file mode 100644 index 0000000000..454a1ae1a9 --- /dev/null +++ b/packages/preview/homework-template/0.1.0/lib.typ @@ -0,0 +1,192 @@ +// ---------- homework-template.typ ---------- + +// ── Axler accent colour ────────────────────────────────────────────────────── +#let _accent = rgb("#2E5FA3") // blue used in LADR covers + +// ── Box colours (matched to LADR 4th ed.) ──────────────────────────────────── +#let _defn-fill = rgb("#FFFDE8") +#let _defn-stroke = rgb("#CFC040") +#let _thm-fill = rgb("#EBF0FA") +#let _thm-stroke = rgb("#8BAAD4") +#let _prf-fill = rgb("#F2FAF4") +#let _prf-stroke = rgb("#6A9E7A") +#let _ans-fill = rgb("#F5F0FF") +#let _ans-stroke = rgb("#9070C8") + +// ── Counters / depth state ─────────────────────────────────────────────────── +#let _q = counter("homework-template.q") +#let _p = counter("homework-template.p") +#let _sp = counter("homework-template.sp") +#let _pt_depth = state("homework-template.pt-depth", 0) +#let _ans_depth = state("homework-template.ans-depth", 0) + +// ── Global text & page ─────────────────────────────────────────────────────── +#set text( + font: "New Computer Modern", + size: 10.5pt, + fallback: false, +) + +#set page( + numbering: "1", + margin: (top: 1.25in, bottom: 1.25in, left: 1.25in, right: 1.25in), +) + +// ── Paragraph spacing (Axler uses generous leading) ────────────────────────── +#set par(leading: 0.75em, spacing: 1.2em) + +// ── Math ───────────────────────────────────────────────────────────────────── +// Change numbering to "(1)" if you want all display equations numbered. +#set math.equation(numbering: none, supplement: [Equation]) + +// ── Show rules ─────────────────────────────────────────────────────────────── +#show link: it => text(fill: _accent, it) + +// Tighten vertical space around display equations +#show math.equation.where(block: true): it => { + v(0.3em, weak: true) + it + v(0.3em, weak: true) +} + +// ── Vector shorthand ───────────────────────────────────────────────────────── +#let vc(sym) = $arrow(#sym)$ + +// ── QED mark (filled blue square, Axler style) ──────────────────────────────── +#let _qed = text(fill: _accent)[■] + +// ── Axler-style content boxes ───────────────────────────────────────────────── + +#let _axler-box(label, fill-col, stroke-col, title, body) = block( + width: 100%, + inset: (x: 1em, top: 0.55em, bottom: 0.8em), + radius: 3pt, + fill: fill-col, + stroke: 0.6pt + stroke-col, + spacing: 1em, +)[ + #text(fill: _accent)[#label]#if title != none [: #emph(title)] \ + #body +] + +// ── Header ─────────────────────────────────────────────────────────────────── +#let header( + name, // required — pass a string or none + course, // required — pass a string or none + hw, // required — pass a string or none + date, // required — pass a string or none + professor: none, + topic: none, + related: none, + material: none +) = [ + #grid( + columns: (1fr, 1fr), + column-gutter: 1em, + align: (left, right), + [ + #if name != none { [#name] } \ + #if course != none { [#course] } \ + #if hw != none { [Homework #hw] } \ + ], + [ + #if date != none { [#date] } \ + #if professor != none { [#professor] } \ + ], + ) + #line(length: 100%, stroke: 0.5pt + luma(160)) + #v(0.6em) +] + +// ── Question — #qs(title: [question text])[body] ───────────────────────────── +#let qs(title: none, body) = { + _q.step() + _p.update(0) + _sp.update(0) + context { + let n = _q.get().at(0) + _axler-box(str(n) + ".", white, luma(190), title, body) + } +} + +// ── Part — #pt(title: [part text])[body] ───────────────────────────────────── +#let pt(title: none, body) = { + _pt_depth.update(d => d + 1) + context if _pt_depth.get() == 1 { + // top-level: a., b., c., … + _p.step() + _sp.update(0) + context { + let n = _p.get().at(0) + let label = ("a","b","c","d","e","f","g","h").at(n - 1) + "." + let in-ans = _ans_depth.get() > 0 + let fill-col = if in-ans { _ans-fill } else { white } + let stroke-col = if in-ans { _ans-stroke } else { luma(210) } + _axler-box(label, fill-col, stroke-col, title, body) + } + } else { + // sub-part: i., ii., iii., … + _sp.step() + context { + let n = _sp.get().at(0) + let label = ("i","ii","iii","iv","v","vi","vii","viii").at(n - 1) + "." + let in-ans = _ans_depth.get() > 0 + let fill-col = if in-ans { _ans-fill } else { white } + let stroke-col = if in-ans { _ans-stroke } else { luma(225) } + _axler-box(label, fill-col, stroke-col, title, body) + } + } + _pt_depth.update(d => d - 1) +} + +// ── Answer box — #ans[...] block for answers/solutions ─────────────────────── +#let ans(body) = { + _ans_depth.update(d => d + 1) + block( + width: 100%, + inset: (x: 1em, top: 0.55em, bottom: 0.8em), + radius: 3pt, + fill: _ans-fill, + stroke: 0.6pt + _ans-stroke, + spacing: 1em, + )[#body] + _ans_depth.update(d => d - 1) +} + +// ── Proof block (green box, flush-right QED) ────────────────────────────────── +#let prf(body) = block( + width: 100%, + inset: (x: 1em, top: 0.55em, bottom: 0.8em), + radius: 3pt, + fill: _prf-fill, + stroke: 0.6pt + _prf-stroke, + spacing: 1em, +)[ + #text(fill: _accent)[_Proof._] #body #h(1fr) #_qed +] + +// Definition box — yellow, #defn(title: [...])[...] +#let defn(title: none, body) = _axler-box( + "Definition", _defn-fill, _defn-stroke, title, body, +) + +// Theorem / result box — blue, #thm(title: [...])[...] +#let thm(title: none, body) = _axler-box( + "Theorem", _thm-fill, _thm-stroke, title, body, +) + +// Example box — white, #eg(title: [...])[...] +#let eg(title: none, body) = _axler-box( + "Example", white, luma(190), title, body, +) + +// Notation box — yellow (same as defn), #notn(title: [...])[...] +#let notn(title: none, body) = _axler-box( + "Notation", _defn-fill, _defn-stroke, title, body, +) + +// ── Remark / note (left-accent rule, Axler margin-note style) ───────────────── +#let note(body) = block( + inset: (left: 1em, top: 0.4em, bottom: 0.4em), + stroke: (left: 2pt + _accent), +)[_Remark._ #body] diff --git a/packages/preview/homework-template/0.1.0/typst.toml b/packages/preview/homework-template/0.1.0/typst.toml new file mode 100644 index 0000000000..a3385e814e --- /dev/null +++ b/packages/preview/homework-template/0.1.0/typst.toml @@ -0,0 +1,11 @@ +[package] +name = "homework-template" +version = "0.1.0" +entrypoint = "lib.typ" +description = "Minimal homework template with question, part, answer, proof, definition, and theorem boxes for math assignments." +authors = ["Deep Hayer"] +license = "MIT" +keywords = ["homework", "math", "template", "axler"] +categories = ["paper"] +repository = "https://github.com/YOUR_USERNAME/homework-template" +compiler = "0.11.0"