svg-term

repository·master·Indexed 41 days ago

https://github.com/marionebl/svg-term

A utility to render asciinema terminal sessions (v1 or v2) into animated SVG files using CSS. It provides a `render` function for generating SVG strings and a React component for embedding terminal sessions in web applications. Features include custom ANSI theme support, playback range control (from, to, at), and visual options like window framing and cursor rendering.

Tokens
4K
Snippets
13
Records
18
Agent score
100%

What's inside svg-term

  1. Understand the ViewModel data structure

    master

    The ViewModel is the primary data contract used to drive the SVG rendering of a terminal session. It is structured to support efficient rendering of text and cursors over time.

    ViewFrame

    Each ViewFrame represents the state of the terminal at a specific stamp (relative to the from timestamp):

    • cursor: The Cursor object (position and visibility).
    • lines: An array of line objects. Each line contains:
      • y: The vertical position calculated using fontSize * lineHeight.
      • words: An array of Word objects representing contiguous segments of text with identical attributes.
      • hash: A unique hash of the words in that line, used for the registry.
      • ref: A reference to a RegistryItem if the line is a duplicate.

    RegistryItem

    To optimize the SVG, the registry identifies lines that appear multiple times in the cast. Instead of rendering the full text for every occurrence, the ViewFrame.lines can use an id to point to a RegistryItem in the registry, which contains the actual words content.

  2. Render an asciicast to an animated SVG

    master

    You can render an asciicast (v1 or v2) into an animated SVG string using the render function. The input can be a raw JSON string, an object representing the cast, or a cast already loaded via load-asciicast.

    Note: If you provide an already loaded cast object as the input, the options parameter will be ignored.

    const fs = require('fs');
    const {promisify} = require('util');
    const readFile = promisify(fs.readFile);
    const {render} = require('svg-term');
    
    (async () => {
      const data = String(await readFile('./asciicast.json'));
      const svg = render(data);
      // => <svg>...</svg>
    })()
  3. Use the render function

    master

    The render function converts terminal session data into an SVG string.

    Signature: render(input: string, options?: Options): string

    Parameters:

    • input: A string or object representing an asciicast (v1 or v2) or a cast loaded via load-asciicast.
    • options: An optional Options object to customize the rendering (see Configure render options).
    render(input: string, options?: Options): string
  4. Convert color inputs to RGB strings using color()

    master

    The color function converts various color representations into a CSS-compatible rgb(r, g, b) string. It supports the following input types:

    1. ColorTuple: An array of three numbers [r, g, b].
    2. Theme Key: A string key that exists within a provided ColorTheme object.
    3. ANSI Color Code: A string or number representing an ANSI color code (e.g., `
  5. Define a custom Theme

    master

    A Theme object defines the colors and typography for the SVG. It uses RGBColor (an array of three numbers [r, g, b]) for color values.

    Required Keys:

    • background: Default background color.
    • bold: Default color for bold text.
    • cursor: Cursor color.
    • text: Default text color.
    • fontSize: Default font size.
    • lineHeight: Default line height.
    • fontFamily: Default font family.
    • ANSI color keys 0 through 15 (e.g., 0 for Black, 1 for Red, etc.).
    interface Theme {
      /** ANSI Black */
      0: RGBColor;
      /** ANSI Red */
      1: RGBColor;
      /** ANSI Green */
      2: RGBColor;
      /** ANSI Yellow */
      3: RGBColor;
      /** ANSI Blue */
      4: RGBColor;
      /** ANSI Magenta */
      5: RGBColor;
      /** ANSI Cyan */
      6: RGBColor;
      /** ANSI White */
      7: RGBColor;
      /** ANSI Light Black */
      8: RGBColor;
      /** ANSI Light Red */
      9: RGBColor;
      /** ANSI Light Green */
      10: RGBColor;
      /** ANSI Light Yellow */
      11: RGBColor;
      /** ANSI Light Blue */
      12: RGBColor;
      /** ANSI Light Magenta */
      13: RGBColor;
      /** ANSI Light Cyan */
      14: RGBColor;
      /** ANSI Light White */
      15: RGBColor;
      /** Default background color */
      background: RGBColor;
      /** Default color for bold text */
      bold: RGBColor;
      /** Cursor color */
      cursor: RGBColor;
      /** Default text color */
      text: RGBColor;
      /** Default font size */
      fontSize: number;
      /** Default line height */
      lineHeight: number;
      /** Default font family */
      fontFamily: string;
    }
    
    type RGBColor = [number, number, number];
  6. Configure render options

    master

    The Options object allows you to customize the appearance and playback of the rendered SVG.

    OptionTypeDescription
    themeThemeANSI theme to use. Defaults to Atom One theme if omitted. Must contain all keys if specified.
    windowbooleanIf true, renders with a framing window. Defaults to false.
    idlenumberIdle time limit in milliseconds.
    fpsnumberFrames per second limit.
    fromnumberLower bound of timeline to render in milliseconds.
    tonumberUpper bound of timeline to render in milliseconds.
    atnumberTimestamp of a single frame to render in milliseconds.
  7. Use the render function to generate SVG terminal sessions

    master

    The render function is the primary entrypoint for converting terminal session data into an SVG representation. It is exported from the main package entrypoint.

    import { render } from 'svg-term';
    
    // Usage depends on the internal implementation of render
    const svg = render(sessionData);
  8. Render terminal sessions with render()

    master

    The render function converts a terminal session (a 'cast') into a static SVG string. It accepts either a raw string path to a cast file or a pre-loaded LoadedCast object. You can customize the output using SvgTermOptions to control the time range, padding, theme, and visual decorations like a window frame or a cursor.

    import { render } from 'svg-term';
    
    const svg = render('path/to/cast.txt', {
      from: 10,
      to: 50,
      paddingX: 20,
      paddingY: 20,
      window: true,
      cursor: true
    });
  9. Transform terminal cast data with toViewModel()

    master

    The toViewModel function converts a loaded terminal session (LoadedCast) into a ViewModel optimized for rendering via SVG and CSS. It handles time-range slicing, theme application (font size and line height), and generates a registry of repeating lines to optimize rendering.

    ViewModelOptions

    When calling toViewModel, you must provide an options object containing:

    • cast: The LoadedCast object containing the terminal frames.
    • from: The starting timestamp (inclusive).
    • to: The ending timestamp (exclusive).
    • theme: A Theme object defining fontSize and lineHeight.
    • cursor (optional): A boolean to determine if the cursor should be rendered. Defaults to true if not specified.
    • height (optional): An override for the display height.

    ViewModel Output

    The returned ViewModel object includes:

    • frames: An array of ViewFrame objects containing cursor positions, line data, and relative timestamps.
    • registry: An array of RegistryItem objects used to reference repeating lines (identified by hash) to reduce redundancy.
    • stamps: An array of relative timestamps for each frame.
    • duration: The total duration (to - from).
    • width, height, displayWidth, displayHeight: Dimensions used for layout calculations.
    import { toViewModel } from './to-view-model';
    
    const viewModel = toViewModel({
      cast: myLoadedCast,
      from: 0,
      to: 100,
      theme: myTheme,
      cursor: true
    });
  10. Define a custom Theme for svg-term

    master

    To customize the appearance of rendered terminal sessions, you can implement the Theme interface. A theme defines the RGB color values for the 16 ANSI colors (0-15), as well as specific colors for the background, text, cursor, and bold styles. It also controls typography via fontSize, lineHeight, and fontFamily.

    import { Theme, RGBTuple } from 'svg-term';
    
    const myCustomTheme: Theme = {
      0: [0, 0, 0],
      1: [255, 0, 0],
      // ... must include all indices 0-15
      2: [0, 255, 0],
      3: [255, 255, 0],
      4: [0, 0, 255],
      5: [255, 0, 255],
      6: [0, 255, 255],
      7: [255, 255, 255],
      8: [50, 50, 50],
      9: [100, 0, 0],
      10: [0, 100, 0],
      11: [100, 100, 0],
      12: [0, 0, 100],
      13: [100, 0, 100],
      14: [0, 100, 100],
      15: [200, 200, 200],
      background: [30, 30, 30],
      bold: [255, 255, 255],
      cursor: [255, 255, 255],
      text: [200, 200, 200],
      fontSize: 1.5,
      lineHeight: 1.2,
      fontFamily: 'monospace'
    };
  11. Use the SvgTerm React component

    master

    The SvgTerm component is the primary entry point for rendering terminal sessions as SVG in a React application. It takes a LoadedCast (the session data), a Theme for styling, and various layout and playback configuration props.

    Key props include:

    • cast: The loaded terminal session data (LoadedCast).
    • theme: The visual theme object (Theme).
    • paddingX / paddingY: Horizontal and vertical padding within the window.
    • decorations: Boolean to show/hide window decorations (like title bars).
    • cursor: Boolean to show/hide the terminal cursor.
    • from, to, at: Numeric values to define the playback range or specific frame within the cast.
    import { SvgTerm } from './svg-term';
    
    // Example usage (assuming cast and theme are provided)
    <SvgTerm
      cast={myLoadedCast}
      theme={myTheme}
      paddingX={10}
      paddingY={10}
      decorations={true}
      cursor={true}
      from={0}
      to={100}
    />