/* * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import MarkdownIt from 'markdown-it/lib' import { useMemo, useRef } from 'react' import { ComponentReplacer, ValidReactDomElement } from '../replace-components/ComponentReplacer' import { LineKeys } from '../types' import { buildTransformer } from '../utils/html-react-transformer' import { calculateNewLineNumberMapping } from '../utils/line-number-mapping' import convertHtmlToReact from '@hedgedoc/html-to-react' import { Document } from 'domhandler' /** * Renders markdown code into react elements * * @param markdownCode The markdown code that should be rendered * @param markdownIt The configured {@link MarkdownIt markdown it} instance that should render the code * @param replacers A function that provides a list of {@link ComponentReplacer component replacers} * @param preprocessNodes A function that processes nodes after parsing the html code that is generated by markdown it. * @return The React DOM that represents the rendered markdown code */ export const useConvertMarkdownToReactDom = ( markdownCode: string, markdownIt: MarkdownIt, replacers: ComponentReplacer[], preprocessNodes?: (nodes: Document) => Document ): ValidReactDomElement[] => { const oldMarkdownLineKeys = useRef() const lastUsedLineId = useRef(0) return useMemo(() => { const html = markdownIt.render(markdownCode) const contentLines = markdownCode.split('\n') const { lines: newLines, lastUsedLineId: newLastUsedLineId } = calculateNewLineNumberMapping( contentLines, oldMarkdownLineKeys.current ?? [], lastUsedLineId.current ) oldMarkdownLineKeys.current = newLines lastUsedLineId.current = newLastUsedLineId const transformer = replacers.length > 0 ? buildTransformer(newLines, replacers) : undefined return convertHtmlToReact(html, { transform: transformer, preprocessNodes: preprocessNodes }) }, [markdownIt, markdownCode, replacers, preprocessNodes]) }