Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spatialillusions/milsymbol/llms.txt

Use this file to discover all available pages before exploring further.

milsymbol was designed from the ground up to be extensible. Every visual feature of a rendered symbol — from the icon to text field layout to direction arrows — is implemented as a modular symbol part, and the same mechanism is exposed publicly so you can inject custom parts, override built-in icons, register entirely new SIDC codes, and reshape label positioning without ever forking the library. All extension functions return the ms namespace object, so calls can be chained.

ms.addSymbolPart()

Registers a new symbol function that participates in every symbol’s rendering pipeline. A symbol part is called once per symbol render and can contribute draw instructions that are painted before (pre) or after (post) all other parts, along with a bounding box that informs milsymbol how much extra space the additions need.
function addSymbolPart(extension: ExtensionFunction): typeof _default;

type ExtensionFunction = (
  this: Symbol,
  ms: typeof _default
) => {
  pre: DrawInstruction[];
  post: DrawInstruction[];
  bbox: BBoxObject;
};
extension
ExtensionFunction
required
A function called with this bound to the current Symbol instance and the ms namespace passed as the first argument. It must return an object with pre (draw instructions rendered before everything else), post (draw instructions rendered after everything else), and bbox (the combined bounding box of those instructions).
Returns the ms namespace object (chainable).
Inside the extension function, use this.getOptions() to read the symbol’s current options and this.getMetadata() to access computed metadata such as affiliation, echelon, and dimension. Both are available because this is the live Symbol instance.

Pre vs. post draw arrays

ArrayWhen it is painted
preBefore the symbol frame, fill, and icon — useful for background layers or halos.
postAfter the symbol frame, fill, and icon — useful for overlays, annotations, or decorators.

Example

import ms from "milsymbol";
import { type DrawInstruction } from "milsymbol";

ms.addSymbolPart(function myExtension(ms) {
  const options = this.getOptions();

  const bbox = new ms.BBox();
  const preDrawArray: DrawInstruction[] = [];
  const postDrawArray: DrawInstruction[] = [];

  // Example: add a small dot in the post layer when a custom option is set
  if (options.customOption) {
    postDrawArray.push({
      type: "circle",
      cx: 100,
      cy: 100,
      r: 10,
      fill: "red",
      stroke: false
    });
  }

  return {
    pre: preDrawArray,
    post: postDrawArray,
    bbox
  };
});
Study the built-in symbol functions in src/symbolfunctions/ (e.g. debug.js) as real-world examples of how milsymbol implements its own features using the same API.

ms.addIconParts()

Registers a function that can add or override entries in the shared icon parts dictionary — the lookup table that maps icon-part keys (like "TP.HARBOR") to DrawInstruction values. Multiple icon parts are combined to build a single symbol icon, which keeps the library lean by reusing common shapes across many SIDCs.
function addIconParts(iconParts: IconPartsFunction): typeof _default;

type IconPartsFunction = (
  this: Symbol,
  iconParts: Record<string, DrawInstruction | DrawInstruction[]>,
  metadata: SymbolMetadata,
  colors: SymbolColors
) => void;
iconParts
IconPartsFunction
required
A function called with this bound to the current Symbol instance. Receives the mutable iconParts dictionary, the symbol’s computed metadata, and the resolved colors object. Modify iconParts in place — no return value is needed.
Returns the ms namespace object (chainable).

Parameters received by IconPartsFunction

ParameterTypeDescription
iconPartsRecord<string, DrawInstruction | DrawInstruction[]>The live dictionary of all registered icon parts. Set a key to add or override a part.
metadataSymbolMetadataComputed metadata for the current symbol (affiliation, echelon, dimension, etc.).
colorsSymbolColorsResolved color values for the current symbol and color mode.

Example — adding a custom tactical point harbor icon

ms.addIconParts(function (iconParts, metadata, colors) {
  // Register a new icon part for a tactical harbor symbol.
  // The key "TP.HARBOR" can now be referenced from addSIDCicons.
  iconParts["TP.HARBOR"] = {
    type: "path",
    fill: false,
    d: "M 80,140 50,60 150,60 120,140"
  };

  // Modifying the object in place — no return needed.
});

ms.addSIDCicons()

Registers a function that maps SIDC codes to icon parts and bounding boxes. Use this to add custom SIDC codes whose icons are assembled from entries in the icon parts dictionary, or to override how existing SIDCs are rendered.
ms.addSIDCicons() is a JavaScript-only API. It is not included in the TypeScript type declarations (index.d.ts). It is available at runtime on the ms namespace but TypeScript will not recognise it without a custom declaration augmentation.
// JavaScript signature (not exported in TypeScript types)
ms.addSIDCicons(sidcFunction, type)
sidcFunction
Function
required
A function called with four arguments: sidc (the mutable SIDC-to-icon-parts mapping), bbox (the mutable SIDC-to-bounding-box mapping), iconParts (the full icon parts dictionary), and std2525 (boolean — true if the active standard is 2525). Modify sidc and bbox in place; no return value is needed. If you omit a bounding box entry for a SIDC, milsymbol falls back to the bounds of the icon octagon.
type
"letter" | "number"
required
Whether the SIDCs being registered use the letter-based format (e.g. "G-T-D-----") or the number-based format.
Returns the ms namespace object (chainable).

Example — registering two custom tactical graphic SIDCs

ms.addSIDCicons(
  function tacticalPoints(sidc, bbox, icnParts, std2525) {
    // Map G-T-D----- to the TP.DESTROY icon part
    sidc["G-T-D-----"] = icnParts["TP.DESTROY"];
    // Provide an explicit bounding box for this SIDC
    bbox["G-T-D-----"] = { x1: 0, x2: 200, y1: 40, y2: 160 };

    // G-T-I----- gets the TP.INTERDICT icon with no explicit bbox,
    // so milsymbol will use the default octagon bounds instead.
    sidc["G-T-I-----"] = icnParts["TP.INTERDICT"];
  },
  "letter"
);

ms.addLabelOverrides()

Registers a function that customizes how text-field labels are positioned for specific SIDC codes. By default, milsymbol places all label fields (unique designation, higher formation, DTG, etc.) at fixed positions relative to the symbol frame. For tactical graphics and other non-standard symbols, those default positions may be wrong — addLabelOverrides lets you specify exact placement per field per SIDC.
ms.addLabelOverrides() is a JavaScript-only API. It is not included in the TypeScript type declarations (index.d.ts). It is available at runtime on the ms namespace but TypeScript will not recognise it without a custom declaration augmentation.
// JavaScript signature (not exported in TypeScript types)
ms.addLabelOverrides(labelFunction, type)
labelFunction
Function
required
A function that receives the mutable sidc label-override object. For each SIDC key you want to override, set a value that is itself an object keyed by field name (e.g. "uniqueDesignation", "hostile", "dtg"), where each field value is an object of draw-instruction properties to merge into that label’s text instruction (x, y, textanchor, fontsize, stroke, etc.). Modify sidc in place — no return value is needed.
type
"letter" | "number"
required
Whether the SIDCs being overridden use the letter-based or number-based format.
Returns the ms namespace object (chainable).

Example — repositioning labels for a control point SIDC

ms.addLabelOverrides(
  function tacticalPoints(sidc) {
    // Override label positions for the passage point SIDC G-G-GPPK--
    sidc["G-G-GPPK--"] = {
      additionalInformation: {
        stroke: false,
        textanchor: "middle",
        x: 100,
        y: -70,
        fontsize: 40
      },
      hostile: {
        stroke: false,
        textanchor: "start",
        x: 150,
        y: 45,
        fontsize: 40
      },
      uniqueDesignation: {
        stroke: false,
        textanchor: "start",
        x: 150,
        y: 0,
        fontsize: 80
      },
      dtg: {
        stroke: false,
        textanchor: "end",
        x: 50,
        y: -30,
        fontsize: 40
      },
      dtg1: {
        stroke: false,
        textanchor: "end",
        x: 50,
        y: 10,
        fontsize: 40
      }
    };
  },
  "letter"
);

ms.getSymbolParts() / ms.setSymbolParts()

These functions provide direct access to the internal array of all registered symbol functions — both the built-in milsymbol parts and any you have added via ms.addSymbolPart().
ms.getSymbolParts() and ms.setSymbolParts() are JavaScript-only APIs. They are not included in the TypeScript type declarations (index.d.ts). Both are available at runtime on the ms namespace but TypeScript will not recognise them without a custom declaration augmentation.

ms.getSymbolParts()

Returns a copy of the current array of all symbol part functions.
// JavaScript-only — not in TypeScript types
ms.getSymbolParts() // → ExtensionFunction[]
Returns an Array of symbol part functions in the order they will be executed during rendering.

ms.setSymbolParts()

Replaces the entire array of symbol part functions with a new one.
// JavaScript-only — not in TypeScript types
ms.setSymbolParts(parts) // parts: ExtensionFunction[] → ms
parts
ExtensionFunction[]
required
The complete replacement array of symbol part functions.
Returns the ms namespace object (chainable).
ms.setSymbolParts() replaces all registered symbol functions, including every built-in milsymbol feature (frames, fills, text fields, direction arrows, mobility indicators, and more). Unless you intentionally want to rebuild the rendering pipeline from scratch, prefer ms.addSymbolPart() to append to the existing parts rather than replacing them. To safely modify or remove a specific built-in part, read the current array with ms.getSymbolParts(), filter or transform it, and then write it back.

Example

import ms from "milsymbol";

// Read all current symbol parts
const parts = ms.getSymbolParts();
console.log(`${parts.length} symbol parts registered`);

// Filter out a specific named function (here, one called "debugOverlay")
const filtered = parts.filter((fn) => fn.name !== "debugOverlay");

// Write the modified array back
ms.setSymbolParts(filtered);

Build docs developers (and LLMs) love