-
Notifications
You must be signed in to change notification settings - Fork 1.1k
nametags:0.1.0 #4798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
nametags:0.1.0 #4798
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| .DS_Store | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) 2026 Cameron Wimpy | ||
|
|
||
| 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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # nametags | ||
|
|
||
| Conference nametag badges (4 × 3 in lanyard inserts) and table tents (tabloid landscape, folded to 11 × 4.25 in) — pure Typst, driven from any CSV or array. | ||
|
|
||
| ## Install | ||
|
|
||
| From Typst Universe (after the package is published): | ||
|
|
||
| ```typst | ||
| #import "@preview/nametags:0.1.0": nametag, nametent | ||
| ``` | ||
|
|
||
| Or use a local checkout: | ||
|
|
||
| ```typst | ||
| #import "/path/to/nametags-package/lib.typ": nametag, nametent | ||
| ``` | ||
|
|
||
| ## Quick start — badges | ||
|
|
||
| `badges.typ`: | ||
|
|
||
| ```typst | ||
| #import "@preview/nametags:0.1.0": nametag | ||
|
|
||
| #let rows = csv("attendees.csv").slice(1) // drop header row | ||
| #let left-logo = read("logo-left.png", encoding: none) // your logo | ||
| #let right-logo = read("logo-right.png", encoding: none) // your logo | ||
|
|
||
| #for row in rows { | ||
| let (first, last, dept, inst) = row | ||
| nametag( | ||
| name: first + " " + last, | ||
| affiliation: inst, | ||
| subaffiliation: dept, | ||
| conference: "Annual Research Symposium", | ||
| year: "2026", | ||
| logo-left: left-logo, | ||
| logo-right: right-logo, | ||
| ) | ||
| } | ||
| ``` | ||
|
|
||
| `attendees.csv`: | ||
|
|
||
| ```csv | ||
| First,Last,Affil1,Affil2 | ||
| Jane,Doe,Department of Sociology,Example State University | ||
| John,Smith,School of Public Affairs,Riverside College | ||
| ``` | ||
|
|
||
| Then: | ||
|
|
||
| ```bash | ||
| typst compile badges.typ | ||
| ``` | ||
|
|
||
| You'll get one 4 × 3 in page per attendee. | ||
|
|
||
| ## Quick start — tents | ||
|
|
||
| ```typst | ||
| #import "@preview/nametags:0.1.0": nametent | ||
|
|
||
| #let rows = csv("attendees.csv").slice(1) | ||
| #let left-logo = read("logo-left.png", encoding: none) // your logo | ||
| #let right-logo = read("logo-right.png", encoding: none) // your logo | ||
|
|
||
| #for row in rows { | ||
| let (first, last, _, inst) = row | ||
| nametent( | ||
| name: first + " " + last, | ||
| affiliation: inst, | ||
| conference: "Annual Research Symposium", | ||
| year: "2026", | ||
| logo-left: left-logo, | ||
| logo-right: right-logo, | ||
| ) | ||
| } | ||
| ``` | ||
|
|
||
| Print on tabloid (11 × 17), trim or fold to 11 × 8.5, then fold along the horizontal center. The top half is rotated 180° so both sides read upright when standing on a table. | ||
|
|
||
| ## API | ||
|
|
||
| ### `nametag(name, affiliation, subaffiliation, conference, year, accent-color, logo-left, logo-right)` | ||
|
|
||
| Renders a single 4 × 3 in badge as one page. | ||
|
|
||
| | Parameter | Type | Default | Notes | | ||
| |----------:|------|---------|-------| | ||
| | `name` | str | `""` | Attendee's full name | | ||
| | `affiliation` | str | `""` | Primary line — typically institution | | ||
| | `subaffiliation` | str | `""` | Secondary line — typically department or title; omitted if empty | | ||
| | `conference` | str | `"Annual Research Symposium"` | Shown in the header bar, uppercased | | ||
| | `year` | str | `"2026"` | Right side of header bar | | ||
| | `accent-color` | color | `rgb("#0d3b66")` | Header-year accent and rule under name | | ||
| | `logo-left` | bytes \| none | `none` | Footer logo, left side. Pass `read("logo.png", encoding: none)` | | ||
| | `logo-right` | bytes \| none | `none` | Footer logo, right side | | ||
|
|
||
| ### `nametent(name, affiliation, conference, year, accent-color, logo-left, logo-right)` | ||
|
|
||
| Renders a single tabloid landscape page that folds into a tent. Same parameter conventions as `nametag` but no `subaffiliation`. Name size is auto-selected (52 / 60 / 68 pt) by character count to keep names on one line. | ||
|
|
||
| ## Notes | ||
|
|
||
| - **Logos are bytes, not paths.** Typst resolves `image()` paths relative to the file containing the call, so passing a path string into a packaged function won't find a file in your project. Loading the bytes once with `read()` and handing them in sidesteps this. | ||
| - **Example logos are placeholders.** `examples/logo-left.png` and `examples/logo-right.png` are simple wordmarks generated for the demo. Replace them with your own. | ||
| - **Fonts.** Both functions default to "Industry Inc Test Base" (headings) and "Oriya MN" (body), with Impact / Times New Roman as fallbacks. Edit the `heading-font` and `body-font` lists at the top of `nametag.typ` / `nametent.typ` to swap. | ||
| - **Quarto users.** A Quarto-driven version of this template lives at [`cwimpy/typst-templates/nametags`](https://github.com/cwimpy/typst-templates/tree/main/nametags), with an R chunk that reads the CSV and emits Typst calls. | ||
|
Check warning on line 110 in packages/preview/nametags/0.1.0/README.md
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you use a perma-link or a link to a specific branch/tag? This will ensure the link stays valid and always links to the correct version. |
||
|
|
||
| ## License | ||
|
|
||
| MIT | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The whole examples directory will be very hard to find on Typst Universe unless it, or the resources are linked from the readme. Given that there are already code examples in the readme, could you either remove it or add links? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| First,Last,Affil1,Affil2 | ||
| Jane,Doe,Department of Sociology,Example State University | ||
| John,Smith,School of Public Affairs,Riverside College | ||
| Alex,Rivera,Department of Political Science,Midwestern University | ||
| Sam,Chen,Institute for Policy Research,Coastal University |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Render one 4x3 in badge per row of attendees.csv. | ||
| // | ||
| // From Typst Universe: | ||
| // #import "@preview/nametags:0.1.0": nametag | ||
| // From a local checkout: | ||
| #import "../lib.typ": nametag | ||
|
|
||
| // CSV columns: First, Last, Affil1 (department), Affil2 (institution) | ||
| #let rows = csv("attendees.csv").slice(1) // drop header row | ||
|
|
||
| // Load logos once as bytes; the package re-uses them on every page. | ||
| #let left-logo = read("logo-left.png", encoding: none) | ||
| #let right-logo = read("logo-right.png", encoding: none) | ||
|
|
||
| #for row in rows { | ||
| let (first, last, affil1, affil2) = row | ||
| nametag( | ||
| name: first + " " + last, | ||
| affiliation: affil2, | ||
| subaffiliation: affil1, | ||
| conference: "Annual Research Symposium", | ||
| year: "2026", | ||
| logo-left: left-logo, | ||
| logo-right: right-logo, | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Render one folded table tent per row of attendees.csv. | ||
| // Print on tabloid (11 x 17), trim to 11 x 8.5 if needed, fold along the | ||
| // horizontal center. | ||
| // | ||
| // From Typst Universe: | ||
| // #import "@preview/nametags:0.1.0": nametent | ||
| // From a local checkout: | ||
| #import "../lib.typ": nametent | ||
|
|
||
| #let rows = csv("attendees.csv").slice(1) // drop header row | ||
|
|
||
| #let left-logo = read("logo-left.png", encoding: none) | ||
| #let right-logo = read("logo-right.png", encoding: none) | ||
|
|
||
| #for row in rows { | ||
| let (first, last, _, affil2) = row | ||
| nametent( | ||
| name: first + " " + last, | ||
| affiliation: affil2, | ||
| conference: "Annual Research Symposium", | ||
| year: "2026", | ||
| logo-left: left-logo, | ||
| logo-right: right-logo, | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // nametags — Typst package entry point | ||
| // Re-exports the two layout functions. | ||
|
|
||
| #import "nametag.typ": nametag | ||
| #import "nametent.typ": nametent |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| // nametag.typ — single 4x3 in conference badge | ||
| // | ||
| // Each call sets the page to 4 x 3 in and renders one badge. Call once | ||
| // per attendee — Typst will start a new page for each. | ||
| // | ||
| // Logos are passed as bytes (e.g. `read("iri.png")`) so paths resolve | ||
| // relative to the *calling* file, not this package. | ||
|
|
||
| #let nametag( | ||
| name: "", | ||
| affiliation: "", | ||
| subaffiliation: "", | ||
| conference: "Annual Research Symposium", | ||
| year: "2026", | ||
| accent-color: rgb("#0d3b66"), | ||
| logo-left: none, | ||
| logo-right: none, | ||
| ) = { | ||
| // ---- Design tokens ---- | ||
| let ink = rgb("#000000") | ||
| let muted = rgb("#555555") | ||
| let faint = rgb("#777777") | ||
| let hairline = rgb("#e5e5e5") | ||
|
|
||
| // Font fallbacks let this render on machines without the licensed | ||
| // fonts (CI, collaborators, Universe sandbox). | ||
| let heading-font = ("Industry Inc Test Base", "Industry Inc", "Industry", "Impact") | ||
| let body-font = ("Oriya MN", "Oriya Sangam MN", "Times New Roman") | ||
|
|
||
| // ---- Page = the badge itself ---- | ||
| set page( | ||
| width: 4in, | ||
| height: 3in, | ||
| margin: 0pt, | ||
| fill: white, | ||
| ) | ||
|
|
||
| // ---- Outer frame: a 3-row grid (header / body / footer) ---- | ||
| block( | ||
| width: 100%, | ||
| height: 100%, | ||
| stroke: 0.5pt + hairline, | ||
| radius: 6pt, | ||
| clip: true, | ||
| { | ||
| grid( | ||
| columns: 1, | ||
| rows: (auto, 1fr, auto), | ||
|
|
||
| // ---- Header bar ---- | ||
| block( | ||
| width: 100%, | ||
| fill: ink, | ||
| inset: (x: 14pt, y: 9pt), | ||
| grid( | ||
| columns: (1fr, auto), | ||
| align: (left + horizon, right + horizon), | ||
| text( | ||
| font: heading-font, | ||
| size: 10pt, | ||
| fill: white, | ||
| tracking: 0.6pt, | ||
| upper(conference), | ||
| ), | ||
| text( | ||
| font: heading-font, | ||
| size: 10pt, | ||
| fill: accent-color, | ||
| year, | ||
| ), | ||
| ), | ||
| ), | ||
|
|
||
| // ---- Body (fills remaining vertical space) ---- | ||
| block( | ||
| width: 100%, | ||
| height: 100%, | ||
| inset: (x: 18pt, y: 14pt), | ||
| align(center + horizon)[ | ||
| #text( | ||
| font: body-font, | ||
| weight: "bold", | ||
| size: 26pt, | ||
| fill: ink, | ||
| )[#name] | ||
| #v(4pt) | ||
| #box(width: 56pt, height: 4pt, fill: accent-color) | ||
| #v(14pt) | ||
| #text(font: body-font, size: 13pt, fill: rgb("#333333"))[#affiliation] | ||
| #if subaffiliation != "" [ | ||
| #v(3pt) | ||
| #block( | ||
| width: 90%, | ||
| text( | ||
| font: body-font, | ||
| size: 11pt, | ||
| fill: faint, | ||
| )[#subaffiliation], | ||
| ) | ||
| ] | ||
| ], | ||
| ), | ||
|
|
||
| // ---- Footer with logos ---- | ||
| block( | ||
| width: 100%, | ||
| stroke: (top: 0.5pt + hairline), | ||
| inset: (x: 14pt, y: 6pt), | ||
| grid( | ||
| columns: (1fr, 1fr), | ||
| align: (left + horizon, right + horizon), | ||
| if logo-left != none { | ||
| image(logo-left, height: 24pt, fit: "contain") | ||
| } else { [] }, | ||
| if logo-right != none { | ||
| image(logo-right, height: 24pt, fit: "contain") | ||
| } else { [] }, | ||
| ), | ||
| ), | ||
| ) | ||
| }, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Packages commonly require the user to pass in an
image. You use a set rule to still specify the default size. This would also allow passing in other content. You're not required to change this, just wanted to give some options :)