Skip to content

Commit

Permalink
feat: allow page break to be before or after a paragraph (#73)
Browse files Browse the repository at this point in the history
Fixes: #31 

BREAKING CHANGE: The `setPageBreakBefore()` and `getPageBreakBefore()` methods have been replaced with `setPageBreak()` and `getPageBreak()`.
  • Loading branch information
connium authored May 10, 2019
1 parent 95e93d7 commit 80f4d13
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] (2019-??-??)
### 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)
- **docs:** add a realistic example

### Changed
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ const document = new simpleOdf.TextDocument();
const body = document.getBody();

const image = body.addParagraph().addImage('/home/homer/myself.png');
image.getStyle().setAnchorType(simpleOdf.AnchorType.AsChar);
image.getStyle().setSize(29.4, 36.5);
image.setAnchorType(simpleOdf.AnchorType.AsChar);
image.setSize(29.4, 36.5);

body.addHeading('Welcome to simple-odf');

Expand All @@ -60,7 +60,7 @@ style1.setTextTransformation(simpleOdf.TextTransformation.Uppercase);
style1.setTypeface(simpleOdf.Typeface.Bold);
// paragraph formatting
style1.setHorizontalAlignment(simpleOdf.HorizontalAlignment.Center);
style1.setPageBreakBefore();
style1.setPageBreak(simpleOdf.PageBreak.Before);
style1.setKeepTogether();
p1.setStyle(style1);
// font usage
Expand Down
2 changes: 1 addition & 1 deletion src/api/office/AutomaticStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class AutomaticStyles implements IStyles {
// paragraph properties
hash.update(paragraphStyle.getHorizontalAlignment());
hash.update(paragraphStyle.getKeepTogether() ? 'kt' : '');
hash.update(paragraphStyle.getPageBreakBefore() ? 'pbb' : '');
hash.update(paragraphStyle.getPageBreak().toString());
paragraphStyle.getTabStops().forEach((tabStop) => {
hash.update(`tab${tabStop.getPosition()}${tabStop.getType()}`);
});
Expand Down
30 changes: 24 additions & 6 deletions src/api/style/IParagraphProperties.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HorizontalAlignment } from './HorizontalAlignment';
import { PageBreak } from './PageBreak';
import { TabStop } from './TabStop';
import { TabStopType } from './TabStopType';

Expand Down Expand Up @@ -27,18 +28,35 @@ export interface IParagraphProperties {
getHorizontalAlignment (): HorizontalAlignment;

/**
* Inserts a new page break to the document before the corresponding element.
* Keeps paragraph lines on the same page (page break before paragraph if necessary).
*
* @since 0.1.0
* @since 0.6.0
*/
setPageBreakBefore (shouldBreakPageBefore?: boolean): void;
setKeepTogether (keepTogether?: boolean): void;

/**
* Keeps paragraph lines on the same page (page break before paragraph if necessary).
* Returns whether the lines of the paragraph should be kept together.
*
* @since 0.6.0
* @returns {boolean} `true` if the paragraph lines should be kept together, `false` otherwise
* @since 0.9.0
*/
setKeepTogether (keepTogether?: boolean): void;
getKeepTogether (): boolean;

/**
* Sets the page break setting of the paragraph.
*
* @param {PageBreak} pageBreak The page break setting
* @since 0.9.0
*/
setPageBreak (pageBreak: PageBreak): void;

/**
* Returns the page break setting of the paragraph.
*
* @returns {PageBreak} The page break setting
* @since 0.9.0
*/
getPageBreak (): PageBreak;

/**
* Adds a new tab stop to this style.
Expand Down
5 changes: 5 additions & 0 deletions src/api/style/PageBreak.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum PageBreak {
None,
Before,
After
}
13 changes: 7 additions & 6 deletions src/api/style/ParagraphProperties.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HorizontalAlignment } from './HorizontalAlignment';
import { PageBreak } from './PageBreak';
import { ParagraphProperties } from './ParagraphProperties';
import { TabStop } from './TabStop';
import { TabStopType } from './TabStopType';
Expand Down Expand Up @@ -39,18 +40,18 @@ describe(ParagraphProperties.name, () => {
});

describe('page break', () => {
it('return false by default', () => {
expect(properties.getPageBreakBefore()).toBe(false);
it('return None by default', () => {
expect(properties.getPageBreak()).toBe(PageBreak.None);
});

it('return previously set state', () => {
properties.setPageBreakBefore();
properties.setPageBreak(PageBreak.Before);

expect(properties.getPageBreakBefore()).toBe(true);
expect(properties.getPageBreak()).toBe(PageBreak.Before);

properties.setPageBreakBefore(false);
properties.setPageBreak(PageBreak.After);

expect(properties.getPageBreakBefore()).toBe(false);
expect(properties.getPageBreak()).toBe(PageBreak.After);
});
});

Expand Down
15 changes: 8 additions & 7 deletions src/api/style/ParagraphProperties.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { HorizontalAlignment } from './HorizontalAlignment';
import { IParagraphProperties } from './IParagraphProperties';
import { PageBreak } from './PageBreak';
import { TabStopType } from './TabStopType';
import { TabStop } from './TabStop';

const DEFAULT_HORIZONTAL_ALIGNMENT = HorizontalAlignment.Default;
const DEFAULT_PAGE_BREAK = false;
const DEFAULT_PAGE_BREAK = PageBreak.None;
const DEFAULT_KEEP_TOGETHER = false;

export class ParagraphProperties implements IParagraphProperties {
private horizontalAlignment: HorizontalAlignment;
private shouldBreakPageBefore: boolean;
private pageBreak: PageBreak;
private shouldKeepTogether: boolean;
private tabStops: TabStop[] = [];

public constructor () {
this.horizontalAlignment = DEFAULT_HORIZONTAL_ALIGNMENT;
this.shouldBreakPageBefore = DEFAULT_PAGE_BREAK;
this.pageBreak = DEFAULT_PAGE_BREAK;
this.shouldKeepTogether = DEFAULT_KEEP_TOGETHER;
}

Expand All @@ -40,13 +41,13 @@ export class ParagraphProperties implements IParagraphProperties {
}

/** @inheritdoc */
public setPageBreakBefore (shouldBreakPageBefore = true): void {
this.shouldBreakPageBefore = shouldBreakPageBefore;
public setPageBreak (pageBreak: PageBreak): void {
this.pageBreak = pageBreak;
}

/** @inheritdoc */
public getPageBreakBefore (): boolean {
return this.shouldBreakPageBefore;
public getPageBreak (): PageBreak {
return this.pageBreak;
}

/** @inheritdoc */
Expand Down
9 changes: 5 additions & 4 deletions src/api/style/ParagraphStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Color } from './Color';
import { HorizontalAlignment } from './HorizontalAlignment';
import { IParagraphProperties } from './IParagraphProperties';
import { ITextProperties } from './ITextProperties';
import { PageBreak } from './PageBreak';
import { ParagraphProperties } from './ParagraphProperties';
import { Style } from './Style';
import { StyleFamily } from './StyleFamily';
Expand Down Expand Up @@ -49,15 +50,15 @@ export class ParagraphStyle extends Style implements IParagraphProperties, IText
}

/** @inheritdoc */
public setPageBreakBefore (shouldBreakPageBefore = true): ParagraphStyle {
this.paragraphProperties.setPageBreakBefore(shouldBreakPageBefore);
public setPageBreak (pageBreak: PageBreak): ParagraphStyle {
this.paragraphProperties.setPageBreak(pageBreak);

return this;
}

/** @inheritdoc */
public getPageBreakBefore (): boolean {
return this.paragraphProperties.getPageBreakBefore();
public getPageBreak (): PageBreak {
return this.paragraphProperties.getPageBreak();
}

/** @inheritdoc */
Expand Down
1 change: 1 addition & 0 deletions src/api/style/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { FontFace } from './FontFace';
export { FontFamilyGeneric } from './FontFamilyGeneric';
export { FontPitch } from './FontPitch';
export { HorizontalAlignment } from './HorizontalAlignment';
export { PageBreak } from './PageBreak';
export { ParagraphProperties } from './ParagraphProperties';
export { ParagraphStyle } from './ParagraphStyle';
export { Style } from './Style';
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { FontFace } from './api/style/FontFace';
export { FontFamilyGeneric } from './api/style/FontFamilyGeneric';
export { FontPitch } from './api/style/FontPitch';
export { HorizontalAlignment } from './api/style/HorizontalAlignment';
export { PageBreak } from './api/style/PageBreak';
export { ParagraphStyle } from './api/style/ParagraphStyle';
export { Style } from './api/style/Style';
export { StyleFamily } from './api/style/StyleFamily';
Expand Down
1 change: 1 addition & 0 deletions src/xml/OdfAttributeName.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum OdfAttributeName {
FormatBreakAfter = 'fo:break-after',
FormatBreakBefore = 'fo:break-before',
FormatKeepTogether = 'fo:keep-together',
FormatColor = 'fo:color',
Expand Down
15 changes: 12 additions & 3 deletions src/xml/office/StylesWriter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DOMImplementation, XMLSerializer } from 'xmldom';
import { CommonStyles, AutomaticStyles } from '../../api/office';
import { Color, HorizontalAlignment, ParagraphStyle, TextTransformation, Typeface, TabStop } from '../../api/style';
import { Color, HorizontalAlignment, PageBreak, ParagraphStyle, TextTransformation, Typeface } from '../../api/style';
// tslint:disable-next-line:no-duplicate-imports
import { TabStopType } from '../../api/style';
import { TabStop, TabStopType } from '../../api/style';
import { OdfElementName } from '../OdfElementName';
import { StylesWriter } from './StylesWriter';

Expand Down Expand Up @@ -96,14 +96,23 @@ describe(StylesWriter.name, () => {
});

it('set page break before', () => {
testStyle.setPageBreakBefore(true);
testStyle.setPageBreak(PageBreak.Before);

stylesWriter.write(commonStyles, testDocument, testRoot);
const documentAsString = new XMLSerializer().serializeToString(testDocument);

expect(documentAsString).toMatch(/<style:paragraph-properties fo:break-before="page"\/>/);
});

it('set page break after', () => {
testStyle.setPageBreak(PageBreak.After);

stylesWriter.write(commonStyles, testDocument, testRoot);
const documentAsString = new XMLSerializer().serializeToString(testDocument);

expect(documentAsString).toMatch(/<style:paragraph-properties fo:break-after="page"\/>/);
});

it('set tab stops', () => {
testStyle.addTabStop(new TabStop(2, TabStopType.Center));
testStyle.addTabStop(new TabStop(4, TabStopType.Char));
Expand Down
13 changes: 10 additions & 3 deletions src/xml/office/StylesWriter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AutomaticStyles, CommonStyles, IStyles } from '../../api/office';
import { HorizontalAlignment, ParagraphStyle, Style, StyleFamily, TabStopType } from '../../api/style';
import { HorizontalAlignment, ParagraphStyle, Style, StyleFamily, TabStopType, PageBreak } from '../../api/style';
// tslint:disable-next-line:no-duplicate-imports
import { TextTransformation, Typeface } from '../../api/style';
import { OdfAttributeName } from '../OdfAttributeName';
Expand Down Expand Up @@ -76,8 +76,15 @@ export class StylesWriter {
paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatKeepTogether, 'always');
}

if (style.getPageBreakBefore() === true) {
paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatBreakBefore, 'page');
switch (style.getPageBreak()) {
case PageBreak.Before:
paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatBreakBefore, 'page');
break;
case PageBreak.After:
paragraphPropertiesElement.setAttribute(OdfAttributeName.FormatBreakAfter, 'page');
break;
default:
break;
}

const tabStops = style.getTabStops();
Expand Down
12 changes: 6 additions & 6 deletions test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { join } from 'path';
import { promisify } from 'util';
import { AnchorType } from '../src/api/draw';
import { TextBody, TextDocument } from '../src/api/office';
import { Color, FontPitch, HorizontalAlignment, ParagraphStyle, TabStop, TabStopType } from '../src/api/style';
import { TextTransformation, Typeface } from '../src/api/style';
import { Color, FontPitch, HorizontalAlignment, PageBreak, ParagraphStyle, TabStop } from '../src/api/style';
import { TabStopType, TextTransformation, Typeface } from '../src/api/style';

const FILEPATH = './integration.fodt';

Expand Down Expand Up @@ -59,7 +59,7 @@ xdescribe('integration', () => {
describe('paragraph formatting', () => {
it('page break', () => {
const style = new ParagraphStyle();
style.setPageBreakBefore();
style.setPageBreak(PageBreak.Before);

const heading = body.addHeading('Paragraph Formatting', 2);
heading.setStyle(style);
Expand Down Expand Up @@ -94,7 +94,7 @@ xdescribe('integration', () => {
describe('text formatting', () => {
beforeAll(() => {
const style = new ParagraphStyle();
style.setPageBreakBefore();
style.setPageBreak(PageBreak.Before);

const heading = body.addHeading('Text Formatting', 2);
heading.setStyle(style);
Expand Down Expand Up @@ -145,7 +145,7 @@ xdescribe('integration', () => {

it('hyperlink', () => {
const style = new ParagraphStyle();
style.setPageBreakBefore();
style.setPageBreak(PageBreak.Before);

const heading = body.addHeading('Hyperlink', 2);
heading.setStyle(style);
Expand All @@ -157,7 +157,7 @@ xdescribe('integration', () => {

it('list', () => {
const style = new ParagraphStyle();
style.setPageBreakBefore();
style.setPageBreak(PageBreak.Before);

const heading = body.addHeading('List', 2);
heading.setStyle(style);
Expand Down

0 comments on commit 80f4d13

Please sign in to comment.