Skip to content

Commit 971a3d7

Browse files
authored
Merge pull request framer#359 from framer/airtable-rich-text
Airtable: improve markdown parsing
2 parents b353fb6 + e22169a commit 971a3d7

4 files changed

Lines changed: 20 additions & 34 deletions

File tree

107 KB
Binary file not shown.

plugins/airtable/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
},
1515
"dependencies": {
1616
"framer-plugin": "^3.5.2",
17+
"marked": "^16.1.1",
1718
"react": "^18.3.1",
1819
"react-dom": "^18.3.1",
1920
"valibot": "^1.1.0"

plugins/airtable/src/utils.ts

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { marked } from "marked"
12
import type { PossibleField } from "./fields"
23

34
/**
@@ -20,40 +21,14 @@ export function assert(condition: boolean, message?: string): asserts condition
2021
* Converts markdown-style rich text to HTML
2122
*/
2223
export function richTextToHTML(cellValue: string): string {
23-
let html = cellValue
24-
.replace(/^###### (.*)$/gim, "<h6>$1</h6>") // H6
25-
.replace(/^##### (.*)$/gim, "<h5>$1</h5>") // H5
26-
.replace(/^#### (.*)$/gim, "<h4>$1</h4>") // H4
27-
.replace(/^### (.*)$/gim, "<h3>$1</h3>") // H3
28-
.replace(/^## (.*)$/gim, "<h2>$1</h2>") // H2
29-
.replace(/^# (.*)$/gim, "<h1>$1</h1>") // H1
30-
.replace(/^> (.*)$/gim, "<blockquote>$1</blockquote>") // Blockquote
31-
.replace(/\*\*(.*?)\*\*/gim, "<strong>$1</strong>") // Bold
32-
.replace(/\*(.*?)\*/gim, "<em>$1</em>") // Italic
33-
.replace(/~~(.*?)~~/gim, "<del>$1</del>") // Strikethrough
34-
.replace(/`([^`]+)`/gim, "<code>$1</code>") // Inline code
35-
.replace(/```([\s\S]*?)```/gim, "<pre><code>$1</code></pre>") // Code block
36-
.replace(/\[(.*?)\]\((.*?)\)/gim, '<a href="$2">$1</a>') // Links
37-
38-
// Handle unordered and ordered lists separately
39-
html = html.replace(/^\s*[-*]\s+(.*)$/gim, "<ul><li>$1</li></ul>")
40-
html = html.replace(/^\s*\d+\.\s+(.*)$/gim, "<ol><li>$1</li></ol>")
41-
42-
// Combine consecutive <ul> or <ol> items
43-
html = html.replace(/<\/ul>\s*<ul>/gim, "").replace(/<\/ol>\s*<ol>/gim, "")
44-
45-
// Ensure paragraphs are correctly wrapped
46-
html = html
47-
.split("\n\n") // Assume two newlines is a new paragraph
48-
.map(paragraph => {
49-
if (!/^<.*>.*<\/.*>$/.test(paragraph)) {
50-
return `<p>${paragraph}</p>`
51-
}
52-
return paragraph
53-
})
54-
.join("")
55-
56-
return html
24+
return marked.parse(cellValue, {
25+
// This is needed for proper typing.
26+
async: false,
27+
// This adds support for tables and code blocks with language tags (```javascript ... ```).
28+
gfm: true,
29+
// This ensures single-line line breaks are preserved.
30+
breaks: true,
31+
})
5732
}
5833

5934
// Allowed file types for attachments

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,6 +3169,7 @@ __metadata:
31693169
"@types/react": "npm:^18.3.23"
31703170
"@types/react-dom": "npm:^18.3.7"
31713171
framer-plugin: "npm:^3.5.2"
3172+
marked: "npm:^16.1.1"
31723173
react: "npm:^18.3.1"
31733174
react-dom: "npm:^18.3.1"
31743175
valibot: "npm:^1.1.0"
@@ -5414,6 +5415,15 @@ __metadata:
54145415
languageName: node
54155416
linkType: hard
54165417

5418+
"marked@npm:^16.1.1":
5419+
version: 16.1.1
5420+
resolution: "marked@npm:16.1.1"
5421+
bin:
5422+
marked: bin/marked.js
5423+
checksum: 10/9f4d2d8f862e1d874f03f1b8614fbf859ae788b4a1b4174be83a65c8ea5ecabf0c991c455dcb6b650e7106fb5b65a94865b9de45667bb2471ca2272e1798971d
5424+
languageName: node
5425+
linkType: hard
5426+
54175427
"material-colors@npm:^1.2.1":
54185428
version: 1.2.6
54195429
resolution: "material-colors@npm:1.2.6"

0 commit comments

Comments
 (0)