) {
}
export function unwrapFromParagraph($: CheerioAPI, $node: Cheerio) {
- // find the nearest or ancestor
- let $wrapper = $node.closest('p, a');
+ // Keep track of processed wrappers to avoid infinite loops
+ const processedWrappers = new Set();
+ let $wrapper = $node.closest('p, a');
while ($wrapper.length) {
- // if the wrapper has only our node inside, replace it entirely
- if ($wrapper.contents().length === 1) {
+ const wrapperElement = $wrapper.get(0);
+
+ // If we've already processed this wrapper, break to avoid infinite loop
+ if (processedWrappers.has(wrapperElement)) {
+ break;
+ }
+
+ processedWrappers.add(wrapperElement);
+
+ // Check if the wrapper contains only whitespace and our target node
+ const hasOnlyTargetNode =
+ $wrapper.contents().filter((_, el) => {
+ const $el = $(el);
+ // Skip whitespace-only text nodes. NodeType 3 = text node
+ if (el.nodeType === 3 && !$el.text().trim()) {
+ return false;
+ }
+ // Return true if this is not our target node
+ return !$el.is($node) && !$node.is($el);
+ }).length === 0;
+
+ if (hasOnlyTargetNode) {
+ // Replace the wrapper entirely with our node
$wrapper.replaceWith($node);
} else {
- // otherwise just move the node to before the wrapper
+ // Move the node to before the wrapper, preserving other content
$wrapper.before($node);
}
+
// look again for any new wrapper around $node
$wrapper = $node.closest('p, a');
}
diff --git a/apps/server/src/integrations/import/utils/import.utils.ts b/apps/server/src/integrations/import/utils/import.utils.ts
index 19cc66bc..1fa10d7a 100644
--- a/apps/server/src/integrations/import/utils/import.utils.ts
+++ b/apps/server/src/integrations/import/utils/import.utils.ts
@@ -64,3 +64,9 @@ export async function collectMarkdownAndHtmlFiles(
await walk(dir);
return results;
}
+
+export function stripNotionID(fileName: string): string {
+ // Handle optional separator (space or dash) + 32 alphanumeric chars at end
+ const notionIdPattern = /[ -]?[a-z0-9]{32}$/i;
+ return fileName.replace(notionIdPattern, '').trim();
+}
diff --git a/package.json b/package.json
index 645cf1e1..9177f81e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "docmost",
"homepage": "https://docmost.com",
- "version": "0.23.1",
+ "version": "0.23.2",
"private": true,
"scripts": {
"build": "nx run-many -t build",
diff --git a/packages/editor-ext/src/lib/table/cell.ts b/packages/editor-ext/src/lib/table/cell.ts
index 25a311b9..63df7dcf 100644
--- a/packages/editor-ext/src/lib/table/cell.ts
+++ b/packages/editor-ext/src/lib/table/cell.ts
@@ -2,33 +2,39 @@ import { TableCell as TiptapTableCell } from "@tiptap/extension-table-cell";
export const TableCell = TiptapTableCell.extend({
name: "tableCell",
- content: "(paragraph | heading | bulletList | orderedList | taskList | blockquote | callout | image | video | attachment | mathBlock | details | codeBlock)+",
-
+ content:
+ "(paragraph | heading | bulletList | orderedList | taskList | blockquote | callout | image | video | attachment | mathBlock | details | codeBlock)+",
+
addAttributes() {
return {
...this.parent?.(),
backgroundColor: {
default: null,
- parseHTML: (element) => element.style.backgroundColor || null,
+ parseHTML: (element) =>
+ element.style.backgroundColor ||
+ element.getAttribute("data-background-color") ||
+ null,
renderHTML: (attributes) => {
if (!attributes.backgroundColor) {
return {};
}
return {
style: `background-color: ${attributes.backgroundColor}`,
- 'data-background-color': attributes.backgroundColor,
+ "data-background-color": attributes.backgroundColor,
};
},
},
backgroundColorName: {
default: null,
- parseHTML: (element) => element.getAttribute('data-background-color-name') || null,
+ parseHTML: (element) =>
+ element.getAttribute("data-background-color-name") || null,
renderHTML: (attributes) => {
if (!attributes.backgroundColorName) {
return {};
}
return {
- 'data-background-color-name': attributes.backgroundColorName.toLowerCase(),
+ "data-background-color-name":
+ attributes.backgroundColorName.toLowerCase(),
};
},
},
diff --git a/packages/editor-ext/src/lib/table/header.ts b/packages/editor-ext/src/lib/table/header.ts
index 399a8cf0..501f089d 100644
--- a/packages/editor-ext/src/lib/table/header.ts
+++ b/packages/editor-ext/src/lib/table/header.ts
@@ -2,36 +2,42 @@ import { TableHeader as TiptapTableHeader } from "@tiptap/extension-table-header
export const TableHeader = TiptapTableHeader.extend({
name: "tableHeader",
- content: "(paragraph | heading | bulletList | orderedList | taskList | blockquote | callout | image | video | attachment | mathBlock | details | codeBlock)+",
-
+ content:
+ "(paragraph | heading | bulletList | orderedList | taskList | blockquote | callout | image | video | attachment | mathBlock | details | codeBlock)+",
+
addAttributes() {
return {
...this.parent?.(),
backgroundColor: {
default: null,
- parseHTML: (element) => element.style.backgroundColor || null,
+ parseHTML: (element) =>
+ element.style.backgroundColor ||
+ element.getAttribute("data-background-color") ||
+ null,
renderHTML: (attributes) => {
if (!attributes.backgroundColor) {
return {};
}
return {
style: `background-color: ${attributes.backgroundColor}`,
- 'data-background-color': attributes.backgroundColor,
+ "data-background-color": attributes.backgroundColor,
};
},
},
backgroundColorName: {
default: null,
- parseHTML: (element) => element.getAttribute('data-background-color-name') || null,
+ parseHTML: (element) =>
+ element.getAttribute("data-background-color-name") || null,
renderHTML: (attributes) => {
if (!attributes.backgroundColorName) {
return {};
}
return {
- 'data-background-color-name': attributes.backgroundColorName.toLowerCase(),
+ "data-background-color-name":
+ attributes.backgroundColorName.toLowerCase(),
};
},
},
};
},
-});
\ No newline at end of file
+});