{"id":31784045,"url":"https://github.com/ydx-2147483647/typst-lure","last_synced_at":"2026-06-10T16:31:08.519Z","repository":{"id":308579836,"uuid":"1033319523","full_name":"YDX-2147483647/typst-lure","owner":"YDX-2147483647","description":"A Typst package to parse and normalize URLs, based on the WHATWG URL Standard, powered by rust-url and WebAssembly.","archived":false,"fork":false,"pushed_at":"2026-02-12T04:32:02.000Z","size":52,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-12T14:23:04.962Z","etag":null,"topics":["rust-url","typst","typst-package","url","wasm","web-assembly"],"latest_commit_sha":null,"homepage":"https://typst.app/universe/package/lure","language":"Typst","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YDX-2147483647.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-06T16:19:21.000Z","updated_at":"2026-02-12T04:31:59.000Z","dependencies_parsed_at":"2025-08-06T18:51:47.753Z","dependency_job_id":null,"html_url":"https://github.com/YDX-2147483647/typst-lure","commit_stats":null,"previous_names":["ydx-2147483647/typst-lure"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/YDX-2147483647/typst-lure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YDX-2147483647%2Ftypst-lure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YDX-2147483647%2Ftypst-lure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YDX-2147483647%2Ftypst-lure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YDX-2147483647%2Ftypst-lure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YDX-2147483647","download_url":"https://codeload.github.com/YDX-2147483647/typst-lure/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YDX-2147483647%2Ftypst-lure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34161283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust-url","typst","typst-package","url","wasm","web-assembly"],"created_at":"2025-10-10T11:00:00.095Z","updated_at":"2026-06-10T16:31:08.514Z","avatar_url":"https://github.com/YDX-2147483647.png","language":"Typst","funding_links":[],"categories":[],"sub_categories":[],"readme":"# typst-lure\n\nParse and normalize URLs, based on the [WHATWG URL Standard](https://url.spec.whatwg.org/), powered by [rust-url](https://crates.io/crates/url) and [WebAssembly](https://typst.app/docs/reference/foundations/plugin/).\n\nFor convenience, this package also provides several functions to create URLs from existing ones.\n\n## Example usages\n\n### Normalize URLs\n\n```typst\n#import \"@preview/lure:0.2.0\": normalize\n#normalize(\"https://ja.wikipedia.org/wiki/アルベルト・アインシュタイン\")\n// ⇒ https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AB%E3%83%99%E3%83%AB%E3%83%88%E3%83%BB%E3%82%A2%E3%82%A4%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3\n```\n\nAs the following example, you can create a wrapper of [`link`](https://typst.app/docs/reference/model/link/) to safely use [URLs containing non-ASCII characters](https://typst-doc-cn.github.io/clreq/#links-containing-non-ascii-characters-are-wrong-when-viewing-pdf-in-safari-ascii-safari-pdf), \nbefore the official Typst compiler fixes [#6128](https://github.com/typst/typst/issues/6128).\n\n```typst\n#import \"@preview/lure:0.2.0\": normalize\n#let link(dest, ..body) = {\n  assert.eq(body.named(), (:))\n  assert(body.pos().len() \u003c= 1)\n\n  std.link(\n    normalize(dest),\n    body.pos().first(default: dest.replace(regex(\"^(mailto|tel)://\"), \"\")),\n  )\n}\n\n#link(\"https://law.go.kr/법령/보건의료기본법/제3조\")[UTF-8 percent-encode automatically]\n#link(\"https://w3c.github.io/clreq/README.zh-Hans.html#%E8%AE%A8%E8%AE%BA\")[Keep it as it is if already encoded]\n```\n\nUnlike [percencode](https://typst.app/universe/package/percencode), this package will not re-encode.\n\n### Convert between absolute and relative URLs\n\n```typst\n#import \"@preview/lure:0.2.0\": join, make-relative\n\n#let base = \"https://owner.github.io/repo/\"\n\n#let absolute = join(base, \"/repo/image.png\")\n#assert.eq(absolute, \"https://owner.github.io/repo/image.png\")\n\n#let relative = make-relative(base, absolute)\n#assert.eq(relative, \"image.png\")\n```\n\n### Parse URLs\n\n```typst\n#import \"@preview/lure:0.2.0\": parse, parse-supplementary\n\n// Parse into components\n#assert.eq(\n  parse(\"ssh://git@ssh.github.com:443/YDX-2147483647/typst-lure.git\"),\n  (\n    scheme: \"ssh\",\n    cannot-be-a-base: false,\n    username: \"git\",\n    password: none,\n    host: \"ssh.github.com\",\n    port: 443,\n    path: \"/YDX-2147483647/typst-lure.git\",\n    query: none,\n    fragment: none,\n  ),\n)\n\n// Get supplementary information\n#assert.eq(\n  parse-supplementary(\"https://typst.app/universe/search/?q=url\"),\n  (\n    origin: (\"https\", \"typst.app\", 443),\n    is-special: true,\n    authority: \"typst.app\",\n    domain: \"typst.app\",\n    port-or-known-default: 443,\n    path-segments: (\"universe\", \"search\", \"\"),\n    query-pairs: ((\"q\", \"url\"),),\n  ),\n)\n```\n\nURLs can be tricky. Please refer to the documentation (hover docs for typst functions, or [rust docs](https://docs.rs/url/latest/url/struct.Url.html)) for detailed explanation of each field.\n\n### Change query pairs\n\n```typst\n#import \"@preview/lure:0.2.0\": parse-supplementary, with-query-pairs\n\n// Add search parameters to a URL\n#assert.eq(\n  with-query-pairs(\"https://typst.app/universe/search/\", (q: \"url\", openSource: \"true\")),\n  \"https://typst.app/universe/search/?q=url\u0026openSource=true\",\n)\n\n// Modify existing query pairs\n#{\n  let url = \"https://www.bilibili.com/video/BV1ys411472E/?vd_source=33a2db04ee4f097f3613aeb5caacc90b\u0026spm_id_from=333.788.videopod.episodes\u0026p=15\"\n\n  let query = parse-supplementary(url).query-pairs\n  // Set time to 0:42\n  query += (t: str(42)).pairs()\n  // Remove trackings\n  query = query.filter(((key, _value)) =\u003e not (\"vd_source\", \"spm_id_from\").contains(key))\n\n  assert.eq(\n    with-query-pairs(url, query),\n    \"https://www.bilibili.com/video/BV1ys411472E/?p=15\u0026t=42\",\n  )\n}\n```\n\n## Changelog\n\n### 0.2.0\n\nAdd `with-query-pairs(url, query)` function.\n\nBump rust-url to 2.5.8.\n\n### 0.1.0\n\nInitial release with rust-url 2.5.4.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fydx-2147483647%2Ftypst-lure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fydx-2147483647%2Ftypst-lure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fydx-2147483647%2Ftypst-lure/lists"}