From f9f76513c664f34c1d19969b5af05bf016de42e3 Mon Sep 17 00:00:00 2001 From: windingwind <33902321+windingwind@users.noreply.github.com> Date: Sat, 24 Feb 2024 17:50:03 +0800 Subject: [PATCH] fix: line break bug in list while syncing fix: #820 fix: #869 --- src/modules/convert/api.ts | 49 ++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/modules/convert/api.ts b/src/modules/convert/api.ts index 146995c..013e26e 100644 --- a/src/modules/convert/api.ts +++ b/src/modules/convert/api.ts @@ -19,7 +19,7 @@ import { h } from "hastscript"; import YAML = require("yamljs"); import { Root as HRoot, RootContent } from "hast"; -import { Root as MRoot } from "mdast"; +import { ListContent, Root as MRoot } from "mdast"; import { Nodes } from "hast-util-to-text/lib"; import { fileExists, @@ -371,6 +371,45 @@ async function rehype2remark(rehype: HRoot) { return defaultHandlers.table(h, node); // } }, + /* + * See https://github.com/windingwind/zotero-better-notes/issues/820 + * The text content separated by non-text content (e.g. inline math) + * inside `li`(rehype) will be converted to `paragraph`(remark), + * which will be turned to line with \n in MD: + * ```rehype + * li: [text, text, inline-math, text] + * ``` + * to + * ```remark + * listitem: [paragraph, inline-math, paragraph] + * ``` + * to + * ```md + * * text text + * inline-math + * text + * ``` + */ + li: (h, node) => { + const mnode = defaultHandlers.li(h, node) as ListContent; + // If no more than 1 children, skip + if (!mnode || mnode.children.length < 2) { + return mnode; + } + const children: any[] = []; + // Merge none-list nodes inside li into the previous paragraph node to avoid line break + while (mnode.children.length > 0) { + const current = mnode.children.shift(); + const cached = children[children.length - 1]; + if (cached?.type === "paragraph" && current?.type !== "list") { + cached.children.push(current); + } else { + children.push(current); + } + } + mnode.children.push(...children); + return mnode; + }, wrapper: (h, node) => { return h(node, "wrapper", toText(node)); }, @@ -546,18 +585,18 @@ function rehype2note(rehype: HRoot) { }, ); - // Wrap lines in list with

(for diff) + // Wrap lines in list with (for diff) visitParents(rehype, "text", (node: any, ancestors) => { const parent = ancestors.length ? ancestors[ancestors.length - 1] : undefined; if ( - node.value.replace(/[\r\n]/g, "") && parent?.type == "element" && - ["li", "td"].includes(parent?.tagName) + ["li", "td"].includes(parent?.tagName) && + node.value.replace(/[\r\n]/g, "") ) { node.type = "element"; - node.tagName = "p"; + node.tagName = "span"; node.children = [ { type: "text", value: node.value.replace(/[\r\n]/g, "") }, ];