diff --git a/src/lib/export/docx.ts b/src/lib/export/docx.ts index de1d947..0972693 100644 --- a/src/lib/export/docx.ts +++ b/src/lib/export/docx.ts @@ -17,7 +17,7 @@ import type { import { unzipSync, zipSync, strFromU8, strToU8 } from 'fflate'; import { isSvgDataUrl, svgToPngDataUrl } from '../import/imageFormats'; import { TEXTBOX_PADDING_CM } from '../editor/extensions/textBox'; -import { SHAPES, isShapeKind, drawingMlPath, type ShapeKind } from '../utils/shapes'; +import { SHAPES, isShapeKind, isLineKind, drawingMlPath, type ShapeKind } from '../utils/shapes'; import { cellFormatCode, isCellFormat } from '../utils/cellFormat'; import { DEFAULT_MARGINS, type PageMargins } from '../storage/pageMargins'; import type { Orientation } from '../storage/pageOrientation'; @@ -976,9 +976,12 @@ type TextBoxDocx = { function textBoxDocxDescriptor(node: TiptapNode): TextBoxDocx { const a = node.attrs ?? {}; const wrapAttr = a.wrap; + // A line has no box (see odt.ts): standing in the default height for a divider of + // none draws it across the frame's diagonal. + const line = isShapeKind(a.shapeKind) && isLineKind(a.shapeKind); return { widthPx: typeof a.width === 'number' && a.width > 0 ? Math.round(a.width) : 280, - heightPx: typeof a.height === 'number' && a.height > 0 ? Math.round(a.height) : 96, + heightPx: typeof a.height === 'number' && a.height > 0 ? Math.round(a.height) : line ? 0 : 96, rotationDeg: typeof a.rotation === 'number' ? a.rotation : 0, wrap: wrapAttr === 'left' || wrapAttr === 'right' || wrapAttr === 'topBottom' || wrapAttr === 'through' ? wrapAttr : 'inline', offsetCm: typeof a.wrapOffset === 'number' ? a.wrapOffset : null, diff --git a/src/lib/export/odt.ts b/src/lib/export/odt.ts index 16ed36a..3a85656 100644 --- a/src/lib/export/odt.ts +++ b/src/lib/export/odt.ts @@ -1001,9 +1001,12 @@ function textBoxDescriptor(node: TiptapNode): TextBoxExport { const pxToCm = (px: number) => round3((px * 2.54) / 96); const a = node.attrs ?? {}; const wrapAttr = a.wrap; + // A line has no box: a frame of no height is the horizontal divider both word + // processors write, and standing in the default for it draws a diagonal instead. + const line = isShapeKind(a.shapeKind) && isLineKind(a.shapeKind); return { widthCm: pxToCm(typeof a.width === 'number' && a.width > 0 ? a.width : 280), - heightCm: pxToCm(typeof a.height === 'number' && a.height > 0 ? a.height : 96), + heightCm: pxToCm(typeof a.height === 'number' && a.height > 0 ? a.height : line ? 0 : 96), rotationDeg: typeof a.rotation === 'number' ? a.rotation : 0, wrap: wrapAttr === 'left' || wrapAttr === 'right' || wrapAttr === 'topBottom' || wrapAttr === 'through' ? wrapAttr : 'inline', wrapOffsetCm: typeof a.wrapOffset === 'number' ? round3(a.wrapOffset) : null,