# preview

Source: https://developers.inkdrop.app/states/preview

An [app state](https://developers.inkdrop.app/guides/flux-architecture) of the Markdown preview pane in Inkdrop.
You can obtain the `preview` state and integrate it with React components.

It also stores abstract syntax trees of Markdown and HTML for additional processing by plugins.

---

## Data Structure

- **dom** (React.ReactElement\<unknown> | null)

  A React DOM that was generated by the Markdown renderer.
- **mdast** (MdastRoot | null)

  An [mdast - Markdown Abstract Syntax Tree format](https://github.com/syntax-tree/mdast) that was generated by the Markdown processor from a currently editing note.
- **hast** (HastRoot | null)

  An [hast - Hypertext Abstract Syntax Tree format](https://github.com/syntax-tree/hast) that was generated by the Markdown processor from a currently editing note.
- **lastError** (Error | null | undefined)

  The last error that occurred while rendering a note.

To get the `preview` state manually:

```js
const { preview } = env.store.getState()
```

Connect the state with your React component:

```js
import { useSelector } from 'react-redux'
const selector = ({ preview }) => preview
const MyComponent = props => {
  const preview = useSelector(selector)
  // render
}
```

---

## Extract YAML frontmatter values from `mdast`

The `mdast` property can contain YAML frontmatter values if the note has them.
For example:

```js
import { useSelector } from 'react-redux'
const selector = ({ preview }) => {
  const { mdast } = preview
  if (mdast?.children[0]?.type === 'yaml') {
    const yamlNode = mdast.children[0]
    const { value: frontmatter } = yamlNode as any
    if (typeof frontmatter === 'object') {
      return (frontmatter.title || frontmatter.subject || '') as string
    }
  }
  return null
}
const MyComponent = props => {
  const title = useSelector(selector)
  // render
}
```

## Extract particular types of nodes from `mdast`

It's easy to extract a particular type of nodes from the `mdast` data.

```ts
import type { Root as MdastRoot, Heading } from 'mdast'
import { visit } from 'unist-util-visit'

function getHeadingNodes(mdast: MdastRoot): Heading[] {
  const headings: Heading[] = []

  visit(mdast, 'heading', (node: Heading) => {
    headings.push(node)
  })

  return headings
}
```

> **Warning:**
>
> Unist, Remark, and Rehype modules are ES Modules but Electron doesn't support importing them from plugins.
> You have to transpile them into CommonJS modules at the moment.

Another example:

```ts
import type { Root as MdastRoot, ListItem } from 'mdast'
import { visit } from 'unist-util-visit'

export type NumberOfTasks = {
  numOfTasks: number
  numOfCheckedTasks: number
}

function countNumberOfTasks(mdast: MdastRoot): NumberOfTasks {
  let numOfTasks = 0,
    numOfCheckedTasks = 0

  visit(mdast, 'listItem', (node: ListItem) => {
    if (typeof node.checked === 'boolean') {
      numOfTasks++
      node.checked && numOfCheckedTasks++
    }
  })

  return {
    numOfTasks,
    numOfCheckedTasks
  }
}
```
