---
title: "Text beside the picture"
description: "You can show the text of a chart or a diagram in a text field of your own, next to the document."
canonical_url: "https://tiptap-docs.lin52025i.qzz.io/diagrams/guides/split-view"
---

# Text beside the picture

You can show the text of a chart or a diagram in a text field of your own, next to the document.

## Functions

| Function                                                                                                                       | What it does                                                                                |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| [`readText({ pos? })`](https://tiptap-docs.lin52025i.qzz.io/diagrams/api-reference/storage.md#reading-a-charts-data)           | Returns the text of a chart or a diagram, with its format                                   |
| [`updateFromText({ text, pos? })`](https://tiptap-docs.lin52025i.qzz.io/diagrams/guides/split-view.md#updatefromtext)          | Changes the chart or diagram from that text                                                 |
| [`highlightSource(text, format)`](https://tiptap-docs.lin52025i.qzz.io/diagrams/api-reference/selectors.md#highlighted-source) | Returns 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' }
```

For a chart, `readText` returns its type line and its rows in the
[Chart syntax](https://tiptap-docs.lin52025i.qzz.io/diagrams/data/chart-syntax.md), split at its delimiter, as the Quick Input shows them. The
format is `'chart-syntax'`. For a diagram, it returns the source, in the diagram's own format:
`'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 same text that `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-docs.lin52025i.qzz.io/diagrams/charts/overview.md#importmermaidchart). The chart's data and type
  change. A Mermaid chart also sets what its source names, such as the title or the axes. The
  rest of the Chart Spec, such as its colors, stays.
- **A diagram** takes the text as its new source, as `updateFlowDiagram` does.
- **Text the command cannot read**, such as an unclosed quote, changes nothing, and the command
  returns `false`. Keep the text in your text field and mark it as invalid, so nothing the user
  typed is lost.
- **A chart whose data is read-only**, because it comes 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 the chart
changes elsewhere. Skip the update that your own text field caused, so the text stays as the
user typed it.

```ts
const textField = document.createElement('textarea')
document.body.append(textField)

let pos = editor.storage.diagrams.listCharts()[0]?.pos ?? null
if (pos !== null) textField.value = editor.storage.diagrams.readText({ pos })?.text ?? ''
let typing = false

editor.on('transaction', ({ transaction }) => {
  // A command that changes a chart replaces its node. Mapping with -1 keeps pos at its 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) {
    textField.value = editor.storage.diagrams.readText({ pos })?.text ?? ''
  }
})

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

## Coloring the text

`highlightSource` returns the text as HTML. Each part sits in a `<span>` with a class such as
`tiptap-diagram-source-keyword`. It colors 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
[Highlighted source](https://tiptap-docs.lin52025i.qzz.io/diagrams/api-reference/selectors.md#highlighted-source) colors of the Quick Input then apply
there too, in light and dark. For a text field the user can edit, lay a transparent `<textarea>`
over a `<pre>` that holds the HTML, with the same font, padding and line height. The demo works
that way.

The [`sourceHighlighting`](https://tiptap-docs.lin52025i.qzz.io/diagrams/api-reference/options.md#sourcehighlighting) option turns the colors off only in the
Quick Input and in a diagram's code view, not in your own text field.
