50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
from os import environ
|
|
from urllib.parse import urlencode
|
|
from datatypes import PDFDestination, PDFPage, PDFSection, PDFReference, Reference
|
|
from typing import assert_never
|
|
from pathlib import Path
|
|
|
|
|
|
def format_pdf_link(ref: PDFReference) -> str:
|
|
path_str = environ.get("TYPST_ROOT", None)
|
|
if path_str is None:
|
|
raise KeyError("Please set TYPST_ROOT to format links with Typst.")
|
|
typst_root = Path(path_str)
|
|
|
|
relative: bool = ref.filepath.is_relative_to(typst_root)
|
|
format_path: str
|
|
|
|
if relative:
|
|
format_path = "/" + str(ref.filepath.relative_to(typst_root))
|
|
else:
|
|
format_path = str(ref.filepath.absolute())
|
|
|
|
params = {}
|
|
default_label = ""
|
|
|
|
match ref:
|
|
case PDFPage():
|
|
params["page"] = ref.page
|
|
case PDFSection():
|
|
params["section"] = ref.title
|
|
default_label = ref.title
|
|
case PDFDestination():
|
|
params["destination"] = ref.name
|
|
case _ as obj:
|
|
assert_never(obj)
|
|
|
|
if relative:
|
|
return (
|
|
f'#lref("{format_path}?{urlencode(params)}", pdfref: true)[{default_label}]'
|
|
)
|
|
else:
|
|
return f'#link("pdfref://{format_path}?{urlencode(params)}")[{default_label}]'
|
|
|
|
|
|
def ref(ref: Reference) -> str:
|
|
"""Formats a Reference."""
|
|
|
|
# for now no other types are implemented
|
|
# replace this with a match/case when that happens
|
|
return format_pdf_link(ref)
|