Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: $convertToMarkdownString() returning null if node is not root #6328

Open
LucaIgnatescu opened this issue Jun 20, 2024 · 1 comment
Open

Comments

@LucaIgnatescu
Copy link

LucaIgnatescu commented Jun 20, 2024

I am trying to convert individual sections, such as paragraphs and headings, into markdown by themselves.
From what I can tell, passing something like a HeadingNode to $convertToMarkdownString leads to a null result, instead of the conversion to markdown.

Lexical version: 0.16

Steps To Reproduce

  1. call $convertToMarkdownString() with a node of type HeadingNode or ParagraphNode.

Fix

The issue seems to stem from the fact that the implementation calls exportTopLevelElements() on the children of the passed in node, without checking whether this should actually be done.

My workaround consists in checking whether the passed in node is a ParagraphNode, HeadingNode etc and adjusting the call apropriately.

Below is a possible fix, where the isTopLevelComponent is added by me, as well as the last line provided (const children ...).

function isTopLevelComponent(node: ElementNode) {// NOTE: make sure didnt miss anything
  return $isParagraphNode(node) || $isHeadingNode(node) || $isCodeNode(node) || $isListNode(node);
}
export function createMarkdownExport(
  transformers: Array<Transformer>,
  shouldPreserveNewLines: boolean = false,
): (node?: ElementNode) => string {
  const byType = transformersByType(transformers);
  const isNewlineDelimited = !shouldPreserveNewLines;

  // Export only uses text formats that are responsible for single format
  // e.g. it will filter out *** (bold, italic) and instead use separate ** and *
  const textFormatTransformers = byType.textFormat.filter(
    (transformer) => transformer.format.length === 1,
  );

  return (node) => {
    node = node || $getRoot();
    const output = [];

    const children = isTopLevelComponent(node) ? [node] : node.getChildren();
...

The fix can be found in this repository.

@etrepum
Copy link
Collaborator

etrepum commented Jun 20, 2024

The assumption in that function is that the given node is the parent of all the elements you want to convert to markdown (the element itself is effectively ignored, it's just a source of children, like the RootNode). It's really not a very good API, but I'm not sure it can be fixed nicely in a backwards compatible way.

I think the function you're looking for is $isRootOrShadowRoot, e.g.

const children = $isRootOrShadowRoot(node) ? node.getChildren() : [node];

Even still I think the function may still have issues if there are any decorators in that root node

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants