Python interface to generate executable Typst code.
Project description
typstpy
Introduction
typstpy is a python package for generating executable typst codes. This package is written primarily in functional programming paradigm with some OOP contents. Each module in this package has greater than 90% unit test coverage.
This package provides interfaces which are as close as possible to typst's native functions. Through typstpy and other data processing packages, you can generate data report instantly.
Repository on GitHub: python-typst. Homepage on PyPI: python-typst. Any contributions are welcome.
Change logs
- 1.4.0:
- Improve type safety with explicit type aliases (
TypstCode,TypstValue,CoreFunc,TypstFunc) in_core/types.py. - Add comprehensive docstrings and examples for core functions (
implement,attach_func,render_value). - Refactor IR (Intermediate Representation) to use formal
TypstExprprotocol with better structure forRawExpr,SequenceExpr, andMappingExpr. - Improve rendering logic in
protocols.pyandrender.pyto handle Typst-specific patterns (e.g., color-map spreading). - Add comprehensive test suite in
tests/typstpy/_core/covering docstrings, exports, IR, protocols, registry, and types.
- Improve type safety with explicit type aliases (
- 1.4.0-alpha.1:
- Centralize core rendering and callable type aliases in
_core.types. - Preserve decorated function types for core decorators and remove broad
Callable[..., Any]usage. - Use explicit
TypstCode,TypstValue,CoreFunc, andTypstFuncannotations across_core,customizations, and docs helpers. - Simplify attrs imports by using
from attrs import frozendirectly.
- Centralize core rendering and callable type aliases in
- 1.4.0-alpha.0:
- Improve internal series spread handling for single children.
- Use explicit exceptions instead of assertions for public argument validation.
- Fix
import_without names andshow_(None, ...)rendering. - Refactor: add
render_content()to IR protocol, removing fragilestrip_bracechar slicing. - Refactor: extract
_make_where_func/_make_with_funcfromimplementdecorator. - Clarify spread logic: split
_should_spread_single_childinto dedicated helpers. - Add missing
Raises:sections to docstrings across std modules. - Migrate type annotations to Python 3.10+ union syntax (
X | Noneetc.). - Add
UP(pyupgrade) to ruff lint ruleset. - Add
call_factory function tocustomizationsmodule.
- 1.3.0:
- Support for typst version: 0.14.2.
- 1.2.1:
- Clear type annotations.
- Improved support for the typst 0.13.1 version.
- 1.2.0:
- Support for typst version: 0.13.x.
- Migrate
set_,show_andimport_totypstpy.stdmodule.
- 1.1.1:
- Fix: Fix the behavior of
with_.
- Fix: Fix the behavior of
- 1.1.0: Provide
customizationsmodule to support custom functions. - 1.0.4: Implement package
subpar. - 1.0.3:
- Fix: Fix the behavior of
show_. - Compatibility: The parameters' order of
show_is flipped compared to previous version.
- Fix: Fix the behavior of
- 1.0.2: Improved type annotations.
- 1.0.1: Implement
set,show, andimport. - 1.0.0: Completed documentation and test cases in
layout,model,textandvisualizemodules. Improved functionality. - 1.0.0-beta.2: Improved the implementation and documentation of functions in the
layoutmodule. - 1.0.0-beta.1: Completely reconstructed the underlying implementation.
Installation
pip install typstpy
How to customize?
typstpy provides the customizations module to support defining functions that are not yet supported in typstpy.
The examples are:
>>> from typstpy.customizations import *
>>> pad = normal('pad')
>>> pad(
... '[Hello, world!]',
... left='4% + 0pt',
... top='4% + 0pt',
... right='4% + 0pt',
... bottom='4% + 0pt',
... )
'#pad([Hello, world!], left: 4% + 0pt, top: 4% + 0pt, right: 4% + 0pt, bottom: 4% + 0pt)'
>>> pagebreak = normal('pagebreak')
>>> pagebreak(weak=True)
'#pagebreak(weak: true)'
>>> rgb = positional('rgb')
>>> color_lighten = instance('lighten')
>>> color_lighten(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).lighten(50%)'
>>> rgb = positional('rgb')
>>> rgb(255, 255, 255, '50%')
'#rgb(255, 255, 255, 50%)'
>>> table = post_series('table')
>>> table(
... '[1]',
... '[2]',
... '[3]',
... columns=['1fr', '2fr', '3fr'],
... rows=['1fr', '2fr', '3fr'],
... gutter=['1fr', '2fr', '3fr'],
... column_gutter=['1fr', '2fr', '3fr'],
... row_gutter=['1fr', '2fr', '3fr'],
... fill='red',
... align=['center', 'center', 'center'],
... )
'#table(columns: (1fr, 2fr, 3fr), rows: (1fr, 2fr, 3fr), gutter: (1fr, 2fr, 3fr), column-gutter: (1fr, 2fr, 3fr), row-gutter: (1fr, 2fr, 3fr), fill: red, align: (center, center, center), [1], [2], [3])'
>>> subpar_grid = pre_series('subpar.grid')
>>> subpar_grid(
... '[]',
... '[]',
... columns=('1fr', '1fr'),
... caption='[A figure composed of two sub figures.]',
... label='<full>',
... )
'#subpar.grid([], [], columns: (1fr, 1fr), caption: [A figure composed of two sub figures.], label: <full>)'
Current Supports
Examples
std.align:
>>> from typstpy.std.text import lorem
>>> align('"Hello, World!"', 'center')
'#align(center, "Hello, World!")'
>>> align('[Hello, World!]', 'center')
'#align(center, [Hello, World!])'
>>> align(lorem(20), 'center')
'#align(center, lorem(20))'
std.bibliography:
>>> bibliography('"bibliography.bib"', style='"cell"')
'#bibliography("bibliography.bib", style: "cell")'
std.block:
>>> from typstpy.std.text import lorem
>>> block('"Hello, World!"')
'#block("Hello, World!")'
>>> block('[Hello, World!]')
'#block([Hello, World!])'
>>> block(lorem(20))
'#block(lorem(20))'
>>> block(lorem(20), width='100%')
'#block(lorem(20), width: 100%)'
std.box:
>>> from typstpy.std.text import lorem
>>> box('"Hello, World!"')
'#box("Hello, World!")'
>>> box('[Hello, World!]')
'#box([Hello, World!])'
>>> box(lorem(20))
'#box(lorem(20))'
>>> box(lorem(20), width='100%')
'#box(lorem(20), width: 100%)'
std.bullet_list:
>>> from typstpy.std.text import lorem
>>> bullet_list(lorem(20), lorem(20), lorem(20))
'#list(lorem(20), lorem(20), lorem(20))'
>>> bullet_list(lorem(20), lorem(20), lorem(20), tight=False)
'#list(tight: false, lorem(20), lorem(20), lorem(20))'
std.bullet_list.item:
>>> bullet_list.item('[Hello, World!]')
'#list.item([Hello, World!])'
std.circle:
>>> circle('[Hello, world!]')
'#circle([Hello, world!])'
>>> circle('[Hello, world!]', radius='10pt')
'#circle([Hello, world!], radius: 10pt)'
>>> circle('[Hello, world!]', width='100%')
'#circle([Hello, world!], width: 100%)'
std.cite:
>>> cite('<label>')
'#cite(<label>)'
>>> cite('<label>', supplement='[Hello, World!]')
'#cite(<label>, supplement: [Hello, World!])'
>>> cite('<label>', form='"prose"')
'#cite(<label>, form: "prose")'
>>> cite('<label>', style='"annual-reviews"')
'#cite(<label>, style: "annual-reviews")'
std.cmyk:
>>> cmyk('0%', '0%', '0%', '0%')
'#cmyk(0%, 0%, 0%, 0%)'
>>> cmyk('50%', '50%', '50%', '50%')
'#cmyk(50%, 50%, 50%, 50%)'
std.colbreak:
>>> colbreak()
'#colbreak()'
>>> colbreak(weak=True)
'#colbreak(weak: true)'
std.color:
>>> color()
'#color'
std.color.components:
>>> color.components(rgb(255, 255, 255))
'#rgb(255, 255, 255).components()'
std.color.darken:
>>> color.darken(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).darken(50%)'
std.color.desaturate:
>>> color.desaturate(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).desaturate(50%)'
std.color.hsl:
>>> color.hsl('0deg', '50%', '50%', '50%')
'#color.hsl(0deg, 50%, 50%, 50%)'
>>> color.hsl('0deg', '50%', '50%')
'#color.hsl(0deg, 50%, 50%)'
std.color.hsv:
>>> color.hsv('0deg', '50%', '50%', '50%')
'#color.hsv(0deg, 50%, 50%, 50%)'
>>> color.hsv('0deg', '50%', '50%')
'#color.hsv(0deg, 50%, 50%)'
std.color.lighten:
>>> color.lighten(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).lighten(50%)'
std.color.linear_rgb:
>>> color.linear_rgb(255, 255, 255)
'#color.linear-rgb(255, 255, 255)'
>>> color.linear_rgb('50%', '50%', '50%', '50%')
'#color.linear-rgb(50%, 50%, 50%, 50%)'
std.color.map:
>>> color.map('turbo')
'#color.map.turbo'
std.color.mix:
>>> color.mix(rgb(255, 255, 255), rgb(0, 0, 0), space='oklch')
'#color.mix(rgb(255, 255, 255), rgb(0, 0, 0), space: oklch)'
std.color.negate:
>>> color.negate(rgb(255, 255, 255))
'#rgb(255, 255, 255).negate()'
>>> color.negate(rgb(255, 255, 255), space='oklch')
'#rgb(255, 255, 255).negate(space: oklch)'
std.color.opacify:
>>> color.opacify(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).opacify(50%)'
std.color.rotate:
>>> color.rotate(rgb(255, 255, 255), '90deg')
'#rgb(255, 255, 255).rotate(90deg)'
std.color.saturate:
>>> color.saturate(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).saturate(50%)'
std.color.space:
>>> color.space(rgb(255, 255, 255))
'#rgb(255, 255, 255).space()'
std.color.to_hex:
>>> color.to_hex(rgb(255, 255, 255))
'#rgb(255, 255, 255).to-hex()'
std.color.transparentize:
>>> color.transparentize(rgb(255, 255, 255), '50%')
'#rgb(255, 255, 255).transparentize(50%)'
std.columns:
>>> from typstpy.std.text import lorem
>>> columns(lorem(20))
'#columns(lorem(20))'
>>> columns(lorem(20), 3)
'#columns(3, lorem(20))'
>>> columns(lorem(20), 3, gutter='8% + 0pt')
'#columns(3, lorem(20), gutter: 8% + 0pt)'
std.curve:
>>> curve(
... curve.move(('0pt', '50pt')),
... curve.line(('100pt', '50pt')),
... curve.cubic(None, ('90pt', '0pt'), ('50pt', '0pt')),
... curve.close(),
... stroke='blue',
... )
'#curve(stroke: blue, curve.move((0pt, 50pt)), curve.line((100pt, 50pt)), curve.cubic(none, (90pt, 0pt), (50pt, 0pt)), curve.close())'
std.curve.close:
>>> curve.close(mode='"smooth"')
'#curve.close()'
>>> curve.close(mode='"straight"')
'#curve.close(mode: "straight")'
std.curve.cubic:
>>> curve.cubic(('10pt', '10pt'), ('20pt', '20pt'), ('30pt', '30pt'))
'#curve.cubic((10pt, 10pt), (20pt, 20pt), (30pt, 30pt))'
>>> curve.cubic(
... ('10pt', '10pt'), ('20pt', '20pt'), ('30pt', '30pt'), relative=True
... )
'#curve.cubic((10pt, 10pt), (20pt, 20pt), (30pt, 30pt), relative: true)'
std.curve.line:
>>> curve.line(('10pt', '10pt'))
'#curve.line((10pt, 10pt))'
>>> curve.line(('10pt', '10pt'), relative=True)
'#curve.line((10pt, 10pt), relative: true)'
std.curve.move:
>>> curve.move(('10pt', '10pt'))
'#curve.move((10pt, 10pt))'
>>> curve.move(('10pt', '10pt'), relative=True)
'#curve.move((10pt, 10pt), relative: true)'
std.curve.quad:
>>> curve.quad(('10pt', '10pt'), ('20pt', '20pt'))
'#curve.quad((10pt, 10pt), (20pt, 20pt))'
>>> curve.quad(('10pt', '10pt'), ('20pt', '20pt'), relative=True)
'#curve.quad((10pt, 10pt), (20pt, 20pt), relative: true)'
std.ellipse:
>>> ellipse('[Hello, World!]')
'#ellipse([Hello, World!])'
>>> ellipse('[Hello, World!]', width='100%')
'#ellipse([Hello, World!], width: 100%)'
std.emph:
>>> emph('"Hello, World!"')
'#emph("Hello, World!")'
>>> emph('[Hello, World!]')
'#emph([Hello, World!])'
std.figure:
>>> from typstpy.std.visualize import image
>>> figure(image('"image.png"'))
'#figure(image("image.png"))'
>>> figure(image('"image.png"'), caption='[Hello, World!]')
'#figure(image("image.png"), caption: [Hello, World!])'
std.figure.caption:
>>> figure.caption('[Hello, World!]')
'#figure.caption([Hello, World!])'
>>> figure.caption('[Hello, World!]', position='top', separator='[---]')
'#figure.caption([Hello, World!], position: top, separator: [---])'
std.footnote:
>>> footnote('[Hello, World!]')
'#footnote([Hello, World!])'
>>> footnote('[Hello, World!]', numbering='"a"')
'#footnote([Hello, World!], numbering: "a")'
std.gradient:
>>> gradient()
'#gradient'
std.gradient.angle:
>>> gradient.angle(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).angle()'
std.gradient.center:
>>> gradient.center(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).center()'
std.gradient.conic:
>>> gradient.conic(color.map('viridis'), angle='90deg', center=('10%', '40%'))
'#gradient.conic(..color.map.viridis, angle: 90deg, center: (10%, 40%))'
std.gradient.focal_center:
>>> gradient.focal_center(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).focal-center()'
std.gradient.focal_radius:
>>> gradient.focal_radius(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).focal-radius()'
std.gradient.kind:
>>> gradient.kind(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).kind()'
std.gradient.linear:
>>> gradient.linear(rgb(255, 255, 255), rgb(0, 0, 0))
'#gradient.linear(rgb(255, 255, 255), rgb(0, 0, 0))'
std.gradient.radial:
>>> gradient.radial(
... color.map('viridis'), focal_center=('10%', '40%'), focal_radius='5%'
... )
'#gradient.radial(..color.map.viridis, focal-center: (10%, 40%), focal-radius: 5%)'
std.gradient.radius:
>>> gradient.radius(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).radius()'
std.gradient.relative:
>>> gradient.relative(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).relative()'
std.gradient.repeat:
>>> gradient.repeat(gradient.radial('aqua', 'white'), 4, mirror=True)
'#gradient.radial(aqua, white).repeat(4, mirror: true)'
std.gradient.sharp:
>>> gradient.sharp(gradient.linear(color.map('rainbow')), 5, smoothness='50%')
'#gradient.linear(..color.map.rainbow).sharp(5, smoothness: 50%)'
std.gradient.space:
>>> gradient.space(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).space()'
std.gradient.stops:
>>> gradient.stops(gradient.linear('red', 'blue'))
'#gradient.linear(red, blue).stops()'
std.grid:
>>> from typstpy.std.text import lorem
>>> grid(lorem(20), lorem(20), lorem(20), align=('center',) * 3)
'#grid(align: (center, center, center), lorem(20), lorem(20), lorem(20))'
std.grid.cell:
>>> from typstpy.std.text import lorem
>>> grid.cell(lorem(20), x=3, y=3)
'#grid.cell(lorem(20), x: 3, y: 3)'
std.heading:
>>> heading('[Hello, World!]')
'#heading([Hello, World!])'
>>> heading('[Hello, World!]', level=1)
'#heading([Hello, World!], level: 1)'
>>> heading('[Hello, World!]', level=1, depth=2)
'#heading([Hello, World!], level: 1, depth: 2)'
>>> heading('[Hello, World!]', level=1, depth=2, offset=10)
'#heading([Hello, World!], level: 1, depth: 2, offset: 10)'
>>> heading('[Hello, World!]', level=1, depth=2, offset=10, numbering='"a"')
'#heading([Hello, World!], level: 1, depth: 2, offset: 10, numbering: "a")'
>>> heading(
... '[Hello, World!]',
... level=1,
... depth=2,
... offset=10,
... numbering='"a"',
... supplement='"Supplement"',
... )
'#heading([Hello, World!], level: 1, depth: 2, offset: 10, numbering: "a", supplement: "Supplement")'
std.hide:
>>> from typstpy.std.text import lorem
>>> hide(lorem(20))
'#hide(lorem(20))'
std.highlight:
>>> highlight('"Hello, world!"', fill=rgb('"#ffffff"'))
'#highlight("Hello, world!", fill: rgb("#ffffff"))'
>>> highlight('"Hello, world!"', fill=rgb('"#ffffff"'), stroke=rgb('"#000000"'))
'#highlight("Hello, world!", fill: rgb("#ffffff"), stroke: rgb("#000000"))'
>>> highlight(
... '"Hello, world!"',
... fill=rgb('"#ffffff"'),
... stroke=rgb('"#000000"'),
... top_edge='"bounds"',
... bottom_edge='"bounds"',
... )
'#highlight("Hello, world!", fill: rgb("#ffffff"), stroke: rgb("#000000"), top-edge: "bounds", bottom-edge: "bounds")'
std.hspace:
>>> hspace('1em')
'#h(1em)'
>>> hspace('1em', weak=True)
'#h(1em, weak: true)'
std.image:
>>> image('"image.png"')
'#image("image.png")'
>>> image('"image.png"', fit='"contain"')
'#image("image.png", fit: "contain")'
std.line:
>>> line()
'#line()'
>>> line(end=('100% + 0pt', '100% + 0pt'))
'#line(end: (100% + 0pt, 100% + 0pt))'
>>> line(angle='90deg')
'#line(angle: 90deg)'
>>> line(stroke='1pt + red')
'#line(stroke: 1pt + red)'
std.linebreak:
>>> linebreak()
'#linebreak()'
>>> linebreak(justify=True)
'#linebreak(justify: true)'
std.link:
>>> link('"https://typst.app"')
'#link("https://typst.app")'
>>> link('"https://typst.app"', '"Typst"')
'#link("https://typst.app", "Typst")'
std.lorem:
>>> lorem(10)
'#lorem(10)'
std.lower:
>>> lower('"Hello, World!"')
'#lower("Hello, World!")'
>>> lower('[Hello, World!]')
'#lower([Hello, World!])'
>>> lower(upper('"Hello, World!"'))
'#lower(upper("Hello, World!"))'
std.luma:
>>> luma('50%')
'#luma(50%)'
>>> luma('50%', '50%')
'#luma(50%, 50%)'
std.move:
>>> from typstpy.std.text import lorem
>>> move(lorem(20), dx='50% + 10pt', dy='10% + 5pt')
'#move(lorem(20), dx: 50% + 10pt, dy: 10% + 5pt)'
std.numbered_list:
>>> from typstpy.std.text import lorem
>>> numbered_list(lorem(20), lorem(20), lorem(20))
'#enum(lorem(20), lorem(20), lorem(20))'
>>> numbered_list(lorem(20), lorem(20), lorem(20), tight=False)
'#enum(tight: false, lorem(20), lorem(20), lorem(20))'
std.numbered_list.item:
>>> numbered_list.item('[Hello, World!]', number=2)
'#enum.item(2, [Hello, World!])'
std.numbering:
>>> numbering('"1.1)"', 1, 2)
'#numbering("1.1)", 1, 2)'
std.oklab:
>>> oklab('50%', '0%', '0%')
'#oklab(50%, 0%, 0%)'
>>> oklab('50%', '0%', '0%', '50%')
'#oklab(50%, 0%, 0%, 50%)'
std.oklch:
>>> oklch('50%', '0%', '0deg')
'#oklch(50%, 0%, 0deg)'
>>> oklch('50%', '0%', '0deg', '50%')
'#oklch(50%, 0%, 0deg, 50%)'
std.outline:
>>> outline()
'#outline()'
>>> outline(title='"Hello, World!"', target=heading.where(outlined=True))
'#outline(title: "Hello, World!", target: heading.where(outlined: true))'
std.overline:
>>> overline('"Hello, World!"')
'#overline("Hello, World!")'
>>> overline('[Hello, World!]')
'#overline([Hello, World!])'
>>> overline(
... upper('"Hello, World!"'),
... stroke='red',
... offset='0pt',
... extent='0pt',
... evade=False,
... background=True,
... )
'#overline(upper("Hello, World!"), stroke: red, offset: 0pt, evade: false, background: true)'
std.pad:
>>> from typstpy.std.text import lorem
>>> pad(
... lorem(20),
... left='4% + 0pt',
... top='4% + 0pt',
... right='4% + 0pt',
... bottom='4% + 0pt',
... )
'#pad(lorem(20), left: 4% + 0pt, top: 4% + 0pt, right: 4% + 0pt, bottom: 4% + 0pt)'
std.page:
>>> from typstpy.std.text import lorem
>>> page(lorem(20))
'#page(lorem(20))'
>>> page(lorem(20), paper='"a0"', width='8.5in', height='11in')
'#page(lorem(20), paper: "a0", width: 8.5in, height: 11in)'
std.pagebreak:
>>> pagebreak()
'#pagebreak()'
>>> pagebreak(weak=True)
'#pagebreak(weak: true)'
>>> pagebreak(to='"even"')
'#pagebreak(to: "even")'
std.par:
>>> par('"Hello, World!"')
'#par("Hello, World!")'
>>> par('[Hello, World!]')
'#par([Hello, World!])'
>>> par(
... '[Hello, World!]',
... leading='0.1em',
... spacing='0.5em',
... justify=True,
... linebreaks='"simple"',
... first_line_indent='0.2em',
... hanging_indent='0.3em',
... )
'#par([Hello, World!], leading: 0.1em, spacing: 0.5em, justify: true, linebreaks: "simple", first-line-indent: 0.2em, hanging-indent: 0.3em)'
std.parbreak:
>>> parbreak()
'#parbreak()'
std.place:
>>> from typstpy.std.text import lorem
>>> place(lorem(20))
'#place(lorem(20))'
>>> place(lorem(20), 'top')
'#place(top, lorem(20))'
std.place.flush:
>>> place.flush()
'#place.flush()'
std.quote:
>>> quote('"Hello, World!"')
'#quote("Hello, World!")'
>>> quote('"Hello, World!"', block=True)
'#quote("Hello, World!", block: true)'
>>> quote('"Hello, World!"', quotes=False)
'#quote("Hello, World!", quotes: false)'
>>> quote('"Hello, World!"', attribution='"John Doe"')
'#quote("Hello, World!", attribution: "John Doe")'
std.raw:
>>> raw('"Hello, World!"')
'#raw("Hello, World!")'
>>> raw('"Hello, World!"', block=True, align='center')
'#raw("Hello, World!", block: true, align: center)'
>>> raw('"Hello, World!"', lang='"rust"')
'#raw("Hello, World!", lang: "rust")'
>>> raw('"Hello, World!"', tab_size=4)
'#raw("Hello, World!", tab-size: 4)'
std.raw.line:
>>> raw.line(1, 1, '"Hello, World!"', '"Hello, World!"')
'#raw.line(1, 1, "Hello, World!", "Hello, World!")'
std.ref:
>>> ref('<label>')
'#ref(<label>)'
>>> ref('<label>', supplement='[Hello, World!]')
'#ref(<label>, supplement: [Hello, World!])'
std.repeat:
>>> from typstpy.std.text import lorem
>>> repeat(lorem(20), gap='0.5em')
'#repeat(lorem(20), gap: 0.5em)'
>>> repeat(lorem(20), gap='0.5em', justify=False)
'#repeat(lorem(20), gap: 0.5em, justify: false)'
std.rgb:
>>> rgb(255, 255, 255)
'#rgb(255, 255, 255)'
>>> rgb('50%', '50%', '50%', '50%')
'#rgb(50%, 50%, 50%, 50%)'
>>> rgb('"#ffffff"')
'#rgb("#ffffff")'
std.rotate:
>>> from typstpy.std.text import lorem
>>> rotate(lorem(20), '20deg')
'#rotate(20deg, lorem(20))'
>>> rotate(lorem(20), '20deg', origin='left + horizon')
'#rotate(20deg, lorem(20), origin: left + horizon)'
std.scale:
>>> from typstpy.std.text import lorem
>>> scale(lorem(20), '50%')
'#scale(50%, lorem(20))'
>>> scale(lorem(20), x='50%', y='50%')
'#scale(lorem(20), x: 50%, y: 50%)'
>>> scale(lorem(20), '50%', x='50%', y='50%')
'#scale(50%, lorem(20), x: 50%, y: 50%)'
std.skew:
>>> from typstpy.std.text import lorem
>>> skew(lorem(20), ax='10deg', ay='20deg')
'#skew(lorem(20), ax: 10deg, ay: 20deg)'
>>> skew(
... lorem(20), ax='10deg', ay='20deg', origin='left + horizon', reflow=True
... )
'#skew(lorem(20), ax: 10deg, ay: 20deg, origin: left + horizon, reflow: true)'
std.smallcaps:
>>> smallcaps('"Hello, World!"')
'#smallcaps("Hello, World!")'
>>> smallcaps('[Hello, World!]')
'#smallcaps([Hello, World!])'
>>> smallcaps('"Hello, World!"', all=True)
'#smallcaps("Hello, World!", all: true)'
std.smartquote:
>>> smartquote(double=False, enabled=False, alternative=True, quotes='"()"')
'#smartquote(double: false, enabled: false, alternative: true, quotes: "()")'
>>> smartquote(quotes=('"()"', '"dict()"'))
'#smartquote(quotes: ("()", "dict()"))'
std.stack:
>>> from typstpy.std.visualize import rect
>>> stack(rect(width='40pt'), dir='btt')
'#stack(dir: btt, rect(width: 40pt))'
>>> stack(
... rect(width='40pt'), rect(width='120pt'), rect(width='90pt'), dir='btt'
... )
'#stack(dir: btt, rect(width: 40pt), rect(width: 120pt), rect(width: 90pt))'
>>> stack(
... (rect(width='40pt'), rect(width='120pt'), rect(width='90pt')), dir='btt'
... )
'#stack(dir: btt, ..(rect(width: 40pt), rect(width: 120pt), rect(width: 90pt)))'
std.strike:
>>> strike('"Hello, World!"')
'#strike("Hello, World!")'
>>> strike('[Hello, World!]')
'#strike([Hello, World!])'
>>> strike(
... upper('"Hello, World!"'),
... stroke='red',
... offset='0.1em',
... extent='0.2em',
... background=True,
... )
'#strike(upper("Hello, World!"), stroke: red, offset: 0.1em, extent: 0.2em, background: true)'
std.strong:
>>> strong('"Hello, World!"')
'#strong("Hello, World!")'
>>> strong('[Hello, World!]', delta=400)
'#strong([Hello, World!], delta: 400)'
std.subscript:
>>> subscript('"Hello, World!"')
'#sub("Hello, World!")'
>>> subscript('[Hello, World!]')
'#sub([Hello, World!])'
>>> subscript(
... '[Hello, World!]', typographic=False, baseline='0.3em', size='0.7em'
... )
'#sub([Hello, World!], typographic: false, baseline: 0.3em, size: 0.7em)'
std.superscript:
>>> superscript('"Hello, World!"')
'#super("Hello, World!")'
>>> superscript('[Hello, World!]')
'#super([Hello, World!])'
>>> superscript(
... '[Hello, World!]', typographic=False, baseline='-0.4em', size='0.7em'
... )
'#super([Hello, World!], typographic: false, baseline: -0.4em, size: 0.7em)'
std.table:
>>> table('[1]')
'#table([1])'
>>> table('[1]', '[2]', '[3]')
'#table([1], [2], [3])'
>>> table(
... '[1]',
... '[2]',
... '[3]',
... columns=['1fr', '2fr', '3fr'],
... rows=['1fr', '2fr', '3fr'],
... gutter=['1fr', '2fr', '3fr'],
... column_gutter=['1fr', '2fr', '3fr'],
... row_gutter=['1fr', '2fr', '3fr'],
... fill='red',
... align=['center', 'center', 'center'],
... )
'#table(columns: (1fr, 2fr, 3fr), rows: (1fr, 2fr, 3fr), gutter: (1fr, 2fr, 3fr), column-gutter: (1fr, 2fr, 3fr), row-gutter: (1fr, 2fr, 3fr), fill: red, align: (center, center, center), [1], [2], [3])'
std.terms:
>>> from typstpy.std.text import lorem
>>> terms(('[1]', lorem(20)))
'#terms(([1], lorem(20)))'
>>> terms(('[1]', lorem(20)), ('[1]', lorem(20)))
'#terms(([1], lorem(20)), ([1], lorem(20)))'
>>> terms(('[1]', lorem(20)), ('[1]', lorem(20)), tight=False)
'#terms(tight: false, ([1], lorem(20)), ([1], lorem(20)))'
>>> terms(terms.item('[1]', lorem(20)), terms.item('[1]', lorem(20)))
'#terms(terms.item([1], lorem(20)), terms.item([1], lorem(20)))'
std.terms.item:
>>> terms.item('"term"', '"description"')
'#terms.item("term", "description")'
std.text:
>>> text('"Hello, World!"')
'#text("Hello, World!")'
>>> text('[Hello, World!]')
'#text([Hello, World!])'
>>> text('[Hello, World!]', font='"Times New Roman"')
'#text([Hello, World!], font: "Times New Roman")'
std.tiling:
>>> from typstpy.std.layout import place
>>> tiling(
... f'[{place(line(start=("0%", "0%"), end=("100%", "100%")))}, {place(line(start=("0%", "100%"), end=("100%", "0%")))}]',
... size=('30pt', '30pt'),
... )
'#tiling([#place(line(start: (0%, 0%), end: (100%, 100%))), #place(line(start: (0%, 100%), end: (100%, 0%)))], size: (30pt, 30pt))'
std.title:
>>> title()
'#title()'
>>> title('[My Thesis]')
'#title([My Thesis])'
std.underline:
>>> underline('"Hello, World!"')
'#underline("Hello, World!")'
>>> underline('[Hello, World!]')
'#underline([Hello, World!])'
>>> underline(
... '[Hello, World!]',
... stroke='1pt + red',
... offset='0pt',
... extent='1pt',
... evade=False,
... background=True,
... )
'#underline([Hello, World!], stroke: 1pt + red, offset: 0pt, extent: 1pt, evade: false, background: true)'
std.upper:
>>> upper('"Hello, World!"')
'#upper("Hello, World!")'
>>> upper('[Hello, World!]')
'#upper([Hello, World!])'
>>> upper(lower('"Hello, World!"'))
'#upper(lower("Hello, World!"))'
std.visualize.path:
>>> path(('0%', '0%'), ('100%', '0%'), ('100%', '100%'), ('0%', '100%'))
'#path((0%, 0%), (100%, 0%), (100%, 100%), (0%, 100%))'
>>> path(
... ('0%', '0%'),
... ('100%', '0%'),
... ('100%', '100%'),
... ('0%', '100%'),
... fill='red',
... )
'#path(fill: red, (0%, 0%), (100%, 0%), (100%, 100%), (0%, 100%))'
>>> path(
... ('0%', '0%'),
... ('100%', '0%'),
... ('100%', '100%'),
... ('0%', '100%'),
... fill='red',
... stroke='blue',
... )
'#path(fill: red, stroke: blue, (0%, 0%), (100%, 0%), (100%, 100%), (0%, 100%))'
std.vspace:
>>> vspace('1em')
'#v(1em)'
>>> vspace('1em', weak=True)
'#v(1em, weak: true)'
universe.subpar.grid:
>>> grid(
... figure(image('"image.png"')),
... '<a>',
... figure(image('"image.png"')),
... '<b>',
... columns=('1fr', '1fr'),
... caption='[A figure composed of two sub figures.]',
... label='<full>',
... )
'#subpar.grid(figure(image("image.png")), <a>, figure(image("image.png")), <b>, columns: (1fr, 1fr), caption: [A figure composed of two sub figures.], label: <full>)'
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file typstpy-1.4.0.tar.gz.
File metadata
- Download URL: typstpy-1.4.0.tar.gz
- Upload date:
- Size: 69.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b43a2a76ff228a6bc1f6f9e0eb333e38b13dcf164ac56c48198db5942781f1b0
|
|
| MD5 |
52d2368f7a6325c2dcd9a4b14e1ebc5e
|
|
| BLAKE2b-256 |
86fd018075d7320b2167f5a06c23580fa28d546b41bfeef6b4a075587d0bce31
|
File details
Details for the file typstpy-1.4.0-py3-none-any.whl.
File metadata
- Download URL: typstpy-1.4.0-py3-none-any.whl
- Upload date:
- Size: 57.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
063371df4236bcafb16a97e7bbd28256979aae783db6a8aba21cd95445782746
|
|
| MD5 |
020bae6da166a9a80a88f09ccd2d7419
|
|
| BLAKE2b-256 |
e73b8a2815bbf5dfaada1806bd76603d40b0837333873bd7c626265bf6fbe23c
|