writr 4.2.0 → 4.3.0
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 +37 -3
- package/dist/writr.d.ts +9 -1
- package/dist/writr.js +53 -25
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- [`.engine`](#engine)
|
|
23
23
|
- [`.render(options?: RenderOptions): Promise<string>`](#renderoptions-renderoptions-promisestring)
|
|
24
24
|
- [`.renderSync(options?: RenderOptions): string`](#rendersyncoptions-renderoptions-string)
|
|
25
|
-
- [`.renderToFile(filePath: string, options?: RenderOptions)
|
|
25
|
+
- [`.renderToFile(filePath: string, options?: RenderOptions)`](#rendertofilefilepath-string-options-renderoptions)
|
|
26
26
|
- [`.renderToFileSync(filePath: string, options?: RenderOptions): void`](#rendertofilesyncfilepath-string-options-renderoptions-void)
|
|
27
27
|
- [`.renderReact(options?: RenderOptions, reactOptions?: HTMLReactParserOptions): Promise<React.JSX.Element />`](#renderreactoptions-renderoptions-reactoptions-htmlreactparseroptions-promise-reactjsxelement-)
|
|
28
28
|
- [`.renderReactSync( options?: RenderOptions, reactOptions?: HTMLReactParserOptions): React.JSX.Element`](#renderreactsync-options-renderoptions-reactoptions-htmlreactparseroptions-reactjsxelement)
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
- [`.loadFromFileSync(filePath: string): void`](#loadfromfilesyncfilepath-string-void)
|
|
31
31
|
- [`.saveToFile(filePath: string): Promise<void>`](#savetofilefilepath-string-promisevoid)
|
|
32
32
|
- [`.saveToFileSync(filePath: string): void`](#savetofilesyncfilepath-string-void)
|
|
33
|
+
- [Hooks](#hooks)
|
|
33
34
|
- [Code of Conduct and Contributing](#code-of-conduct-and-contributing)
|
|
34
35
|
- [License](#license)
|
|
35
36
|
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
* Github Flavor Markdown (remark-gfm).
|
|
48
49
|
* Emoji Support (remark-emoji).
|
|
49
50
|
* MDX Support (remark-mdx).
|
|
51
|
+
* Built in Hooks for adding code to render pipeline.
|
|
50
52
|
|
|
51
53
|
# ESM and Node Version Support
|
|
52
54
|
|
|
@@ -252,7 +254,7 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
252
254
|
const html = writr.renderSync(); // <h1>Hello World 🙂</h1><p>This is a test.</p>
|
|
253
255
|
```
|
|
254
256
|
|
|
255
|
-
## '.renderToFile(filePath: string, options?: RenderOptions)
|
|
257
|
+
## '.renderToFile(filePath: string, options?: RenderOptions)'
|
|
256
258
|
|
|
257
259
|
Rendering markdown to a file. The options are based on RenderOptions.
|
|
258
260
|
|
|
@@ -347,9 +349,41 @@ writr.cache.store.lruSize = 100;
|
|
|
347
349
|
writr.cache.store.ttl = '5m'; // setting it to 5 minutes
|
|
348
350
|
```
|
|
349
351
|
|
|
352
|
+
# Hooks
|
|
353
|
+
|
|
354
|
+
Hooks are a way to add additional parsing to the render pipeline. You can add hooks to the the Writr instance. Here is an example of adding a hook to the instance of Writr:
|
|
355
|
+
|
|
356
|
+
```javascript
|
|
357
|
+
import { Writr, WritrHooks } from 'writr';
|
|
358
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
359
|
+
writr.onHook(WritrHooks.beforeRender, data => {
|
|
360
|
+
data.body = 'Hello, Universe!';
|
|
361
|
+
});
|
|
362
|
+
const result = await writr.render();
|
|
363
|
+
console.log(result); // Hello, Universe!
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
For `beforeRender` the data object is a `renderData` object. Here is the interface for `renderData`:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
export type renderData {
|
|
370
|
+
body: string;
|
|
371
|
+
content: string;
|
|
372
|
+
options: RenderOptions;
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
For `afterRender` the data object is a `resultData` object. Here is the interface for `resultData`:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
export type resultData {
|
|
380
|
+
result: string;
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
350
384
|
# Code of Conduct and Contributing
|
|
351
385
|
[Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing](CONTRIBUTING.md) guidelines.
|
|
352
386
|
|
|
353
387
|
# License
|
|
354
388
|
|
|
355
|
-
MIT © [Jared Wray](https://jaredwray.com)
|
|
389
|
+
[MIT](LICENSE) & © [Jared Wray](https://jaredwray.com)
|
package/dist/writr.d.ts
CHANGED
|
@@ -49,6 +49,14 @@ type RenderOptions = {
|
|
|
49
49
|
mdx?: boolean;
|
|
50
50
|
caching?: boolean;
|
|
51
51
|
};
|
|
52
|
+
declare enum WritrHooks {
|
|
53
|
+
beforeRender = "beforeRender",
|
|
54
|
+
afterRender = "afterRender",
|
|
55
|
+
beforeSaveToFile = "beforeSaveToFile",
|
|
56
|
+
afterSaveToFile = "afterSaveToFile",
|
|
57
|
+
beforeLoadFromFile = "beforeLoadFromFile",
|
|
58
|
+
afterLoadFromFile = "afterLoadFromFile"
|
|
59
|
+
}
|
|
52
60
|
declare class Writr extends Hookified {
|
|
53
61
|
engine: unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
|
|
54
62
|
private readonly _options;
|
|
@@ -182,4 +190,4 @@ declare class Writr extends Hookified {
|
|
|
182
190
|
private mergeRenderOptions;
|
|
183
191
|
}
|
|
184
192
|
|
|
185
|
-
export { type RenderOptions, Writr, type WritrOptions };
|
|
193
|
+
export { type RenderOptions, Writr, WritrHooks, type WritrOptions };
|
package/dist/writr.js
CHANGED
|
@@ -54,6 +54,15 @@ var WritrCache = class {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
// src/writr.ts
|
|
57
|
+
var WritrHooks = /* @__PURE__ */ ((WritrHooks2) => {
|
|
58
|
+
WritrHooks2["beforeRender"] = "beforeRender";
|
|
59
|
+
WritrHooks2["afterRender"] = "afterRender";
|
|
60
|
+
WritrHooks2["beforeSaveToFile"] = "beforeSaveToFile";
|
|
61
|
+
WritrHooks2["afterSaveToFile"] = "afterSaveToFile";
|
|
62
|
+
WritrHooks2["beforeLoadFromFile"] = "beforeLoadFromFile";
|
|
63
|
+
WritrHooks2["afterLoadFromFile"] = "afterLoadFromFile";
|
|
64
|
+
return WritrHooks2;
|
|
65
|
+
})(WritrHooks || {});
|
|
57
66
|
var Writr = class extends Hookified {
|
|
58
67
|
engine = unified().use(remarkParse).use(remarkGfm).use(remarkToc).use(remarkEmoji).use(remarkRehype).use(rehypeSlug).use(remarkMath).use(rehypeKatex).use(rehypeHighlight).use(remarkMDX).use(rehypeStringify);
|
|
59
68
|
// Stringify HTML
|
|
@@ -201,24 +210,33 @@ ${yamlString}---
|
|
|
201
210
|
*/
|
|
202
211
|
async render(options) {
|
|
203
212
|
try {
|
|
204
|
-
let result = "";
|
|
205
|
-
if (this.isCacheEnabled(options)) {
|
|
206
|
-
const cached = this._cache.get(this._content, options);
|
|
207
|
-
if (cached) {
|
|
208
|
-
return cached;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
213
|
let { engine } = this;
|
|
212
214
|
if (options) {
|
|
213
215
|
options = { ...this._options.renderOptions, ...options };
|
|
214
216
|
engine = this.createProcessor(options);
|
|
215
217
|
}
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
const renderData = {
|
|
219
|
+
content: this._content,
|
|
220
|
+
body: this.body,
|
|
221
|
+
options
|
|
222
|
+
};
|
|
223
|
+
await this.hook("beforeRender" /* beforeRender */, renderData);
|
|
224
|
+
const resultData = {
|
|
225
|
+
result: ""
|
|
226
|
+
};
|
|
227
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
228
|
+
const cached = this._cache.get(renderData.content, renderData.options);
|
|
229
|
+
if (cached) {
|
|
230
|
+
return cached;
|
|
231
|
+
}
|
|
220
232
|
}
|
|
221
|
-
|
|
233
|
+
const file = await engine.process(renderData.body);
|
|
234
|
+
resultData.result = String(file);
|
|
235
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
236
|
+
this._cache.set(renderData.content, resultData.result, renderData.options);
|
|
237
|
+
}
|
|
238
|
+
await this.hook("afterRender" /* afterRender */, resultData);
|
|
239
|
+
return resultData.result;
|
|
222
240
|
} catch (error) {
|
|
223
241
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
224
242
|
}
|
|
@@ -230,24 +248,33 @@ ${yamlString}---
|
|
|
230
248
|
*/
|
|
231
249
|
renderSync(options) {
|
|
232
250
|
try {
|
|
233
|
-
let result = "";
|
|
234
|
-
if (this.isCacheEnabled(options)) {
|
|
235
|
-
const cached = this._cache.get(this._content, options);
|
|
236
|
-
if (cached) {
|
|
237
|
-
return cached;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
251
|
let { engine } = this;
|
|
241
252
|
if (options) {
|
|
242
253
|
options = { ...this._options.renderOptions, ...options };
|
|
243
254
|
engine = this.createProcessor(options);
|
|
244
255
|
}
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
const renderData = {
|
|
257
|
+
content: this._content,
|
|
258
|
+
body: this.body,
|
|
259
|
+
options
|
|
260
|
+
};
|
|
261
|
+
this.hook("beforeRender" /* beforeRender */, renderData);
|
|
262
|
+
const resultData = {
|
|
263
|
+
result: ""
|
|
264
|
+
};
|
|
265
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
266
|
+
const cached = this._cache.get(renderData.content, renderData.options);
|
|
267
|
+
if (cached) {
|
|
268
|
+
return cached;
|
|
269
|
+
}
|
|
249
270
|
}
|
|
250
|
-
|
|
271
|
+
const file = engine.processSync(renderData.body);
|
|
272
|
+
resultData.result = String(file);
|
|
273
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
274
|
+
this._cache.set(renderData.content, resultData.result, renderData.options);
|
|
275
|
+
}
|
|
276
|
+
this.hook("afterRender" /* afterRender */, resultData);
|
|
277
|
+
return resultData.result;
|
|
251
278
|
} catch (error) {
|
|
252
279
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
253
280
|
}
|
|
@@ -433,5 +460,6 @@ ${yamlString}---
|
|
|
433
460
|
}
|
|
434
461
|
};
|
|
435
462
|
export {
|
|
436
|
-
Writr
|
|
463
|
+
Writr,
|
|
464
|
+
WritrHooks
|
|
437
465
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writr",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "Markdown Rendering Simplified",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/writr.js",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"website:serve": "rimraf ./site/README.md ./site/dist && npx docula serve -s ./site -o ./site/dist"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"cacheable": "^1.8.
|
|
57
|
-
"hookified": "^1.
|
|
58
|
-
"html-react-parser": "^5.
|
|
56
|
+
"cacheable": "^1.8.7",
|
|
57
|
+
"hookified": "^1.6.0",
|
|
58
|
+
"html-react-parser": "^5.2.2",
|
|
59
59
|
"js-yaml": "^4.1.0",
|
|
60
|
-
"react": "^
|
|
60
|
+
"react": "^19.0.0",
|
|
61
61
|
"rehype-highlight": "^7.0.1",
|
|
62
62
|
"rehype-katex": "^7.0.1",
|
|
63
63
|
"rehype-slug": "^6.0.0",
|
|
@@ -73,17 +73,17 @@
|
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/js-yaml": "^4.0.9",
|
|
76
|
-
"@types/node": "^22.10.
|
|
77
|
-
"@types/react": "^
|
|
78
|
-
"@vitest/coverage-v8": "^2.1.
|
|
79
|
-
"docula": "^0.9.
|
|
76
|
+
"@types/node": "^22.10.2",
|
|
77
|
+
"@types/react": "^19.0.2",
|
|
78
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
79
|
+
"docula": "^0.9.6",
|
|
80
80
|
"rimraf": "^6.0.1",
|
|
81
81
|
"ts-node": "^10.9.2",
|
|
82
82
|
"tsup": "^8.3.5",
|
|
83
83
|
"typescript": "^5.7.2",
|
|
84
|
-
"vitest": "^2.1.
|
|
85
|
-
"webpack": "^5.
|
|
86
|
-
"xo": "^0.
|
|
84
|
+
"vitest": "^2.1.8",
|
|
85
|
+
"webpack": "^5.97.1",
|
|
86
|
+
"xo": "^0.60.0"
|
|
87
87
|
},
|
|
88
88
|
"xo": {
|
|
89
89
|
"ignores": [
|