/// Typst handout library, used for all documents in this repository. /// If false, hide instructor info. /// /// Compile with the following command to hide solutions: /// `typst compile main.typ --input show_solutions=false` /// /// Solutions are shown by default. This behavior /// is less surprising than hiding content by default. #let show_solutions = { if "show_solutions" in sys.inputs { // Show solutions unless they're explicitly disabled not ( sys.inputs.show_solutions == "false" or sys.inputs.show_solutions == "no" ) } else { // Show solutions by default true } } // Colors #let ored = rgb("D62121") #let ogrape = rgb("9C36B5") #let ocyan = rgb("2288BF") #let oteal = rgb("12B886") #let ogreen = rgb("37B26D") #let oblue = rgb("1C7ED6") // // MARK: header // #let make_title( group, quarter, title, subtitle, ) = { align( center, block( width: 60%, height: auto, breakable: false, align( center, stack( spacing: 7pt, ( text(size: 10pt, group) + h(1fr) + text(size: 10pt, quarter) ), line(length: 100%, stroke: 0.2mm), ( text(size: 20pt, title) + linebreak() + text(size: 10pt, subtitle) ), line(length: 100%, stroke: 0.2mm), ), ), ), ) } #let warn = { set text(ored) align( center, block( width: 60%, height: auto, breakable: false, fill: rgb(255, 255, 255), stroke: ored + 2pt, inset: 3mm, ( align(center, text(weight: "bold", size: 12pt, [Instructor's Handout])) + parbreak() + align( left, text( size: 10pt, [This handout contains solutions and notes.] + linebreak() + [Recompile without solutions before distributing.], ), ) ), ), ) } #let preparedby(name) = ( text( size: 10pt, [Prepared by ] + name + [ on ] + datetime .today() .display("[month repr:long] [day padding:none], [year]"), ) ) // // MARK: Solutions // #let solution(content) = { if show_solutions { align( center, stack( block( width: 100%, breakable: false, fill: ored, stroke: ored + 2pt, inset: 1.5mm, ( align(left, text(fill: white, weight: "bold", [Solution:])) ), ), block( width: 100%, height: auto, breakable: false, fill: ored.lighten(80%).desaturate(10%), stroke: ored + 2pt, inset: 3mm, align(left, content), ), ), ) } } #let notsolution(content) = { if not show_solutions { content } } // // MARK: Sections // #let generic(t) = block( above: 8mm, below: 2mm, text(weight: "bold", t), ) #let _generic_base(kind, ..args) = { counter("obj").step() if args.pos().len() == 0 { generic([ #kind #context counter("obj").display(): ]) } else { generic( [ #kind #context counter("obj").display(): ] + " " + args.pos().at(0), ) } } #let problem(..args) = _generic_base("Problem", ..args) #let definition(..args) = _generic_base("Definition", ..args) #let theorem(..args) = _generic_base("Theorem", ..args) // // MARK: Misc // #let hint(content) = { text(fill: rgb(100, 100, 100), style: "oblique", "Hint: ") text(fill: rgb(100, 100, 100), content) } #let note(content) = { text(fill: rgb(100, 100, 100), content) } #let examplesolution(content) = { let c = oblue align( center, stack( block( width: 100%, breakable: false, fill: c, stroke: c + 2pt, inset: 1.5mm, ( align(left, text(fill: white, weight: "bold", [Example solution:])) ), ), block( width: 100%, height: auto, breakable: false, fill: c.lighten(80%).desaturate(10%), stroke: c + 2pt, inset: 3mm, align(left, content), ), ), ) } // // MARK: wrapper // #let handout( doc, group: none, quarter: none, title: none, by: none, subtitle: none, ) = { set par(leading: 0.55em, first-line-indent: 0mm, justify: true) set text(font: "New Computer Modern") set par(spacing: 0.5em) show list: set block(spacing: 0.5em, below: 1em) set heading(numbering: (..nums) => nums.pos().at(0)) set page( margin: 20mm, width: 8in, height: 11.5in, footer: align( center, context counter(page).display(), ), footer-descent: 5mm, ) set list( tight: false, indent: 5mm, spacing: 3mm, ) show heading.where(level: 1): it => { set align(center) set text(weight: "bold") block[ Section #counter(heading).display(): #text(it.body) ] } make_title( group, quarter, title, { if by == none { none } else { [#preparedby(by)\ ] } if subtitle == none { none } else { subtitle } }, ) if show_solutions { warn } doc }