You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop: Use plugins whenever printing or exporting notes
Ref: https://discourse.joplinapp.org/t/external-css-per-note-is-being-ignored/13016/6
This commit is contained in:
		| @@ -4,6 +4,7 @@ import shim from '@joplin/lib/shim'; | ||||
| import { ExportOptions, FileSystemItem, Module } from '@joplin/lib/services/interop/types'; | ||||
|  | ||||
| import { _ } from '@joplin/lib/locale'; | ||||
| import { PluginStates } from '@joplin/lib/services/plugins/reducer'; | ||||
| const bridge = require('electron').remote.require('./bridge').default; | ||||
| const Setting = require('@joplin/lib/models/Setting').default; | ||||
| const Note = require('@joplin/lib/models/Note.js'); | ||||
| @@ -20,6 +21,7 @@ interface ExportNoteOptions { | ||||
| 	pageSize?: string; | ||||
| 	landscape?: boolean; | ||||
| 	includeConflicts?: boolean; | ||||
| 	plugins?: PluginStates; | ||||
| } | ||||
|  | ||||
| export default class InteropServiceHelper { | ||||
| @@ -54,6 +56,7 @@ export default class InteropServiceHelper { | ||||
| 		try { | ||||
| 			const exportOptions = { | ||||
| 				customCss: options.customCss ? options.customCss : '', | ||||
| 				plugins: options.plugins, | ||||
| 			}; | ||||
|  | ||||
| 			htmlFile = await this.exportNoteToHtmlFile(noteId, exportOptions); | ||||
| @@ -162,6 +165,7 @@ export default class InteropServiceHelper { | ||||
| 		exportOptions.path = path; | ||||
| 		exportOptions.format = module.format; | ||||
| 		// exportOptions.modulePath = module.path; | ||||
| 		if (options.plugins) exportOptions.plugins = options.plugins; | ||||
| 		exportOptions.target = module.target; | ||||
| 		exportOptions.includeConflicts = !!options.includeConflicts; | ||||
| 		if (options.sourceFolderIds) exportOptions.sourceFolderIds = options.sourceFolderIds; | ||||
|   | ||||
| @@ -373,6 +373,7 @@ class MainScreenComponent extends React.Component<Props, State> { | ||||
| 					pageSize: Setting.value('export.pdfPageSize'), | ||||
| 					landscape: Setting.value('export.pdfPageOrientation') === 'landscape', | ||||
| 					customCss: this.props.customCss, | ||||
| 					plugins: this.props.plugins, | ||||
| 				}); | ||||
| 				await shim.fsDriver().writeFile(options.path, pdfData, 'buffer'); | ||||
| 			} catch (error) { | ||||
|   | ||||
| @@ -88,6 +88,7 @@ interface Props { | ||||
| 	pluginMenus: any[]; | ||||
| 	['spellChecker.enabled']: boolean; | ||||
| 	['spellChecker.language']: string; | ||||
| 	plugins: PluginStates; | ||||
| } | ||||
|  | ||||
| const commandNames: string[] = menuCommandNames(); | ||||
| @@ -233,7 +234,11 @@ function useMenu(props: Props) { | ||||
| 					exportItems.push({ | ||||
| 						label: module.fullLabel(), | ||||
| 						click: async () => { | ||||
| 							await InteropServiceHelper.export((action: any) => props.dispatch(action), module); | ||||
| 							await InteropServiceHelper.export( | ||||
| 								(action: any) => props.dispatch(action), | ||||
| 								module, | ||||
| 								{ plugins: props.plugins } | ||||
| 							); | ||||
| 						}, | ||||
| 					}); | ||||
| 				} | ||||
| @@ -471,7 +476,7 @@ function useMenu(props: Props) { | ||||
| 					label: _('Import'), | ||||
| 					submenu: importItems, | ||||
| 				}, { | ||||
| 					label: _('Export'), | ||||
| 					label: _('Export all'), | ||||
| 					submenu: exportItems, | ||||
| 				}, { | ||||
| 					type: 'separator', | ||||
| @@ -750,7 +755,7 @@ function useMenu(props: Props) { | ||||
| 		} else { | ||||
| 			setMenu(Menu.buildFromTemplate(template)); | ||||
| 		} | ||||
| 	}, [props.routeName, props.pluginMenuItems, props.pluginMenus, keymapLastChangeTime, modulesLastChangeTime, props['spellChecker.language'], props['spellChecker.enabled']]); | ||||
| 	}, [props.routeName, props.pluginMenuItems, props.pluginMenus, keymapLastChangeTime, modulesLastChangeTime, props['spellChecker.language'], props['spellChecker.enabled'], props.plugins]); | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		const whenClauseContext = CommandService.instance().currentWhenClauseContext(); | ||||
| @@ -847,6 +852,7 @@ const mapStateToProps = (state: AppState) => { | ||||
| 		pluginMenus: stateUtils.selectArrayShallow({ array: pluginUtils.viewsByType(state.pluginService.plugins, 'menu') }, 'menuBar.pluginMenus'), | ||||
| 		['spellChecker.language']: state.settings['spellChecker.language'], | ||||
| 		['spellChecker.enabled']: state.settings['spellChecker.enabled'], | ||||
| 		plugins: state.pluginService.plugins, | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ interface KeyToLabelMap { | ||||
| let markupToHtml_: any = null; | ||||
| function markupToHtml() { | ||||
| 	if (markupToHtml_) return markupToHtml_; | ||||
| 	markupToHtml_ = markupLanguageUtils.newMarkupToHtml(); | ||||
| 	markupToHtml_ = markupLanguageUtils.newMarkupToHtml({}); | ||||
| 	return markupToHtml_; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -154,7 +154,7 @@ function NoteEditor(props: NoteEditorProps) { | ||||
| 	const allAssets = useCallback(async (markupLanguage: number): Promise<any[]> => { | ||||
| 		const theme = themeStyle(props.themeId); | ||||
|  | ||||
| 		const markupToHtml = markupLanguageUtils.newMarkupToHtml({ | ||||
| 		const markupToHtml = markupLanguageUtils.newMarkupToHtml({}, { | ||||
| 			resourceBaseUrl: `file://${Setting.value('resourceDir')}/`, | ||||
| 		}); | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { PluginStates } from '@joplin/lib/services/plugins/reducer'; | ||||
| import { contentScriptsToRendererRules } from '@joplin/lib/services/plugins/utils/loadContentScripts'; | ||||
| import { useCallback, useMemo } from 'react'; | ||||
| import { ResourceInfos } from './types'; | ||||
| import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; | ||||
| @@ -23,9 +22,8 @@ export default function useMarkupToHtml(deps: HookDependencies) { | ||||
| 	const { themeId, customCss, plugins } = deps; | ||||
|  | ||||
| 	const markupToHtml = useMemo(() => { | ||||
| 		return markupLanguageUtils.newMarkupToHtml({ | ||||
| 		return markupLanguageUtils.newMarkupToHtml(deps.plugins, { | ||||
| 			resourceBaseUrl: `file://${Setting.value('resourceDir')}/`, | ||||
| 			extraRendererRules: contentScriptsToRendererRules(plugins), | ||||
| 		}); | ||||
| 	}, [plugins]); | ||||
|  | ||||
|   | ||||
| @@ -116,7 +116,7 @@ class NoteRevisionViewerComponent extends React.PureComponent { | ||||
|  | ||||
| 		const theme = themeStyle(this.props.themeId); | ||||
|  | ||||
| 		const markupToHtml = markupLanguageUtils.newMarkupToHtml({ | ||||
| 		const markupToHtml = markupLanguageUtils.newMarkupToHtml({}, { | ||||
| 			resourceBaseUrl: `file://${Setting.value('resourceDir')}/`, | ||||
| 		}); | ||||
|  | ||||
|   | ||||
| @@ -288,7 +288,7 @@ class SideBarComponent extends React.Component<Props, State> { | ||||
| 					new MenuItem({ | ||||
| 						label: module.fullLabel(), | ||||
| 						click: async () => { | ||||
| 							await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] }); | ||||
| 							await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId], plugins: this.pluginsRef.current }); | ||||
| 						}, | ||||
| 					}) | ||||
| 				); | ||||
|   | ||||
| @@ -153,6 +153,7 @@ export default class NoteListUtils { | ||||
| 							await InteropServiceHelper.export(props.dispatch.bind(this), module, { | ||||
| 								sourceNoteIds: noteIds, | ||||
| 								includeConflicts: props.inConflictFolder, | ||||
| 								plugins: props.plugins, | ||||
| 							}); | ||||
| 						}, | ||||
| 					}) | ||||
|   | ||||
| @@ -248,7 +248,7 @@ class Dialog extends React.PureComponent<Props, State> { | ||||
|  | ||||
| 	markupToHtml() { | ||||
| 		if (this.markupToHtml_) return this.markupToHtml_; | ||||
| 		this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml(); | ||||
| 		this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml({}); | ||||
| 		return this.markupToHtml_; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -38,7 +38,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number, | ||||
| 	}, [themeId, paddingBottom]); | ||||
|  | ||||
| 	const markupToHtml = useMemo(() => { | ||||
| 		return markupLanguageUtils.newMarkupToHtml(); | ||||
| 		return markupLanguageUtils.newMarkupToHtml({}); | ||||
| 	}, [isFirstRender]); | ||||
|  | ||||
| 	// To address https://github.com/laurent22/joplin/issues/433 | ||||
|   | ||||
| @@ -2,6 +2,8 @@ import markdownUtils from './markdownUtils'; | ||||
| import Setting from './models/Setting'; | ||||
| import shim from './shim'; | ||||
| import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml'; | ||||
| import { PluginStates } from './services/plugins/reducer'; | ||||
| import { contentScriptsToRendererRules } from './services/plugins/utils/loadContentScripts'; | ||||
|  | ||||
| const htmlUtils = require('./htmlUtils'); | ||||
| const Resource = require('./models/Resource'); | ||||
| @@ -19,7 +21,7 @@ class MarkupLanguageUtils { | ||||
|  | ||||
| 	// Create a new MarkupToHtml instance while injecting options specific to Joplin | ||||
| 	// desktop and mobile applications. | ||||
| 	newMarkupToHtml(options: any = null) { | ||||
| 	newMarkupToHtml(plugins: PluginStates, options: any = null) { | ||||
| 		const subValues = Setting.subValues('markdown.plugin', Setting.toPlainObject()); | ||||
| 		const pluginOptions: any = {}; | ||||
| 		for (const n in subValues) { | ||||
| @@ -31,6 +33,7 @@ class MarkupLanguageUtils { | ||||
| 			pluginOptions: pluginOptions, | ||||
| 			tempDir: Setting.value('tempDir'), | ||||
| 			fsDriver: shim.fsDriver(), | ||||
| 			extraRendererRules: contentScriptsToRendererRules(plugins), | ||||
| 		}, options); | ||||
|  | ||||
| 		return new MarkupToHtml(options); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte | ||||
| 		this.resourceDir_ = this.destDir_ ? `${this.destDir_}/_resources` : null; | ||||
|  | ||||
| 		await shim.fsDriver().mkdir(this.destDir_); | ||||
| 		this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml(); | ||||
| 		this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml(options.plugins); | ||||
| 		this.resources_ = []; | ||||
| 		this.style_ = themeStyle(Setting.THEME_LIGHT); | ||||
| 	} | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { _ } from '../../locale'; | ||||
| import { PluginStates } from '../plugins/reducer'; | ||||
|  | ||||
| export interface CustomImportContext { | ||||
| 	sourcePath: string; | ||||
| @@ -94,6 +95,7 @@ export interface ExportOptions { | ||||
| 	// modulePath?: string; | ||||
| 	target?: FileSystemItem; | ||||
| 	includeConflicts?: boolean; | ||||
| 	plugins?: PluginStates; | ||||
| } | ||||
|  | ||||
| export interface ImportExportResult { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user