@file-viewer/renderer-text 2.0.11
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/LICENSE +160 -0
- package/README.en.md +40 -0
- package/README.md +40 -0
- package/dist/code.d.ts +11 -0
- package/dist/code.js +243 -0
- package/dist/gitBundle.d.ts +2 -0
- package/dist/gitBundle.js +580 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +25 -0
- package/dist/markdown.d.ts +2 -0
- package/dist/markdown.js +81 -0
- package/dist/patch.d.ts +2 -0
- package/dist/patch.js +123 -0
- package/package.json +74 -0
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter, readFileViewerText as readText, registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
|
|
3
|
+
const markdownStyle = `
|
|
4
|
+
.markdown-viewer{min-height:100%;padding:28px 16px 48px;background:#eef1f4;overflow:auto;box-sizing:border-box}
|
|
5
|
+
.markdown-body{color-scheme:light;--bgColor-default:#fff;--bgColor-muted:#f6f8fa;--bgColor-neutral-muted:#818b981f;--borderColor-default:#d1d9e0;--borderColor-muted:#d1d9e0b3;--borderColor-neutral-muted:#d1d9e0b3;--fgColor-default:#1f2328;--fgColor-muted:#59636e;--fgColor-accent:#0969da;background:var(--bgColor-default);border:1px solid rgba(20,35,53,.1);border-radius:12px;margin:0 auto;box-sizing:border-box;min-width:200px;max-width:var(--markdown-max-width,980px);padding:var(--markdown-padding,45px);color:var(--fgColor-default);font-size:var(--markdown-font-size,16px);box-shadow:0 18px 42px rgba(15,23,42,.1)}
|
|
6
|
+
.markdown-body h1,.markdown-body h2,.markdown-body h3{margin-top:24px;margin-bottom:16px;font-weight:700;line-height:1.25}
|
|
7
|
+
.markdown-body h1{padding-bottom:.3em;border-bottom:1px solid var(--borderColor-muted);font-size:2em}
|
|
8
|
+
.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid var(--borderColor-muted);font-size:1.5em}
|
|
9
|
+
.markdown-body p,.markdown-body ul,.markdown-body ol,.markdown-body blockquote,.markdown-body table,.markdown-body pre{margin-top:0;margin-bottom:16px}
|
|
10
|
+
.markdown-body a{color:var(--fgColor-accent);text-decoration:none}
|
|
11
|
+
.markdown-body a:hover{text-decoration:underline}
|
|
12
|
+
.markdown-body code{padding:.2em .4em;border-radius:6px;background:var(--bgColor-neutral-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:85%}
|
|
13
|
+
.markdown-body pre{padding:16px;overflow:auto;border-radius:8px;background:var(--bgColor-muted)}
|
|
14
|
+
.markdown-body pre code{padding:0;background:transparent;font-size:100%}
|
|
15
|
+
.markdown-body table{display:block;width:max-content;max-width:100%;overflow:auto;border-spacing:0;border-collapse:collapse}
|
|
16
|
+
.markdown-body th,.markdown-body td{padding:6px 13px;border:1px solid var(--borderColor-default)}
|
|
17
|
+
.markdown-body tr{background:var(--bgColor-default);border-top:1px solid var(--borderColor-muted)}
|
|
18
|
+
.markdown-body tr:nth-child(2n){background:var(--bgColor-muted)}
|
|
19
|
+
.markdown-body blockquote{padding:0 1em;color:var(--fgColor-muted);border-left:.25em solid var(--borderColor-default)}
|
|
20
|
+
.file-viewer[data-viewer-theme='dark'] .markdown-viewer{background:#101820}
|
|
21
|
+
.file-viewer[data-viewer-theme='dark'] .markdown-body{color-scheme:dark;--bgColor-default:#0d1117;--bgColor-muted:#151b23;--bgColor-neutral-muted:#656c7633;--borderColor-default:#3d444d;--borderColor-muted:#3d444db3;--borderColor-neutral-muted:#3d444db3;--fgColor-default:#f0f6fc;--fgColor-muted:#9198a1;--fgColor-accent:#4493f8;background:var(--bgColor-default);border-color:rgba(139,148,158,.26);color:var(--fgColor-default);box-shadow:0 24px 56px rgba(0,0,0,.38)}
|
|
22
|
+
@media (max-width:767px){.markdown-viewer{padding:14px 10px 28px}.markdown-body{padding:22px 18px;border-radius:10px}}
|
|
23
|
+
@media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .markdown-viewer{background:#101820}.file-viewer[data-viewer-theme='system'] .markdown-body{color-scheme:dark;--bgColor-default:#0d1117;--bgColor-muted:#151b23;--bgColor-neutral-muted:#656c7633;--borderColor-default:#3d444d;--borderColor-muted:#3d444db3;--borderColor-neutral-muted:#3d444db3;--fgColor-default:#f0f6fc;--fgColor-muted:#9198a1;--fgColor-accent:#4493f8;background:var(--bgColor-default);border-color:rgba(139,148,158,.26);color:var(--fgColor-default);box-shadow:0 24px 56px rgba(0,0,0,.38)}}
|
|
24
|
+
`;
|
|
25
|
+
const createStyle = () => {
|
|
26
|
+
const style = document.createElement('style');
|
|
27
|
+
style.textContent = markdownStyle;
|
|
28
|
+
return style;
|
|
29
|
+
};
|
|
30
|
+
const clampZoom = (value) => {
|
|
31
|
+
return Math.min(2.4, Math.max(0.6, Number(value.toFixed(2))));
|
|
32
|
+
};
|
|
33
|
+
const applyMarkdownZoom = (host, zoom) => {
|
|
34
|
+
host.style.setProperty('--markdown-max-width', `${980 * zoom}px`);
|
|
35
|
+
host.style.setProperty('--markdown-padding', `${45 * zoom}px`);
|
|
36
|
+
host.style.setProperty('--markdown-font-size', `${16 * zoom}px`);
|
|
37
|
+
};
|
|
38
|
+
export default async function renderMarkdown(buffer, target) {
|
|
39
|
+
const text = await readText(buffer);
|
|
40
|
+
let zoom = 1;
|
|
41
|
+
const zoomEmitter = createZoomChangeEmitter();
|
|
42
|
+
const root = document.createElement('div');
|
|
43
|
+
root.className = 'markdown-viewer';
|
|
44
|
+
root.dataset.viewerZoomProvider = 'markdown';
|
|
45
|
+
const article = document.createElement('article');
|
|
46
|
+
article.className = 'markdown-body';
|
|
47
|
+
article.innerHTML = await marked(text);
|
|
48
|
+
applyMarkdownZoom(root, zoom);
|
|
49
|
+
root.append(article);
|
|
50
|
+
target.replaceChildren(createStyle(), root);
|
|
51
|
+
const getZoomState = () => ({
|
|
52
|
+
scale: zoom,
|
|
53
|
+
label: `${Math.round(zoom * 100)}%`,
|
|
54
|
+
canZoomIn: zoom < 2.4,
|
|
55
|
+
canZoomOut: zoom > 0.6,
|
|
56
|
+
canReset: zoom !== 1,
|
|
57
|
+
minScale: 0.6,
|
|
58
|
+
maxScale: 2.4,
|
|
59
|
+
});
|
|
60
|
+
const setZoom = (scale) => {
|
|
61
|
+
zoom = clampZoom(scale);
|
|
62
|
+
applyMarkdownZoom(root, zoom);
|
|
63
|
+
zoomEmitter.emit();
|
|
64
|
+
return getZoomState();
|
|
65
|
+
};
|
|
66
|
+
registerFileViewerZoomProvider(root, {
|
|
67
|
+
zoomIn: () => setZoom(zoom + 0.1),
|
|
68
|
+
zoomOut: () => setZoom(zoom - 0.1),
|
|
69
|
+
resetZoom: () => setZoom(1),
|
|
70
|
+
setZoom,
|
|
71
|
+
getState: getZoomState,
|
|
72
|
+
subscribe: zoomEmitter.subscribe,
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
$el: target,
|
|
76
|
+
unmount() {
|
|
77
|
+
unregisterFileViewerZoomProvider(root);
|
|
78
|
+
target.replaceChildren();
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
package/dist/patch.d.ts
ADDED
package/dist/patch.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter, readFileViewerText as readText, registerFileViewerZoomProvider, unregisterFileViewerZoomProvider } from '@file-viewer/core';
|
|
2
|
+
import { html as diffToHtml } from 'diff2html';
|
|
3
|
+
const patchStyle = `
|
|
4
|
+
.patch-viewer{min-height:100%;--patch-bg:#f6f8fa;--patch-surface:#fff;--patch-border:rgba(31,35,40,.12);--patch-text:#24292f;--patch-muted:#57606a;--patch-add:#dafbe1;--patch-del:#ffebe9;--patch-info:#ddf4ff;--patch-font-size:13px;background:var(--patch-bg);color:var(--patch-text);box-sizing:border-box}
|
|
5
|
+
.patch-toolbar{position:sticky;top:0;z-index:2;display:flex;height:46px;align-items:center;justify-content:space-between;gap:12px;padding:0 16px;border-bottom:1px solid var(--patch-border);background:rgba(255,255,255,.92);backdrop-filter:blur(12px);box-sizing:border-box}
|
|
6
|
+
.patch-toolbar span,.patch-toolbar strong{color:var(--patch-muted);font-size:12px;font-weight:800;letter-spacing:0}
|
|
7
|
+
.patch-body{padding:16px;overflow:auto;font-size:var(--patch-font-size)}
|
|
8
|
+
.patch-body .d2h-wrapper{min-width:860px}
|
|
9
|
+
.patch-body .d2h-file-wrapper{margin:0 0 16px;overflow:hidden;border:1px solid var(--patch-border);border-radius:8px;background:var(--patch-surface)}
|
|
10
|
+
.patch-body .d2h-file-header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--patch-border);background:#f8fafc;color:var(--patch-muted);font-weight:800}
|
|
11
|
+
.patch-body .d2h-file-name-wrapper{display:flex;min-width:0;align-items:center;gap:8px}
|
|
12
|
+
.patch-body .d2h-file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
13
|
+
.patch-body .d2h-diff-table{width:100%;border-collapse:collapse;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:1em;line-height:1.58}
|
|
14
|
+
.patch-body .d2h-code-side-linenumber,.patch-body .d2h-code-linenumber{width:56px;padding:0 8px;border-right:1px solid var(--patch-border);color:var(--patch-muted);text-align:right;user-select:none}
|
|
15
|
+
.patch-body .d2h-code-side-line,.patch-body .d2h-code-line{padding:0 10px;white-space:pre-wrap;word-break:break-word}
|
|
16
|
+
.patch-body .d2h-ins{background:var(--patch-add)}
|
|
17
|
+
.patch-body .d2h-del{background:var(--patch-del)}
|
|
18
|
+
.patch-body .d2h-info{background:var(--patch-info);color:var(--patch-muted)}
|
|
19
|
+
.patch-body .d2h-file-list-wrapper{margin:0 0 16px;border:1px solid var(--patch-border);border-radius:8px;background:var(--patch-surface)}
|
|
20
|
+
.patch-body .d2h-file-list-header{padding:10px 12px;border-bottom:1px solid var(--patch-border);color:var(--patch-muted);font-weight:800}
|
|
21
|
+
.patch-body .d2h-file-list{margin:0;padding:8px 12px;list-style:none}
|
|
22
|
+
.patch-body .d2h-file-list-line{display:flex;gap:8px;padding:4px 0;color:var(--patch-text);font-size:.95em}
|
|
23
|
+
.patch-fallback{margin:0;padding:18px 20px;overflow:auto;border-radius:8px;background:#0d1117;color:#e6edf3;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--patch-font-size);line-height:1.7;white-space:pre}
|
|
24
|
+
.file-viewer[data-viewer-theme='dark'] .patch-viewer{--patch-bg:#0d1117;--patch-surface:#161b22;--patch-border:rgba(139,148,158,.24);--patch-text:#e6edf3;--patch-muted:#8b949e;--patch-add:rgba(46,160,67,.26);--patch-del:rgba(248,81,73,.24);--patch-info:rgba(56,139,253,.18)}
|
|
25
|
+
.file-viewer[data-viewer-theme='dark'] .patch-toolbar{background:rgba(13,17,23,.92)}
|
|
26
|
+
.file-viewer[data-viewer-theme='dark'] .patch-body .d2h-file-header{background:#161b22}
|
|
27
|
+
@media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .patch-viewer{--patch-bg:#0d1117;--patch-surface:#161b22;--patch-border:rgba(139,148,158,.24);--patch-text:#e6edf3;--patch-muted:#8b949e;--patch-add:rgba(46,160,67,.26);--patch-del:rgba(248,81,73,.24);--patch-info:rgba(56,139,253,.18)}.file-viewer[data-viewer-theme='system'] .patch-toolbar{background:rgba(13,17,23,.92)}.file-viewer[data-viewer-theme='system'] .patch-body .d2h-file-header{background:#161b22}}
|
|
28
|
+
`;
|
|
29
|
+
const createElement = (documentRef, tagName, className, text) => {
|
|
30
|
+
const element = documentRef.createElement(tagName);
|
|
31
|
+
if (className) {
|
|
32
|
+
element.className = className;
|
|
33
|
+
}
|
|
34
|
+
if (typeof text === 'string') {
|
|
35
|
+
element.textContent = text;
|
|
36
|
+
}
|
|
37
|
+
return element;
|
|
38
|
+
};
|
|
39
|
+
const createStyle = (documentRef) => {
|
|
40
|
+
const style = documentRef.createElement('style');
|
|
41
|
+
style.textContent = patchStyle;
|
|
42
|
+
return style;
|
|
43
|
+
};
|
|
44
|
+
const clampZoom = (value) => {
|
|
45
|
+
return Math.min(2.4, Math.max(0.6, Number(value.toFixed(2))));
|
|
46
|
+
};
|
|
47
|
+
const countFiles = (text) => {
|
|
48
|
+
var _a;
|
|
49
|
+
const matches = text.match(/^diff --git\s+/gm);
|
|
50
|
+
if (matches === null || matches === void 0 ? void 0 : matches.length) {
|
|
51
|
+
return matches.length;
|
|
52
|
+
}
|
|
53
|
+
return ((_a = text.match(/^---\s+/gm)) === null || _a === void 0 ? void 0 : _a.length) || 1;
|
|
54
|
+
};
|
|
55
|
+
const escapeHtml = (value) => {
|
|
56
|
+
return value.replace(/[&<>"']/g, char => {
|
|
57
|
+
const entities = {
|
|
58
|
+
'&': '&',
|
|
59
|
+
'<': '<',
|
|
60
|
+
'>': '>',
|
|
61
|
+
'"': '"',
|
|
62
|
+
"'": '''
|
|
63
|
+
};
|
|
64
|
+
return entities[char];
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
export default async function renderPatch(buffer, target, type = 'patch') {
|
|
68
|
+
const documentRef = target.ownerDocument || document;
|
|
69
|
+
const text = await readText(buffer);
|
|
70
|
+
let zoom = 1;
|
|
71
|
+
const zoomEmitter = createZoomChangeEmitter();
|
|
72
|
+
const root = createElement(documentRef, 'div', 'patch-viewer');
|
|
73
|
+
root.dataset.viewerZoomProvider = 'patch';
|
|
74
|
+
const toolbar = createElement(documentRef, 'div', 'patch-toolbar');
|
|
75
|
+
toolbar.append(createElement(documentRef, 'span', undefined, type.toUpperCase()), createElement(documentRef, 'strong', undefined, `${countFiles(text)} files · side-by-side`));
|
|
76
|
+
const body = createElement(documentRef, 'div', 'patch-body');
|
|
77
|
+
try {
|
|
78
|
+
body.innerHTML = diffToHtml(text, {
|
|
79
|
+
drawFileList: true,
|
|
80
|
+
matching: 'lines',
|
|
81
|
+
outputFormat: 'side-by-side',
|
|
82
|
+
renderNothingWhenEmpty: false
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
const fallback = createElement(documentRef, 'pre', 'patch-fallback');
|
|
87
|
+
fallback.innerHTML = escapeHtml(text);
|
|
88
|
+
body.replaceChildren(fallback);
|
|
89
|
+
}
|
|
90
|
+
root.append(toolbar, body);
|
|
91
|
+
root.style.setProperty('--patch-font-size', `${13 * zoom}px`);
|
|
92
|
+
target.replaceChildren(createStyle(documentRef), root);
|
|
93
|
+
const getZoomState = () => ({
|
|
94
|
+
scale: zoom,
|
|
95
|
+
label: `${Math.round(zoom * 100)}%`,
|
|
96
|
+
canZoomIn: zoom < 2.4,
|
|
97
|
+
canZoomOut: zoom > 0.6,
|
|
98
|
+
canReset: zoom !== 1,
|
|
99
|
+
minScale: 0.6,
|
|
100
|
+
maxScale: 2.4
|
|
101
|
+
});
|
|
102
|
+
const setZoom = (scale) => {
|
|
103
|
+
zoom = clampZoom(scale);
|
|
104
|
+
root.style.setProperty('--patch-font-size', `${13 * zoom}px`);
|
|
105
|
+
zoomEmitter.emit();
|
|
106
|
+
return getZoomState();
|
|
107
|
+
};
|
|
108
|
+
registerFileViewerZoomProvider(root, {
|
|
109
|
+
zoomIn: () => setZoom(zoom + 0.1),
|
|
110
|
+
zoomOut: () => setZoom(zoom - 0.1),
|
|
111
|
+
resetZoom: () => setZoom(1),
|
|
112
|
+
setZoom,
|
|
113
|
+
getState: getZoomState,
|
|
114
|
+
subscribe: zoomEmitter.subscribe
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
$el: root,
|
|
118
|
+
unmount() {
|
|
119
|
+
unregisterFileViewerZoomProvider(root);
|
|
120
|
+
target.replaceChildren();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@file-viewer/renderer-text",
|
|
3
|
+
"version": "2.0.11",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Standalone code, text, Markdown, patch diff, and Git bundle renderer plugin for Flyfish File Viewer.",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"file-viewer",
|
|
9
|
+
"renderer",
|
|
10
|
+
"text",
|
|
11
|
+
"code",
|
|
12
|
+
"markdown",
|
|
13
|
+
"patch",
|
|
14
|
+
"git-bundle",
|
|
15
|
+
"highlight.js",
|
|
16
|
+
"document-preview",
|
|
17
|
+
"document-viewer",
|
|
18
|
+
"file-preview",
|
|
19
|
+
"self-hosted"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public",
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"author": {
|
|
26
|
+
"name": "Wangyu",
|
|
27
|
+
"email": "wybaby168@gmail.com"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/flyfish-dev/file-viewer-renderer-text.git",
|
|
32
|
+
"directory": "packages/renderers/text"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://doc.file-viewer.app/guide/on-demand-renderers",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/flyfish-dev/file-viewer-renderer-text/issues"
|
|
37
|
+
},
|
|
38
|
+
"funding": {
|
|
39
|
+
"type": "individual",
|
|
40
|
+
"url": "https://dev.flyfish.group/shop"
|
|
41
|
+
},
|
|
42
|
+
"main": "./dist/index.js",
|
|
43
|
+
"module": "./dist/index.js",
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"import": "./dist/index.js",
|
|
49
|
+
"default": "./dist/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./package.json": "./package.json"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist",
|
|
55
|
+
"README.md",
|
|
56
|
+
"README.en.md",
|
|
57
|
+
"LICENSE"
|
|
58
|
+
],
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@file-viewer/core": "^2.0.11",
|
|
61
|
+
"diff2html": "^3.4.56",
|
|
62
|
+
"highlight.js": "^11.11.1",
|
|
63
|
+
"marked": "^18.0.5",
|
|
64
|
+
"pako": "^2.1.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"typescript": "^6.0.3"
|
|
68
|
+
},
|
|
69
|
+
"license": "Apache-2.0",
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsc -b tsconfig.json",
|
|
72
|
+
"type-check": "tsc -b tsconfig.json"
|
|
73
|
+
}
|
|
74
|
+
}
|