lini 0.22.0

Pretty diagrams, charts, and technical drawings from plain text, with fine-grained control. Compiles to clean, themeable SVG.
Documentation
{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "name": "Lini",
  "scopeName": "source.lini",
  "patterns": [
    { "include": "#comment" },
    { "include": "#string" },
    { "include": "#var-declaration" },
    { "include": "#binding" },
    { "include": "#property-declaration" },
    { "include": "#type-bars" },
    { "include": "#css-var" },
    { "include": "#link-op" },
    { "include": "#class" },
    { "include": "#side" },
    { "include": "#hex-color" },
    { "include": "#id-selector" },
    { "include": "#number" },
    { "include": "#punctuation" }
  ],
  "repository": {
    "comment": {
      "match": "(//).*$",
      "name": "comment.line.double-slash.lini",
      "captures": {
        "1": { "name": "punctuation.definition.comment.lini" }
      }
    },
    "string": {
      "name": "string.quoted.double.lini",
      "begin": "\"",
      "beginCaptures": {
        "0": { "name": "punctuation.definition.string.begin.lini" }
      },
      "end": "\"",
      "endCaptures": {
        "0": { "name": "punctuation.definition.string.end.lini" }
      },
      "patterns": [
        {
          "match": "\\\\[\"\\\\nt]",
          "name": "constant.character.escape.lini"
        }
      ]
    },
    "var-declaration": {
      "begin": "(--[A-Za-z_][\\w-]*)\\s*(:)(?!:)",
      "beginCaptures": {
        "1": { "name": "variable.other.lini" },
        "2": { "name": "punctuation.separator.key-value.lini" }
      },
      "end": "(?=[;}])|$",
      "patterns": [{ "include": "#value-body" }]
    },
    "property-declaration": {
      "begin": "([A-Za-z_][\\w-]*)\\s*(:)(?!:)",
      "beginCaptures": {
        "1": { "name": "support.type.property-name.lini" },
        "2": { "name": "punctuation.separator.key-value.lini" }
      },
      "end": "(?=[;}])|$",
      "patterns": [{ "include": "#value-body" }]
    },
    "binding": {
      "comment": "An = binding (SPEC §10.7): name = value, or name(params) = value. The right-hand side is an expression, so it reads through #value-body.",
      "begin": "([A-Za-z_][\\w-]*)\\s*(\\([A-Za-z_,\\s-]*\\))?\\s*(=)(?!=)",
      "beginCaptures": {
        "1": { "name": "entity.name.function.lini" },
        "2": { "name": "variable.parameter.lini" },
        "3": { "name": "keyword.operator.assignment.lini" }
      },
      "end": "(?=[;}])|$",
      "patterns": [{ "include": "#value-body" }]
    },
    "value-body": {
      "patterns": [
        { "include": "#comment" },
        { "include": "#string" },
        { "include": "#css-var" },
        { "include": "#hex-color" },
        { "include": "#function-call" },
        { "include": "#number" },
        { "include": "#color-name" },
        { "include": "#value-keyword" },
        {
          "comment": "Math operators inside a (…) group or a call's arguments (SPEC §10.7).",
          "match": "\\*|/|\\^|<=|>=|==|!=|<|>|\\?",
          "name": "keyword.operator.arithmetic.lini"
        },
        {
          "match": "[(),]",
          "name": "punctuation.separator.value.lini"
        }
      ]
    },
    "type-bars": {
      "comment": "Bars hold identity (SPEC §3): a type (|box|), a type with an id (|box#cat|), an id alone (|#cat|), or a name::base define. A worn class lives after the bars (see #class); a descendant selector is space-separated bars (|table| |box|), each its own pair.",
      "begin": "\\|",
      "beginCaptures": {
        "0": { "name": "punctuation.definition.type.begin.lini entity.name.tag.lini" }
      },
      "end": "\\|",
      "endCaptures": {
        "0": { "name": "punctuation.definition.type.end.lini entity.name.tag.lini" }
      },
      "patterns": [
        {
          "comment": "name::base define",
          "match": "([A-Za-z_][\\w-]*)\\s*(::)\\s*([A-Za-z_][\\w-]*)",
          "captures": {
            "1": { "name": "entity.name.type.lini" },
            "2": { "name": "keyword.operator.define.lini" },
            "3": { "name": "entity.other.inherited-class.lini" }
          }
        },
        {
          "comment": "an #id pinned in the bars (|box#cat|, |#cat|)",
          "match": "(#)([A-Za-z_][\\w-]*)",
          "captures": {
            "1": { "name": "punctuation.definition.entity.lini" },
            "2": { "name": "entity.name.tag.id.lini" }
          }
        },
        {
          "comment": "a built-in primitive or template",
          "match": "(?<![\\w-])(box|oval|line|path|poly|hex|slant|cyl|diamond|cloud|icon|image|block|rect|group|caption|footnote|header|footer|entity|badge|note|row|column|grid|table|sequence|loop|opt|alt|else)(?![\\w-])",
          "name": "entity.name.tag.lini"
        },
        {
          "comment": "a user-defined type",
          "match": "[A-Za-z_][\\w-]*",
          "name": "entity.name.tag.instance.lini"
        }
      ]
    },
    "css-var": {
      "match": "--[A-Za-z_][\\w-]*",
      "name": "variable.other.lini"
    },
    "link-op": {
      "comment": "[start_marker?] line [end_marker?]; line is - / -- / --- / ~ (longest first).",
      "match": "(?:<>|[<>*])?(?:---|--|~|-)(?:<>|[<>*])?",
      "name": "keyword.operator.link.lini"
    },
    "class": {
      "comment": "A class outside the bars: a definition (.hot { }), or worn by a node or link after its type/endpoints (|box| .hot, a -> b .loud), chained .hot.loud. A '.' after a word char is an endpoint path (a.b), not a class.",
      "match": "(?<![\\w-])(?:\\.[A-Za-z_][\\w-]*)+",
      "name": "entity.other.attribute-name.class.lini"
    },
    "side": {
      "comment": "A forced side on a link endpoint (a:left); sides are free as ids elsewhere (SPEC §18).",
      "match": "(:)(top|bottom|left|right)(?![\\w-])",
      "captures": {
        "1": { "name": "punctuation.separator.side.lini" },
        "2": { "name": "support.constant.side.lini" }
      }
    },
    "id-selector": {
      "comment": "An #id at a rule head (#hero { }); a #hex run is a colour (handled first).",
      "match": "#[A-Za-z_][\\w-]*",
      "name": "entity.name.tag.id.lini"
    },
    "hex-color": {
      "match": "#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])",
      "name": "constant.other.color.lini"
    },
    "number": {
      "match": "(?<![\\w-])[-+]?(?:\\d+\\.\\d+|\\d+|\\.\\d+)",
      "name": "constant.numeric.lini"
    },
    "function-call": {
      "comment": "Any call in value position: the colour / track builders and the math library, pen calls, and bindings — all `name(` (SPEC §10.7).",
      "match": "(?<![\\w-])[A-Za-z_][\\w-]*(?=\\s*\\()",
      "name": "support.function.lini"
    },
    "value-keyword": {
      "match": "(?<![\\w-])(flow|grid|row|column|start|center|end|stretch|evenly|none|auto|true|false|solid|dashed|dotted|wavy|arrow|dot|diamond|crow|outlined|filled|rounded|sharp|top|bottom|left|right|all|rows|columns)(?![\\w-])",
      "name": "support.constant.lini"
    },
    "color-name": {
      "match": "(?<![\\w-])(white|black|red|green|blue|gray|grey|crimson|orange|yellow|gold|silver|navy|teal|purple|pink|brown|cyan|magenta|lime|maroon|olive|cornflowerblue|currentColor|transparent)(?![\\w-])",
      "name": "support.constant.color.lini"
    },
    "punctuation": {
      "patterns": [
        { "match": "[{}]", "name": "punctuation.section.block.lini" },
        { "match": "[\\[\\]]", "name": "punctuation.section.children.lini" },
        { "match": ";", "name": "punctuation.terminator.lini" },
        { "match": ",", "name": "punctuation.separator.lini" },
        { "match": "&", "name": "keyword.operator.fanout.lini" }
      ]
    }
  }
}