Skip to content

Commit

Permalink
Respect tab and sequence of space characters (#12)
Browse files Browse the repository at this point in the history
replace tab and multiple space characters with respective element
  • Loading branch information
connium authored Apr 29, 2018
1 parent 5188c81 commit b1099b2
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- **paragraph:** Add hyperlinks to a paragraph, closes [#5](https://github.com/connium/simple-odf/issues/5)
- **paragraph:** Add images to a paragraph, closes [#7](https://github.com/connium/simple-odf/issues/7)
- **paragraph:** Replace tab character with tab element, closes [#10](https://github.com/connium/simple-odf/issues/10)
- **paragraph:** Replace sequence of space characters with space element, closes [#10](https://github.com/connium/simple-odf/issues/10)

### Changed
- **general:** Full rewrite of the public API to use the terminology of the Open Document Format
Expand Down
2 changes: 2 additions & 0 deletions src/OdfElementName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ export enum OdfElementName {
TextList = "text:list",
TextListItem = "text:list-item",
TextParagraph = "text:p",
TextSpace = "text:s",
TextTabulation = "text:tab",
}
113 changes: 106 additions & 7 deletions src/text/OdfTextElement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { OdfElement } from "../OdfElement";
import { OdfElementName } from "../OdfElementName";

const SPACE = " ";

/**
* This class represents text in a paragraph.
*
Expand Down Expand Up @@ -43,16 +45,113 @@ export class OdfTextElement extends OdfElement {
return;
}

const lines = this.text.split("\n");
let str = "";
for (let index = 0; index < this.text.length; index++) {
const currentChar = this.text.charAt(index);
switch (currentChar) {
case SPACE:
str += currentChar;

for (let i = 0; i < lines.length; i++) {
if (i > 0) {
const lineBreak = document.createElement(OdfElementName.TextLineBreak);
parent.appendChild(lineBreak);
const count = this.findNextNonSpaceCharacter(this.text, index) - 1;
if (count > 0) {
this.appendTextNode(document, parent, str);
this.appendSpaceNode(document, parent, count);
str = "";
index += count;
}
break;
case "\n":
this.appendTextNode(document, parent, str);
this.appendLineBreakNode(document, parent);
str = "";
break;
case "\t":
this.appendTextNode(document, parent, str);
this.appendTabNode(document, parent);
str = "";
break;
default:
str += currentChar;
break;
}
}

this.appendTextNode(document, parent, str);
}

/**
* Creates a text node with the provided text and appends it to the parent element.
*
* @param {Document} document The XML document
* @param {Element} parent The parent node
* @param {string} text The text value of the text node
* @since 0.3.0
*/
private appendTextNode(document: Document, parent: Element, text: string): void {
if (text.length === 0) {
return;
}

const textNode = document.createTextNode(text);
parent.appendChild(textNode);
}

/**
* Creates a space node representing the specified number of space characters and appends it to the parent element.
* If a single space character should be represented, the `c` attribute is omitted.
*
* @param {Document} document The XML document
* @param {Element} parent The parent node
* @param {number} count The number of space characters the node should represent
* @since 0.3.0
*/
private appendSpaceNode(document: Document, parent: Element, count: number): void {
const space = document.createElement(OdfElementName.TextSpace);
parent.appendChild(space);

if (count > 1) {
space.setAttribute("c", count.toString(10));
}
}

/**
* Creates a tabulation node and appends it to the parent element.
*
* @param {Document} document The XML document
* @param {Element} parent The parent node
* @since 0.3.0
*/
private appendTabNode(document: Document, parent: Element): void {
const tabulation = document.createElement(OdfElementName.TextTabulation);
parent.appendChild(tabulation);
}

const textNode = document.createTextNode(lines[i]);
parent.appendChild(textNode);
/**
* Creates a line break node and appends it to the parent element.
*
* @param {Document} document The XML document
* @param {Element} parent The parent node
* @since 0.3.0
*/
private appendLineBreakNode(document: Document, parent: Element): void {
const lineBreak = document.createElement(OdfElementName.TextLineBreak);
parent.appendChild(lineBreak);
}

/**
* Finds the next non-space character and returns the number of space characters that occur before.
*
* @param {string} text The text to search in
* @param {number} offset The index at which to start the search
* @returns {number} The number of space characters before the next non-space character
* @since 0.3.0
*/
private findNextNonSpaceCharacter(text: string, offset: number): number {
for (let index = offset; index < text.length; index++) {
if (text.charAt(index) !== SPACE) {
return index - offset;
}
}
return text.length - offset;
}
}
13 changes: 13 additions & 0 deletions test/text/Paragraph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ describe(Paragraph.name, () => {
expect(document.toString()).toMatch(/<text:p>some text<text:line-break\/>some more text<\/text:p>/);
});

it("replace tab with tabulation", () => {
document.addParagraph("some\ttabbed\t\ttext");

expect(document.toString()).toMatch(/<text:p>some<text:tab\/>tabbed<text:tab\/><text:tab\/>text<\/text:p>/);
});

it("replace sequence of spaces with space node", () => {
document.addParagraph(" some spacey text ");

/* tslint:disable-next-line:max-line-length */
expect(document.toString()).toMatch(/<text:p> some <text:s\/>spacey <text:s c="2"\/>text <text:s c="3"\/><\/text:p>/);
});

describe("#addHyperlink", () => {
it("append a linked text", () => {
document.addParagraph("some text").addHyperlink(" some linked text", "http://example.org/");
Expand Down

0 comments on commit b1099b2

Please sign in to comment.