Skip to content

Commit b3961ed

Browse files
committed
feat: support local images in markdown. #41
1 parent 6a3cbd9 commit b3961ed

6 files changed

Lines changed: 89 additions & 2 deletions

File tree

docs/quickreference.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,26 @@ LICENSE=Copyright (c) <b>2022</b> Support for HTML strings
243243

244244
Create `.env` file in project root directory.
245245

246+
### Image
247+
248+
![](./quickreference.svg?#sss=1)
249+
250+
<img src="./quickreference.svg?#sss=1" height="95" width="95" />
251+
252+
<hr />
253+
254+
```markdown
255+
![](./quickreference.svg?#sss=1)
256+
257+
<img
258+
src="./quickreference.svg?#sss=1"
259+
height="95"
260+
width="95"
261+
/>
262+
```
263+
264+
在 Markdown 中引入图片
265+
246266
Markdown Comments Syntax
247267
---
248268

@@ -1148,4 +1168,9 @@ Each section can have the following subitems:
11481168
注释配置:
11491169
`<!--rehype:wrap-style=background: #1b5064;-->`
11501170
```
1151-
<!--rehype:className=wrap-text -->
1171+
<!--rehype:className=wrap-text -->
1172+
1173+
另见
1174+
---
1175+
1176+
- [首页](../README.md)

docs/quickreference.svg

Lines changed: 5 additions & 0 deletions
Loading

src/utils/copyAsset.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import fs from 'fs-extra';
2+
import path from 'path';
3+
import type { Root, RootContent } from 'hast';
4+
import * as log from './log.js';
5+
import { Options } from './create.js';
6+
7+
export function copyied(fromPath: string, toPath: string) {
8+
const stat = fs.statSync(fromPath);
9+
if (!stat.isFile()) {
10+
return;
11+
}
12+
fs.ensureDir(path.dirname(toPath), (err) => {
13+
if (err) {
14+
console.log(` \x1b[31midoc:copy:\x1b[0m`, err);
15+
return;
16+
}
17+
fs.copyFile(decodeURIComponent(fromPath), decodeURIComponent(toPath))
18+
.then((result) => {
19+
log.output('\x1b[35;1mcopy\x1b[0m')(decodeURIComponent(fromPath), decodeURIComponent(toPath));
20+
})
21+
.catch((err) => {
22+
console.log(` \x1b[31midoc:asset:copy:\x1b[0m`, err);
23+
});
24+
});
25+
}
26+
27+
export function copyAsset(node: Root | RootContent, options: Options = {}) {
28+
let mdpath = options.fromPath || '';
29+
30+
if (node.type !== 'element' || !/^(img|a|video|source|audio)$/.test(node.tagName)) return;
31+
let src = node.properties.src as string;
32+
if (typeof src !== 'string' || /^https?:\/\//.test(src) || !src || /^data:/.test(src)) return;
33+
let outputHTMLPath = options.outputHTMLPath || '';
34+
const assetFromPath = path.resolve(path.dirname(mdpath), decodeURIComponent(src)).replace(/[?#].*$/, '');
35+
const assetToPath = path.resolve(path.dirname(outputHTMLPath), decodeURIComponent(src)).replace(/[?#].*$/, '');
36+
copyied(assetFromPath, assetToPath);
37+
}

src/utils/create.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { giscus } from '../nodes/giscus.js';
1313
import { googleAnalytics } from '../nodes/google.js';
1414
import { rehypeUrls } from './rehypeUrls.js';
1515
import { tooltips } from './tooltips.js';
16+
import { copyAsset } from './copyAsset.js';
1617
import { homeCardIcons } from './homeCardIcons.js';
1718
import { getTocsTree, getTocsTitleNode, getTocsTitleNodeWarpper, addTocsInWarp } from './getTocsTree.js';
1819
import { rehypeTitle } from './rehypeTitle.js';
@@ -116,6 +117,7 @@ export function create(str = '', options: Options = {}) {
116117
return plugins;
117118
},
118119
rewrite: (node, index, parent) => {
120+
copyAsset(node, options);
119121
const iconName = rehypeTitle(node, options);
120122
if (iconName) {
121123
detailData.icon = iconName;

src/utils/log.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import path from 'path';
2+
3+
export const log =
4+
(mark: string = 'refs') =>
5+
(filepath: string) => {
6+
console.log(` \x1b[32;1m✔\x1b[0m ${mark}: \x1b[37;1m${filepath}\x1b[0m`);
7+
};
8+
9+
export const output =
10+
(mark: string = 'idoc') =>
11+
(form: string, to: string) => {
12+
console.log(` \x1b[32;1m✔\x1b[0m ${mark}: \x1b[37;1m${form}\x1b[0m -> \x1b[32;1m${to}\x1b[0m`);
13+
};

src/utils/utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,12 @@ export async function createHTML(files: IFileDirStat[] = [], opts: Options, num
112112
],
113113
};
114114
process.env.RELATIVE_PATH = path.relative(path.dirname(outputHTMLPath), opts.output).replace(/[\\/]/g, '/');
115-
const { html, data } = create(mdstr.toString(), { ...options, ...opts });
115+
const { html, data } = create(mdstr.toString(), {
116+
...options,
117+
...opts,
118+
fromPath: dataFile.path,
119+
outputHTMLPath,
120+
});
116121
if (!options.isHome) {
117122
const searchData = await fs.readJSON(SEARCH_DATA_CACHE);
118123
data.path = path.relative(opts.output, outputHTMLPath).replace(/[\\/]/g, '/');

0 commit comments

Comments
 (0)