Text beside the picture

Show the text of a chart or a diagram in an editor of your own, next to the document, and let each change the other. The package reads and writes the text; the editor and the layout are yours.
Pro ExtensionAlphaPilot program
New tab

The tools

ToolWhat it does
readText({ pos? })The text of a chart or a diagram, with its format
updateFromText({ text, pos? })Changes the chart or diagram from that text
highlightSource(text, format)The text as HTML with its parts colored, from @tiptap-pro/extension-diagrams/core

Reading the text

const current = editor.storage.diagrams.readText({ pos })
// { format: 'chart-syntax', text: 'bar\nMonth | Revenue\nJan | 120' }
  • A chart gives its type line and its rows in the chart syntax, split at its delimiter, as the Quick Input shows them. The format is 'chart-syntax'.
  • A diagram gives its source. The format is its own: 'mermaid', 'drawio' or 'bpmn'.
  • Without a chart or a diagram at pos, or selected, it returns null.

Writing it back

updateFromText

Changes a chart or a diagram from its text, the text readText returns.

editor.commands.updateFromText({ pos, text: 'pie\nDogs, 3\nCats, 2' })
OptionTypeDescription
textstringThe text
posnumberThe position of the chart or diagram. Defaults to the selected one
  • A chart reads the text as the Quick Input does: rows in the chart syntax below an optional type line, or a Mermaid chart. Its data and type change; title, colors, axes and the rest of the Chart Spec stay.
  • A diagram takes the text as its new source, as updateFlowDiagram does.
  • Returns false for text it cannot read, such as an unclosed quote, and changes nothing. Keep the text in your editor and mark it, so nothing typed is lost.
  • A chart whose data is read-only, from a linked Data Source, returns false for new data.

Following the selection

Read the text again when the selection moves to another chart or diagram, or when it changes elsewhere. Skip the update your own pane caused, so what was typed stays as it was typed.

let pos = editor.storage.diagrams.listCharts()[0]?.pos ?? null
let typing = false

editor.on('transaction', ({ transaction }) => {
  // Map to the left: a Command that changes the chart replaces its Node from the start
  if (pos !== null) pos = transaction.mapping.map(pos, -1)
  const { node, from } = editor.state.selection
  if (node && ['chart', 'flowDiagram'].includes(node.type.name)) pos = from
  if (!typing && pos !== null) pane.value = editor.storage.diagrams.readText({ pos })?.text ?? ''
})

pane.addEventListener('input', () => {
  typing = true
  const valid = editor.commands.updateFromText({ pos, text: pane.value })
  typing = false
  pane.toggleAttribute('data-invalid', !valid)
})

Coloring the text

highlightSource returns the text as HTML, each part in a <span> with a class such as tiptap-diagram-source-keyword. It reads the chart syntax and Mermaid; leave draw.io and BPMN XML as plain text.

import { highlightSource } from '@tiptap-pro/extension-diagrams/core'

const { delimiters, chartTypes } = editor.storage.diagrams.describeCapabilities()
code.innerHTML = highlightSource(text, 'chart-syntax', {
  delimiters,
  types: chartTypes.map((type) => type.id),
})
  • Put the class tiptap-diagram-source on the element around the HTML. The colors of the Quick Input apply there too, with their light and dark values.
  • For an editable pane, lay a transparent <textarea> over a <pre> with the HTML, in the same font, padding and line height. The demo does it that way.
  • The colors are custom properties, listed under Highlighted source.
  • The sourceHighlighting option turns the colors off in the Quick Input and the code view only. Your own pane decides for itself.