diff --git a/src/renderer/plugins/copy-rendered-content.tsx b/src/renderer/plugins/copy-rendered-content.tsx
index 6c9ae069..9fefcb7c 100644
--- a/src/renderer/plugins/copy-rendered-content.tsx
+++ b/src/renderer/plugins/copy-rendered-content.tsx
@@ -1,4 +1,5 @@
import type { Plugin } from '@fe/context'
+import type Token from 'markdown-it/lib/token'
export default {
name: 'copy-rendered-content',
@@ -8,7 +9,7 @@ export default {
inlineLocalImage: false,
uploadLocalImage: false,
highlightCode: false,
- type: 'rtf' as 'html' | 'rtf',
+ type: 'rtf' as 'html' | 'rtf' | 'markdown',
})
const panel = ctx.lib.vue.defineComponent({
@@ -24,26 +25,76 @@ export default {
})
return () =>
}
})
+ async function transformMarkdown () {
+ let markdown = ctx.store.state.currentContent
+ const tokens = ctx.view.getRenderEnv()?.tokens
+ if (!markdown || !tokens) {
+ return
+ }
+
+ const processImg = async (tokens: Token[]) => {
+ for (let token of tokens) {
+ if (token.children) {
+ await processImg(token.children)
+ }
+
+
+ if (token.tag === 'img' && token.attrGet(ctx.constant.DOM_ATTR_NAME.LOCAL_IMAGE)) {
+ const srcAttr = token.attrGet('src')
+ const originSrc = token.attrGet(ctx.constant.DOM_ATTR_NAME.ORIGIN_SRC)
+ if (srcAttr && originSrc) {
+ const res: Response = await ctx.api.fetchHttp(srcAttr)
+ const fileName = ctx.utils.path.basename(originSrc)
+ const file = new File(
+ [await res.blob()],
+ fileName,
+ { type: ctx.lib.mime.getType(fileName) || undefined }
+ )
+
+ let url: string | undefined
+ if (options.inlineLocalImage) {
+ url = await ctx.utils.fileToBase64URL(file)
+ } else if (options.uploadLocalImage) {
+ url = await ctx.action.getActionHandler('plugin.image-hosting-picgo.upload')(file)
+ }
+
+ if (url) {
+ markdown = markdown.replace(
+ new RegExp(ctx.utils.encodeMarkdownLink(originSrc), 'g'),
+ ctx.utils.encodeMarkdownLink(url)
+ )
+ }
+ }
+ }
+ }
+ }
+
+ await processImg(tokens)
+
+ return markdown
+ }
+
async function copyContent () {
if (await ctx.ui.useModal().confirm({
title: ctx.i18n.t('status-bar.tool.copy-content'),
@@ -52,17 +103,19 @@ export default {
try {
const startedAt = Date.now()
ctx.ui.useToast().show('info', ctx.i18n.t('loading'), 10000)
- const html = await ctx.view.getContentHtml(options)
+ const content = options.type === 'markdown'
+ ? await transformMarkdown()
+ : await ctx.view.getContentHtml(options)
if (Date.now() - startedAt > 3000) {
await ctx.ui.useModal().alert({ content: ctx.i18n.t('copy-rendered-content.complete') })
}
if (options.type === 'rtf') {
- await ctx.base.writeToClipboard('text/html', html)
+ await ctx.base.writeToClipboard('text/html', content)
ctx.ui.useToast().show('info', ctx.i18n.t('copied'))
} else {
- ctx.utils.copyText(html)
+ ctx.utils.copyText(content)
}
} catch (error: any) {
console.error(error)
diff --git a/src/renderer/services/markdown.ts b/src/renderer/services/markdown.ts
index ba43657d..c664bedd 100644
--- a/src/renderer/services/markdown.ts
+++ b/src/renderer/services/markdown.ts
@@ -49,5 +49,6 @@ markdown.block.tokenize = function (state, startLine, endLine) {
markdown.core.ruler.after('normalize', 'after_normalize', state => {
state.env.source = state.src
+ state.env.tokens = state.tokens
return true
})
diff --git a/src/renderer/types.ts b/src/renderer/types.ts
index 63b38e2c..62915eed 100644
--- a/src/renderer/types.ts
+++ b/src/renderer/types.ts
@@ -1,4 +1,5 @@
import type { Language } from '@share/i18n'
+import type Token from 'markdown-it/lib/token'
import type * as Monaco from 'monaco-editor'
export interface PathItem {
@@ -92,7 +93,13 @@ export type ThemeName = 'system' | 'dark' | 'light'
export type LanguageName = 'system' | Language
export type ExportTypes = 'pdf' | 'docx' | 'html' | 'rst' | 'adoc'
-export type RenderEnv = { source: string, file: Doc | null, renderCount: number, attributes?: Record