react-pdf-html-flabs-2 1.0.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 +243 -0
- package/dist/Html.d.ts +13 -0
- package/dist/Html.js +12 -0
- package/dist/Html.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/ordered.type.d.ts +3 -0
- package/dist/ordered.type.js +34 -0
- package/dist/ordered.type.js.map +1 -0
- package/dist/parse.d.ts +23 -0
- package/dist/parse.js +131 -0
- package/dist/parse.js.map +1 -0
- package/dist/parse.test.d.ts +1 -0
- package/dist/parse.test.js.map +1 -0
- package/dist/render.d.ts +45 -0
- package/dist/render.js +241 -0
- package/dist/render.js.map +1 -0
- package/dist/render.test.d.ts +1 -0
- package/dist/render.test.js.map +1 -0
- package/dist/renderers.d.ts +9 -0
- package/dist/renderers.js +144 -0
- package/dist/renderers.js.map +1 -0
- package/dist/styles.d.ts +10 -0
- package/dist/styles.js +165 -0
- package/dist/styles.js.map +1 -0
- package/dist/supportedStyles.d.ts +2 -0
- package/dist/supportedStyles.js +102 -0
- package/dist/supportedStyles.js.map +1 -0
- package/dist/tags.d.ts +2 -0
- package/dist/tags.js +60 -0
- package/dist/tags.js.map +1 -0
- package/package.json +59 -0
- package/tsconfig.json +70 -0
package/dist/render.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.applyStylesheets = exports.renderElements = exports.renderBucketElement = exports.collapseWhitespace = exports.renderElement = exports.bucketElements = exports.hasBlockContent = exports.isBlockStyle = void 0;
|
|
30
|
+
const react_1 = __importDefault(require("react"));
|
|
31
|
+
const renderers_1 = __importStar(require("./renderers"));
|
|
32
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
33
|
+
const parse_1 = __importDefault(require("./parse"));
|
|
34
|
+
const styles_1 = require("./styles");
|
|
35
|
+
const tags_1 = require("./tags");
|
|
36
|
+
const convertEntities = (input) => {
|
|
37
|
+
const entities = [
|
|
38
|
+
['amp', '&'],
|
|
39
|
+
['apos', "'"],
|
|
40
|
+
['#x27', "'"],
|
|
41
|
+
['#x2F', '/'],
|
|
42
|
+
['#39', "'"],
|
|
43
|
+
['#47', '/'],
|
|
44
|
+
['lt', '<'],
|
|
45
|
+
['gt', '>'],
|
|
46
|
+
['nbsp', ' '],
|
|
47
|
+
['quot', '"'],
|
|
48
|
+
];
|
|
49
|
+
let text = input;
|
|
50
|
+
for (let entity of entities) {
|
|
51
|
+
text = text.replace(new RegExp('&' + entity[0] + ';', 'g'), entity[1]);
|
|
52
|
+
}
|
|
53
|
+
return text;
|
|
54
|
+
};
|
|
55
|
+
const isBlockStyle = (style) => ['block', 'flex'].includes(style.display);
|
|
56
|
+
exports.isBlockStyle = isBlockStyle;
|
|
57
|
+
const hasBlockContent = (element) => {
|
|
58
|
+
var _a;
|
|
59
|
+
if (typeof element === 'string') {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (element.tag === 'a' || tags_1.isText[element.tag]) {
|
|
63
|
+
if ((_a = element.style) === null || _a === void 0 ? void 0 : _a.some(exports.isBlockStyle)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
// anchor tags match their content
|
|
67
|
+
if (element.content) {
|
|
68
|
+
return element.content.some(exports.hasBlockContent);
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
};
|
|
74
|
+
exports.hasBlockContent = hasBlockContent;
|
|
75
|
+
const ltrim = (text) => text.replace(/^\s+/, '');
|
|
76
|
+
const rtrim = (text) => text.replace(/\s+$/, '');
|
|
77
|
+
/**
|
|
78
|
+
* Groups all block and non-block elements into buckets so that all non-block elements can be rendered in a parent Text element
|
|
79
|
+
* @param elements Elements to place in buckets of block and non-block content
|
|
80
|
+
* @param collapse
|
|
81
|
+
* @param parentTag
|
|
82
|
+
*/
|
|
83
|
+
const bucketElements = (elements, collapse, parentTag) => {
|
|
84
|
+
let bucket;
|
|
85
|
+
let hasBlock;
|
|
86
|
+
const buckets = [];
|
|
87
|
+
elements.forEach((element, index) => {
|
|
88
|
+
// clear empty strings between block elements
|
|
89
|
+
if (typeof element === 'string') {
|
|
90
|
+
if (collapse) {
|
|
91
|
+
if (parentTag === 'pre') {
|
|
92
|
+
if (element[0] === '\n') {
|
|
93
|
+
element = element.substr(1);
|
|
94
|
+
}
|
|
95
|
+
if (element[element.length - 1] === '\n') {
|
|
96
|
+
element = element.substr(0, element.length - 1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
if (hasBlock || hasBlock === undefined) {
|
|
101
|
+
element = ltrim(element);
|
|
102
|
+
}
|
|
103
|
+
const next = elements[index + 1];
|
|
104
|
+
if (next && (0, exports.hasBlockContent)(next)) {
|
|
105
|
+
element = rtrim(element);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (element === '') {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const block = (0, exports.hasBlockContent)(element);
|
|
114
|
+
if (block !== hasBlock) {
|
|
115
|
+
hasBlock = block;
|
|
116
|
+
bucket = {
|
|
117
|
+
hasBlock,
|
|
118
|
+
content: [],
|
|
119
|
+
};
|
|
120
|
+
buckets.push(bucket);
|
|
121
|
+
}
|
|
122
|
+
bucket.content.push(element);
|
|
123
|
+
});
|
|
124
|
+
return buckets;
|
|
125
|
+
};
|
|
126
|
+
exports.bucketElements = bucketElements;
|
|
127
|
+
const renderElement = (element, stylesheets, renderers, children, index) => {
|
|
128
|
+
if (typeof element === 'string') {
|
|
129
|
+
element = convertEntities(element);
|
|
130
|
+
if (/(\s )|( \s)/.test(element)) {
|
|
131
|
+
// hack to avoid collapsing sequential spaces
|
|
132
|
+
return element
|
|
133
|
+
.split(/(\s{2,})/g)
|
|
134
|
+
.reduce((strings, string, index) => string === ''
|
|
135
|
+
? strings
|
|
136
|
+
: strings.concat(index % 2 ? string.split('') : string), []);
|
|
137
|
+
}
|
|
138
|
+
return element;
|
|
139
|
+
}
|
|
140
|
+
let Element = renderers[element.tag];
|
|
141
|
+
if (!Element) {
|
|
142
|
+
if (!(element.tag in tags_1.isText)) {
|
|
143
|
+
// Unknown element, do nothing
|
|
144
|
+
console.warn(`Excluding "${element.tag}" because it has no renderer`);
|
|
145
|
+
Element = renderers_1.renderNoop;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
Element = (0, exports.hasBlockContent)(element) ? renderers_1.renderBlock : renderers_1.renderInline;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return (react_1.default.createElement(Element, { key: index, style: element.style, children: children, element: element, stylesheets: stylesheets }));
|
|
152
|
+
};
|
|
153
|
+
exports.renderElement = renderElement;
|
|
154
|
+
const collapseWhitespace = (string) => string.replace(/(\s+)/g, ' ');
|
|
155
|
+
exports.collapseWhitespace = collapseWhitespace;
|
|
156
|
+
const renderBucketElement = (element, options, index) => {
|
|
157
|
+
if (typeof element === 'string') {
|
|
158
|
+
return (0, exports.renderElement)(options.collapse ? (0, exports.collapseWhitespace)(element) : element, options.stylesheets, options.renderers, undefined, index);
|
|
159
|
+
}
|
|
160
|
+
return (0, exports.renderElement)(element, options.stylesheets, options.renderers, (0, exports.renderElements)(element.content, element.tag === 'pre' ? Object.assign(Object.assign({}, options), { collapse: false }) : options, element), index);
|
|
161
|
+
};
|
|
162
|
+
exports.renderBucketElement = renderBucketElement;
|
|
163
|
+
const isAnchor = (content) => {
|
|
164
|
+
return Array.isArray(content)
|
|
165
|
+
? content.length === 1 &&
|
|
166
|
+
typeof content[0] !== 'string' &&
|
|
167
|
+
content[0].tag === 'a'
|
|
168
|
+
: content.tag === 'a';
|
|
169
|
+
};
|
|
170
|
+
const renderElements = (elements, options, parent) => {
|
|
171
|
+
const buckets = (0, exports.bucketElements)(elements, options.collapse, parent === null || parent === void 0 ? void 0 : parent.tag);
|
|
172
|
+
const parentIsText = parent && !isAnchor(parent) && !(0, exports.hasBlockContent)(parent);
|
|
173
|
+
const renderedBuckets = buckets.map((bucket, bucketIndex) => {
|
|
174
|
+
const wrapWithText = !bucket.hasBlock && !parentIsText && !isAnchor(bucket.content);
|
|
175
|
+
// Avoid extra array
|
|
176
|
+
if (bucket.content.length === 1 && !wrapWithText) {
|
|
177
|
+
return (0, exports.renderBucketElement)(bucket.content[0], options, bucketIndex);
|
|
178
|
+
}
|
|
179
|
+
let rendered = bucket.content.map((element, index) => {
|
|
180
|
+
return (0, exports.renderBucketElement)(element, options, index);
|
|
181
|
+
});
|
|
182
|
+
// unwrap extra array
|
|
183
|
+
if (rendered.length === 1) {
|
|
184
|
+
rendered = rendered[0];
|
|
185
|
+
}
|
|
186
|
+
if (wrapWithText) {
|
|
187
|
+
return react_1.default.createElement(renderer_1.Text, { key: bucketIndex }, rendered);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return buckets.length === 1 ? (rendered) : (react_1.default.createElement(react_1.default.Fragment, { key: bucketIndex }, rendered));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// unwrap extra array
|
|
194
|
+
return buckets.length === 1
|
|
195
|
+
? renderedBuckets[0]
|
|
196
|
+
: renderedBuckets;
|
|
197
|
+
};
|
|
198
|
+
exports.renderElements = renderElements;
|
|
199
|
+
const applyStylesheets = (stylesheets, rootElement) => {
|
|
200
|
+
stylesheets.forEach((stylesheet) => {
|
|
201
|
+
for (const selector of Object.keys(stylesheet)) {
|
|
202
|
+
const elements = rootElement.querySelectorAll(selector);
|
|
203
|
+
elements.forEach((element) => {
|
|
204
|
+
element.style.push(stylesheet[selector]);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
exports.applyStylesheets = applyStylesheets;
|
|
210
|
+
const renderHtml = (text, options = {}) => {
|
|
211
|
+
const defaultFontSize = 10;
|
|
212
|
+
const fontSizeStyle = { fontSize: defaultFontSize };
|
|
213
|
+
const styles = options.style
|
|
214
|
+
? Array.isArray(options.style)
|
|
215
|
+
? options.style
|
|
216
|
+
: [options.style]
|
|
217
|
+
: [];
|
|
218
|
+
styles.forEach((style) => {
|
|
219
|
+
if (!style) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (typeof style.fontSize === 'number') {
|
|
223
|
+
fontSizeStyle.fontSize = style.fontSize;
|
|
224
|
+
}
|
|
225
|
+
if (typeof style.fontSize === 'string' && style.fontSize.endsWith('px')) {
|
|
226
|
+
fontSizeStyle.fontSize = parseInt(style.fontSize, 10);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const baseStyles = (0, styles_1.createHtmlStylesheet)(fontSizeStyle.fontSize, options.resetStyles);
|
|
230
|
+
const parsed = (0, parse_1.default)(text);
|
|
231
|
+
const stylesheets = options.stylesheet
|
|
232
|
+
? Array.isArray(options.stylesheet)
|
|
233
|
+
? options.stylesheet
|
|
234
|
+
: [options.stylesheet]
|
|
235
|
+
: [];
|
|
236
|
+
const opts = Object.assign(Object.assign({ collapse: true, resetStyles: false }, options), { renderers: Object.assign(Object.assign({}, renderers_1.default), options.renderers), stylesheets: [baseStyles, ...stylesheets, ...parsed.stylesheets] });
|
|
237
|
+
(0, exports.applyStylesheets)(opts.stylesheets, parsed.rootElement);
|
|
238
|
+
return (react_1.default.createElement(renderer_1.View, { style: Object.assign(Object.assign({}, styles), fontSizeStyle) }, (0, exports.renderElements)(parsed.rootElement.content, opts)));
|
|
239
|
+
};
|
|
240
|
+
exports.default = renderHtml;
|
|
241
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactElement } from 'react';\nimport renderers, { renderBlock, renderInline, renderNoop } from './renderers';\nimport { Text, View } from '@react-pdf/renderer';\nimport parseHtml, { HtmlContent, HtmlElement } from './parse';\nimport { createHtmlStylesheet, HtmlStyle, HtmlStyles } from './styles';\nimport { Style } from '@react-pdf/types';\nimport { isText, Tag } from './tags';\n\nexport type HtmlRenderer = React.FC<\n React.PropsWithChildren<{\n element: HtmlElement;\n style: Style[];\n stylesheets: HtmlStyles[];\n }>\n>;\n\nexport type HtmlRenderers = Record<Tag | string, HtmlRenderer>;\n\nexport type HtmlRenderOptions = {\n collapse: boolean;\n renderers: HtmlRenderers;\n stylesheets: HtmlStyles[];\n resetStyles: boolean;\n};\n\ntype ContentBucket = {\n hasBlock: boolean;\n content: HtmlContent;\n};\n\nconst convertEntities = (input: string) => {\n const entities = [\n ['amp', '&'],\n ['apos', \"'\"],\n ['#x27', \"'\"],\n ['#x2F', '/'],\n ['#39', \"'\"],\n ['#47', '/'],\n ['lt', '<'],\n ['gt', '>'],\n ['nbsp', ' '],\n ['quot', '\"'],\n ];\n\n let text = input;\n for (let entity of entities) {\n text = text.replace(new RegExp('&' + entity[0] + ';', 'g'), entity[1]);\n }\n return text;\n};\n\nexport const isBlockStyle = (style: HtmlStyle) =>\n ['block', 'flex'].includes(style.display);\n\nexport const hasBlockContent = (element: HtmlElement | string): boolean => {\n if (typeof element === 'string') {\n return false;\n }\n\n if (element.tag === 'a' || isText[element.tag]) {\n if (element.style?.some(isBlockStyle)) {\n return true;\n }\n\n // anchor tags match their content\n if (element.content) {\n return element.content.some(hasBlockContent);\n }\n return false;\n }\n\n return true;\n};\n\nconst ltrim = (text: string): string => text.replace(/^\\s+/, '');\nconst rtrim = (text: string): string => text.replace(/\\s+$/, '');\n\n/**\n * Groups all block and non-block elements into buckets so that all non-block elements can be rendered in a parent Text element\n * @param elements Elements to place in buckets of block and non-block content\n * @param collapse\n * @param parentTag\n */\nexport const bucketElements = (\n elements: HtmlContent,\n collapse: boolean,\n parentTag?: Tag | string\n): ContentBucket[] => {\n let bucket: ContentBucket;\n let hasBlock: boolean;\n const buckets: ContentBucket[] = [];\n elements.forEach((element, index) => {\n // clear empty strings between block elements\n if (typeof element === 'string') {\n if (collapse) {\n if (parentTag === 'pre') {\n if (element[0] === '\\n') {\n element = element.substr(1);\n }\n if (element[element.length - 1] === '\\n') {\n element = element.substr(0, element.length - 1);\n }\n } else {\n if (hasBlock || hasBlock === undefined) {\n element = ltrim(element);\n }\n const next = elements[index + 1];\n if (next && hasBlockContent(next)) {\n element = rtrim(element);\n }\n }\n }\n if (element === '') {\n return;\n }\n }\n const block = hasBlockContent(element);\n if (block !== hasBlock) {\n hasBlock = block;\n bucket = {\n hasBlock,\n content: [],\n };\n buckets.push(bucket);\n }\n bucket.content.push(element);\n });\n\n return buckets;\n};\n\ntype RenderedContent = ReactElement | ReactElement[] | string | string[];\n\nexport const renderElement = (\n element: HtmlElement | string,\n stylesheets: HtmlStyles[],\n renderers: HtmlRenderers,\n children?: any,\n index?: number\n): RenderedContent => {\n if (typeof element === 'string') {\n element = convertEntities(element);\n if (/(\\s )|( \\s)/.test(element)) {\n // hack to avoid collapsing sequential spaces\n return element\n .split(/(\\s{2,})/g)\n .reduce(\n (strings, string, index) =>\n string === ''\n ? strings\n : strings.concat(index % 2 ? string.split('') : string),\n [] as string[]\n );\n }\n return element;\n }\n let Element: HtmlRenderer | undefined = renderers[element.tag];\n if (!Element) {\n if (!(element.tag in isText)) {\n // Unknown element, do nothing\n console.warn(`Excluding \"${element.tag}\" because it has no renderer`);\n Element = renderNoop;\n } else {\n Element = hasBlockContent(element) ? renderBlock : renderInline;\n }\n }\n\n return (\n <Element\n key={index}\n style={element.style}\n children={children}\n element={element}\n stylesheets={stylesheets}\n />\n );\n};\n\nexport const collapseWhitespace = (string: any): string =>\n string.replace(/(\\s+)/g, ' ');\n\nexport const renderBucketElement = (\n element: HtmlElement | string,\n options: HtmlRenderOptions,\n index: number\n): RenderedContent => {\n if (typeof element === 'string') {\n return renderElement(\n options.collapse ? collapseWhitespace(element) : element,\n options.stylesheets,\n options.renderers,\n undefined,\n index\n );\n }\n return renderElement(\n element,\n options.stylesheets,\n options.renderers,\n renderElements(\n element.content,\n element.tag === 'pre' ? { ...options, collapse: false } : options,\n element\n ),\n index\n );\n};\n\nconst isAnchor = (content: HtmlContent | HtmlElement): boolean => {\n return Array.isArray(content)\n ? content.length === 1 &&\n typeof content[0] !== 'string' &&\n content[0].tag === 'a'\n : content.tag === 'a';\n};\n\nexport const renderElements = (\n elements: HtmlContent,\n options: HtmlRenderOptions,\n parent?: HtmlElement\n): RenderedContent | RenderedContent[] => {\n const buckets = bucketElements(elements, options.collapse, parent?.tag);\n const parentIsText = parent && !isAnchor(parent) && !hasBlockContent(parent);\n\n const renderedBuckets: (RenderedContent[] | RenderedContent)[] = buckets.map(\n (bucket, bucketIndex) => {\n const wrapWithText =\n !bucket.hasBlock && !parentIsText && !isAnchor(bucket.content);\n\n // Avoid extra array\n if (bucket.content.length === 1 && !wrapWithText) {\n return renderBucketElement(bucket.content[0], options, bucketIndex);\n }\n\n let rendered: RenderedContent | RenderedContent[] = bucket.content.map(\n (element, index) => {\n return renderBucketElement(element, options, index);\n }\n );\n\n // unwrap extra array\n if (rendered.length === 1) {\n rendered = rendered[0];\n }\n\n if (wrapWithText) {\n return <Text key={bucketIndex}>{rendered}</Text>;\n } else {\n return buckets.length === 1 ? (\n rendered\n ) : (\n <React.Fragment key={bucketIndex}>{rendered}</React.Fragment>\n );\n }\n }\n );\n\n // unwrap extra array\n return buckets.length === 1\n ? (renderedBuckets[0] as RenderedContent)\n : (renderedBuckets as RenderedContent[]);\n};\n\nexport const applyStylesheets = (\n stylesheets: HtmlStyles[],\n rootElement: HtmlElement\n) => {\n stylesheets.forEach((stylesheet) => {\n for (const selector of Object.keys(stylesheet)) {\n const elements = rootElement.querySelectorAll(selector) as HtmlElement[];\n elements.forEach((element) => {\n element.style.push(stylesheet[selector]);\n });\n }\n });\n};\n\nconst renderHtml = (\n text: string,\n options: {\n collapse?: boolean;\n renderers?: HtmlRenderers;\n style?: Style | (Style | undefined)[];\n stylesheet?: HtmlStyles | HtmlStyles[];\n resetStyles?: boolean;\n } = {}\n): ReactElement => {\n const defaultFontSize = 10;\n const fontSizeStyle: any = { fontSize: defaultFontSize };\n const styles = options.style\n ? Array.isArray(options.style)\n ? options.style\n : [options.style]\n : [];\n\n styles.forEach((style) => {\n if (!style) {\n return;\n }\n if (typeof style.fontSize === 'number') {\n fontSizeStyle.fontSize = style.fontSize as unknown as number;\n }\n if (typeof style.fontSize === 'string' && style.fontSize.endsWith('px')) {\n fontSizeStyle.fontSize = parseInt(style.fontSize, 10);\n }\n });\n const baseStyles = createHtmlStylesheet(\n fontSizeStyle.fontSize,\n options.resetStyles\n );\n const parsed = parseHtml(text);\n\n const stylesheets = options.stylesheet\n ? Array.isArray(options.stylesheet)\n ? options.stylesheet\n : [options.stylesheet]\n : [];\n\n const opts: HtmlRenderOptions = {\n collapse: true,\n resetStyles: false,\n ...options,\n renderers: { ...renderers, ...options.renderers },\n stylesheets: [baseStyles, ...stylesheets, ...parsed.stylesheets],\n };\n\n applyStylesheets(opts.stylesheets, parsed.rootElement);\n\n return (\n <View style={{ ...styles, ...fontSizeStyle }}>\n {renderElements(parsed.rootElement.content, opts)}\n </View>\n );\n};\n\nexport default renderHtml;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.test.js","sourceRoot":"","sources":["../src/render.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactElement, ReactNode } from 'react';\nconst stringify = require('json-stringify-safe');\nimport { HtmlContent, HtmlElement } from './parse';\nimport renderHtml, {\n bucketElements,\n collapseWhitespace,\n hasBlockContent,\n} from './render';\n\nconst scrub = (object: any) => {\n if (Array.isArray(object)) {\n object.forEach(scrub);\n } else if (object && typeof object === 'object') {\n if (object.parentNode) {\n delete object.parentNode;\n }\n if (object.childNodes) {\n delete object.childNodes;\n }\n Object.keys(object).forEach((key) => scrub(object[key]));\n }\n};\n\nimport ReactPDF, {\n Text,\n View,\n Page,\n Document,\n Font,\n renderToString,\n} from '@react-pdf/renderer';\nimport path from 'path';\nimport renderers, {\n renderBlock,\n renderNoop,\n renderPassThrough,\n} from './renderers';\n\nconst inlineElement: HtmlElement = {\n tag: 'span',\n} as HtmlElement;\n\nconst blockElement: HtmlElement = {\n tag: 'div',\n} as HtmlElement;\n\ndescribe('render', () => {\n describe('collapseWhitespace', () => {\n it('Should reduce all continuous whitespace to a single space', () => {\n expect(collapseWhitespace('\\n\\n foo \\t bar ')).toBe(' foo bar ');\n });\n });\n\n describe('bucketElements', () => {\n it('Should bucket elements and trim strings correctly with collapse: true', () => {\n const stringContent = ` foo\n bar\n \n `;\n\n const elements: HtmlContent = [\n blockElement,\n blockElement,\n inlineElement,\n stringContent,\n blockElement,\n ];\n\n const bucketed = bucketElements(elements, true);\n\n expect(bucketed).toEqual([\n { hasBlock: true, content: [blockElement, blockElement] },\n { hasBlock: false, content: [inlineElement, ' foo\\n bar'] },\n { hasBlock: true, content: [blockElement] },\n ]);\n });\n\n it('Should bucket elements and not trim strings with collapse: false', () => {\n const stringContent = ` foo\n bar\n \n `;\n\n const elements: HtmlContent = [\n blockElement,\n blockElement,\n inlineElement,\n stringContent,\n blockElement,\n ];\n\n const bucketed = bucketElements(elements, false);\n\n expect(bucketed).toEqual([\n { hasBlock: true, content: [blockElement, blockElement] },\n { hasBlock: false, content: [inlineElement, stringContent] },\n { hasBlock: true, content: [blockElement] },\n ]);\n });\n });\n\n describe('hasBlockContent', () => {\n it('Should return false for string elements', () => {\n expect(hasBlockContent('')).toBe(false);\n });\n\n it('Should return false for inline elements', () => {\n expect(hasBlockContent(inlineElement)).toBe(false);\n });\n\n it('Should return true for block elements', () => {\n expect(hasBlockContent(blockElement)).toBe(true);\n });\n\n it('Should return true for inline elements with block content', () => {\n const inlineElementWithBlockContent: HtmlElement = {\n tag: 'span' as any,\n content: [blockElement],\n } as HtmlElement;\n expect(hasBlockContent(inlineElementWithBlockContent)).toBe(true);\n });\n\n it('Should return true for anchor elements with block content', () => {\n const anchorWithBlockContent: HtmlElement = {\n tag: 'a' as any,\n content: [blockElement],\n } as HtmlElement;\n expect(hasBlockContent(anchorWithBlockContent)).toBe(true);\n });\n\n it('Should return false for anchor elements with inline content', () => {\n const anchorWithInlineContent: HtmlElement = {\n tag: 'a' as any,\n content: [inlineElement],\n } as HtmlElement;\n expect(hasBlockContent(anchorWithInlineContent)).toBe(false);\n });\n\n it('Should return false for inline elements with inline content', () => {\n const inlineElementWithBlockContent: HtmlElement = {\n tag: 'span' as any,\n content: [inlineElement],\n } as HtmlElement;\n expect(hasBlockContent(inlineElementWithBlockContent)).toBe(false);\n });\n });\n\n describe('renderHtml', () => {\n it('Should use a custom renderer', () => {\n const foo = jest.fn();\n\n const html = '<foo>Custom Content</foo>';\n const rootView = renderHtml(html, {\n renderers: {\n foo,\n },\n });\n expect(rootView.type).toBe(View);\n const firstChild = rootView.props.children;\n expect(firstChild.type).toBe(foo);\n });\n\n it('Should render a link with text inside it', () => {\n const html = '<a href=\"http://google.com\">link text</a>';\n const rootView = renderHtml(html);\n expect(rootView.type).toBe(View);\n\n const a = rootView.props.children;\n expect(a.type).toBe(renderers.a);\n expect(a.props.element.tag).toBe('a');\n\n const aText = a.props.children;\n expect(aText.type).toBe(Text);\n expect(aText.props.children).toEqual('link text');\n });\n\n it('Should render inline elements with proper text wrapper', () => {\n const html = `<p>Paragraph with <strong>bold</strong>, <i>italic</i>, <u>underline</u> and <s>strikethrough</s></p>`;\n const rootView = renderHtml(html);\n expect(rootView.type).toBe(View);\n\n const p = rootView.props.children;\n expect(p.props.element.tag).toBe('p');\n expect(p.type).toBe(renderBlock);\n\n const pText = p.props.children;\n expect(pText.type).toBe(Text);\n expect(pText.props.children.length).toBe(8);\n });\n\n it('Should render anchors as inline if their content is inline', () => {\n const html = `<p>Link to <a href=\"//www.google.com\">Google</a> using react-pdf-html.</p>`;\n const rootView = renderHtml(html);\n expect(rootView.type).toBe(View);\n\n const p = rootView.props.children;\n expect(p.props.element.tag).toBe('p');\n expect(p.type).toBe(renderBlock);\n\n const pText = p.props.children;\n expect(pText.type).toBe(Text);\n expect(pText.props.children.length).toBe(3);\n\n expect(pText.props.children[0]).toBe('Link to ');\n\n const anchor = pText.props.children[1];\n expect(anchor.props.element.tag).toBe('a');\n\n const anchorText = anchor.props.children;\n expect(anchorText.type).toBe(Text);\n expect(anchorText.props.children).toBe('Google');\n\n expect(pText.props.children[2]).toBe(' using react-pdf-html.');\n });\n\n it('Should render span as block style suggests it is block', () => {\n const html = `<p>Expecting <span style=\"display: block\">block text!</span> to render correctly</p>`;\n const rootView = renderHtml(html);\n expect(rootView.type).toBe(View);\n\n const p = rootView.props.children;\n expect(p.props.element.tag).toBe('p');\n expect(p.type).toBe(renderBlock);\n expect(p.props.children.length).toBe(3);\n\n const pText1 = p.props.children[0];\n expect(pText1.type).toBe(Text);\n expect(pText1.props.children).toBe('Expecting');\n\n const blockSpan = p.props.children[1];\n expect(blockSpan.props.element.tag).toBe('span');\n expect(blockSpan.type).toBe(renderBlock);\n const spanText = blockSpan.props.children;\n expect(spanText.type).toBe(Text);\n expect(spanText.props.children).toBe('block text!');\n\n const pText2 = p.props.children[2];\n expect(pText2.type).toBe(Text);\n expect(pText2.props.children).toBe('to render correctly');\n });\n\n it('Should render a PDF with custom font without errors', async () => {\n const fonts = path.resolve(__dirname, 'fonts');\n\n Font.clear();\n Font.register({\n family: 'Open Sans',\n fonts: [\n { src: fonts + '/Open_Sans/OpenSans-Regular.ttf' },\n { src: fonts + '/Open_Sans/OpenSans-Bold.ttf', fontWeight: 'bold' },\n {\n src: fonts + '/Open_Sans/OpenSans-Italic.ttf',\n fontStyle: 'italic',\n },\n {\n src: fonts + '/Open_Sans/OpenSans-BoldItalic.ttf',\n fontWeight: 'bold',\n fontStyle: 'italic',\n },\n ],\n });\n\n await Font.load({ fontFamily: 'Open Sans' });\n\n const content = `<html>\n <style>\n body {\n font-family: 'Open Sans';\n }\n </style>\n <body>\n <p>\n Paragraph with <strong>bold</strong>, <i>italic</i>, <u>underline</u> and <s>strikethrough</s>\n <img src=\"https://images.unsplash.com/photo-1485546246426-74dc88dec4d9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2069&q=80\" />\n </p>\n <ul>\n <li>\n First level\n <ul><li>Second level</li></ul>\n </li>\n </ul>\n </body>\n</html>`;\n\n const rootView = renderHtml(content);\n expect(rootView.type).toBe(View);\n\n const html = rootView.props.children;\n expect(html.type).toBe(renderPassThrough);\n expect(html.props.children.length).toBe(2);\n\n const style = html.props.children[0];\n expect(style.type).toBe(renderNoop);\n expect(style.props.element.tag).toBe('style');\n\n const body = html.props.children[1];\n expect(body.type).toBe(renderBlock);\n expect(body.props.element.tag).toBe('body');\n expect(body.props.children.length).toBe(2);\n\n const p = body.props.children[0];\n expect(p.type).toBe(renderBlock);\n expect(p.props.element.tag).toBe('p');\n expect(p.props.children.length).toBe(2);\n\n const pText = p.props.children[0];\n expect(pText.type).toBe(Text);\n expect(pText.props.children.length).toBe(8);\n\n const image = p.props.children[1];\n expect(image.type).toBe(renderers.img);\n expect(image.props.element.tag).toBe('img');\n\n const ul = body.props.children[1];\n expect(ul.type).toBe(renderBlock);\n expect(ul.props.element.tag).toBe('ul');\n\n const li = ul.props.children;\n expect(li.props.children.length).toBe(2);\n\n // pText.props.children.forEach((child: any) => {\n // if (typeof child === 'string') {\n // console.log(`\"${child}\"`);\n // } else {\n // console.log(child.props?.element?.tag, child.type);\n // }\n // });\n\n const document = (\n <Document>\n <Page size=\"LETTER\">\n <>{rootView}</>\n </Page>\n </Document>\n );\n\n try {\n const pdfString = await renderToString(document);\n // console.log(pdfString);\n } catch (e) {\n fail(e);\n }\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HtmlRenderer, HtmlRenderers } from './render';
|
|
3
|
+
export declare const renderNoop: HtmlRenderer;
|
|
4
|
+
export declare const renderPassThrough: React.FC<React.PropsWithChildren<any>>;
|
|
5
|
+
export declare const renderBlock: HtmlRenderer;
|
|
6
|
+
export declare const renderInline: HtmlRenderer;
|
|
7
|
+
export declare const renderCell: HtmlRenderer;
|
|
8
|
+
declare const renderers: HtmlRenderers;
|
|
9
|
+
export default renderers;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderCell = exports.renderInline = exports.renderBlock = exports.renderPassThrough = exports.renderNoop = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
9
|
+
const ordered_type_1 = require("./ordered.type");
|
|
10
|
+
const renderNoop = ({ children }) => react_1.default.createElement(react_1.default.Fragment, null);
|
|
11
|
+
exports.renderNoop = renderNoop;
|
|
12
|
+
const renderPassThrough = ({ children, }) => children;
|
|
13
|
+
exports.renderPassThrough = renderPassThrough;
|
|
14
|
+
const renderBlock = ({ style, children }) => (react_1.default.createElement(renderer_1.View, { style: style }, children));
|
|
15
|
+
exports.renderBlock = renderBlock;
|
|
16
|
+
const renderInline = ({ style, children }) => (react_1.default.createElement(renderer_1.Text, { style: style }, children));
|
|
17
|
+
exports.renderInline = renderInline;
|
|
18
|
+
const renderCell = ({ style, element, children }) => {
|
|
19
|
+
const table = element.closest('table');
|
|
20
|
+
if (!table) {
|
|
21
|
+
throw new Error('td element rendered outside of a table');
|
|
22
|
+
}
|
|
23
|
+
const tableStyles = table.style.reduce((combined, tableStyle) => Object.assign(combined, tableStyle), {});
|
|
24
|
+
const baseStyles = {
|
|
25
|
+
border: tableStyles.border,
|
|
26
|
+
borderColor: tableStyles.borderColor,
|
|
27
|
+
borderWidth: tableStyles.borderWidth,
|
|
28
|
+
borderStyle: tableStyles.borderStyle,
|
|
29
|
+
};
|
|
30
|
+
if (tableStyles.borderSpacing &&
|
|
31
|
+
tableStyles.borderCollapse !== 'collapse') {
|
|
32
|
+
baseStyles.width = tableStyles.borderWidth;
|
|
33
|
+
baseStyles.margin = tableStyles.borderSpacing;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
baseStyles.borderRightWidth = 0;
|
|
37
|
+
baseStyles.borderBottomWidth = 0;
|
|
38
|
+
if (element.indexOfType !== 0) {
|
|
39
|
+
baseStyles.borderLeftWidth = tableStyles.borderWidth;
|
|
40
|
+
baseStyles.borderTopWidth = tableStyles.borderWidth;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const overrides = {};
|
|
44
|
+
if (element.attributes && element.attributes.colspan) {
|
|
45
|
+
const colspan = parseInt(element.attributes.colspan, 10);
|
|
46
|
+
if (!isNaN(colspan)) {
|
|
47
|
+
overrides.flexBasis = colspan;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const finalStyles = Object.assign({}, baseStyles, ...style, overrides);
|
|
51
|
+
if (!finalStyles.width)
|
|
52
|
+
finalStyles.flex = 1;
|
|
53
|
+
delete finalStyles.height;
|
|
54
|
+
return react_1.default.createElement(renderer_1.View, { style: finalStyles }, children);
|
|
55
|
+
};
|
|
56
|
+
exports.renderCell = renderCell;
|
|
57
|
+
const renderers = {
|
|
58
|
+
style: exports.renderNoop,
|
|
59
|
+
script: exports.renderNoop,
|
|
60
|
+
html: exports.renderPassThrough,
|
|
61
|
+
li: ({ element, stylesheets, style, children }) => {
|
|
62
|
+
var _a;
|
|
63
|
+
const bulletStyles = stylesheets.map((stylesheet) => stylesheet.li_bullet);
|
|
64
|
+
const contentStyles = stylesheets.map((stylesheet) => stylesheet.li_content);
|
|
65
|
+
const list = element.closest('ol, ul');
|
|
66
|
+
const ordered = (list === null || list === void 0 ? void 0 : list.tag) === 'ol' || element.parentNode.tag === 'ol';
|
|
67
|
+
const listStyle = ((_a = list === null || list === void 0 ? void 0 : list.style) === null || _a === void 0 ? void 0 : _a.reduce((combined, listStyle) => Object.assign(combined, listStyle), {})) || {};
|
|
68
|
+
const itemStyle = element.style.reduce((combined, itemStyle) => Object.assign(combined, itemStyle), {});
|
|
69
|
+
const listStyleType = itemStyle.listStyleType ||
|
|
70
|
+
itemStyle.listStyle ||
|
|
71
|
+
listStyle.listStyleType ||
|
|
72
|
+
listStyle.listStyle ||
|
|
73
|
+
'';
|
|
74
|
+
let bullet;
|
|
75
|
+
if (listStyleType.includes('none')) {
|
|
76
|
+
bullet = false;
|
|
77
|
+
}
|
|
78
|
+
else if (listStyleType.includes('url(')) {
|
|
79
|
+
bullet = (react_1.default.createElement(renderer_1.Image, { src: listStyleType.match(/\((.*?)\)/)[1].replace(/(['"])/g, '') }));
|
|
80
|
+
}
|
|
81
|
+
else if (ordered) {
|
|
82
|
+
if (ordered_type_1.lowerAlpha.includes(listStyleType)) {
|
|
83
|
+
bullet = (react_1.default.createElement(renderer_1.Text, null,
|
|
84
|
+
ordered_type_1.orderedAlpha[element.indexOfType].toLowerCase(),
|
|
85
|
+
"."));
|
|
86
|
+
}
|
|
87
|
+
else if (ordered_type_1.upperAlpha.includes(listStyleType)) {
|
|
88
|
+
bullet = (react_1.default.createElement(renderer_1.Text, null,
|
|
89
|
+
ordered_type_1.orderedAlpha[element.indexOfType].toUpperCase(),
|
|
90
|
+
"."));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
bullet = react_1.default.createElement(renderer_1.Text, null,
|
|
94
|
+
element.indexOfType + 1,
|
|
95
|
+
".");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// if (listStyleType.includes('square')) {
|
|
100
|
+
// bullet = <Text>■</Text>;
|
|
101
|
+
// } else {
|
|
102
|
+
bullet = react_1.default.createElement(renderer_1.Text, null, "\u2022");
|
|
103
|
+
// }
|
|
104
|
+
}
|
|
105
|
+
return (react_1.default.createElement(renderer_1.View, { style: style },
|
|
106
|
+
bullet && react_1.default.createElement(renderer_1.View, { style: bulletStyles }, bullet),
|
|
107
|
+
react_1.default.createElement(renderer_1.View, { style: contentStyles }, children)));
|
|
108
|
+
},
|
|
109
|
+
a: ({ style, element, children }) => (react_1.default.createElement(renderer_1.Link, { style: style, src: element.attributes.href }, children)),
|
|
110
|
+
img: ({ style, element }) => {
|
|
111
|
+
const { width, height } = element.attributes;
|
|
112
|
+
const dimensions = {};
|
|
113
|
+
if (width) {
|
|
114
|
+
dimensions.width = width;
|
|
115
|
+
}
|
|
116
|
+
if (height) {
|
|
117
|
+
dimensions.height = height;
|
|
118
|
+
}
|
|
119
|
+
const finalStyles = Object.assign({}, ...style, dimensions);
|
|
120
|
+
return react_1.default.createElement(renderer_1.Image, { style: finalStyles, src: element.attributes.src });
|
|
121
|
+
},
|
|
122
|
+
table: ({ element, style, children }) => {
|
|
123
|
+
const tableStyles = element.style.reduce((combined, tableStyle) => Object.assign(combined, tableStyle), {});
|
|
124
|
+
const overrides = {};
|
|
125
|
+
if (!tableStyles.borderSpacing ||
|
|
126
|
+
tableStyles.borderCollapse === 'collapse') {
|
|
127
|
+
overrides.borderLeftWidth = 0;
|
|
128
|
+
overrides.borderTopWidth = 0;
|
|
129
|
+
}
|
|
130
|
+
const finalStyles = Object.assign({}, ...style, overrides);
|
|
131
|
+
delete finalStyles.height;
|
|
132
|
+
return react_1.default.createElement(renderer_1.View, { style: finalStyles }, children);
|
|
133
|
+
},
|
|
134
|
+
tr: ({ style, children }) => {
|
|
135
|
+
const finalStyles = Object.assign({}, ...style);
|
|
136
|
+
delete finalStyles.height;
|
|
137
|
+
return (react_1.default.createElement(renderer_1.View, { wrap: true, style: finalStyles }, children));
|
|
138
|
+
},
|
|
139
|
+
br: ({ style }) => (react_1.default.createElement(renderer_1.Text, { wrap: false, style: style }, '\n')),
|
|
140
|
+
td: exports.renderCell,
|
|
141
|
+
th: exports.renderCell,
|
|
142
|
+
};
|
|
143
|
+
exports.default = renderers;
|
|
144
|
+
//# sourceMappingURL=renderers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderers.js","sourceRoot":"","sources":["../src/renderers.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Link, Text, View, Image } from '@react-pdf/renderer';\nimport { HtmlRenderer, HtmlRenderers } from './render';\nimport { HtmlElement } from './parse';\nimport { HtmlStyle } from './styles';\nimport { lowerAlpha, orderedAlpha, upperAlpha } from './ordered.type';\n\nexport const renderNoop: HtmlRenderer = ({ children }) => <></>;\n\nexport const renderPassThrough: React.FC<React.PropsWithChildren<any>> = ({\n children,\n}) => children;\n\nexport const renderBlock: HtmlRenderer = ({ style, children }) => (\n <View style={style}>{children}</View>\n);\n\nexport const renderInline: HtmlRenderer = ({ style, children }) => (\n <Text style={style}>{children}</Text>\n);\n\nexport const renderCell: HtmlRenderer = ({ style, element, children }) => {\n const table = element.closest('table') as HtmlElement | undefined;\n if (!table) {\n throw new Error('td element rendered outside of a table');\n }\n const tableStyles = table.style.reduce(\n (combined, tableStyle) => Object.assign(combined, tableStyle),\n {} as HtmlStyle\n );\n\n const baseStyles: HtmlStyle = {\n border: tableStyles.border,\n borderColor: tableStyles.borderColor,\n borderWidth: tableStyles.borderWidth,\n borderStyle: tableStyles.borderStyle,\n };\n if (\n (tableStyles as any).borderSpacing &&\n (tableStyles as any).borderCollapse !== 'collapse'\n ) {\n baseStyles.width = tableStyles.borderWidth;\n baseStyles.margin = (tableStyles as any).borderSpacing;\n } else {\n baseStyles.borderRightWidth = 0;\n baseStyles.borderBottomWidth = 0;\n if (element.indexOfType !== 0) {\n baseStyles.borderLeftWidth = tableStyles.borderWidth;\n baseStyles.borderTopWidth = tableStyles.borderWidth;\n }\n }\n\n const overrides: HtmlStyle = {};\n if (element.attributes && element.attributes.colspan) {\n const colspan = parseInt(element.attributes.colspan, 10);\n if (!isNaN(colspan)) {\n overrides.flexBasis = colspan;\n }\n }\n\n const finalStyles = Object.assign({}, baseStyles, ...style, overrides);\n if (!finalStyles.width) finalStyles.flex = 1;\n delete finalStyles.height;\n return <View style={finalStyles}>{children}</View>;\n};\n\nconst renderers: HtmlRenderers = {\n style: renderNoop,\n script: renderNoop,\n html: renderPassThrough,\n li: ({ element, stylesheets, style, children }) => {\n const bulletStyles = stylesheets.map((stylesheet) => stylesheet.li_bullet);\n const contentStyles = stylesheets.map(\n (stylesheet) => stylesheet.li_content\n );\n const list: HtmlElement = element.closest('ol, ul') as HtmlElement;\n const ordered = list?.tag === 'ol' || element.parentNode.tag === 'ol';\n const listStyle =\n list?.style?.reduce(\n (combined, listStyle) => Object.assign(combined, listStyle),\n {} as HtmlStyle\n ) || {};\n const itemStyle = element.style.reduce(\n (combined, itemStyle) => Object.assign(combined, itemStyle),\n {} as HtmlStyle\n );\n const listStyleType =\n itemStyle.listStyleType ||\n itemStyle.listStyle ||\n listStyle.listStyleType ||\n listStyle.listStyle ||\n '';\n\n let bullet;\n if (listStyleType.includes('none')) {\n bullet = false;\n } else if (listStyleType.includes('url(')) {\n bullet = (\n <Image\n src={listStyleType.match(/\\((.*?)\\)/)[1].replace(/(['\"])/g, '')}\n />\n );\n } else if (ordered) {\n if (lowerAlpha.includes(listStyleType)) {\n bullet = (\n <Text>{orderedAlpha[element.indexOfType].toLowerCase()}.</Text>\n );\n } else if (upperAlpha.includes(listStyleType)) {\n bullet = (\n <Text>{orderedAlpha[element.indexOfType].toUpperCase()}.</Text>\n );\n } else {\n bullet = <Text>{element.indexOfType + 1}.</Text>;\n }\n } else {\n // if (listStyleType.includes('square')) {\n // bullet = <Text>■</Text>;\n // } else {\n bullet = <Text>•</Text>;\n // }\n }\n\n return (\n <View style={style}>\n {bullet && <View style={bulletStyles}>{bullet}</View>}\n <View style={contentStyles}>{children}</View>\n </View>\n );\n },\n a: ({ style, element, children }) => (\n <Link style={style} src={element.attributes.href}>\n {children}\n </Link>\n ),\n img: ({ style, element }) => {\n const { width, height } = element.attributes;\n const dimensions: any = {};\n if (width) {\n dimensions.width = width;\n }\n if (height) {\n dimensions.height = height;\n }\n const finalStyles = Object.assign({}, ...style, dimensions);\n return <Image style={finalStyles} src={element.attributes.src} />;\n },\n table: ({ element, style, children }) => {\n const tableStyles = element.style.reduce(\n (combined, tableStyle) => Object.assign(combined, tableStyle),\n {} as HtmlStyle\n );\n const overrides: HtmlStyle = {};\n if (\n !(tableStyles as any).borderSpacing ||\n (tableStyles as any).borderCollapse === 'collapse'\n ) {\n overrides.borderLeftWidth = 0;\n overrides.borderTopWidth = 0;\n }\n const finalStyles = Object.assign({}, ...style, overrides);\n delete finalStyles.height;\n return <View style={finalStyles}>{children}</View>;\n },\n tr: ({ style, children }) => {\n const finalStyles = Object.assign({}, ...style);\n delete finalStyles.height;\n return (\n <View wrap={true} style={finalStyles}>\n {children}\n </View>\n );\n },\n br: ({ style }) => (\n <Text wrap={false} style={style}>\n {'\\n'}\n </Text>\n ),\n td: renderCell,\n th: renderCell,\n};\n\nexport default renderers;\n"]}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Style } from '@react-pdf/types';
|
|
2
|
+
import { Tag } from './tags';
|
|
3
|
+
export type HtmlStyle = (Style & {
|
|
4
|
+
listStyle?: string;
|
|
5
|
+
listStyleType?: string;
|
|
6
|
+
borderSpacing?: number | string;
|
|
7
|
+
borderCollapse?: string;
|
|
8
|
+
}) | any;
|
|
9
|
+
export type HtmlStyles = Record<Tag | string, HtmlStyle>;
|
|
10
|
+
export declare const createHtmlStylesheet: <T extends HtmlStyles>(fontSize: number, reset?: boolean) => HtmlStyles;
|