@uniweb/content-writer 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Content Writer
|
|
2
|
+
|
|
3
|
+
A JavaScript library for converting ProseMirror/TipTap document JSON back to Markdown. The inverse of [@uniweb/content-reader](https://github.com/uniweb/content-reader).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Full round-trip fidelity with `@uniweb/content-reader`
|
|
8
|
+
- Headings, paragraphs, blockquotes, horizontal rules
|
|
9
|
+
- Bold, italic, inline code, and nested formatting
|
|
10
|
+
- Links with title, attributes, and download support
|
|
11
|
+
- Buttons with variant, size, and icon attributes
|
|
12
|
+
- Bracketed spans with class, ID, and custom attributes
|
|
13
|
+
- Images with role, caption, dimensions, fit/position
|
|
14
|
+
- Video and PDF media with playback/preview attributes
|
|
15
|
+
- Icons (library+name dash format and `icon:` prefix)
|
|
16
|
+
- Component references (`@ComponentName` inset syntax)
|
|
17
|
+
- Fenced code blocks with language and tagged data blocks
|
|
18
|
+
- Bullet and ordered lists with nesting
|
|
19
|
+
- GFM tables with column alignment
|
|
20
|
+
- YAML frontmatter serialization
|
|
21
|
+
- Plain text extraction (no formatting, just content)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @uniweb/content-writer
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Convert ProseMirror to Markdown
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { proseMirrorToMarkdown } from '@uniweb/content-writer'
|
|
35
|
+
|
|
36
|
+
const doc = {
|
|
37
|
+
type: 'doc',
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: 'heading',
|
|
41
|
+
attrs: { level: 1 },
|
|
42
|
+
content: [{ type: 'text', text: 'Hello World' }]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'paragraph',
|
|
46
|
+
content: [
|
|
47
|
+
{ type: 'text', text: 'This is ' },
|
|
48
|
+
{ type: 'text', text: 'bold', marks: [{ type: 'bold' }] },
|
|
49
|
+
{ type: 'text', text: ' text.' }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const markdown = proseMirrorToMarkdown(doc)
|
|
56
|
+
// # Hello World
|
|
57
|
+
//
|
|
58
|
+
// This is **bold** text.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Serialize a Complete Section File
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
import { serializeSection } from '@uniweb/content-writer'
|
|
65
|
+
|
|
66
|
+
const params = { type: 'Hero', alignment: 'center' }
|
|
67
|
+
const doc = {
|
|
68
|
+
type: 'doc',
|
|
69
|
+
content: [
|
|
70
|
+
{ type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: 'Welcome' }] }
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const file = serializeSection(params, doc)
|
|
75
|
+
// ---
|
|
76
|
+
// type: Hero
|
|
77
|
+
// alignment: center
|
|
78
|
+
// ---
|
|
79
|
+
//
|
|
80
|
+
// # Welcome
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Serialize Frontmatter Only
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
import { serializeFrontmatter } from '@uniweb/content-writer'
|
|
87
|
+
|
|
88
|
+
const yaml = serializeFrontmatter({ type: 'Hero', hidden: true })
|
|
89
|
+
// ---
|
|
90
|
+
// type: Hero
|
|
91
|
+
// hidden: true
|
|
92
|
+
// ---
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Extract Plain Text
|
|
96
|
+
|
|
97
|
+
Strip all formatting and return just the text content. Useful for word counting, search indexing, and generating summaries.
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
import { docToPlainText } from '@uniweb/content-writer'
|
|
101
|
+
|
|
102
|
+
const doc = {
|
|
103
|
+
type: 'doc',
|
|
104
|
+
content: [
|
|
105
|
+
{ type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: 'Title' }] },
|
|
106
|
+
{
|
|
107
|
+
type: 'paragraph',
|
|
108
|
+
content: [
|
|
109
|
+
{ type: 'text', text: 'Click ' },
|
|
110
|
+
{ type: 'text', text: 'here', marks: [{ type: 'link', attrs: { href: '/page' } }] },
|
|
111
|
+
{ type: 'text', text: ' for details.' }
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const text = docToPlainText(doc)
|
|
118
|
+
// Title
|
|
119
|
+
//
|
|
120
|
+
// Click here for details.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`docToPlainText` preserves text from headings, paragraphs, lists, code blocks, blockquotes, and tables. It strips all marks (bold, italic, links) and skips images, dividers, component references, and data blocks.
|
|
124
|
+
|
|
125
|
+
### Using with TipTap
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
import { Editor } from '@tiptap/core'
|
|
129
|
+
import { proseMirrorToMarkdown } from '@uniweb/content-writer'
|
|
130
|
+
|
|
131
|
+
// Get markdown from editor state
|
|
132
|
+
const markdown = proseMirrorToMarkdown(editor.getJSON())
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Extended Syntax
|
|
136
|
+
|
|
137
|
+
The serializer handles the same extended syntax as `@uniweb/content-reader`:
|
|
138
|
+
|
|
139
|
+
### Curly Brace Attributes
|
|
140
|
+
|
|
141
|
+
```markdown
|
|
142
|
+
{role=hero width=1200 fit=cover}
|
|
143
|
+
[Styled text]{.highlight .large}
|
|
144
|
+
[Download](./file.pdf){download="report.pdf"}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Buttons
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
[Get Started](button:https://example.com){variant=primary size=lg}
|
|
151
|
+
[Learn More](button:/docs){variant=secondary icon=arrow-right}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Icons
|
|
155
|
+
|
|
156
|
+
```markdown
|
|
157
|
+

|
|
158
|
+

|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Component References
|
|
162
|
+
|
|
163
|
+
```markdown
|
|
164
|
+
{param=value}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Tables with Alignment
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
| Left | Center | Right |
|
|
171
|
+
| :--- | :----: | ----: |
|
|
172
|
+
| Text | Text | Text |
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## API
|
|
176
|
+
|
|
177
|
+
| Export | Signature | Description |
|
|
178
|
+
|--------|-----------|-------------|
|
|
179
|
+
| `proseMirrorToMarkdown` | `(doc) => string` | Convert ProseMirror document JSON to markdown |
|
|
180
|
+
| `serializeSection` | `(params, doc) => string` | Serialize frontmatter + body as a complete file |
|
|
181
|
+
| `serializeFrontmatter` | `(params) => string` | Serialize an object to a YAML frontmatter block |
|
|
182
|
+
| `docToPlainText` | `(doc) => string` | Extract plain text content (no formatting) |
|
|
183
|
+
|
|
184
|
+
## Development
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
git clone https://github.com/uniweb/content-writer.git
|
|
188
|
+
cd content-writer
|
|
189
|
+
npm install
|
|
190
|
+
npm test
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
GPL-3.0-or-later
|