diff --git a/packages/desktop/src/renderer/src/components/editorWithTabs/editor.vue b/packages/desktop/src/renderer/src/components/editorWithTabs/editor.vue index de80df4eae..6d2999ba17 100644 --- a/packages/desktop/src/renderer/src/components/editorWithTabs/editor.vue +++ b/packages/desktop/src/renderer/src/components/editorWithTabs/editor.vue @@ -1327,7 +1327,7 @@ const handleExport = async (options: unknown) => { headerFooterStyled: headerFooterStyled as boolean | undefined, dir: props.textDirection }) - printer!.renderMarkdown(html, true) + printer!.renderMarkdown(html, true, props.textDirection) editorStore.EXPORT({ type, pageOptions }) } catch (err) { log.error('Failed to export document:', err) @@ -1353,7 +1353,7 @@ const handleExport = async (options: unknown) => { headerFooterStyled: headerFooterStyled as boolean | undefined, dir: props.textDirection }) - printer!.renderMarkdown(html, true) + printer!.renderMarkdown(html, true, props.textDirection) editorStore.PRINT_RESPONSE() } catch (err) { log.error('Failed to export document:', err) diff --git a/packages/desktop/src/renderer/src/services/printService.ts b/packages/desktop/src/renderer/src/services/printService.ts index 747a00ec16..f42b14b756 100644 --- a/packages/desktop/src/renderer/src/services/printService.ts +++ b/packages/desktop/src/renderer/src/services/printService.ts @@ -9,11 +9,18 @@ class MarkdownPrint { * * @param html HTML string * @param renderStatic Render for static files like PDF documents + * @param dir Text direction to mirror onto the container. `innerHTML` drops + * the exporter's outer `` shell and the container is a sibling + * of `.editor-wrapper`, so RTL documents print LTR unless we set it here + * (#4833). LTR is the default and stays implicit. */ - renderMarkdown(html: string, renderStatic?: boolean): void { + renderMarkdown(html: string, renderStatic?: boolean, dir?: string): void { this.clearup() const printContainer = document.createElement('article') printContainer.classList.add('print-container') + if (dir === 'rtl' || dir === 'auto') { + printContainer.setAttribute('dir', dir) + } this.container = printContainer printContainer.innerHTML = html diff --git a/packages/desktop/test/unit/specs/printService-direction.spec.ts b/packages/desktop/test/unit/specs/printService-direction.spec.ts new file mode 100644 index 0000000000..55ab2b7e6c --- /dev/null +++ b/packages/desktop/test/unit/specs/printService-direction.spec.ts @@ -0,0 +1,52 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' + +// `printService` imports `resolveLocalImageSrc`, which reads `window.path` / +// `window.DIRNAME` for its relative-resolve branch. Stub those preload +// surfaces before the hoisted import runs (mirrors printService-image.spec.ts). +vi.hoisted(() => { + const w = globalThis as unknown as { + window?: { path?: { sep: string }; DIRNAME?: string } + } + w.window ??= {} + w.window.path ??= { sep: '/' } + w.window.DIRNAME = '/docs' +}) + +import MarkdownPrint from '@/services/printService' + +// PDF / print render into an `