diff --git a/packages/preview/jurlstify/0.2.1/LICENSE b/packages/preview/jurlstify/0.2.1/LICENSE new file mode 100644 index 0000000000..44362484f3 --- /dev/null +++ b/packages/preview/jurlstify/0.2.1/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 SchrodingerBlume + +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/jurlstify/0.2.1/README.md b/packages/preview/jurlstify/0.2.1/README.md new file mode 100644 index 0000000000..0a5200884a --- /dev/null +++ b/packages/preview/jurlstify/0.2.1/README.md @@ -0,0 +1,276 @@ +

+ jurlstify
+ URL typesetting with line-break opportunities — the url.sty port for Typst +

+ +

+ version: 0.2.1 + license: MIT + minimum typst version: 0.13.0 +

+ +

+ English | 中文 +

+ +--- + +## English + +A Typst package that ports LaTeX's [`url.sty`](https://ctan.org/pkg/url) line-breaking logic. In justified paragraphs, bare URLs either overflow the margin or force ugly gaps into the surrounding text. jurlstify inserts break opportunities at the same character classes as `url.sty` (`/`, `?`, `&`, `:`, etc.) so Typst's line-breaker can wrap URLs naturally without touching word spacing elsewhere in the paragraph. + +### Features + +- **url.sty-compatible break classes** — breaks after `.` `/` `?` `&` `#` `:` and more, matching `\UrlBreaks` / `\UrlBigBreaks` / `\UrlNoBreaks` +- **Hyphen control** — breaks after `-` are suppressed by default (like url.sty); enable with `hyphens: true` +- **Font inheritance** — defaults to `auto` (inherits body font), avoiding the metric mismatch that monospace causes in CJK text +- **Stretch mode** — opt-in `stretch: true` lets URL-internal lines align to the right margin in justified paragraphs +- **Long-run fallback** — opt-in `every: N` adds break opportunities inside unbroken letter/digit runs that contain no natural break character +- **Visible-hyphen mode** — opt-in `show-hyphen: true` shows a `-` at *every* line break (natural `/` `.` `?` … breaks and `every`-inserted ones alike); default `false` is url.sty-faithful — copy-safe, no hyphen shown +- **Three usage modes** — standalone `jurlstify()`, hyperlink wrapper `jurl()`, and document-level show rule `jurlstify-links()` +- **Fully customisable** — override break character lists, font, size, color, and hyphen interval per call + +### Quick Start + +```typst +#import "@preview/jurlstify:0.2.1": jurlstify, jurl, jurlstify-links + +// Render a URL string with break opportunities +#jurlstify("https://example.com/very/long/path?query=value&more=stuff#fragment") + +// Clickable link — same breaking, wrapped in link() +#jurl("https://example.com/very/long/path?query=value&more=stuff#fragment") + +// Apply automatically to every link() in the document +#show: jurlstify-links.with() +#link("https://example.com/automatically/handled") +``` + +### API Reference + +#### `jurlstify(url, ..options)` — core function + +Renders `url` as inline content with Unicode break opportunities at url.sty-compatible positions. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `url` | `str` | *(required)* | The URL string to render. | +| `hyphens` | `bool` | `false` | Allow line breaks after `-`. Mirrors url.sty's `hyphens` option. Off by default so `my-domain.com` never breaks mid-word. | +| `stretch` | `bool` | `false` | Make break points stretchable so URL-internal justified lines reach the right margin. Trade-off: small visible gaps may appear at break points. | +| `spaces` | `str` | `"nobreak"` | How to handle literal spaces inside a URL. `"nobreak"` → no-break space; `"break"` → ordinary breakable space; `"strip"` → discard. | +| `breaks` | `array` | *url.sty defaults* | Characters after which a break opportunity is inserted. | +| `big-breaks` | `array` | `(":",)` | Higher-priority break characters (`\UrlBigBreaks`). | +| `no-breaks` | `array` | `("(","[","{","<")` | Characters that suppress the break opportunity immediately before them (`\mathopen` class). | +| `font` | `auto` \| `str` \| `array` | `auto` | URL font. `auto` inherits the surrounding body font. Pass a name or array to override, e.g. a monospace stack. | +| `size` | `auto` \| `length` | `auto` | Font size. `auto` inherits from context. | +| `fill` | `auto` \| `color` | `auto` | Text color. `auto` inherits from context. | +| `every` | `none` \| `int` | `none` | Insert a break opportunity after every N consecutive non-break characters. The marker is invisible unless the line actually breaks there. Useful for URLs with long unbroken letter/digit runs. Disabled by default. | +| `show-hyphen` | `bool` | `false` | Render **every** break opportunity — the natural `/` `.` `?` `&` `:` breaks **and** any added by `every` — as a visible soft hyphen (`U+00AD`) when the line breaks there. `false` (default) → zero-width space (`U+200B`): breakable but shows nothing; the url.sty-faithful, copy-safe behaviour. `true` → a `-` appears at each broken line end (including after punctuation, e.g. line ends like `…com/-`). A real `-` (under `hyphens: true`) is never doubled. | + +```typst +// Inherit body font, break at / ? & : etc. +#jurlstify("https://example.com/path?a=1&b=2") + +// Allow hyphen breaks +#jurlstify("https://my-very-long-sub-domain.example.org/path", hyphens: true) + +// Justify URL-internal lines to the right margin +#jurlstify("https://example.com/long/path", stretch: true) + +// Add break points every 8 chars in long unbroken runs (invisible by default) +#jurlstify("https://example.com/averylongpathsegmentwithnobreaks", every: 8) + +// Show a "-" at EVERY line break — natural breaks and `every` ones alike +#jurlstify("https://example.com/very/long/path/segment", show-hyphen: true) + +// Monospace font (classic url.sty look) +#jurlstify("https://example.com/path", + font: ("DejaVu Sans Mono", "Menlo", "Consolas", "Courier New")) + +// Custom color and size +#jurlstify("https://example.com/path", fill: blue, size: 9pt) +``` + +#### `jurl(dest, display: none, ..options)` — hyperlink wrapper + +Renders a clickable hyperlink whose visible text is formatted by `jurlstify`. Accepts all the same keyword options. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `dest` | `str` | *(required)* | Link destination (URL). | +| `display` | `none` \| `str` \| content | `none` | Custom display. `none` → destination string formatted by `jurlstify`; string → also formatted by `jurlstify`; content → used as-is. | + +```typst +#jurl("https://example.com/very/long/path") +#jurl("https://example.com/very/long/path", display: "example site") +#jurl("https://example.com/path", hyphens: true, fill: blue) +``` + +#### `jurlstify-links(..options, body)` — show-rule helper + +Document-level show rule that makes every `#link("http://…")` (where body equals destination) automatically use `jurlstify`. Links with explicit display content (`#link(dest, "click here")`) are left untouched. + +```typst +// Declare once near the top of your document +#show: jurlstify-links.with() + +The homepage is #link("https://example.com/very/long/path"). // auto-formatted +See #link("https://example.com", "the docs") for details. // untouched +``` + +Pass options to apply them document-wide: + +```typst +#show: jurlstify-links.with(hyphens: true, fill: blue) +``` + +### Default Break Characters + +| Parameter | Default characters | +|-----------|--------------------| +| `breaks` | `. @ \ / ! _ \| ; > ] ) , ? & ' + = #` | +| `big-breaks` | `:` | +| `no-breaks` | `( [ { <` | + +### Notes on Justification + +jurlstify inserts `U+200B` (ZERO WIDTH SPACE) at break positions — zero width, not stretchable, faithfully mirroring url.sty's zero-stretch muskips. A line consisting entirely of URL characters may end slightly short of the right margin. + +Enable `stretch: true` for invisible-but-stretchable word spaces; the paragraph justifier will then align URL-only lines to the right margin at the cost of small visible gaps at break points. + +Break quality depends on Typst's optimizer. jurlstify only inserts declarative markers; improvements to Typst's engine automatically improve output. + +### License + +MIT License — see [LICENSE](LICENSE) for details. + +--- + +## 中文 + +将 LaTeX [`url.sty`](https://ctan.org/pkg/url) 的换行逻辑移植到 Typst 的排版包。在两端对齐的段落中,裸露的 URL 要么溢出页边距,要么迫使周围文字产生大块空白。jurlstify 在与 `url.sty` 相同的字符类(`/`、`?`、`&`、`:` 等)后插入换行机会,使 Typst 的断行器能在这些位置自然换行,而不影响段落其余部分的字间距。 + +### 功能特性 + +- **url.sty 兼容断点** — 在 `.` `/` `?` `&` `#` `:` 等字符处断行,对应 `\UrlBreaks` / `\UrlBigBreaks` / `\UrlNoBreaks` +- **连字符控制** — 默认抑制 `-` 处的换行(与 url.sty 一致);可通过 `hyphens: true` 开启 +- **字体继承** — 默认 `auto`,继承正文字体,避免等宽字体在中文段落中造成字距错位 +- **拉伸模式** — 可选 `stretch: true`,让整行 URL 也能对齐两端对齐段落的右边距 +- **长串兜底** — 可选 `every: N`,在没有任何自然断点字符的长串字母/数字段中插入额外的换行机会 +- **连字符模式** — 可选 `show-hyphen: true`,让*每一个*断点(`/` `.` `?` … 等自然断点以及 `every` 插入的断点)在实际换行处显示 `-`;默认 `false` 与 url.sty 一致——可安全复制、不显示连字符 +- **三种使用方式** — 独立函数 `jurlstify()`、超链接包装器 `jurl()`、文档级 show rule `jurlstify-links()` +- **完全可定制** — 可按需覆盖断点字符列表、字体、字号、颜色和软连字符间隔 + +### 快速上手 + +```typst +#import "@preview/jurlstify:0.2.1": jurlstify, jurl, jurlstify-links + +// 渲染带换行机会的 URL 字符串 +#jurlstify("https://example.com/very/long/path?query=value&more=stuff#fragment") + +// 可点击超链接,同样支持换行 +#jurl("https://example.com/very/long/path?query=value&more=stuff#fragment") + +// 全局 show rule:让文档中所有 link() 自动使用 jurlstify +#show: jurlstify-links.with() +#link("https://example.com/automatically/handled") +``` + +### API 参考 + +#### `jurlstify(url, ..options)` — 核心函数 + +将 `url` 渲染为行内内容,在与 url.sty 兼容的位置插入 Unicode 换行机会。 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `url` | `str` | *必填* | 要渲染的 URL 字符串。 | +| `hyphens` | `bool` | `false` | 是否允许在 `-` 后换行。对应 url.sty 的 `hyphens` 选项。默认关闭,防止 `my-domain.com` 在单词中间断行。 | +| `stretch` | `bool` | `false` | 让换行点参与两端对齐的拉伸,使纯 URL 行也能对齐右边距。代价:这些行的换行点处可能出现小间隙。 | +| `spaces` | `str` | `"nobreak"` | URL 内部空格的处理方式。`"nobreak"` → 不换行空格;`"break"` → 普通可换行空格;`"strip"` → 删除空格。 | +| `breaks` | `array` | *url.sty 默认值* | 插入换行机会的字符列表。 | +| `big-breaks` | `array` | `(":",)` | 高优先级断点字符(对应 `\UrlBigBreaks`)。 | +| `no-breaks` | `array` | `("(","[","{","<")` | 禁止在其之前断行的字符(对应 `\mathopen` 类)。 | +| `font` | `auto` \| `str` \| `array` | `auto` | URL 字体。`auto` 继承正文字体(中文段落推荐)。传入字体名或数组可指定其他字体,例如等宽字体栈。 | +| `size` | `auto` \| `length` | `auto` | 字号。`auto` 继承上下文。 | +| `fill` | `auto` \| `color` | `auto` | 文字颜色。`auto` 继承上下文。 | +| `every` | `none` \| `int` | `none` | 在连续的非断点字符序列中每隔 N 个字符插入一个换行机会。该标记平时不可见,仅在该处实际换行时显示。适用于含有长段字母/数字序列、缺乏自然断点的 URL。默认禁用。 | +| `show-hyphen` | `bool` | `false` | 让**每一个**断点(`/` `.` `?` `&` `:` 等自然断点**以及** `every` 插入的断点)在实际换行处显示软连字符(`U+00AD`,可见的 `-`)。`false`(默认)→ 改用零宽空格(`U+200B`):可断行但不显示任何字符,与 url.sty 一致、可安全复制。`true` → 每个换行行尾出现 `-`(包括标点后,如行尾 `…com/-`)。真实的 `-`(`hyphens: true` 时)不会被叠加成 `--`。 | + +```typst +// 继承正文字体,在 / ? & : 等处断行 +#jurlstify("https://example.com/path?a=1&b=2") + +// 允许连字符处断行 +#jurlstify("https://my-very-long-sub-domain.example.org/path", hyphens: true) + +// 使纯 URL 行对齐右边距 +#jurlstify("https://example.com/long/path", stretch: true) + +// 在长段无断点路径中每 8 字符加一个断点(默认不可见) +#jurlstify("https://example.com/averylongpathsegmentwithnobreaks", every: 8) + +// 让每一个换行处都显示 “-” —— 自然断点与 every 断点一视同仁 +#jurlstify("https://example.com/very/long/path/segment", show-hyphen: true) + +// 等宽字体(经典 url.sty 风格) +#jurlstify("https://example.com/path", + font: ("DejaVu Sans Mono", "Menlo", "Consolas", "Courier New")) + +// 自定义颜色与字号 +#jurlstify("https://example.com/path", fill: blue, size: 9pt) +``` + +#### `jurl(dest, display: none, ..options)` — 超链接包装器 + +渲染可点击的超链接,可见文字由 `jurlstify` 格式化。支持与 `jurlstify` 相同的所有关键字选项。 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `dest` | `str` | *必填* | 链接目标(URL)。 | +| `display` | `none` \| `str` \| content | `none` | 自定义显示内容。`none` → 显示目标 URL 本身(经 `jurlstify` 格式化);字符串 → 同样经 `jurlstify` 处理;content → 原样显示。 | + +```typst +#jurl("https://example.com/very/long/path") +#jurl("https://example.com/very/long/path", display: "示例网站") +#jurl("https://example.com/path", hyphens: true, fill: blue) +``` + +#### `jurlstify-links(..options, body)` — show rule 辅助函数 + +文档级 show rule,让所有 body 与目标相同的 `#link("http://…")` 自动使用 `jurlstify` 断行。有显式显示内容的链接(如 `#link(dest, "点击这里")`)不受影响。 + +```typst +// 在文档顶部声明一次 +#show: jurlstify-links.with() + +项目主页为 #link("https://example.com/very/long/path")。 // 自动格式化 +详见 #link("https://example.com", "文档")。 // 不受影响 +``` + +全局传入选项: + +```typst +#show: jurlstify-links.with(hyphens: true, fill: blue) +``` + +### 默认断点字符 + +| 参数 | 默认字符 | +|------|----------| +| `breaks` | `. @ \ / ! _ \| ; > ] ) , ? & ' + = #` | +| `big-breaks` | `:` | +| `no-breaks` | `( [ { <` | + +### 关于两端对齐的说明 + +jurlstify 在断点位置插入 `U+200B`(零宽空格)——宽度为零且不可拉伸,忠实还原了 url.sty 的零伸缩粘连。因此,整行都是 URL 字符的行可能无法对齐右边距。 + +开启 `stretch: true` 可改为插入不可见但可拉伸的字间距,使段落排版器在纯 URL 行也能对齐右边距,代价是这些行的换行点处可能出现小间隙。 + +断行质量取决于 Typst 引擎的优化器。jurlstify 只插入声明式标记,Typst 引擎的改进会自动改善输出,无需修改本包。 + +### 许可 + +MIT 许可证 — 详见 [LICENSE](LICENSE)。 diff --git a/packages/preview/jurlstify/0.2.1/lib.typ b/packages/preview/jurlstify/0.2.1/lib.typ new file mode 100644 index 0000000000..e90033e4cd --- /dev/null +++ b/packages/preview/jurlstify/0.2.1/lib.typ @@ -0,0 +1,248 @@ +// jurlstify — URL typesetting with line-break opportunities. +// +// Ported from Donald Arseneau's LaTeX `url.sty` (LPPL). +// +// Raggedness note: +// url.sty sets every math-mode muskip to `0mu` — zero natural width AND +// zero stretch/shrink. That means a line that falls entirely inside a +// URL has no stretchable glue in LaTeX either, so it can only reach the +// right margin by luck of where break points fall. The common sense +// that "url.sty makes URLs justify" is a misconception propagated by +// TeX's Knuth-Plass breaker, which is aggressive enough that ragged +// URL-internal lines are rare in practice. We cannot reproduce Knuth- +// Plass, so we offer the same two trade-offs LaTeX has: +// +// 1. `stretch: false` (default, matches url.sty): emit U+200B at +// break points — zero-width, breakable, non-stretchable. Lines +// that fall entirely inside a URL may end short of the right +// margin. This is the honest port of url.sty. +// +// 2. `stretch: true`: emit a real U+0020 space wrapped in +// `text(tracking: …)` that pulls the space advance to zero. The +// space is invisible when the line is not justified, but the +// paragraph justifier will expand it like any word space on +// justified URL-internal lines — buying right-margin alignment +// at the cost of small visible gaps between URL segments on +// those lines. +// +// Hyphen handling: +// Unicode assigns "-" to line-break class HY (break after). url.sty +// keeps hyphens in UrlOrds by default (no break) and only promotes +// them to UrlBigBreaks under the `hyphens` option. We emit U+2060 +// (WORD JOINER) after "-" when `hyphens: false` to suppress Typst's +// default break at hyphens. + +// ───────────────────────────────────────────────────────────────────────────── +// Break-class tables — kept identical to `url.sty` defaults. +// \UrlBreaks / \UrlBigBreaks / \UrlNoBreaks (url.sty §32–35) + +#let breaks-default = ( + ".", "@", "\\", "/", "!", "_", "|", ";", ">", "]", + ")", ",", "?", "&", "'", "+", "=", "#", +) + +#let big-breaks-default = (":",) + +#let no-breaks-default = ("(", "[", "{", "<") + +// Invisible characters used internally. +#let _zwsp = "\u{200B}" // ZERO WIDTH SPACE — break, zero width, no stretch +#let _wj = "\u{2060}" // WORD JOINER — forbids line break +#let _nbsp = "\u{00A0}" // NO-BREAK SPACE + +// Stretchable invisible break. A real U+0020 with enough negative tracking to +// cancel its advance — invisible on unjustified lines, but *does* participate +// in paragraph justification on URL-internal lines. Opt-in via `stretch: true`. +#let _stretch-break = text(tracking: -1em, " ") + +// ───────────────────────────────────────────────────────────────────────────── +// Core: render a URL with break+stretch opportunities. +// +// Arguments +// --------- +// url : str — the URL text. +// hyphens : bool — allow breaks after "-" (url.sty `hyphens` option). +// stretch : bool — if true, URL-internal lines can stretch to reach +// the right margin in a justified paragraph. Trade- +// off: visible gaps appear at break points on those +// lines. Default false (matches url.sty's +// zero-stretch muskips; lines may be ragged). +// spaces : str — "nobreak" | "break" | "strip". url.sty default is +// "nobreak" (\penalty\@M); `spaces` option gives "break". +// breaks : array — override normal break chars. +// big-breaks : array — override high-priority break chars. +// no-breaks : array — chars explicitly suppressed from breaking (a break +// opportunity that would otherwise land *before* one +// of these is dropped, matching url.sty's `\mathopen` +// class). +// font : auto | str | array — URL font; `auto` inherits the +// surrounding body font. Pass a font name or array +// (e.g. monospace stack) to override. +// size : auto | length +// fill : auto | color +// every : none | int — insert a break opportunity after every N +// consecutive non-break characters. The marker is +// invisible unless the line actually breaks there. +// Disabled by default (none). Useful when URLs contain +// long unbroken letter/digit runs that resist all +// natural break points. +// show-hyphen : bool — render EVERY break opportunity — the natural url.sty +// breaks (after "/ . ? & : …") as well as any inserted +// by `every` — as a visible hyphen when the line +// actually breaks there. +// false (default): U+200B ZERO WIDTH SPACE — breakable +// but shows nothing. The url.sty-faithful, copy-safe +// behaviour, since a stray "-" could be mistaken for a +// real character of the URL. +// true: U+00AD SOFT HYPHEN at every break — a "-" +// appears at each broken line end. Note this also puts +// a "-" after punctuation breaks (line ends like +// "…com/-"). A real "-" (under hyphens: true) is left +// as the break's own visible hyphen, never doubled. + +#let jurlstify( + url, + hyphens: false, + stretch: false, + spaces: "nobreak", + breaks: breaks-default, + big-breaks: big-breaks-default, + no-breaks: no-breaks-default, + font: auto, + size: auto, + fill: auto, + every: none, + show-hyphen: false, +) = { + assert( + type(url) == str, + message: "jurlstify: expected a string, got " + str(type(url)), + ) + assert( + spaces in ("nobreak", "break", "strip"), + message: "jurlstify: `spaces` must be \"nobreak\", \"break\", or \"strip\"", + ) + assert( + every == none or (type(every) == int and every >= 1), + message: "jurlstify: `every` must be none or a positive integer", + ) + assert( + type(show-hyphen) == bool, + message: "jurlstify: `show-hyphen` must be a boolean", + ) + + let big = if hyphens { big-breaks + ("-",) } else { big-breaks } + let all-breaks = breaks + big + + // url.sty runs inside math mode, which suppresses automatic hyphenation + // and ligatures. Typst has no math-mode escape for strings, so we disable + // those features directly; otherwise Typst would insert fake hyphens + // ("exam-ple.com") and apply language-specific ligatures inside URLs. + set text( + hyphenate: false, + historical-ligatures: false, + discretionary-ligatures: false, + ) + set text(font: font) if font != auto + set text(size: size) if size != auto + set text(fill: fill) if fill != auto + + // Invisible break: U+200B (or a stretchable space in `stretch` mode). + // Visible break: U+00AD SOFT HYPHEN — renders "-" only where the line + // actually breaks. `show-hyphen` selects which one EVERY break uses. + let plain-break = if stretch { _stretch-break } else { _zwsp } + let break-marker = if show-hyphen { "\u{00AD}" } else { plain-break } + + // Emit content incrementally: text runs punctuated by break markers. + let chars = url.clusters() + let n = chars.len() + let i = 0 + let word-run = 0 // consecutive non-break chars since the last natural break + while i < n { + let c = chars.at(i) + + if c == " " { + word-run = 0 + if spaces == "nobreak" { _nbsp } + else if spaces == "break" { c } + // "strip": drop the space + i += 1 + continue + } + + c + + if c in all-breaks { + word-run = 0 + let nxt = if i + 1 < n { chars.at(i + 1) } else { none } + if nxt not in no-breaks { + // A real "-" (only reachable under hyphens: true) is already a + // visible hyphen — break after it, but don't stack a soft hyphen on + // top, which would render an ugly "--" at the line end. + if show-hyphen and c == "-" { plain-break } else { break-marker } + } + } else if c == "-" and not hyphens { + word-run = 0 + _wj + } else { + word-run += 1 + if every != none and word-run >= every and i + 1 < n { + break-marker + word-run = 0 + } + } + + i += 1 + } +} + +// ───────────────────────────────────────────────────────────────────────────── +// Convenience wrapper: hyperlink + jurlstify +// +// #jurl("https://example.com/long/path") +// #jurl("https://example.com/long/path", display: "example") + +#let jurl( + dest, + display: none, + ..opts, +) = { + let shown = if display == none { dest } else { display } + let body = if type(shown) == str { + jurlstify(shown, ..opts.named()) + } else { + shown + } + link(dest, body) +} + +// ───────────────────────────────────────────────────────────────────────────── +// Show-rule helper: make the built-in `link` element use jurlstify's breaking +// wherever its body is a plain text run (`link("http://…")`, etc). +// +// #show: jurlstify-links.with() +// #link("https://example.com/foo/bar") // auto-formatted + +#let jurlstify-links( + ..opts, + body, +) = { + let kwargs = opts.named() + show link: it => { + // Only rewrite when the body is the auto-generated textual form of + // `dest` (the common `link("http://…")` case). Explicit display + // content such as `link(dest, "click me")` is left untouched — the + // user picked it on purpose and almost certainly isn't a URL. + if ( + type(it.dest) == str + and it.body.func() == text + and type(it.body.text) == str + and it.body.text == it.dest + ) { + link(it.dest, jurlstify(it.body.text, ..kwargs)) + } else { + it + } + } + body +} diff --git a/packages/preview/jurlstify/0.2.1/typst.toml b/packages/preview/jurlstify/0.2.1/typst.toml new file mode 100644 index 0000000000..d436f0ce77 --- /dev/null +++ b/packages/preview/jurlstify/0.2.1/typst.toml @@ -0,0 +1,12 @@ +[package] +name = "jurlstify" +version = "0.2.1" +entrypoint = "lib.typ" +authors = ["SchrodingerBlume "] +license = "MIT" +description = "URL typesetting with line-break opportunities, inspired by LaTeX's url package." +repository = "https://github.com/SchrodingerBlume/typst-jurlstify" +keywords = ["url", "linebreak", "justify", "hyperref"] +categories = ["text", "utility", "layout"] +compiler = "0.13.0" +exclude = ["*.pdf"]