diff --git a/CHANGELOG.md b/CHANGELOG.md index 62a97a97..a67571cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - **style:** add common styles - **style:** allow page break to be before or after a paragraph, closes [#31](https://github.com/connium/simple-odf/issues/31) +- **style:** add keep-with-next flag - **docs:** add a realistic example ### Changed diff --git a/src/api/style/IParagraphProperties.ts b/src/api/style/IParagraphProperties.ts index 839d4762..5040f440 100644 --- a/src/api/style/IParagraphProperties.ts +++ b/src/api/style/IParagraphProperties.ts @@ -42,6 +42,21 @@ export interface IParagraphProperties { */ getKeepTogether (): boolean; + /** + * TODO + * + * @since 0.9.0 + */ + setKeepWithNext (keepWithNext?: boolean): void; + + /** + * TODO + * + * @returns {boolean} `true` TODO, `false` otherwise + * @since 0.9.0 + */ + getKeepWithNext (): boolean; + /** * Sets the page break setting of the paragraph. * diff --git a/src/api/style/ParagraphProperties.spec.ts b/src/api/style/ParagraphProperties.spec.ts index 90ec96b6..b936036b 100644 --- a/src/api/style/ParagraphProperties.spec.ts +++ b/src/api/style/ParagraphProperties.spec.ts @@ -39,6 +39,22 @@ describe(ParagraphProperties.name, () => { }); }); + describe('keep with next', () => { + it('return false by default', () => { + expect(properties.getKeepWithNext()).toBe(false); + }); + + it('return previously set state', () => { + properties.setKeepWithNext(); + + expect(properties.getKeepWithNext()).toBe(true); + + properties.setKeepWithNext(false); + + expect(properties.getKeepWithNext()).toBe(false); + }); + }); + describe('page break', () => { it('return None by default', () => { expect(properties.getPageBreak()).toBe(PageBreak.None); diff --git a/src/api/style/ParagraphProperties.ts b/src/api/style/ParagraphProperties.ts index 96b69b63..d89b3a5d 100644 --- a/src/api/style/ParagraphProperties.ts +++ b/src/api/style/ParagraphProperties.ts @@ -7,17 +7,20 @@ import { TabStop } from './TabStop'; const DEFAULT_HORIZONTAL_ALIGNMENT = HorizontalAlignment.Default; const DEFAULT_PAGE_BREAK = PageBreak.None; const DEFAULT_KEEP_TOGETHER = false; +const DEFAULT_KEEP_WITH_NEXT = false; export class ParagraphProperties implements IParagraphProperties { private horizontalAlignment: HorizontalAlignment; private pageBreak: PageBreak; private shouldKeepTogether: boolean; + private shouldKeepWithNext: boolean; private tabStops: TabStop[] = []; public constructor () { this.horizontalAlignment = DEFAULT_HORIZONTAL_ALIGNMENT; this.pageBreak = DEFAULT_PAGE_BREAK; this.shouldKeepTogether = DEFAULT_KEEP_TOGETHER; + this.shouldKeepWithNext = DEFAULT_KEEP_WITH_NEXT; } /** @inheritdoc */ @@ -40,6 +43,16 @@ export class ParagraphProperties implements IParagraphProperties { return this.shouldKeepTogether; } + /** @inheritdoc */ + setKeepWithNext (keepWithNext = true): void { + this.shouldKeepWithNext = keepWithNext; + } + + /** @inheritdoc */ + getKeepWithNext (): boolean { + return this.shouldKeepWithNext; + } + /** @inheritdoc */ public setPageBreak (pageBreak: PageBreak): void { this.pageBreak = pageBreak; diff --git a/src/api/style/ParagraphStyle.ts b/src/api/style/ParagraphStyle.ts index 6bb4d1e8..a8a721d5 100644 --- a/src/api/style/ParagraphStyle.ts +++ b/src/api/style/ParagraphStyle.ts @@ -49,6 +49,18 @@ export class ParagraphStyle extends Style implements IParagraphProperties, IText return this.paragraphProperties.getKeepTogether(); } + /** @inheritdoc */ + public setKeepWithNext (keepWithNext = true): ParagraphStyle { + this.paragraphProperties.setKeepWithNext(keepWithNext); + + return this; + } + + /** @inheritdoc */ + public getKeepWithNext (): boolean { + return this.paragraphProperties.getKeepWithNext(); + } + /** @inheritdoc */ public setPageBreak (pageBreak: PageBreak): ParagraphStyle { this.paragraphProperties.setPageBreak(pageBreak); diff --git a/src/xml/OdfAttributeName.ts b/src/xml/OdfAttributeName.ts index 736e268f..1cdcd89d 100644 --- a/src/xml/OdfAttributeName.ts +++ b/src/xml/OdfAttributeName.ts @@ -2,6 +2,7 @@ export enum OdfAttributeName { FormatBreakAfter = 'fo:break-after', FormatBreakBefore = 'fo:break-before', FormatKeepTogether = 'fo:keep-together', + FormatKeepWithNext = 'fo:keep-with-next', FormatColor = 'fo:color', FormatFontSize = 'fo:font-size', FormatFontStyle = 'fo:font-style', diff --git a/src/xml/office/StylesWriter.spec.ts b/src/xml/office/StylesWriter.spec.ts index b9e4a27d..7c757bf8 100644 --- a/src/xml/office/StylesWriter.spec.ts +++ b/src/xml/office/StylesWriter.spec.ts @@ -95,6 +95,15 @@ describe(StylesWriter.name, () => { expect(documentAsString).toMatch(//); }); + it('set keep with next', () => { + testStyle.setKeepWithNext(true); + + stylesWriter.write(commonStyles, testDocument, testRoot); + const documentAsString = new XMLSerializer().serializeToString(testDocument); + + expect(documentAsString).toMatch(//); + }); + it('set page break before', () => { testStyle.setPageBreak(PageBreak.Before); diff --git a/src/xml/office/StylesWriter.ts b/src/xml/office/StylesWriter.ts index f9816bbe..862ef938 100644 --- a/src/xml/office/StylesWriter.ts +++ b/src/xml/office/StylesWriter.ts @@ -76,6 +76,10 @@ export class StylesWriter { paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatKeepTogether, 'always'); } + if (style.getKeepWithNext() === true) { + paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatKeepWithNext, 'always'); + } + switch (style.getPageBreak()) { case PageBreak.Before: paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatBreakBefore, 'page'); diff --git a/test/integration.spec.ts b/test/integration.spec.ts index 3f7da528..bd252161 100644 --- a/test/integration.spec.ts +++ b/test/integration.spec.ts @@ -65,11 +65,19 @@ xdescribe('integration', () => { heading.setStyle(style); }); + it('keep with next', () => { + const style = new ParagraphStyle(); + style.setKeepWithNext(); + + const heading = body.addParagraph('Keep together with next paragraph'); + heading.setStyle(style); + }); + it('keep together', () => { const style = new ParagraphStyle(); style.setKeepTogether(); - const heading = body.addParagraph('Paragraph Formatting'); + const heading = body.addParagraph('Do\nnot\nsplit\nthis\nparagraph'); heading.setStyle(style); });