---
title: "Text beside the picture"
description: "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."
canonical_url: "https://tiptap.dev/docs/diagrams/guides/split-view"
---

# 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 tools

| Tool                                                                                                              | What it does                                                                        |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| [`readText({ pos? })`](https://tiptap.dev/docs/diagrams/api-reference/storage.md#reading-a-charts-data)           | The text of a chart or a diagram, with its format                                   |
| [`updateFromText({ text, pos? })`](https://tiptap.dev/docs/diagrams/guides/split-view.md#updatefromtext)          | Changes the chart or diagram from that text                                         |
| [`highlightSource(text, format)`](https://tiptap.dev/docs/diagrams/api-reference/selectors.md#highlighted-source) | The text as HTML with its parts colored, from `@tiptap-pro/extension-diagrams/core` |

## Reading the text

```ts
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](https://tiptap.dev/docs/diagrams/data/chart-syntax.md), 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.

```ts
editor.commands.updateFromText({ pos, text: 'pie\nDogs, 3\nCats, 2' })
```

| Option | Type     | Description                                                        |
| ------ | -------- | ------------------------------------------------------------------ |
| `text` | `string` | The text                                                           |
| `pos`  | `number` | The 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](https://tiptap.dev/docs/diagrams/charts/overview.md#importmermaidchart). 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.

```ts
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.

```ts
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](https://tiptap.dev/docs/diagrams/api-reference/selectors.md#highlighted-source).
- **The `sourceHighlighting` option** turns the colors off in the Quick Input and the code view
  only. Your own pane decides for itself.
