fletcher

repository·main·Indexed 22 days ago

https://github.com/jollywatt/typst-fletcher

A Typst package built on the CeTZ library for drawing complex diagrams with arrows, including mathematical diagrams, flowcharts, state machines, and Feynman diagrams. It provides a coordinate system supporting absolute and elastic positions, customizable node shapes (such as diamond, cylinder, and trapezium), and advanced edge configuration with bending, labels, and Crow's foot notation.

Tokens
1.8K
Snippets
5
Records
11
Agent score
27%

What's inside fletcher

  1. Coordinate systems and snapping

    main

    Fletcher features an enhanced coordinate system that supports both absolute (physical lengths) and "elastic" (row/column positions) coordinates.

    • CeTZ Integration: Supports CeTZ-style coordinate expressions, including relative, polar, interpolating, and named coordinates. You can use CeTZ anchors in edge coordinates, e.g., edge(<a.east>, ..).
    • Edge Snapping: Edges automatically snap to node outlines. You can control this behavior using the snap-to option in edge(), which can be set to none to disable snapping.
  2. Use custom shapes and advanced node styling

    main

    You can extend fletcher by importing additional shapes (like diamond) from fletcher.shapes. Nodes support various styling options:

    • shape: Changes the geometry of the node (e.g., shape: diamond).
    • corner-radius: Adjusts the roundness of corners.
    • extrude: Adjusts the node's footprint/size in specific directions.
    • node-fill: Sets the background color, including support for gradient.radial.
    • align: Controls content alignment within the node.

    Example of a flowchart node with a diamond shape:

    #import fletcher.shapes: diamond
    
    #diagram(
    	node-stroke: 1pt,
    	node((0,0), [Start], corner-radius: 2pt, extrude: (0, 3)),
    	edge("-|>"),
    	node((0,1), align(center)[\nHey, wait,\ this flowchart\ is a trap!\n], shape: diamond),
    	edge("d,r,u,l", "-|>", [Yes], label-pos: 0.1)
    )
    #import fletcher.shapes: diamond
    #set text(font: "Comic Neue", weight: 600)
    
    #diagram(
    	node-stroke: 1pt,
    	node((0,0), [Start], corner-radius: 2pt, extrude: (0, 3)),
    	edge("-|>"),
    	node((0,1), align(center)[
    	Hey, wait,
    	this flowchart
    	is a trap!
    ], shape: diamond),
    	edge("d,r,u,l", "-|>", [Yes], label-pos: 0.1)
    )
  3. Requirements and Dependencies

    main

    Depending on your version of Fletcher, ensure your environment meets the following requirements:

    • Typst Version:
      • For version 0.5.6 and above: Requires typst >= 0.13.0.
      • For version 0.5.2 and above: Requires typst >= 0.12.0.
    • CeTZ Dependency: Fletcher relies on the cetz package. Versions 0.5.7+ use cetz 0.3.4.
  4. Install and import fletcher

    main

    To use fletcher in your Typst project, import it from the Typst Universe preview. You can alias the imported functions to diagram, node, and edge for cleaner syntax.

    #import "@preview/fletcher:0.5.9" as fletcher: diagram, node, edge
    #import "@preview/fletcher:0.5.9" as fletcher: diagram, node, edge
  5. Configure edge properties like bending and labels

    main

    Edges in fletcher can be highly customized using parameters like bend, label-pos, and label-side.

    • bend: Uses degrees (e.g., bend: 130deg) to curve the edge.
    • label-pos: Adjusts the position of the label along the edge (e.g., 0 for start, 1 for end).
    • label-side: Determines which side of the edge the label appears on (e.g., center).

    Example of a state machine with curved edges and centered labels:

    #diagram(
    	node-stroke: .1em,
    	node-fill: gradient.radial(blue.lighten(80%), blue, center: (30%, 20%), radius: 80%),
    	spacing: 4em,
    	edge((-1,0), "r", "-|>", `open(path)`, label-pos: 0, label-side: center),
    	node((0,0), `reading`, radius: 2em),
    	edge(`read()`, "-|>"),
    	node((1,0), `eof`, radius: 2em),
    	edge(`close()`, "-|>"),
    	node((2,0), `closed`, radius: 2em, extrude: (-2.5, 0)),
    	edge((0,0), (0,0), `read()`, "--|>", bend: 130deg),
    	edge((0,0), (2,0), `close()`, "-|>", bend: -40deg),
    )
    #diagram(
    	node-stroke: .1em,
    	node-fill: gradient.radial(blue.lighten(80%), blue, center: (30%, 20%), radius: 80%),
    	spacing: 4em,
    	edge((-1,0), "r", "-|>", `open(path)`, label-pos: 0, label-side: center),
    	node((0,0), `reading`, radius: 2em),
    	edge(`read()`, "-|>"),
    	node((1,0), `eof`, radius: 2em),
    	edge(`close()`, "-|>"),
    	node((2,0), `closed`, radius: 2em, extrude: (-2.5, 0)),
    	edge((0,0), (0,0), `read()`, "--|>", bend: 130deg),
    	edge((0,0), (2,0), `close()`, "-|>", bend: -40deg),
    )
  6. Create a basic diagram with nodes and edges

    main

    The core workflow of fletcher involves using the diagram function to wrap node and edge calls.

    • diagram(): The container for the drawing. It accepts configuration like cell-size or spacing.
    • node(): Defines a point in the diagram. It can take coordinates, content, and styling like shape, radius, or extrude.
    • edge(): Defines connections between nodes. It can be used with mathematical notation (inside $ $ blocks) or as a standard function call.

    Example of a mathematical diagram using Typst math mode:

    #diagram(cell-size: 15mm, $
    	G edge(f, ->) edge("d", pi, ->>) & im(f) \\
    	G slash ker(f) edge("ur", tilde(f), "hook-->")
    $
    )
    #diagram(cell-size: 15mm, $
    	G edge(f, ->) edge("d", pi, ->>) & im(f) \\
    	G slash ker(f) edge("ur", tilde(f), "hook-->")
    $
    )
  7. Use various node shapes and decorations

    main

    Fletcher provides a wide variety of node shapes and edge decorations to customize diagram aesthetics.

    Node Shapes

    Common shapes include:

    • cylinder, brace, bracket, paren (added in 0.5.8)
    • trapezium (added in 0.5.0)
    • ellipse, octagon (added in 0.4.4)
    • diamond, pill, parallelogram, hexagon (via shapes submodule, added in 0.4.1)
    • isosceles triangle (added in 0.4.5)

    You can use the node-shape option in diagram() to set a default shape, or specify it per node.

    Edge Decorations

    You can apply CeTZ path decorations to edges using the decorations option in edge():

    • "wave"
    • "zigzag"
    • "coil"
  8. Manage diagram layout and visibility

    main

    Hiding elements

    Use fletcher.hide() to hide elements without affecting the overall layout. This is particularly useful for creating incremental diagrams in presentations or slides.

    Floating elements

    To prevent certain objects from affecting the diagram's calculated bounds (size and layout), use the floating option in edge(). This also applies to debug annotations.

  9. Configure edge label positions and styling

    main

    In recent versions (0.5.x), you can precisely control how edge labels are positioned and styled.

    • Positioning: Use the label-pos option in edge() to specify a position as a tuple of (segment, position). It also supports relative lengths.
    • Styling: Use the label-angle option to rotate labels. The label-wrapper option allows for advanced customization of the label's appearance, including inset, outline stroke, and other properties.
    • Sizing: Use label-size to set a default text size for all edge labels in a diagram.
    // Example conceptual usage based on changelog features
    edge(..., label-pos: (1, 0.5), label-angle: 45, label-wrapper: (inset: 2pt))
  10. Configure edge marks and arrowheads

    main

    Fletcher allows for highly customizable marks on edges.

    • Placement: You can place marks anywhere along an edge. Shorthands support middle marks, e.g., |->-| or hook-/->>.
    • Custom Arrowheads: Supports various styles including solid arrowheads like <|-, -|>, and double-bar ||-, -||.
    • Additional Styles: Includes }>, <{, /, \, x, X, * (solid dot), and @ (solid circle).