inklet 2.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- inklet-2.5.0/.gitattributes +2 -0
- inklet-2.5.0/.github/workflows/checks.yml +77 -0
- inklet-2.5.0/.gitignore +35 -0
- inklet-2.5.0/CHANGELOG.md +62 -0
- inklet-2.5.0/CONTRACT.md +76 -0
- inklet-2.5.0/CONTRIBUTING.md +94 -0
- inklet-2.5.0/LICENSE +21 -0
- inklet-2.5.0/PKG-INFO +171 -0
- inklet-2.5.0/README.md +145 -0
- inklet-2.5.0/THIRD_PARTY_NOTICES.md +67 -0
- inklet-2.5.0/docs/api.md +1085 -0
- inklet-2.5.0/docs/cli.md +92 -0
- inklet-2.5.0/docs/concepts.md +92 -0
- inklet-2.5.0/docs/cookbook.md +2723 -0
- inklet-2.5.0/docs/data.md +101 -0
- inklet-2.5.0/docs/design/page_grid.md +133 -0
- inklet-2.5.0/docs/design/v2.md +40 -0
- inklet-2.5.0/docs/diagram-components.md +25 -0
- inklet-2.5.0/docs/diagrams.md +93 -0
- inklet-2.5.0/docs/examples.md +63 -0
- inklet-2.5.0/docs/export-review.md +135 -0
- inklet-2.5.0/docs/index.md +49 -0
- inklet-2.5.0/docs/installation.md +101 -0
- inklet-2.5.0/docs/layout.md +87 -0
- inklet-2.5.0/docs/migration.md +66 -0
- inklet-2.5.0/docs/plotting.md +105 -0
- inklet-2.5.0/docs/publication-plots.md +70 -0
- inklet-2.5.0/docs/quickstart.md +106 -0
- inklet-2.5.0/docs/release-checks.md +48 -0
- inklet-2.5.0/docs/stress20.md +77 -0
- inklet-2.5.0/docs/stylesheets/code.css +162 -0
- inklet-2.5.0/docs/stylesheets/inklet.css +30 -0
- inklet-2.5.0/docs/three-images.md +85 -0
- inklet-2.5.0/docs/troubleshooting.md +85 -0
- inklet-2.5.0/docs/v2.5.md +169 -0
- inklet-2.5.0/docs/v2.md +172 -0
- inklet-2.5.0/examples/broken_axis.py +59 -0
- inklet-2.5.0/examples/feature_flow.py +21 -0
- inklet-2.5.0/examples/gallery.py +217 -0
- inklet-2.5.0/examples/graph.py +79 -0
- inklet-2.5.0/examples/hello_figure.py +30 -0
- inklet-2.5.0/examples/panels.py +72 -0
- inklet-2.5.0/examples/polar.py +93 -0
- inklet-2.5.0/examples/render_smoke.py +61 -0
- inklet-2.5.0/examples/state_machine.py +52 -0
- inklet-2.5.0/examples/stress20.py +289 -0
- inklet-2.5.0/examples/v25_document.py +64 -0
- inklet-2.5.0/examples/v2_cases.py +63 -0
- inklet-2.5.0/examples/v2_document.py +61 -0
- inklet-2.5.0/figures/annot.py +169 -0
- inklet-2.5.0/figures/bio3d.py +69 -0
- inklet-2.5.0/figures/cartoon.py +7 -0
- inklet-2.5.0/figures/chem_data.py +2154 -0
- inklet-2.5.0/figures/chem_fingerprints.py +887 -0
- inklet-2.5.0/figures/data/1m17-kinase.pdb +1395 -0
- inklet-2.5.0/figures/data/README.md +8 -0
- inklet-2.5.0/figures/drug_discovery.py +664 -0
- inklet-2.5.0/figures/mouse_brain_data.py +269 -0
- inklet-2.5.0/figures/neural_activity.py +154 -0
- inklet-2.5.0/figures/pdbfile.py +181 -0
- inklet-2.5.0/figures/showcase_part.py +80 -0
- inklet-2.5.0/figures/showcase_process.py +81 -0
- inklet-2.5.0/figures/showcase_season.py +97 -0
- inklet-2.5.0/figures/structure.py +1022 -0
- inklet-2.5.0/figures/structure_data.py +201 -0
- inklet-2.5.0/figures/target.py +468 -0
- inklet-2.5.0/figures/trial.py +229 -0
- inklet-2.5.0/gallery/README.md +27 -0
- inklet-2.5.0/gallery/chem_fingerprints.png +0 -0
- inklet-2.5.0/gallery/flow.png +0 -0
- inklet-2.5.0/gallery/part.png +0 -0
- inklet-2.5.0/gallery/plots.png +0 -0
- inklet-2.5.0/gallery/polar.png +0 -0
- inklet-2.5.0/gallery/process.png +0 -0
- inklet-2.5.0/gallery/season.png +0 -0
- inklet-2.5.0/gallery/stress20.png +0 -0
- inklet-2.5.0/gallery/structure.png +0 -0
- inklet-2.5.0/mkdocs.yml +68 -0
- inklet-2.5.0/pyproject.toml +57 -0
- inklet-2.5.0/requirements-ci.txt +24 -0
- inklet-2.5.0/requirements-docs.txt +47 -0
- inklet-2.5.0/scripts/bench_svg.py +291 -0
- inklet-2.5.0/scripts/rasterise.sh +19 -0
- inklet-2.5.0/scripts/sanity_typeset.py +40 -0
- inklet-2.5.0/src/inklet/__init__.py +451 -0
- inklet-2.5.0/src/inklet/__main__.py +2 -0
- inklet-2.5.0/src/inklet/assets/__init__.py +42 -0
- inklet-2.5.0/src/inklet/assets/asset.py +374 -0
- inklet-2.5.0/src/inklet/assets/cache.py +134 -0
- inklet-2.5.0/src/inklet/assets/cutout.py +205 -0
- inklet-2.5.0/src/inklet/assets/deps.py +83 -0
- inklet-2.5.0/src/inklet/assets/harmonise.py +191 -0
- inklet-2.5.0/src/inklet/assets/lineart.py +313 -0
- inklet-2.5.0/src/inklet/assets/mask.py +117 -0
- inklet-2.5.0/src/inklet/assets/provenance.py +135 -0
- inklet-2.5.0/src/inklet/assets/raster.py +157 -0
- inklet-2.5.0/src/inklet/assets/sidecar.py +112 -0
- inklet-2.5.0/src/inklet/assets/silhouette.py +300 -0
- inklet-2.5.0/src/inklet/cli.py +197 -0
- inklet-2.5.0/src/inklet/components.py +143 -0
- inklet-2.5.0/src/inklet/core/__init__.py +26 -0
- inklet-2.5.0/src/inklet/core/diagram.py +574 -0
- inklet-2.5.0/src/inklet/core/envelope.py +269 -0
- inklet-2.5.0/src/inklet/core/geom.py +201 -0
- inklet-2.5.0/src/inklet/core/prims.py +342 -0
- inklet-2.5.0/src/inklet/core/style.py +179 -0
- inklet-2.5.0/src/inklet/core/trace.py +165 -0
- inklet-2.5.0/src/inklet/core/units.py +61 -0
- inklet-2.5.0/src/inklet/diagnostics/__init__.py +126 -0
- inklet-2.5.0/src/inklet/diagnostics/abut.py +54 -0
- inklet-2.5.0/src/inklet/diagnostics/break_rules.py +292 -0
- inklet-2.5.0/src/inklet/diagnostics/color.py +149 -0
- inklet-2.5.0/src/inklet/diagnostics/cross.py +97 -0
- inklet-2.5.0/src/inklet/diagnostics/image.py +164 -0
- inklet-2.5.0/src/inklet/diagnostics/key_rules.py +570 -0
- inklet-2.5.0/src/inklet/diagnostics/link_rules.py +572 -0
- inklet-2.5.0/src/inklet/diagnostics/path_rules.py +886 -0
- inklet-2.5.0/src/inklet/diagnostics/plot_rules.py +122 -0
- inklet-2.5.0/src/inklet/diagnostics/report.py +58 -0
- inklet-2.5.0/src/inklet/diagnostics/rules.py +3137 -0
- inklet-2.5.0/src/inklet/diagnostics/three_rules.py +218 -0
- inklet-2.5.0/src/inklet/document/__init__.py +15 -0
- inklet-2.5.0/src/inklet/document/compiler.py +504 -0
- inklet-2.5.0/src/inklet/document/composition.py +233 -0
- inklet-2.5.0/src/inklet/document/data.py +301 -0
- inklet-2.5.0/src/inklet/document/module.py +75 -0
- inklet-2.5.0/src/inklet/document/publication.py +61 -0
- inklet-2.5.0/src/inklet/document/spec.py +255 -0
- inklet-2.5.0/src/inklet/draw/__init__.py +51 -0
- inklet-2.5.0/src/inklet/draw/annotate.py +892 -0
- inklet-2.5.0/src/inklet/draw/clip.py +531 -0
- inklet-2.5.0/src/inklet/draw/coords.py +283 -0
- inklet-2.5.0/src/inklet/draw/path.py +249 -0
- inklet-2.5.0/src/inklet/draw/place.py +155 -0
- inklet-2.5.0/src/inklet/draw/shapes.py +226 -0
- inklet-2.5.0/src/inklet/figure.py +418 -0
- inklet-2.5.0/src/inklet/layout/__init__.py +27 -0
- inklet-2.5.0/src/inklet/layout/fit.py +228 -0
- inklet-2.5.0/src/inklet/layout/flow.py +754 -0
- inklet-2.5.0/src/inklet/layout/graph.py +712 -0
- inklet-2.5.0/src/inklet/layout/graph_force.py +202 -0
- inklet-2.5.0/src/inklet/layout/graph_layered.py +1129 -0
- inklet-2.5.0/src/inklet/layout/graph_tree.py +226 -0
- inklet-2.5.0/src/inklet/layout/labels.py +490 -0
- inklet-2.5.0/src/inklet/layout/sankey.py +1054 -0
- inklet-2.5.0/src/inklet/links/__init__.py +29 -0
- inklet-2.5.0/src/inklet/links/curves.py +173 -0
- inklet-2.5.0/src/inklet/links/link.py +2464 -0
- inklet-2.5.0/src/inklet/plot/__init__.py +73 -0
- inklet-2.5.0/src/inklet/plot/axis.py +523 -0
- inklet-2.5.0/src/inklet/plot/breaks.py +429 -0
- inklet-2.5.0/src/inklet/plot/categories.py +130 -0
- inklet-2.5.0/src/inklet/plot/facets.py +255 -0
- inklet-2.5.0/src/inklet/plot/inset.py +310 -0
- inklet-2.5.0/src/inklet/plot/key.py +202 -0
- inklet-2.5.0/src/inklet/plot/marks.py +1150 -0
- inklet-2.5.0/src/inklet/plot/notes.py +220 -0
- inklet-2.5.0/src/inklet/plot/panel.py +1775 -0
- inklet-2.5.0/src/inklet/plot/png.py +125 -0
- inklet-2.5.0/src/inklet/plot/polar.py +1717 -0
- inklet-2.5.0/src/inklet/plot/ramp.py +74 -0
- inklet-2.5.0/src/inklet/plot/raster.py +191 -0
- inklet-2.5.0/src/inklet/plot/ribbon.py +187 -0
- inklet-2.5.0/src/inklet/plot/scale.py +1202 -0
- inklet-2.5.0/src/inklet/plot/scatter_raster.py +161 -0
- inklet-2.5.0/src/inklet/plot/series.py +138 -0
- inklet-2.5.0/src/inklet/plot/timescale.py +417 -0
- inklet-2.5.0/src/inklet/render/__init__.py +18 -0
- inklet-2.5.0/src/inklet/render/bundle.py +75 -0
- inklet-2.5.0/src/inklet/render/fontembed.py +391 -0
- inklet-2.5.0/src/inklet/render/glyphs.py +200 -0
- inklet-2.5.0/src/inklet/render/outline.py +173 -0
- inklet-2.5.0/src/inklet/render/paint.py +60 -0
- inklet-2.5.0/src/inklet/render/pathdata.py +207 -0
- inklet-2.5.0/src/inklet/render/pdf.py +853 -0
- inklet-2.5.0/src/inklet/render/pdftext.py +213 -0
- inklet-2.5.0/src/inklet/render/preview.py +70 -0
- inklet-2.5.0/src/inklet/render/review.py +94 -0
- inklet-2.5.0/src/inklet/render/revision.py +47 -0
- inklet-2.5.0/src/inklet/render/svg.py +1005 -0
- inklet-2.5.0/src/inklet/themes/__init__.py +46 -0
- inklet-2.5.0/src/inklet/themes/color.py +384 -0
- inklet-2.5.0/src/inklet/themes/palettes.py +192 -0
- inklet-2.5.0/src/inklet/themes/theme.py +422 -0
- inklet-2.5.0/src/inklet/three/__init__.py +136 -0
- inklet-2.5.0/src/inklet/three/api.py +1545 -0
- inklet-2.5.0/src/inklet/three/backend.py +942 -0
- inklet-2.5.0/src/inklet/three/blender/__init__.py +58 -0
- inklet-2.5.0/src/inklet/three/blender/discover.py +204 -0
- inklet-2.5.0/src/inklet/three/blender/lineart.py +451 -0
- inklet-2.5.0/src/inklet/three/blender/options.py +133 -0
- inklet-2.5.0/src/inklet/three/blender/script.py +541 -0
- inklet-2.5.0/src/inklet/three/blender/svgread.py +214 -0
- inklet-2.5.0/src/inklet/three/blender/tracing.py +220 -0
- inklet-2.5.0/src/inklet/three/blender_backend.py +202 -0
- inklet-2.5.0/src/inklet/three/camera.py +326 -0
- inklet-2.5.0/src/inklet/three/deps.py +93 -0
- inklet-2.5.0/src/inklet/three/depth.py +196 -0
- inklet-2.5.0/src/inklet/three/drill.py +1129 -0
- inklet-2.5.0/src/inklet/three/edges.py +478 -0
- inklet-2.5.0/src/inklet/three/hlr.py +463 -0
- inklet-2.5.0/src/inklet/three/linalg.py +195 -0
- inklet-2.5.0/src/inklet/three/mesh.py +462 -0
- inklet-2.5.0/src/inklet/three/occlude.py +372 -0
- inklet-2.5.0/src/inklet/three/order.py +945 -0
- inklet-2.5.0/src/inklet/three/parse.py +602 -0
- inklet-2.5.0/src/inklet/three/place.py +156 -0
- inklet-2.5.0/src/inklet/three/protein.py +679 -0
- inklet-2.5.0/src/inklet/three/shade.py +828 -0
- inklet-2.5.0/src/inklet/three/solids.py +594 -0
- inklet-2.5.0/src/inklet/typeset/__init__.py +42 -0
- inklet-2.5.0/src/inklet/typeset/fonts.py +383 -0
- inklet-2.5.0/src/inklet/typeset/markup.py +421 -0
- inklet-2.5.0/src/inklet/typeset/onpath.py +760 -0
- inklet-2.5.0/src/inklet/typeset/outline.py +275 -0
- inklet-2.5.0/src/inklet/typeset/shaping.py +761 -0
- inklet-2.5.0/stress/assets/mouse.inklet.json +2 -0
- inklet-2.5.0/stress/assets/mouse.png +0 -0
- inklet-2.5.0/stress/dense_graph.py +36 -0
- inklet-2.5.0/stress/draw_probe.py +148 -0
- inklet-2.5.0/stress/electro/assets/sem.png +0 -0
- inklet-2.5.0/stress/electro/assets/tem.png +0 -0
- inklet-2.5.0/stress/electro/cell.py +707 -0
- inklet-2.5.0/stress/electro/common.py +141 -0
- inklet-2.5.0/stress/electro/data.py +267 -0
- inklet-2.5.0/stress/electro/imaging.py +332 -0
- inklet-2.5.0/stress/electro/kinetics.py +600 -0
- inklet-2.5.0/stress/electro/micrograph.py +165 -0
- inklet-2.5.0/stress/electro/system.py +566 -0
- inklet-2.5.0/stress/electro_figure.py +210 -0
- inklet-2.5.0/stress/fidelity.py +59 -0
- inklet-2.5.0/stress/flow.py +109 -0
- inklet-2.5.0/stress/hard_figure.py +126 -0
- inklet-2.5.0/stress/label_storm.py +107 -0
- inklet-2.5.0/stress/mega_figure.py +226 -0
- inklet-2.5.0/stress/meshes/README.md +13 -0
- inklet-2.5.0/stress/meshes/brain-lh.obj +27003 -0
- inklet-2.5.0/stress/meshes/spot.obj +12311 -0
- inklet-2.5.0/stress/panels/apparatus.py +904 -0
- inklet-2.5.0/stress/panels/graphs.py +1261 -0
- inklet-2.5.0/stress/panels/relations.py +1142 -0
- inklet-2.5.0/stress/panels/responses.py +1114 -0
- inklet-2.5.0/stress/panels/sections.py +1267 -0
- inklet-2.5.0/stress/probes.py +319 -0
- inklet-2.5.0/stress/three_figure.py +148 -0
- inklet-2.5.0/tests/test_alignment_contract.py +437 -0
- inklet-2.5.0/tests/test_annotate.py +368 -0
- inklet-2.5.0/tests/test_annotate_letters.py +176 -0
- inklet-2.5.0/tests/test_assets.py +733 -0
- inklet-2.5.0/tests/test_assets_provenance.py +110 -0
- inklet-2.5.0/tests/test_categories.py +44 -0
- inklet-2.5.0/tests/test_chem_figure.py +708 -0
- inklet-2.5.0/tests/test_cli.py +33 -0
- inklet-2.5.0/tests/test_components.py +37 -0
- inklet-2.5.0/tests/test_contrast_and_labels.py +164 -0
- inklet-2.5.0/tests/test_cookbook.py +52 -0
- inklet-2.5.0/tests/test_core.py +377 -0
- inklet-2.5.0/tests/test_core_amendments.py +526 -0
- inklet-2.5.0/tests/test_diagnostics.py +2163 -0
- inklet-2.5.0/tests/test_diagnostics_api.py +95 -0
- inklet-2.5.0/tests/test_diagnostics_artwork.py +41 -0
- inklet-2.5.0/tests/test_diagnostics_break_distorts.py +240 -0
- inklet-2.5.0/tests/test_diagnostics_crossing.py +181 -0
- inklet-2.5.0/tests/test_diagnostics_image_contrast.py +118 -0
- inklet-2.5.0/tests/test_diagnostics_ink.py +81 -0
- inklet-2.5.0/tests/test_diagnostics_keys.py +314 -0
- inklet-2.5.0/tests/test_diagnostics_links.py +328 -0
- inklet-2.5.0/tests/test_diagnostics_paths.py +309 -0
- inklet-2.5.0/tests/test_diagnostics_plot_box.py +132 -0
- inklet-2.5.0/tests/test_docs.py +157 -0
- inklet-2.5.0/tests/test_docs_site.py +56 -0
- inklet-2.5.0/tests/test_document.py +179 -0
- inklet-2.5.0/tests/test_document_data.py +65 -0
- inklet-2.5.0/tests/test_document_v25.py +234 -0
- inklet-2.5.0/tests/test_draw_clip.py +365 -0
- inklet-2.5.0/tests/test_draw_path.py +325 -0
- inklet-2.5.0/tests/test_draw_place.py +161 -0
- inklet-2.5.0/tests/test_draw_shapes.py +169 -0
- inklet-2.5.0/tests/test_export_bundle.py +45 -0
- inklet-2.5.0/tests/test_figure.py +256 -0
- inklet-2.5.0/tests/test_fit.py +161 -0
- inklet-2.5.0/tests/test_guides.py +74 -0
- inklet-2.5.0/tests/test_layout.py +697 -0
- inklet-2.5.0/tests/test_layout_graph.py +498 -0
- inklet-2.5.0/tests/test_layout_graph_fit.py +148 -0
- inklet-2.5.0/tests/test_layout_origin.py +264 -0
- inklet-2.5.0/tests/test_layout_sankey.py +410 -0
- inklet-2.5.0/tests/test_links.py +645 -0
- inklet-2.5.0/tests/test_links_avoid.py +201 -0
- inklet-2.5.0/tests/test_links_shapes.py +397 -0
- inklet-2.5.0/tests/test_neural_activity.py +42 -0
- inklet-2.5.0/tests/test_output_contract.py +305 -0
- inklet-2.5.0/tests/test_paint_program.py +42 -0
- inklet-2.5.0/tests/test_place_labels.py +285 -0
- inklet-2.5.0/tests/test_plot_axis.py +698 -0
- inklet-2.5.0/tests/test_plot_broken_axis.py +362 -0
- inklet-2.5.0/tests/test_plot_clip.py +128 -0
- inklet-2.5.0/tests/test_plot_facets.py +247 -0
- inklet-2.5.0/tests/test_plot_inset.py +231 -0
- inklet-2.5.0/tests/test_plot_key.py +233 -0
- inklet-2.5.0/tests/test_plot_labels.py +199 -0
- inklet-2.5.0/tests/test_plot_legend.py +187 -0
- inklet-2.5.0/tests/test_plot_marks.py +702 -0
- inklet-2.5.0/tests/test_plot_notes.py +181 -0
- inklet-2.5.0/tests/test_plot_polar.py +498 -0
- inklet-2.5.0/tests/test_plot_publication.py +174 -0
- inklet-2.5.0/tests/test_plot_raster.py +331 -0
- inklet-2.5.0/tests/test_plot_ribbon.py +183 -0
- inklet-2.5.0/tests/test_plot_scale.py +439 -0
- inklet-2.5.0/tests/test_plot_swarm.py +255 -0
- inklet-2.5.0/tests/test_plot_time.py +204 -0
- inklet-2.5.0/tests/test_render_embed.py +168 -0
- inklet-2.5.0/tests/test_render_glyphs.py +201 -0
- inklet-2.5.0/tests/test_render_outline.py +323 -0
- inklet-2.5.0/tests/test_render_pdf.py +495 -0
- inklet-2.5.0/tests/test_render_pdf_text.py +323 -0
- inklet-2.5.0/tests/test_render_style_fields.py +215 -0
- inklet-2.5.0/tests/test_render_svg_perf.py +290 -0
- inklet-2.5.0/tests/test_review_v25.py +83 -0
- inklet-2.5.0/tests/test_round4_plot.py +259 -0
- inklet-2.5.0/tests/test_routing_avoid.py +471 -0
- inklet-2.5.0/tests/test_scatter_rendering.py +63 -0
- inklet-2.5.0/tests/test_showcase_round3.py +342 -0
- inklet-2.5.0/tests/test_structure_figure.py +392 -0
- inklet-2.5.0/tests/test_svg.py +762 -0
- inklet-2.5.0/tests/test_target_pose.py +151 -0
- inklet-2.5.0/tests/test_text_markup.py +561 -0
- inklet-2.5.0/tests/test_text_on_path.py +394 -0
- inklet-2.5.0/tests/test_theme_font_style.py +82 -0
- inklet-2.5.0/tests/test_themes.py +645 -0
- inklet-2.5.0/tests/test_three_anchor_pin.py +158 -0
- inklet-2.5.0/tests/test_three_api.py +1730 -0
- inklet-2.5.0/tests/test_three_backend_blender.py +163 -0
- inklet-2.5.0/tests/test_three_blender.py +748 -0
- inklet-2.5.0/tests/test_three_depth_order.py +215 -0
- inklet-2.5.0/tests/test_three_drill.py +276 -0
- inklet-2.5.0/tests/test_three_hlr.py +532 -0
- inklet-2.5.0/tests/test_three_mesh.py +347 -0
- inklet-2.5.0/tests/test_three_order_vector.py +331 -0
- inklet-2.5.0/tests/test_three_overlay.py +196 -0
- inklet-2.5.0/tests/test_three_parse.py +311 -0
- inklet-2.5.0/tests/test_three_patches.py +258 -0
- inklet-2.5.0/tests/test_three_place.py +252 -0
- inklet-2.5.0/tests/test_three_protein.py +262 -0
- inklet-2.5.0/tests/test_three_ridges.py +159 -0
- inklet-2.5.0/tests/test_three_sort.py +181 -0
- inklet-2.5.0/tests/test_three_sort_budget.py +256 -0
- inklet-2.5.0/tests/test_three_view.py +211 -0
- inklet-2.5.0/tests/test_typeset.py +766 -0
- inklet-2.5.0/tests/test_watch_review.py +57 -0
- inklet-2.5.0/tests/visual/README.md +26 -0
- inklet-2.5.0/tests/visual/baseline/categories-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/categories-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/components-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/components-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/dense-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/dense-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/fonts.json +5 -0
- inklet-2.5.0/tests/visual/baseline/inset-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/inset-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/markers-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/markers-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/type-opacity-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/type-opacity-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-category-subset-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-category-subset-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-dense-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-dense-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-late-inset-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-late-inset-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-shared-scales-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-shared-scales-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-twins-matrix-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-twins-matrix-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-workflow-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v2-workflow-svg.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v25-document-pdf.png +0 -0
- inklet-2.5.0/tests/visual/baseline/v25-document-svg.png +0 -0
- inklet-2.5.0/tests/visual/fixtures.py +61 -0
- inklet-2.5.0/tests/visual/v2-budgets.json +9 -0
- inklet-2.5.0/tools/benchmark_v2.py +35 -0
- inklet-2.5.0/tools/check_wheel.py +69 -0
- inklet-2.5.0/tools/dock_ligand.py +263 -0
- inklet-2.5.0/tools/docs_site.py +51 -0
- inklet-2.5.0/tools/gen_api.py +180 -0
- inklet-2.5.0/tools/stress20.py +139 -0
- inklet-2.5.0/tools/strip_pdb.py +105 -0
- inklet-2.5.0/tools/visual_check.py +80 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Release checks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: checks-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
figures:
|
|
18
|
+
runs-on: ubuntu-24.04
|
|
19
|
+
timeout-minutes: 25
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
22
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.12'
|
|
25
|
+
- name: Install fonts and independent PDF renderer
|
|
26
|
+
run: |
|
|
27
|
+
sudo apt-get update
|
|
28
|
+
sudo apt-get install -y fonts-dejavu-core fonts-dejavu-extra fonts-noto-core fonts-liberation fonts-urw-base35 poppler-utils
|
|
29
|
+
google-chrome --version
|
|
30
|
+
pdftoppm -v
|
|
31
|
+
- name: Install locked test dependencies
|
|
32
|
+
run: |
|
|
33
|
+
uv venv
|
|
34
|
+
uv pip install -r requirements-ci.txt -e .
|
|
35
|
+
.venv/bin/inklet doctor
|
|
36
|
+
- name: Unit and integration tests
|
|
37
|
+
run: .venv/bin/python -m pytest -q --junitxml=out/tests.xml
|
|
38
|
+
- name: Generated API documentation
|
|
39
|
+
run: .venv/bin/python tools/gen_api.py --check
|
|
40
|
+
- name: Build documentation with strict link validation
|
|
41
|
+
run: |
|
|
42
|
+
uv pip install -r requirements-docs.txt
|
|
43
|
+
.venv/bin/python -m mkdocs build --strict
|
|
44
|
+
.venv/bin/python -m pytest -q tests/test_docs_site.py
|
|
45
|
+
- name: Build the v2.5 publication review
|
|
46
|
+
run: .venv/bin/inklet build examples/v25_document.py --output out/v25 --name document
|
|
47
|
+
- name: Complete figure visual regressions
|
|
48
|
+
run: .venv/bin/python tools/visual_check.py --output out/visual
|
|
49
|
+
- name: Complete figure performance checks
|
|
50
|
+
run: .venv/bin/python tools/benchmark_v2.py --output out/benchmarks
|
|
51
|
+
- name: Twenty-panel mixed-media stress test
|
|
52
|
+
run: .venv/bin/python tools/stress20.py --output out/stress20
|
|
53
|
+
- name: Preserve review artifacts
|
|
54
|
+
if: always()
|
|
55
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
56
|
+
with:
|
|
57
|
+
name: figure-checks
|
|
58
|
+
path: out/
|
|
59
|
+
retention-days: 7
|
|
60
|
+
if-no-files-found: ignore
|
|
61
|
+
|
|
62
|
+
wheel:
|
|
63
|
+
runs-on: ubuntu-24.04
|
|
64
|
+
timeout-minutes: 10
|
|
65
|
+
strategy:
|
|
66
|
+
fail-fast: false
|
|
67
|
+
matrix:
|
|
68
|
+
python: ['3.11', '3.12', '3.13']
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
71
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
72
|
+
with:
|
|
73
|
+
python-version: ${{ matrix.python }}
|
|
74
|
+
- name: Build and install with core dependencies only
|
|
75
|
+
run: |
|
|
76
|
+
uv build --wheel --out-dir out/dist
|
|
77
|
+
uv run --no-project python tools/check_wheel.py out/dist/inklet-*.whl
|
inklet-2.5.0/.gitignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Environments and local configuration
|
|
2
|
+
.venv/
|
|
3
|
+
.env
|
|
4
|
+
.env.*
|
|
5
|
+
!.env.example
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.remember/
|
|
10
|
+
|
|
11
|
+
# Builds, exports and development experiments
|
|
12
|
+
/out/
|
|
13
|
+
/tmp/
|
|
14
|
+
/dist/
|
|
15
|
+
/build/
|
|
16
|
+
/site/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
/figures/out/
|
|
19
|
+
/examples/*.svg
|
|
20
|
+
/examples/*.png
|
|
21
|
+
/examples/*.pdf
|
|
22
|
+
/stress/*.svg
|
|
23
|
+
/stress/*.png
|
|
24
|
+
/stress/*.pdf
|
|
25
|
+
/stress/panels/*.svg
|
|
26
|
+
/stress/panels/*.png
|
|
27
|
+
/stress/panels/*.pdf
|
|
28
|
+
/stress/electro/*.svg
|
|
29
|
+
/stress/electro/*.png
|
|
30
|
+
/stress/electro/*.pdf
|
|
31
|
+
|
|
32
|
+
# Editor / OS files
|
|
33
|
+
.DS_Store
|
|
34
|
+
.idea/
|
|
35
|
+
.vscode/
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.5.0
|
|
4
|
+
|
|
5
|
+
- Prepare the standalone release tree with an MIT license, third-party notices,
|
|
6
|
+
maintained examples, and explicit source-distribution contents.
|
|
7
|
+
- Refresh Blender's evaluated scene after baking Line Art so SVG exports retain
|
|
8
|
+
every baked stroke. Invalidate earlier bake caches and verify fresh exports.
|
|
9
|
+
- Rework the README around installation, a runnable first figure and supported
|
|
10
|
+
workflows. Add task-based guides, command-line and troubleshooting references,
|
|
11
|
+
a searchable local documentation site and contributor instructions.
|
|
12
|
+
- Execute introductory documentation examples and validate links and site
|
|
13
|
+
navigation in CI. Preserve the generated API reference and existing recipes.
|
|
14
|
+
|
|
15
|
+
- Add nested subfigures that share measurement caches and inherit page themes.
|
|
16
|
+
- Add measured compositions with named children, algebraic size/anchor references,
|
|
17
|
+
cycle detection, branch and return routing, and editable architecture modules.
|
|
18
|
+
- Reserve panel-letter space during layout. Resolve deferred callouts after
|
|
19
|
+
insets and brackets, considering measured marks and existing furniture.
|
|
20
|
+
- Add general publication presets for physical widths, typography, stroke sizes,
|
|
21
|
+
export defaults and print-size diagnostics; record profiles in manifests.
|
|
22
|
+
- Add component/severity filters and search to review pages, plus saved-revision
|
|
23
|
+
overlays and pixel differences. Handle size/DPI changes without invalid scores.
|
|
24
|
+
Watch mode compares successive successful builds and preserves failed-build output.
|
|
25
|
+
- Rebuild the AlphaFold architecture and full proteome layout with public
|
|
26
|
+
composition APIs, removing their custom renderer classes. Preserve the reviewed
|
|
27
|
+
PDF appearance and existing SVG tolerance.
|
|
28
|
+
- Add a complete v2.5 example, regression coverage and installed-wheel checks.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
- Migrate AlphaFold Figure 1e to measured module components and named ports;
|
|
32
|
+
migrate the complete proteome figure to live plots, data and category filters.
|
|
33
|
+
- Add `derive()` for explicit transformations of live data dependencies.
|
|
34
|
+
- Consolidate thin-stroke warnings within named, intentionally touching artwork
|
|
35
|
+
while retaining all targets; show component paths in HTML and JSON findings.
|
|
36
|
+
- Check unit tests, complete SVG/PDF figures, performance budgets and isolated
|
|
37
|
+
wheel installations in GitHub Actions. Lock the scientific test dependencies.
|
|
38
|
+
- Preserve the native mesh when optional trimesh repair dependencies are absent.
|
|
39
|
+
- Avoid global theme changes when importing the Nature examples, and keep the
|
|
40
|
+
generated API reference consistent across Python versions.
|
|
41
|
+
- Check repeated drawing identities with a set, avoiding quadratic placement
|
|
42
|
+
work for dense scatter layers.
|
|
43
|
+
|
|
44
|
+
## 2.0.0
|
|
45
|
+
|
|
46
|
+
- Add live documents with versioned plot and component definitions, compiled
|
|
47
|
+
snapshots, bounded geometry caches and deterministic drawing identities.
|
|
48
|
+
- Fit plots to physical pages with weighted tracks, spanning cells, shared
|
|
49
|
+
furniture margins and explicit errors for unsatisfiable constraints.
|
|
50
|
+
- Add datasets, shared numeric scales, series with uncertainty, live category
|
|
51
|
+
selections, units, data sources and file dependencies.
|
|
52
|
+
- Resolve inherited paint once for SVG and PDF while preserving clipping,
|
|
53
|
+
transformations and group compositing.
|
|
54
|
+
- Add `inklet build`, `watch` and `doctor`, clickable SVG diagnostics, JSON
|
|
55
|
+
findings, and export manifests with data, font and asset provenance.
|
|
56
|
+
- Add six complete v2 visual fixtures, performance budgets and compatibility
|
|
57
|
+
comparisons for all four Nature Figure 1 reconstructions.
|
|
58
|
+
- Avoid repeated child-index construction in crowding diagnostics for large
|
|
59
|
+
drawings, and isolate document themes throughout text and shape creation.
|
|
60
|
+
|
|
61
|
+
Existing Diagram, Panel and Figure APIs remain available. See
|
|
62
|
+
[the migration guide](docs/migration.md) and [v2 guide](docs/v2.md).
|
inklet-2.5.0/CONTRACT.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Inklet module contract
|
|
2
|
+
|
|
3
|
+
The core represents geometry, styles, primitives and immutable diagram trees.
|
|
4
|
+
Typesetting measures text; layout places nodes; routing connects them;
|
|
5
|
+
diagnostics inspect the resolved figure; rendering exports it.
|
|
6
|
+
|
|
7
|
+
Core changes affect every layer. Preserve the invariants below and add focused
|
|
8
|
+
regression coverage for changes to measurement, placement or traversal.
|
|
9
|
+
|
|
10
|
+
## Non-negotiables
|
|
11
|
+
|
|
12
|
+
- **Millimetres everywhere.** `core.units.mm("89mm") -> 89.0`, `pt(7) -> 2.47`.
|
|
13
|
+
Bare numbers are already mm. Pixels exist only inside a raster backend.
|
|
14
|
+
- **y grows downward** (SVG convention). North is `-y`.
|
|
15
|
+
- **Primitives are centred on their local origin.**
|
|
16
|
+
- **Deterministic output.** No `uuid4`, no dict-order dependence, no
|
|
17
|
+
`time`/`random`. The same script must emit byte-identical SVG twice.
|
|
18
|
+
- **Core never measures text.** `TextPrim` arrives pre-shaped.
|
|
19
|
+
- Python 3.11 or later, `from __future__ import annotations`, dataclasses, type hints.
|
|
20
|
+
Stdlib + the deps already in `pyproject.toml` only.
|
|
21
|
+
|
|
22
|
+
## Core API you build against
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
Vec2(x, y) # + - * dot cross length normalized perp angle
|
|
26
|
+
Affine(a,b,c,d,e,f) # .translation .rotation .scaling A @ B = B then A
|
|
27
|
+
# .apply(pt) .apply_vector(v) .inverse() .is_identity
|
|
28
|
+
Rect(x0,y0,x1,y1) # .width .height .center .corners .union .pad .overlap
|
|
29
|
+
Envelope # .extent(unit_dir) -> float|None support function
|
|
30
|
+
# .union .transform .pad .bbox()
|
|
31
|
+
Trace # .exit(origin, dir) .boundary_point(origin, dir)
|
|
32
|
+
Style(...) # all fields Optional, None = inherit; .over(base) .with_()
|
|
33
|
+
Prim: RectPrim(w,h,radius) EllipsePrim(rx,ry)
|
|
34
|
+
PathPrim(subpaths,filled,fill_rule) # fill_rule: nonzero | evenodd
|
|
35
|
+
TextPrim(lines,font_family,font_size,ascent,descent,align,font_path,
|
|
36
|
+
...,features) # features = sorted (tag, value) pairs it was
|
|
37
|
+
# shaped with; core.text_features() canonicalises
|
|
38
|
+
ImagePrim(source,width,height,pixel_size,outline,data,smooth)
|
|
39
|
+
# data = encoded PNG/JPEG bytes; then source is a label
|
|
40
|
+
# smooth: None = backend's call, False = nearest-neighbour
|
|
41
|
+
PhantomPrim(box) # occupies space, draws nothing, empty trace
|
|
42
|
+
Envelope.expand(t,r,b,l) # padding: a disc sweep when uniform, box sum when not
|
|
43
|
+
Diagram(envelope_override=...) # claim space the contents do not; trace untouched
|
|
44
|
+
Diagram(prim=, children=(), transform=, style=, kind=, name=, notes={})
|
|
45
|
+
.local_envelope .envelope # local = before self.transform; plain = after
|
|
46
|
+
.local_trace .trace .bbox .local_bbox .width .height .extent(dir)
|
|
47
|
+
.anchor(name, (u,v)|Vec2) # (u,v) are fractions of local bbox, (0,0)=top-left
|
|
48
|
+
.anchor_point(name) # compass: n s e w ne nw se sw center. LOCAL:
|
|
49
|
+
# pre-transform. Placement.point re-reads the
|
|
50
|
+
# compass off the placed box (M10)
|
|
51
|
+
.registered_point(name) # a registered anchor, looking through the
|
|
52
|
+
# wrappers translated/rotated/scaled leave
|
|
53
|
+
# behind, or None (M16)
|
|
54
|
+
.note(key, value) -> self # per-node annotation core does not read;
|
|
55
|
+
.notes # survives replace/apply_theme/build (M17)
|
|
56
|
+
.carry_notes(source) # inherit a single child's notes, moved into
|
|
57
|
+
# this node's frame (M19)
|
|
58
|
+
note_through(affine, value) # how one note value moves: a Rect is re-cornered,
|
|
59
|
+
# everything else is carried verbatim (M19)
|
|
60
|
+
.at(name) -> AnchorRef
|
|
61
|
+
.placed(affine) .translated .rotated .scaled .centered .styled .named .copy
|
|
62
|
+
.walk() .find(name)
|
|
63
|
+
resolve(root) -> {id: Placement} # Placement: .world .style .envelope .trace
|
|
64
|
+
# .bbox .point(anchor) .depth
|
|
65
|
+
flatten(root) -> [RenderItem] # RenderItem: .prim .world .style .id .name
|
|
66
|
+
world_point(ref_or_diagram, placements) -> Vec2
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Combinators **wrap, never rewrite**: `d.translated(3)` returns a new parent
|
|
70
|
+
whose child is the very same `d` object, so a caller's handle stays valid after
|
|
71
|
+
being stacked. Never place one Diagram object twice — `resolve()` raises.
|
|
72
|
+
|
|
73
|
+
## Testing
|
|
74
|
+
|
|
75
|
+
`.venv/bin/python -m pytest tests/ -q`. Place regression tests alongside the relevant feature tests. Test behaviour
|
|
76
|
+
and numerical results.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Contributing to Inklet
|
|
2
|
+
|
|
3
|
+
Use a focused change with a runnable example or minimal reproducer. Describe
|
|
4
|
+
the resulting behavior and how it was checked. Keep numerical inputs and
|
|
5
|
+
expected results explicit; use simulated data when source data cannot be shared.
|
|
6
|
+
|
|
7
|
+
## Development environment
|
|
8
|
+
|
|
9
|
+
From a checkout with Python 3.12 and `uv` installed:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
uv venv --python 3.12
|
|
13
|
+
uv pip install -r requirements-ci.txt -e .
|
|
14
|
+
.venv/bin/python -m inklet doctor
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The lock file is the tested scientific environment. Vector-only development
|
|
18
|
+
needs fewer packages, but the full suite also exercises optional image and 3D
|
|
19
|
+
features. CI installs fonts, Chrome and Poppler as described in
|
|
20
|
+
[release checks](docs/release-checks.md).
|
|
21
|
+
|
|
22
|
+
## Test a change
|
|
23
|
+
|
|
24
|
+
Run the tests relevant to the modified behavior first:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
.venv/bin/python -m pytest -q tests/test_document.py tests/test_document_v25.py
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For a release or a broad rendering change:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
.venv/bin/python -m pytest -q
|
|
34
|
+
.venv/bin/python tools/gen_api.py --check
|
|
35
|
+
.venv/bin/python tools/visual_check.py --output out/visual
|
|
36
|
+
.venv/bin/python tools/benchmark_v2.py --output out/benchmarks
|
|
37
|
+
.venv/bin/python tools/stress20.py --output out/stress20
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Visual checks need the preview tools. Inspect differences before changing a
|
|
41
|
+
baseline; see [visual test instructions](tests/visual/README.md). Performance
|
|
42
|
+
results are machine-dependent, so include workload and environment details.
|
|
43
|
+
|
|
44
|
+
## Documentation
|
|
45
|
+
|
|
46
|
+
User guides live in `docs/`, with navigation in `mkdocs.yml`. Markdown should
|
|
47
|
+
remain readable in both GitHub and the local site. Link to repository files
|
|
48
|
+
relatively; the site hook includes gallery images and converts other
|
|
49
|
+
out-of-docs links to repository URLs. This avoids duplicate copies of examples
|
|
50
|
+
and preview assets.
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
uv pip install -r requirements-docs.txt
|
|
54
|
+
.venv/bin/python -m pytest -q tests/test_docs.py tests/test_cookbook.py tests/test_guides.py tests/test_docs_site.py
|
|
55
|
+
.venv/bin/python tools/gen_api.py --check
|
|
56
|
+
.venv/bin/python -m mkdocs build --strict
|
|
57
|
+
.venv/bin/python -m mkdocs serve
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The static site is written to `out/docs-site/`; local serving uses port 8000.
|
|
61
|
+
The [MkDocs configuration reference](https://www.mkdocs.org/user-guide/configuration/)
|
|
62
|
+
describes navigation and strict validation. CI builds the site and uploads it
|
|
63
|
+
as an artifact. There is no automatic public deployment.
|
|
64
|
+
|
|
65
|
+
New introductory guides should use complete Python examples or clearly state
|
|
66
|
+
what preceding blocks they depend on. `tests/test_guides.py` executes registered
|
|
67
|
+
pages in a temporary directory, sharing a namespace only within each page.
|
|
68
|
+
Prefix a Python fence with `<!-- Requires preview renderers. -->` followed by
|
|
69
|
+
a blank line for examples needing preview tools; those examples are exercised
|
|
70
|
+
when the tools are available. File-dependent fragments
|
|
71
|
+
should state which user files are needed.
|
|
72
|
+
|
|
73
|
+
`docs/api.md` is generated from public signatures and docstrings. Change the
|
|
74
|
+
source docstrings or `tools/gen_api.py`, then regenerate it; do not edit the
|
|
75
|
+
generated file by hand. Keep instructions literal and document limitations
|
|
76
|
+
alongside the corresponding feature.
|
|
77
|
+
|
|
78
|
+
## Repository structure
|
|
79
|
+
|
|
80
|
+
| Path | Purpose |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `src/inklet/document/` | Live definitions, data, measurement and compilation |
|
|
83
|
+
| `src/inklet/plot/`, `draw/`, `layout/`, `links/` | Charts, geometry composition and routing |
|
|
84
|
+
| `src/inklet/three/`, `assets/` | Meshes, vector 3D and image processing |
|
|
85
|
+
| `src/inklet/typeset/`, `themes/` | Shaped text and physical styling |
|
|
86
|
+
| `src/inklet/render/`, `diagnostics/` | Export backends, review and drawing checks |
|
|
87
|
+
| `tests/` | Unit, integration and visual regression checks |
|
|
88
|
+
| `examples/`, `figures/`, `stress/` | Runnable figures and larger workloads |
|
|
89
|
+
| `tools/` | Documentation generation, wheel checks and benchmarks |
|
|
90
|
+
|
|
91
|
+
Read [the core contract](CONTRACT.md) before changing fundamental geometry,
|
|
92
|
+
and [the compilation contract](docs/design/v2.md) before changing dependency,
|
|
93
|
+
measurement or caching semantics. Update [the changelog](CHANGELOG.md) for
|
|
94
|
+
user-visible changes.
|
inklet-2.5.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mapika and Inklet contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
inklet-2.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: inklet
|
|
3
|
+
Version: 2.5.0
|
|
4
|
+
Summary: Scientific figures with live data, measured layout, and consistent vector exports.
|
|
5
|
+
Project-URL: Repository, https://github.com/Mapika/inklet
|
|
6
|
+
Project-URL: Documentation, https://github.com/Mapika/inklet/blob/master/docs/index.md
|
|
7
|
+
Project-URL: Issues, https://github.com/Mapika/inklet/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Requires-Dist: fonttools>=4.53
|
|
13
|
+
Requires-Dist: uharfbuzz>=0.39
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
16
|
+
Provides-Extra: docs
|
|
17
|
+
Requires-Dist: mkdocs<2,>=1.6; extra == 'docs'
|
|
18
|
+
Requires-Dist: pygments<3,>=2.18; extra == 'docs'
|
|
19
|
+
Provides-Extra: images
|
|
20
|
+
Requires-Dist: numpy>=1.24; extra == 'images'
|
|
21
|
+
Requires-Dist: pillow>=10.0; extra == 'images'
|
|
22
|
+
Provides-Extra: three
|
|
23
|
+
Requires-Dist: numpy>=1.24; extra == 'three'
|
|
24
|
+
Requires-Dist: trimesh>=4.0; extra == 'three'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# Inklet
|
|
28
|
+
|
|
29
|
+
**Scientific figures from Python, with measured layout and editable SVG/PDF output.**
|
|
30
|
+
|
|
31
|
+
Combine plots, diagrams, images and native 3D artwork on a page sized in
|
|
32
|
+
millimetres. Keep data and labels live, compile the figure, and inspect its
|
|
33
|
+
layout and print diagnostics before exporting.
|
|
34
|
+
|
|
35
|
+
[Get started](docs/quickstart.md) · [Documentation](docs/index.md) ·
|
|
36
|
+
[Examples](docs/examples.md) · [API reference](docs/api.md)
|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
This [twenty-panel stress test](docs/stress20.md) includes 30,000 scatter points,
|
|
41
|
+
5,580 mesh triangles and 7,200 vector events. Its data are simulated. Only the
|
|
42
|
+
dense scatter and scalar field are rasterized; the other artwork remains vector.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
Python **3.11 or later** is required. Install from this repository using an
|
|
47
|
+
account with access to `Mapika/inklet`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
git clone https://github.com/Mapika/inklet.git
|
|
51
|
+
cd inklet
|
|
52
|
+
python -m venv .venv
|
|
53
|
+
source .venv/bin/activate
|
|
54
|
+
python -m pip install -e .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
SVG/PDF output and the built-in 3D renderer need no browser or external rendering
|
|
58
|
+
engine. Text needs an installed font. For PNG layers and visual review, install
|
|
59
|
+
`python -m pip install -e '.[images]'` plus Chrome/Chromium and Poppler.
|
|
60
|
+
See [installation](docs/installation.md) for system packages, Windows activation,
|
|
61
|
+
optional dependencies and environment checks.
|
|
62
|
+
|
|
63
|
+
## Your first figure
|
|
64
|
+
|
|
65
|
+
Save this as `first_figure.py` and run `python first_figure.py`:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
import inklet as i
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def make_document():
|
|
72
|
+
data = i.dataset(
|
|
73
|
+
{'time': [0, 1, 2, 3], 'signal': [1, 3, 2, 4]},
|
|
74
|
+
name='response',
|
|
75
|
+
source=i.Source('Quickstart demonstration', method='simulated'),
|
|
76
|
+
)
|
|
77
|
+
plot = i.plot_spec(x=(0, 3), y=(0, 5))
|
|
78
|
+
plot.line(data.points('time', 'signal'), name='Signal', stroke='#176b9b')
|
|
79
|
+
plot.axes(x='Time / s', y='Signal / mV').legend(side='bottom')
|
|
80
|
+
|
|
81
|
+
doc = i.publication('single-column').document()
|
|
82
|
+
doc.add('response', plot, min_height=55)
|
|
83
|
+
return doc
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if __name__ == '__main__':
|
|
87
|
+
figure = make_document().compile()
|
|
88
|
+
figure.save('response.svg', 'response.pdf')
|
|
89
|
+
print(figure.report())
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The document measures axis labels and the legend, fits the plot to an 89 mm
|
|
93
|
+
page, and saves SVG and PDF with embedded text. It does not shrink the font to
|
|
94
|
+
make the plot fit. The [quickstart](docs/quickstart.md) continues with live data
|
|
95
|
+
edits, multiple panels and review exports.
|
|
96
|
+
|
|
97
|
+
## Build, inspect, revise
|
|
98
|
+
|
|
99
|
+
With the [preview dependencies](docs/installation.md#visual-review) installed:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
inklet doctor
|
|
103
|
+
inklet build first_figure.py --output out/review
|
|
104
|
+
inklet watch first_figure.py --output out/review
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`build` writes the vector files, PNG previews, diagnostics, a provenance manifest
|
|
108
|
+
and a local HTML review page. `watch` serves a preview at
|
|
109
|
+
`http://127.0.0.1:8765/` and rebuilds when the authoring code changes. Review pages
|
|
110
|
+
support diagnostic filters, SVG highlights and comparisons with a saved revision.
|
|
111
|
+
|
|
112
|
+
For an environment without preview tools, use
|
|
113
|
+
`inklet build first_figure.py --output out/review --vectors-only`.
|
|
114
|
+
|
|
115
|
+
## What you can build
|
|
116
|
+
|
|
117
|
+
| Task | Main tools | Guide |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Multi-panel figures | `document`, `subfigure`, weighted columns, spans, panel letters | [Layout](docs/layout.md) |
|
|
120
|
+
| Scientific plots | `plot_spec`, axes, bands, distributions, heatmaps, insets, polar plots | [Plotting](docs/plotting.md) |
|
|
121
|
+
| Data-driven revisions | `Dataset`, `Series`, shared scales, categories, `derive`, source records | [Live data](docs/data.md) |
|
|
122
|
+
| Architecture and flow diagrams | `composition`, `module`, named ports, measured connections, `graph` | [Diagrams](docs/diagrams.md) |
|
|
123
|
+
| 3D and image panels | `solid`, `model`, `scene`, `asset`, explicit file dependencies | [3D and images](docs/three-images.md) |
|
|
124
|
+
| Publication exports | Physical presets, embedded or outlined text, SVG/PDF, review bundles | [Export and review](docs/export-review.md) |
|
|
125
|
+
|
|
126
|
+
## How Inklet works
|
|
127
|
+
|
|
128
|
+
A `Document` holds live definitions. `compile()` measures their contents, places
|
|
129
|
+
them, routes connections and produces a snapshot used by both export backends.
|
|
130
|
+
Updating a dataset or named instruction invalidates dependent components;
|
|
131
|
+
unchanged definitions can reuse their cached geometry. Earlier snapshots remain
|
|
132
|
+
unchanged.
|
|
133
|
+
|
|
134
|
+
Numeric lengths, including low-level text sizes, are **millimetres**. Use
|
|
135
|
+
`i.pt(8)` for an 8-point text size; publication profile options such as
|
|
136
|
+
`font_pt=8` take points explicitly. Plot coordinates follow their data scales.
|
|
137
|
+
|
|
138
|
+
The direct `Figure`, `Panel` and `Diagram` APIs remain supported for fixed
|
|
139
|
+
drawings. See [the authoring model](docs/concepts.md) for when to use each layer.
|
|
140
|
+
|
|
141
|
+
## Scope and limits
|
|
142
|
+
|
|
143
|
+
- Layout respects physical constraints. Impossible fits raise `LayoutError`;
|
|
144
|
+
changing page width does not automatically rearrange the number of columns.
|
|
145
|
+
- Diagnostics help find collisions, small type and other print issues. Review
|
|
146
|
+
the rendered figure as well; a clean report does not establish scientific accuracy.
|
|
147
|
+
- Rasterization keeps dense exports compact, but dense-scatter rebuilds can
|
|
148
|
+
still be expensive. The [stress report](docs/stress20.md) records the workload,
|
|
149
|
+
timings and remaining limitations.
|
|
150
|
+
- Reproducible appearance requires consistent inputs, fonts and dependencies.
|
|
151
|
+
The export manifest records dataset and font hashes for comparison.
|
|
152
|
+
|
|
153
|
+
## Documentation and development
|
|
154
|
+
|
|
155
|
+
Start at the [documentation index](docs/index.md). The source Markdown is readable
|
|
156
|
+
on GitHub; a searchable site can also be served locally:
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
python -m pip install -e '.[docs]'
|
|
160
|
+
python -m mkdocs serve
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
See [contributing](CONTRIBUTING.md) for tests, documentation checks and visual
|
|
164
|
+
regressions. Existing users can consult [migration](docs/migration.md),
|
|
165
|
+
[the v2.5 changes](docs/v2.5.md) and [the changelog](CHANGELOG.md).
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
Inklet code is available under the [MIT license](LICENSE). Included third-party
|
|
170
|
+
meshes and structural data retain their own terms; see
|
|
171
|
+
[third-party notices](THIRD_PARTY_NOTICES.md).
|