From bd6e68a73b17363f4fcfcb6afe68c0894dfa09f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 24 Sep 2015 09:02:25 +0200 Subject: [PATCH 01/16] Fix default Unicode alternate skip count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the Word2007 RTF specs page 18 for control word \ucN, the default value is to skip one byte after a Unicode character. I was reading weird ‚?‘ characters after German Umlauts, until I understood what the problem is. This RTF does not contain the \ucN control word anywhere, but relies on the default. --- .../src/com/rtfparserkit/parser/standard/ParserState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/standard/ParserState.java b/RTF Parser Kit/src/com/rtfparserkit/parser/standard/ParserState.java index 057e4d8..4fe7b3f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/standard/ParserState.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/standard/ParserState.java @@ -37,5 +37,5 @@ public ParserState(ParserState state) public int currentFont; public String currentEncoding; public String currentFontEncoding; - public int unicodeAlternateSkipCount; + public int unicodeAlternateSkipCount = 1; } From 33a4ca9c36b8934e03e9a7df465bc9ee93ae42a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 1 Oct 2015 10:14:52 +0200 Subject: [PATCH 02/16] Initial document model and document building parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a package „document“ which defines a bunch of basic interfaces which represent aspects of an RTF document. DocumentPart refers to an object that can contain paragraphs of styled text. There are currently three areas of the document supported: The Header, Footer and the document itself. The document is divided into Sections, which is a concept supported by RTF and many text editing applications. Global formatting properties can change at section breaks. Furthermore, the Document contains a ColorTable, FontTable, StyleSheet and DocumentSettings. The idea is that code that works with the document model gets an instance of a Document and can get instances of all the other interfaces from the document instance. There is an implementation of all interfaces in the package document.impl. The classes sometimes offer additional functionality, but in the last iterations of changes, I have eliminated the need for that by moving functionality into the interfaces. In the package parser.builder, there is a new RtfListener implementation called DocumentBuilder. The DocumentBuilder is created with an instance of Document. Then it is passed to the StandardParser.parse() method. The idea behind DocumentBuilder is that it maintains a stack of RtfContext instances and delegates all events to the currently active context. RtfContext has an interface almost exactly like RtfListener, except there is an additional processGroupStart() method version which has the same parameters as processCommand(). The reason is that some RTF groups start with a specific command and denote an RTF „destination“. DocumentBuilder has therefore the notion of a „delayed group start“. In processGroupStart() it will only mark that it is currently at a group start, but does nothing further yet. In processCommand() it will try to form a command based group start when it encounters a destination command. Otherwise it will just process the delayed group start before processing any other events. Various RtfContext implementations exist which can already process events to build many parts of the document model. --- .../src/com/rtfparserkit/document/Chunk.java | 18 + .../src/com/rtfparserkit/document/Color.java | 18 + .../com/rtfparserkit/document/ColorTable.java | 18 + .../com/rtfparserkit/document/Document.java | 25 ++ .../rtfparserkit/document/DocumentPart.java | 23 ++ .../document/DocumentSettings.java | 14 + .../src/com/rtfparserkit/document/Font.java | 18 + .../com/rtfparserkit/document/FontTable.java | 28 ++ .../src/com/rtfparserkit/document/Footer.java | 12 + .../src/com/rtfparserkit/document/Header.java | 12 + .../rtfparserkit/document/PageSettings.java | 24 ++ .../com/rtfparserkit/document/Paragraph.java | 18 + .../com/rtfparserkit/document/Section.java | 23 ++ .../src/com/rtfparserkit/document/Style.java | 124 ++++++ .../com/rtfparserkit/document/StyleSheet.java | 17 + .../document/impl/DefaultChunk.java | 34 ++ .../document/impl/DefaultColor.java | 49 +++ .../document/impl/DefaultColorTable.java | 28 ++ .../document/impl/DefaultDocument.java | 116 ++++++ .../document/impl/DefaultFont.java | 39 ++ .../document/impl/DefaultFontTable.java | 29 ++ .../document/impl/DefaultFooter.java | 15 + .../document/impl/DefaultHeader.java | 15 + .../document/impl/DefaultParagraph.java | 108 +++++ .../document/impl/DefaultSection.java | 79 ++++ .../document/impl/DefaultStyle.java | 372 ++++++++++++++++++ .../document/impl/DefaultStyleSheet.java | 29 ++ .../document/impl/PageMargins.java | 15 + .../rtfparserkit/document/impl/PageSize.java | 13 + .../document/impl/ParagraphList.java | 149 +++++++ .../document/impl/SectionList.java | 89 +++++ .../parser/builder/AbstractRtfContext.java | 56 +++ .../parser/builder/ColorTableContext.java | 56 +++ .../parser/builder/DocumentBuilder.java | 105 +++++ .../parser/builder/DocumentContext.java | 89 +++++ .../parser/builder/DocumentPartContext.java | 245 ++++++++++++ .../builder/DocumentSettingsContext.java | 47 +++ .../parser/builder/FontContext.java | 116 ++++++ .../parser/builder/FontTableContext.java | 33 ++ .../parser/builder/NullContext.java | 45 +++ .../parser/builder/RootContext.java | 42 ++ .../parser/builder/RtfContext.java | 30 ++ .../parser/builder/RtfContextStack.java | 40 ++ .../document/ParagraphListTest.java | 59 +++ .../rtfparserkit/document/ParagraphTest.java | 95 +++++ .../parser/builder/BuilderParseTest.java | 111 ++++++ .../parser/builder/data/lineSeparator.rtf | 1 + .../parser/builder/data/variousStyles.rtf | 26 ++ .../builder/data/variousStylesGrouped.rtf | 26 ++ .../builder/data/variousStylesPages.rtf | 43 ++ 50 files changed, 2836 insertions(+) create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Color.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Document.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Font.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Footer.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Header.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Section.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Style.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java create mode 100644 RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java create mode 100644 RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/lineSeparator.rtf create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStyles.rtf create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesGrouped.rtf create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesPages.rtf diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java new file mode 100644 index 0000000..60dae04 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java @@ -0,0 +1,18 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * A chunk of text with a certain style. + * + * @author stippi + */ +public interface Chunk { + + public String getString(); + + public Style getStyle(); + + public void append(String string); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Color.java b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java new file mode 100644 index 0000000..f145d79 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java @@ -0,0 +1,18 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * + * @author stippi + */ +public interface Color { + + public int getRed(); + + public int getGreen(); + + public int getBlue(); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java new file mode 100644 index 0000000..5009d86 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java @@ -0,0 +1,18 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for adding a color to the global color table. + * + * @author stippi + */ +public interface ColorTable { + + public void addColor(int red, int green, int blue); + + public int countColors(); + + public Color colorAt(int index); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Document.java b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java new file mode 100644 index 0000000..3b4f113 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java @@ -0,0 +1,25 @@ +package com.rtfparserkit.document; + +/** + * Interface for getting to all relevant parts of the document model. + * + * @author stippi + */ +public interface Document extends DocumentPart { + + public FontTable getFontTable(); + + public ColorTable getColorTable(); + + public StyleSheet getStyleSheet(); + + public DocumentSettings getDocumentSettings(); + + public int countSections(); + + public Section sectionAt(int index); + + public void nextSection(); + + public Section getLastSection(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java new file mode 100644 index 0000000..7fd3341 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java @@ -0,0 +1,23 @@ +package com.rtfparserkit.document; + +/** + * Interface for appending text to a destination. + * + * @author stippi + */ +public interface DocumentPart { + + public String getText(); + + public int countParagraphs(); + + public Paragraph paragraphAt(int index); + + public void append(String text, Style style); + + public void nextParagraph(Style lastStyle); + + public void nextLine(); + + public Style createDefaultStyle(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java new file mode 100644 index 0000000..3d46192 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java @@ -0,0 +1,14 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for controlling global settings of the document. + * + * @author stippi + */ +public interface DocumentSettings { + + public PageSettings getPageSettings(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Font.java b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java new file mode 100644 index 0000000..b4b25a0 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java @@ -0,0 +1,18 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Simple interface for storing font information. + * + * @author stippi + */ +public interface Font { + + public void setName(String name); + + public String getName(); + + public boolean equals(Font other); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java new file mode 100644 index 0000000..7e7edf0 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java @@ -0,0 +1,28 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for adding a font definition to the global font table. + * + * @author stippi + */ +public interface FontTable { + + public enum FontFamily { + DEFAULT, + ROMAN, + SWISS, + MODERN, + SCRIPT, + DECOR, + TECH, + BIDI + } + + public void addFont(String name, String alternativeName, String fileName, + FontFamily fontFamily); + + public Font getFont(int index); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java new file mode 100644 index 0000000..c0b4d0a --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java @@ -0,0 +1,12 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * + * @author stippi + */ +public interface Footer extends DocumentPart { + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Header.java b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java new file mode 100644 index 0000000..4ba3cca --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java @@ -0,0 +1,12 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * + * @author stippi + */ +public interface Header extends DocumentPart { + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java new file mode 100644 index 0000000..5fd4932 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java @@ -0,0 +1,24 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for controlling page settings + * + * @author stippi + */ +public interface PageSettings { + + public void setPageMarginLeft(int value); + + public void setPageMarginRight(int value); + + public void setPageMarginTop(int value); + + public void setPageMarginBottom(int value); + + public void setPageWidth(int value); + + public void setPageHeight(int value); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java new file mode 100644 index 0000000..baace2d --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java @@ -0,0 +1,18 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for paragraph functionality. + * + * @author stippi + */ +public interface Paragraph extends Iterable { + + public String getText(); + + public int countChunks(); + + public Chunk chunkAt(int index); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Section.java b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java new file mode 100644 index 0000000..af25ee3 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java @@ -0,0 +1,23 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for starting a new section in a document. A section can have + * its own paper settings (for example orientation and margins). + * + * @author stippi + */ +public interface Section extends DocumentPart { + + public Header createHeader(); + + public Footer createFooter(); + + public Header getHeader(); + + public Footer getFooter(); + + public PageSettings getPageSettings(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java new file mode 100644 index 0000000..09f80a6 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java @@ -0,0 +1,124 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for setting style parameters. + * + * @author stippi + */ +public interface Style { + + public enum Alignment { + LEFT, + RIGHT, + CENTER, + JUSTIFIED, + DISTRIBUTED, + } + + public enum TabAlignment { + LEFT, + CENTER, + RIGHT, + DECIMAL, + } + + public enum UnderlineStyle { + NONE, + SINGLE, + DOUBLE, + WORD, + DOTTED, + DASHED, + DASH_DOTTED, + DASH_DOT_DOTTED, + LONG_DASHED, + THICK, + THICK_DOTTED, + THICK_DASHED, + THICK_DASH_DOTTED, + THICK_DASH_DOT_DOTTED, + THICK_LONG_DASHED, + WAVE, + HEAVY_WAVE, + DOUBLE_WAVE + } + + public void resetToDefaults(); + + public void resetFontToDefaults(); + + public Style createDerivedStyle(); + + public Style createFlattenedStyle(); + + public boolean equals(Style other); + + public void setAlignment(Alignment alignment); + + public Alignment getAlignment(); + + public void setSpacingTop(float value); + + public float getSpacingTop(); + + public void setSpacingBottom(float value); + + public float getSpacingBottom(); + + public void setFirstLineIndent(float value); + + public float getFirstLineIndent(); + + public void setLeftIndent(float value); + + public float getLeftIndent(); + + public void setRightIndent(float value); + + public float getRightIndent(); + + public void setLineSpacing(float value); + + public float getLineSpacing(); + + public void addTab(float position, TabAlignment aligment); + + public void setFont(Font font); + + public Font getFont(); + + public void setFontSize(float value); + + public float getFontSize(); + + public void setBold(boolean bold); + + public boolean getBold(); + + public void setItalic(boolean italic); + + public boolean getItalic(); + + public void setUnderlined(UnderlineStyle style); + + public UnderlineStyle getUnderlined(); + + public void setStrikeOut(boolean strikeOut); + + public boolean getStrikeOut(); + + public void setCaps(boolean caps); + + public boolean getCaps(); + + public void setBackgroundColor(Color color); + + public Color getBackgroundColor(); + + public void setForegroundColor(Color color); + + public Color getForegroundColor(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java new file mode 100644 index 0000000..aaac4be --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java @@ -0,0 +1,17 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +/** + * Interface for adding a style definition to a global style sheet. + * + * @author stippi + */ +public interface StyleSheet { + + public Style addStyle(); + + public Style get(int index); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java new file mode 100644 index 0000000..e9fb2c5 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -0,0 +1,34 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.Style; + +/** + * Default Chunk implementation. + * + * @author stippi + */ +public class DefaultChunk implements Chunk { + private final StringBuilder stringBuilder; + private final Style style; + + public DefaultChunk(Style style) { + stringBuilder = new StringBuilder(); + this.style = style; + } + + public String getString() { + return stringBuilder.toString(); + } + + public Style getStyle() { + return style; + } + + public void append(String string) { + stringBuilder.append(string); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java new file mode 100644 index 0000000..d3f704f --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java @@ -0,0 +1,49 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Color; + +/** + * + * @author stippi + */ +public class DefaultColor implements Color { + + private final int red; + private final int green; + private final int blue; + + static final DefaultColor BLACK = new DefaultColor(0, 0, 0); + static final DefaultColor WHITE = new DefaultColor(255, 255, 255); + + public DefaultColor(int red, int green, int blue) { + this.red = red; + this.green = green; + this.blue = blue; + } + + public DefaultColor(Color other) { + this.red = other.getRed(); + this.green = other.getGreen(); + this.blue = other.getBlue(); + } + + public int getRed() { + return red; + } + + public int getGreen() { + return green; + } + + public int getBlue() { + return blue; + } + + @Override + public String toString() { + return "(r" + red + "g" + green + "b" + blue + ")"; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java new file mode 100644 index 0000000..af81889 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java @@ -0,0 +1,28 @@ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.List; + +import com.rtfparserkit.document.Color; +import com.rtfparserkit.document.ColorTable; + +public class DefaultColorTable implements ColorTable { + + private final List colors; + + public DefaultColorTable() { + colors = new ArrayList(); + } + + public void addColor(int red, int green, int blue) { + colors.add(new DefaultColor(red, green, blue)); + } + + public int countColors() { + return colors.size(); + } + + public Color colorAt(int index) { + return colors.get(index); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java new file mode 100644 index 0000000..7c8ce40 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -0,0 +1,116 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Document; +import com.rtfparserkit.document.DocumentSettings; +import com.rtfparserkit.document.PageSettings; +import com.rtfparserkit.document.Paragraph; +import com.rtfparserkit.document.Section; +import com.rtfparserkit.document.Style; + +/** + * + * @author stippi + */ +public class DefaultDocument extends SectionList implements Document { + + private final DefaultColorTable colors = new DefaultColorTable(); + private final DefaultFontTable fonts = new DefaultFontTable(); + private final DefaultStyleSheet styles = new DefaultStyleSheet(); + + private final PageMargins pageMargins = new PageMargins(); + private final PageSize pageSize = new PageSize(); + + public DefaultFontTable getFontTable() { + return fonts; + } + + public DefaultColorTable getColorTable() { + return colors; + } + + public DefaultStyleSheet getStyleSheet() { + return styles; + } + + public PageMargins getPageMargins() { + return pageMargins; + } + + public PageSize getPageSize() { + return pageSize; + } + + public DocumentSettings getDocumentSettings() { + return new DocumentSettings() { + + public PageSettings getPageSettings() { + return new PageSettings() { + public void setPageMarginLeft(int value) { + pageMargins.left = value; + } + + public void setPageMarginRight(int value) { + pageMargins.right = value; + } + + public void setPageMarginTop(int value) { + pageMargins.top = value; + } + + public void setPageMarginBottom(int value) { + pageMargins.bottom = value; + } + + public void setPageWidth(int value) { + pageSize.width = value; + } + + public void setPageHeight(int value) { + pageSize.height = value; + } + }; + } + }; + } + + public void append(String text, Style style) { + getLastSection().append(text, style); + } + + public void nextParagraph(Style lastStyle) { + getLastSection().nextParagraph(lastStyle); + } + + public void nextLine() { + getLastSection().nextLine(); + } + + public Style createDefaultStyle() { + return getLastSection().createDefaultStyle(); + } + + public int countParagraphs() { + int count = 0; + for (Section section : this) + count += section.countParagraphs(); + return count; + } + + public Paragraph paragraphAt(int index) { + int originalIndex = index; + for (Section section : this) { + int paragrapgsInSection = section.countParagraphs(); + if (index > paragrapgsInSection) { + index -= paragrapgsInSection; + continue; + } + return section.paragraphAt(index); + } + + throw new IndexOutOfBoundsException("paragraphs in section: " + + countParagraphs() + ", requested index: " + originalIndex); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java new file mode 100644 index 0000000..bd05d97 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Font; + +/** + * Default Font implementation + * + * @author stippi + */ +public class DefaultFont implements Font { + private String name; + + public DefaultFont(String fontName) { + name = fontName; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equals(Font object) { + if (object == this) + return true; + if (object == null || object.getClass() != DefaultFont.class) + return false; + DefaultFont other = (DefaultFont) object; + return name.equals(other.name); + } + + // TODO: Hold all necessary data. + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java new file mode 100644 index 0000000..f8a7a3d --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -0,0 +1,29 @@ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.List; + +import com.rtfparserkit.document.Font; +import com.rtfparserkit.document.FontTable; + +public class DefaultFontTable implements FontTable { + + private final List fonts; + + public DefaultFontTable() { + fonts = new ArrayList(); + } + + public void addFont(String name, String alternativeName, String fileName, + FontFamily fontFamily) { + fonts.add(new DefaultFont(name)); + } + + public int countFonts() { + return fonts.size(); + } + + public Font getFont(int index) { + return fonts.get(index); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java new file mode 100644 index 0000000..20f98ec --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java @@ -0,0 +1,15 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Footer; + + +/** + * + * @author stippi + */ +public class DefaultFooter extends ParagraphList implements Footer { + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java new file mode 100644 index 0000000..9d8c848 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java @@ -0,0 +1,15 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Header; + + +/** + * + * @author stippi + */ +public class DefaultHeader extends ParagraphList implements Header { + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java new file mode 100644 index 0000000..cd393dc --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -0,0 +1,108 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.Paragraph; +import com.rtfparserkit.document.Style; + +/** + * A Paragraph contains text which is formed by chunks. + * + * @author stippi + */ +public class DefaultParagraph implements Iterable, Paragraph { + private final List chunks; + + public DefaultParagraph() { + chunks = new ArrayList(); + } + + public Iterator iterator() { + return chunks.iterator(); + } + + public String getText() { + StringBuilder builder = new StringBuilder(); + for (Chunk chunk : chunks) + builder.append(chunk.getString()); + return builder.toString(); + } + + public int countChunks() { + return chunks.size(); + } + + public Chunk chunkAt(int index) { + return chunks.get(index); + } + + public void append(Chunk chunk) { + if (chunk == null) + throw new IllegalArgumentException("Chunk may not be null"); + chunks.add(chunk); + } + + public Chunk getLastChunk() { + if (chunks.size() > 0) + return chunks.get(chunks.size() - 1); + return null; + } + + public void append(String string) { + Style style; + Chunk defaultChunk = getLastChunk(); + if (defaultChunk == null) + style = new DefaultStyle(); + else + style = defaultChunk.getStyle(); + append(string, style); + } + + public void append(String string, Style style) { + if (string == null) + throw new IllegalArgumentException("String may not be null!"); + if (style == null) + throw new IllegalArgumentException("Style may not be null!"); + int firstLineBreak = string.indexOf('\n'); + if (firstLineBreak >= 0 && firstLineBreak != string.length() - 1) { + throw new IllegalArgumentException("String must not contain a " + + "line-break (\\n) unless right at the end."); + } + assertNotDelimited(); + appendString(string, style); + } + + /** + * Makes sure that the paragraph doesn't already end with '\n'. + */ + private void assertNotDelimited() { + Chunk last = getLastChunk(); + if (last != null && last.getString().endsWith("\n")) { + throw new IllegalArgumentException( + "Paragraph is already delimited."); + } + } + + public void end() { + end(new DefaultStyle()); + } + + public void end(Style lastStyle) { + append("\n", lastStyle); + } + + private void appendString(String string, Style style) { + Chunk chunk = getLastChunk(); + if (chunk == null || !chunk.getStyle().equals(style)) { + chunk = new DefaultChunk(style); + append(chunk); + } + chunk.append(string); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java new file mode 100644 index 0000000..5c00426 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java @@ -0,0 +1,79 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.Footer; +import com.rtfparserkit.document.Header; +import com.rtfparserkit.document.PageSettings; +import com.rtfparserkit.document.Section; + +/** + * + * @author stippi + */ +public class DefaultSection extends ParagraphList implements Section { + + private DefaultHeader header; + private DefaultFooter footer; + private final PageMargins pageMargins = new PageMargins(); + private final PageSize pageSize = new PageSize(); + + public Header createHeader() { + if (header == null) + header = new DefaultHeader(); + return header; + } + + public Header getHeader() { + return header; + } + + public Footer createFooter() { + if (footer == null) + footer = new DefaultFooter(); + return footer; + } + + public Footer getFooter() { + return footer; + } + + public PageMargins getPageMargins() { + return pageMargins; + } + + public PageSize getPageSize() { + return pageSize; + } + + public PageSettings getPageSettings() { + return new PageSettings() { + + public void setPageMarginLeft(int value) { + pageMargins.left = value; + } + + public void setPageMarginRight(int value) { + pageMargins.right = value; + } + + public void setPageMarginTop(int value) { + pageMargins.top = value; + } + + public void setPageMarginBottom(int value) { + pageMargins.bottom = value; + } + + public void setPageWidth(int value) { + pageSize.width = value; + } + + public void setPageHeight(int value) { + pageSize.height = value; + } + }; + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java new file mode 100644 index 0000000..3b4c7fd --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java @@ -0,0 +1,372 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import java.util.EnumSet; + +import com.rtfparserkit.document.Color; +import com.rtfparserkit.document.Font; +import com.rtfparserkit.document.Style; + +/** + * Default Style implementation + * + * @author stippi + */ +public class DefaultStyle implements Style { + + public enum Property { + ALIGNMENT, SPACING_TOP, SPACING_BOTTOM, FIRST_LINE_INDENT, LEFT_INDENT, + RIGHT_INDENT, LINE_SPACING, TABS, FONT, FONT_SIZE, BOLD, ITALIC, + UNDERLINED, STRIKE_OUT, CAPS, BACKGROUND_COLOR, FOREGROUND_COLOR + } + + private final Style parent; + private EnumSet overriddenProperties; + + private Alignment alignment; + private float spacingTop; + private float spacingBottom; + private float firstLineIndent; + private float leftIndent; + private float rightIndent; + private float lineSpacing; + private Font font; + private float fontSize; + // TODO: ... + private boolean bold; + private boolean italic; + private UnderlineStyle underlineStyle; + private boolean strikeOut; + private boolean caps; + private Color backgroundColor; + private Color foregroundColor; + + public DefaultStyle() { + parent = null; + resetToDefaults(); + } + + public DefaultStyle(Style other) { + parent = other; + overriddenProperties = EnumSet.noneOf(Property.class); + } + + public void resetToDefaults() { + alignment = Alignment.LEFT; + spacingTop = 0; + spacingBottom = 0; + firstLineIndent = 0; + leftIndent = 0; + rightIndent = 0; + lineSpacing = 0; + // TODO: ... + overriddenProperties = EnumSet.allOf(Property.class); + + resetFontToDefaults(); + } + + public void resetFontToDefaults() { + // TODO: Mechanics should probably be changed. Instead of having a + // method resetFontToDefaults() here, the StyleSheet should have methods + // to set and get the default style. And Style should have a method + // to set(Style other) to copy the values from the parameter. + // Then \plain can be handled by copying the default style. The problem + // is that there are RTF commands which define the default style values. + font = new DefaultFont("default"); + fontSize = 12.0f; + bold = false; + italic = false; + underlineStyle = UnderlineStyle.NONE; + strikeOut = false; + caps = false; + backgroundColor = DefaultColor.WHITE; + foregroundColor = DefaultColor.BLACK; + + overriddenProperties.addAll(EnumSet.of( + Property.FONT, + Property.FONT_SIZE, + Property.BOLD, + Property.ITALIC, + Property.UNDERLINED, + Property.STRIKE_OUT, + Property.CAPS, + Property.BACKGROUND_COLOR, + Property.FOREGROUND_COLOR + )); + } + + public Style createDerivedStyle() { + return new DefaultStyle(this); + } + + public Style createFlattenedStyle() { + DefaultStyle style = new DefaultStyle(); + style.copyFrom(this); + return style; + } + + private void copyFrom(Style style) { + alignment = style.getAlignment(); + spacingTop = style.getSpacingTop(); + spacingBottom = style.getSpacingBottom(); + firstLineIndent = style.getFirstLineIndent(); + leftIndent = style.getLeftIndent(); + rightIndent = style.getRightIndent(); + lineSpacing = style.getLineSpacing(); + // TODO: ... + font = style.getFont(); + fontSize = style.getFontSize(); + bold = style.getBold(); + italic = style.getItalic(); + underlineStyle = style.getUnderlined(); + strikeOut = style.getStrikeOut(); + caps = style.getCaps(); + backgroundColor = style.getBackgroundColor(); + foregroundColor = style.getForegroundColor(); + + overriddenProperties = EnumSet.allOf(Property.class); + } + + public boolean equals(Style object) { + if (object == this) + return true; + if (object == null || object.getClass() != DefaultStyle.class) + return false; + + DefaultStyle other = (DefaultStyle) object; + return parent == other.parent + && overriddenProperties.equals(other.overriddenProperties) + && alignment == other.alignment + && spacingTop == other.spacingTop + && spacingBottom == other.spacingBottom + && firstLineIndent == other.firstLineIndent + && leftIndent == other.leftIndent + && rightIndent == other.rightIndent + && lineSpacing == other.lineSpacing + // TODO: ... + && (font != null ? font.equals(other.font) : other.font == null) + && fontSize == other.fontSize + && bold == other.bold + && italic == other.italic + && underlineStyle == other.underlineStyle + && strikeOut == other.strikeOut + && caps == other.caps + && backgroundColor == other.backgroundColor + && foregroundColor == other.foregroundColor; + } + + public void setAlignment(Alignment alignment) { + this.alignment = alignment; + overriddenProperties.add(Property.ALIGNMENT); + } + + public Alignment getAlignment() { + if (overriddenProperties.contains(Property.ALIGNMENT)) + return alignment; + else + return parent.getAlignment(); + } + + public void setSpacingTop(float value) { + spacingTop = value; + overriddenProperties.add(Property.SPACING_TOP); + } + + public float getSpacingTop() { + if (overriddenProperties.contains(Property.SPACING_TOP)) + return spacingTop; + else + return parent.getSpacingTop(); + } + + public void setSpacingBottom(float value) { + spacingBottom = value; + overriddenProperties.add(Property.SPACING_BOTTOM); + } + + public float getSpacingBottom() { + if (overriddenProperties.contains(Property.SPACING_BOTTOM)) + return spacingBottom; + else + return parent.getSpacingBottom(); + } + + public void setFirstLineIndent(float value) { + firstLineIndent = value; + overriddenProperties.add(Property.FIRST_LINE_INDENT); + } + + public float getFirstLineIndent() { + if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) + return firstLineIndent; + else + return parent.getFirstLineIndent(); + } + + public void setLeftIndent(float value) { + leftIndent = value; + overriddenProperties.add(Property.LEFT_INDENT); + } + + public float getLeftIndent() { + if (overriddenProperties.contains(Property.LEFT_INDENT)) + return leftIndent; + else + return parent.getLeftIndent(); + } + + public void setRightIndent(float value) { + rightIndent = value; + overriddenProperties.add(Property.RIGHT_INDENT); + } + + public float getRightIndent() { + if (overriddenProperties.contains(Property.RIGHT_INDENT)) + return rightIndent; + else + return parent.getRightIndent(); + } + + public void setLineSpacing(float value) { + lineSpacing = value; + overriddenProperties.add(Property.LINE_SPACING); + } + + public float getLineSpacing() { + if (overriddenProperties.contains(Property.LINE_SPACING)) + return lineSpacing; + else + return parent.getLineSpacing(); + } + + public void addTab(float position, TabAlignment aligment) { + // TODO Auto-generated method stub + } + + public void setFont(Font font) { + this.font = font; + overriddenProperties.add(Property.FONT); + } + + public Font getFont() { + if (overriddenProperties.contains(Property.BOLD)) + return font; + else + return parent.getFont(); + } + + public void setFontSize(float value) { + this.fontSize = value; + overriddenProperties.add(Property.FONT_SIZE); + } + + public float getFontSize() { + if (overriddenProperties.contains(Property.FONT_SIZE)) + return fontSize; + else + return parent.getFontSize(); + } + + public void setBold(boolean bold) { + this.bold = bold; + overriddenProperties.add(Property.BOLD); + } + + public boolean getBold() { + if (overriddenProperties.contains(Property.BOLD)) + return bold; + else + return parent.getBold(); + } + + public void setItalic(boolean italic) { + this.italic = italic; + overriddenProperties.add(Property.ITALIC); + } + + public boolean getItalic() { + if (overriddenProperties.contains(Property.ITALIC)) + return italic; + else + return parent.getItalic(); + } + + public void setUnderlined(UnderlineStyle style) { + this.underlineStyle = style; + overriddenProperties.add(Property.UNDERLINED); + } + + public UnderlineStyle getUnderlined() { + if (overriddenProperties.contains(Property.UNDERLINED)) + return underlineStyle; + else + return parent.getUnderlined(); + } + + public void setStrikeOut(boolean strikeOut) { + this.strikeOut = strikeOut; + overriddenProperties.add(Property.STRIKE_OUT); + } + + public boolean getStrikeOut() { + if (overriddenProperties.contains(Property.STRIKE_OUT)) + return strikeOut; + else + return parent.getStrikeOut(); + } + + public void setCaps(boolean caps) { + this.caps = caps; + overriddenProperties.add(Property.CAPS); + } + + public boolean getCaps() { + if (overriddenProperties.contains(Property.CAPS)) + return caps; + else + return parent.getCaps(); + } + + public void setBackgroundColor(Color color) { + if (color instanceof DefaultColor) { + backgroundColor = (DefaultColor) color; + overriddenProperties.add(Property.BACKGROUND_COLOR); + } + } + + public Color getBackgroundColor() { + if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) + return backgroundColor; + else + return parent.getBackgroundColor(); + } + + public void setForegroundColor(Color color) { + if (color instanceof DefaultColor) { + foregroundColor = (DefaultColor) color; + overriddenProperties.add(Property.FOREGROUND_COLOR); + } + } + + public Color getForegroundColor() { + if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) + return foregroundColor; + else + return parent.getForegroundColor(); + } + + @Override + public String toString() { + return "DefaultStyle(" + + alignment.name() + ", " + + (font != null ? font.getName() : "") + "@" + fontSize + ", " + + (bold ? "bold, " : "") + + (italic ? "italic, " : "") + + (underlineStyle != UnderlineStyle.NONE ? ("underline: " + underlineStyle.name() + ", ") : "") + + "fg: " + foregroundColor + ", " + + "bg: " + backgroundColor + + ")"; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java new file mode 100644 index 0000000..2ecec13 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java @@ -0,0 +1,29 @@ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.List; + +import com.rtfparserkit.document.StyleSheet; + +public class DefaultStyleSheet implements StyleSheet { + + private final List styles; + + public DefaultStyleSheet() { + styles = new ArrayList(); + } + + public DefaultStyle addStyle() { + DefaultStyle style = new DefaultStyle(); + styles.add(style); + return style; + } + + public int countStyles() { + return styles.size(); + } + + public DefaultStyle get(int index) { + return styles.get(index); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java new file mode 100644 index 0000000..7b21d80 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java @@ -0,0 +1,15 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +/** + * + * @author stippi + */ +public class PageMargins { + public int left; + public int right; + public int top; + public int bottom; +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java new file mode 100644 index 0000000..a812be5 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java @@ -0,0 +1,13 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +/** + * + * @author stippi + */ +public class PageSize { + public int width; + public int height; +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java new file mode 100644 index 0000000..41cbdaf --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -0,0 +1,149 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.DocumentPart; +import com.rtfparserkit.document.Paragraph; +import com.rtfparserkit.document.Style; + +/** + * A list of Paragraph objects. There is always at least one, empty paragraph + * in the list. + * + * @author stippi + */ +public class ParagraphList implements Iterable, DocumentPart { + private final List defaultParagraphs; + + /** + * Creates a new instance which already contains an empty initial paragraph + * by calling clear(). + */ + public ParagraphList() { + defaultParagraphs = new ArrayList(); + clear(); + } + + /** + * Returns and iterator over the Paragraphs contained in this list. + */ + public Iterator iterator() { + return defaultParagraphs.iterator(); + } + + /** + * Finalizes the current paragraph by appending a line-break character '\n'. + * Starts the next paragraph by appending a new empty Paragraph to the list. + */ + public void nextParagraph(Style lastStyle) { + if (countParagraphs() > 0) + getCurrentParagraph().end(lastStyle); + DefaultParagraph next = new DefaultParagraph(); + defaultParagraphs.add(next); + } + + /** + * Implements nextLine() by appending the Unicode character "Line Separator" + * to the current paragraph. + */ + public void nextLine() { + getCurrentParagraph().append("\u2028"); + } + + /** + * @return The concatenated text of all contained Paragraphs. + */ + public String getText() { + StringBuilder builder = new StringBuilder(); + for (DefaultParagraph defaultParagraph : defaultParagraphs) + builder.append(defaultParagraph.getText()); + return builder.toString(); + } + + public Style createDefaultStyle() { + return new DefaultStyle(); + } + + /** + * Implements handleText() by separating the given text at line-breaks + * (calling nextParagraph() at '\n') and appending the chunks between + * line-breaks to the currently last Paragraph. This makes sure that all + * paragraphs in this list are normalized in that the last paragraph never + * contains a line-break, while all preceding paragraphs contain exactly + * one line-break which is at the very end of the paragraph. + * + * @param text The string to append. + * + * @see #nextParagraph() + */ + public void append(String text, Style style) { + int offset = 0; + while (offset < text.length()) { + int nextLineBreak = text.indexOf('\n', offset); + if (nextLineBreak == offset) { + nextParagraph(style); + offset++; + continue; + } + + int end = nextLineBreak > offset ? nextLineBreak : text.length(); + String subString = text.substring(offset, end); + getCurrentParagraph().append(subString, style); + + offset = end; + } + } + + public void append(String string) { + Style style; + Chunk chunk = getCurrentParagraph().getLastChunk(); + if (chunk != null) + style = chunk.getStyle(); + else + style = new DefaultStyle(); + append(string, style); + } + + /** + * Removes all Paragraphs that are currently in the list and adds a new + * empty Paragraph as the initial Paragraph by calling nextParagraph() + */ + public void clear() { + defaultParagraphs.clear(); + // Add the initial empty paragraph + nextParagraph(new DefaultStyle()); + } + + /** + * @return The last Paragraph of the list. There is always at least + * one paragraph in the list. + */ + public DefaultParagraph getCurrentParagraph() { + return defaultParagraphs.get(defaultParagraphs.size() - 1); + } + + /** + * @return The number of paragraphs in this list. + */ + public int countParagraphs() { + return defaultParagraphs.size(); + } + + /** + * Return the Paragraph at the specified index. + * + * @param index The index of the desired paragraph. The index must be + * >= 0 and < countParagraphs(). + * @return The paragraph at the given index. Throws an + * IndexOutOfBoundsExpception if index is out of bounds. + */ + public Paragraph paragraphAt(int index) { + return defaultParagraphs.get(index); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java new file mode 100644 index 0000000..46e02a0 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java @@ -0,0 +1,89 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A list of Section objects. There is always at least one, empty section + * in the list. + * + * @author stippi + */ +public class SectionList implements Iterable { + private final List sections; + + /** + * Creates a new instance which already contains an empty initial section + * by calling clear(). + */ + public SectionList() { + sections = new ArrayList(); + clear(); + } + + /** + * Returns and iterator over the Sections contained in this list. + */ + public Iterator iterator() { + return sections.iterator(); + } + + /** + * Starts the next Section by appending a new empty Section to the list. + */ + public void nextSection() { + DefaultSection next = new DefaultSection(); + sections.add(next); + } + + /** + * Removes all Sections that are currently in the list and adds a new + * empty Section as the initial Section by calling nextSection() + */ + public void clear() { + sections.clear(); + // Add the initial empty section + nextSection(); + } + + /** + * @return The last Paragraph of the list. There is always at least + * one paragraph in the list. + */ + public DefaultSection getLastSection() { + return sections.get(sections.size() - 1); + } + + /** + * @return The number of paragraphs in this list. + */ + public int countSections() { + return sections.size(); + } + + /** + * Return the Section at the specified index. + * + * @param index The index of the desired section. The index must be + * >= 0 and < countSections(). + * @return The Section at the given index. Throws an + * IndexOutOfBoundsExpception if index is out of bounds. + */ + public DefaultSection sectionAt(int index) { + return sections.get(index); + } + + /** + * @return The concatenated text of all contained Sections. + */ + public String getText() { + StringBuilder builder = new StringBuilder(); + for (DefaultSection section : sections) + builder.append(section.getText()); + return builder.toString(); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java new file mode 100644 index 0000000..7b4e689 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java @@ -0,0 +1,56 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.rtf.Command; + +abstract class AbstractRtfContext implements RtfContext { + + private final boolean throwExceptions; + + protected AbstractRtfContext() { + this(true); + } + + protected AbstractRtfContext(boolean throwExceptions) { + this.throwExceptions = throwExceptions; + } + + public void processGroupStart(RtfContextStack stack) { + handleUnexpectedEvent("Unexpected anonymous group start"); + stack.pushContext(this); + } + + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + handleUnexpectedEvent("Unexpected destination group start"); + stack.pushContext(this); + } + + public void processGroupEnd(RtfContextStack stack) { + stack.popContext(); + } + + public void processCharacterBytes(byte[] data) { + handleUnexpectedEvent("Unexpected character bytes"); + } + + public void processBinaryBytes(byte[] data) { + handleUnexpectedEvent("Unexpected binary bytes"); + } + + public void processString(String string) { + handleUnexpectedEvent("Unexpected string '" + string + "'"); + } + + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + handleUnexpectedEvent("Unexpected command '" + command + "'"); + } + + private void handleUnexpectedEvent(String eventInfo) { + if (throwExceptions) + throw new IllegalStateException(eventInfo); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java new file mode 100644 index 0000000..0a431ee --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java @@ -0,0 +1,56 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.ColorTable; +import com.rtfparserkit.rtf.Command; + +/** + * Processes RTF events that may be encountered in the color table section of + * the file. Whenever a color entry is closed with ';' a new color entry is + * added to the ColorTable instance which is passed on construction. + * + * @author stippi + */ +class ColorTableContext extends AbstractRtfContext { + + private final ColorTable table; + + private int red; + private int green; + private int blue; + + ColorTableContext(ColorTable table) { + this.table = table; + } + + @Override + public void processString(String string) { + if (";".equals(string)) { + table.addColor(red, green, blue); + } else { + throw new IllegalStateException("Unexpected string in color table"); + } + } + + @Override + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + switch (command) { + case red: + red = parameter; + break; + case green: + green = parameter; + break; + case blue: + blue = parameter; + break; + default: + throw new IllegalStateException( + "Unexpected command in color table"); + } + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java new file mode 100644 index 0000000..233e066 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java @@ -0,0 +1,105 @@ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.Document; +import com.rtfparserkit.parser.IRtfListener; +import com.rtfparserkit.rtf.Command; +import com.rtfparserkit.rtf.CommandType; + +public class DocumentBuilder implements IRtfListener { + + private int level = 0; + private boolean atGroupStart = false; + + private final RtfContextStack stack; + + public DocumentBuilder(Document document) { + stack = new RtfContextStack(new RootContext(document)); + } + + public void processDocumentStart() { + } + + public void processDocumentEnd() { + } + + public void processGroupStart() { + atGroupStart = true; + } + + public void processGroupEnd() { + handleDelayedGroupStart(); + System.out.println(getIndentation() + "processGroupEnd()"); + stack.getContext().processGroupEnd(stack); + level--; + atGroupStart = false; + } + + public void processCharacterBytes(byte[] data) { + handleDelayedGroupStart(); + System.out.println(getIndentation() + "processCharacterBytes()"); + stack.getContext().processCharacterBytes(data); + } + + public void processBinaryBytes(byte[] data) { + handleDelayedGroupStart(); + System.out.println(getIndentation() + "processBinaryBytes()"); + stack.getContext().processBinaryBytes(data); + } + + public void processString(String string) { + handleDelayedGroupStart(); + System.out.println(getIndentation() + "processString(" + string + ")"); + stack.getContext().processString(string); + } + + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + if (atGroupStart) { + // Handle delayed group start. + if (command.getCommandType() == CommandType.Destination) { + System.out.println(getIndentation() + "processGroupStart(" + + command + ")"); + level++; + stack.getContext().processGroupStart(stack, command, parameter, + hasParameter, optional); + // Do not handle this command as processCommand() a second time. + groupStarted(); + return; + } else { + handleDelayedGroupStart(); + } + } + + System.out.print(getIndentation() + "processCommand() " + command); + if (hasParameter) + System.out.print(", parameter: " + parameter); + if (optional) + System.out.print(" (optional)"); + System.out.println(); + + stack.getContext().processCommand(command, parameter, hasParameter, + optional); + } + + private String getIndentation() { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < level; i++) + builder.append(" "); + builder.append(stack.getContext().getClass().getSimpleName()); + builder.append('.'); + return builder.toString(); + } + + private void handleDelayedGroupStart() { + if (atGroupStart) { + System.out.println(getIndentation() + "processGroupStart()"); + level++; + stack.getContext().processGroupStart(stack); + groupStarted(); + } + } + + private void groupStarted() { + atGroupStart = false; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java new file mode 100644 index 0000000..f2ef202 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java @@ -0,0 +1,89 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.Document; +import com.rtfparserkit.rtf.Command; + +/** + * Initial RtfContext. + * + * @author stippi + */ +class DocumentContext extends DocumentPartContext { + + private final Document document; + + DocumentContext(Document document) { + super(document, document); + this.document = document; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + switch (command) { + case header: + stack.pushContext(new DocumentPartContext( + document.getLastSection().createHeader(), + document)); + break; + case footer: + stack.pushContext(new DocumentPartContext( + document.getLastSection().createFooter(), + document)); + break; + case colortbl: + stack.pushContext(new ColorTableContext(document.getColorTable())); + break; + case fonttbl: + stack.pushContext(new FontTableContext(document.getFontTable())); + break; + + default: + // Unknown destinations should be ignored. + stack.pushContext(new NullContext()); + break; + } + } + + @Override + public void processGroupStart(RtfContextStack stack) { + stack.pushContext(new DocumentPartContext(document, document)); + } + + @Override + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + switch (command) { + case margl: + document.getDocumentSettings() + .getPageSettings().setPageMarginLeft(parameter); + break; + case margr: + document.getDocumentSettings() + .getPageSettings().setPageMarginRight(parameter); + break; + case margt: + document.getDocumentSettings() + .getPageSettings().setPageMarginTop(parameter); + break; + case margb: + document.getDocumentSettings() + .getPageSettings().setPageMarginBottom(parameter); + break; + case paperw: + document.getDocumentSettings() + .getPageSettings().setPageWidth(parameter); + break; + case paperh: + document.getDocumentSettings() + .getPageSettings().setPageHeight(parameter); + break; + + default: + super.processCommand(command, parameter, hasParameter, optional); + } + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java new file mode 100644 index 0000000..977a067 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -0,0 +1,245 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.ColorTable; +import com.rtfparserkit.document.Document; +import com.rtfparserkit.document.DocumentPart; +import com.rtfparserkit.document.FontTable; +import com.rtfparserkit.document.Style; +import com.rtfparserkit.document.Style.Alignment; +import com.rtfparserkit.document.Style.UnderlineStyle; +import com.rtfparserkit.document.StyleSheet; +import com.rtfparserkit.rtf.Command; + +/** + * + * @author stippi + */ +class DocumentPartContext extends AbstractRtfContext { + + private final DocumentPart documentPart; + private final ColorTable colorTable; + private final FontTable fontTable; + private final StyleSheet styleSheet; + private final Style style; + + DocumentPartContext(DocumentPart part, Document document) { + documentPart = part; + this.colorTable = document.getColorTable(); + this.fontTable = document.getFontTable(); + this.styleSheet = document.getStyleSheet(); + style = part.createDefaultStyle(); + } + + DocumentPartContext(DocumentPartContext parent) { + documentPart = parent.documentPart; + colorTable = parent.colorTable; + fontTable = parent.fontTable; + styleSheet = parent.styleSheet; + style = parent.style.createDerivedStyle(); + } + + @Override + public void processGroupStart(RtfContextStack stack) { + // TODO: Push new style context + stack.pushContext(new DocumentPartContext(this)); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // TODO: Push new style context + stack.pushContext(new DocumentPartContext(this)); + } + + @Override + public void processCharacterBytes(byte[] data) { + // Ignore + } + + @Override + public void processBinaryBytes(byte[] data) { + // Ignore + } + + @Override + public void processString(String string) { + documentPart.append(string, style.createFlattenedStyle()); + } + + @Override + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + switch (command) { + case par: + documentPart.nextParagraph(style.createFlattenedStyle()); + break; + case line: + documentPart.nextLine(); + break; + + // Text styles + case plain: + style.resetFontToDefaults(); + break; + case f: + style.setFont(fontTable.getFont(parameter)); + break; + case fs: + style.setFontSize(fromHalfPoints(parameter)); + break; + case b: + if (!hasParameter) + style.setBold(true); + else + style.setBold(parameter != 0); + break; + case i: + if (!hasParameter) + style.setItalic(true); + else + style.setItalic(parameter != 0); + break; + case caps: + if (!hasParameter) + style.setCaps(true); + else + style.setCaps(parameter != 0); + break; + case strike: + case striked: + if (!hasParameter) + style.setStrikeOut(true); + else + style.setStrikeOut(parameter != 0); + break; + case ul: + setUnderlined(UnderlineStyle.SINGLE, hasParameter, parameter); + break; + case uld: + setUnderlined(UnderlineStyle.DOTTED, hasParameter, parameter); + break; + case uldash: + setUnderlined(UnderlineStyle.DASHED, hasParameter, parameter); + break; + case uldashd: + setUnderlined(UnderlineStyle.DASH_DOTTED, hasParameter, parameter); + break; + case uldashdd: + setUnderlined(UnderlineStyle.DASH_DOT_DOTTED, hasParameter, + parameter); + break; + case uldb: + setUnderlined(UnderlineStyle.DOUBLE, hasParameter, parameter); + break; + case ulhwave: + setUnderlined(UnderlineStyle.HEAVY_WAVE, hasParameter, parameter); + break; + case ulldash: + setUnderlined(UnderlineStyle.LONG_DASHED, hasParameter, parameter); + break; + case ulnone: + style.setUnderlined(UnderlineStyle.NONE); + break; + case ulth: + setUnderlined(UnderlineStyle.THICK, hasParameter, parameter); + break; + case ulthd: + setUnderlined(UnderlineStyle.THICK_DOTTED, hasParameter, parameter); + break; + case ulthdash: + setUnderlined(UnderlineStyle.THICK_DASHED, hasParameter, parameter); + break; + case ulthdashd: + setUnderlined(UnderlineStyle.THICK_DASH_DOTTED, hasParameter, + parameter); + break; + case ulthdashdd: + setUnderlined(UnderlineStyle.THICK_DASH_DOT_DOTTED, hasParameter, + parameter); + break; + case ulthldash: + setUnderlined(UnderlineStyle.THICK_LONG_DASHED, hasParameter, + parameter); + break; + case ululdbwave: + setUnderlined(UnderlineStyle.DOUBLE_WAVE, hasParameter, parameter); + break; + case ulw: + setUnderlined(UnderlineStyle.WORD, hasParameter, + parameter); + break; + case ulwave: + setUnderlined(UnderlineStyle.WAVE, hasParameter, parameter); + break; + case cb: + style.setBackgroundColor(colorTable.colorAt(parameter)); + break; + case cf: + style.setForegroundColor(colorTable.colorAt(parameter)); + break; + + // Alignment + case qc: + style.setAlignment(Alignment.CENTER); + break; + case qj: + style.setAlignment(Alignment.JUSTIFIED); + break; + case ql: + style.setAlignment(Alignment.LEFT); + break; + case qr: + style.setAlignment(Alignment.RIGHT); + break; + case qd: + style.setAlignment(Alignment.DISTRIBUTED); + break; + + // Indents + case fi: + style.setFirstLineIndent(fromTwips(parameter)); + break; + case li: + style.setLeftIndent(fromTwips(parameter)); + break; + case ri: + style.setRightIndent(fromTwips(parameter)); + break; + + // spacing + case sb: + style.setSpacingTop(fromTwips(parameter)); + break; + case sa: + style.setSpacingBottom(fromTwips(parameter)); + break; + case sl: + style.setLineSpacing(fromTwips(parameter)); + break; + + default: +// System.out.println("DocumentPartContext.processCommand(" +// + command + ") not handled!"); + break; + } + } + + private void setUnderlined(UnderlineStyle underline, boolean hasParamter, + int parameter) { + if (!hasParamter || parameter == 0) + style.setUnderlined(UnderlineStyle.NONE); + else + style.setUnderlined(underline); + } + + private static float fromTwips(int value) { + return (float) value / 20.0f; + } + + private static float fromHalfPoints(int value) { + return (float) value / 2.0f; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java new file mode 100644 index 0000000..b3eedee --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java @@ -0,0 +1,47 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.DocumentSettings; +import com.rtfparserkit.rtf.Command; + +/** + * RtfContext implementing the storing of global settings to the document. + * + * @author stippi + */ +class DocumentSettingsContext extends AbstractRtfContext { + + private final DocumentSettings settings; + + DocumentSettingsContext(DocumentSettings settings) { + this.settings = settings; + } + + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + switch (command) { + case margl: + settings.getPageSettings().setPageMarginLeft(parameter); + break; + case margr: + settings.getPageSettings().setPageMarginRight(parameter); + break; + case margt: + settings.getPageSettings().setPageMarginTop(parameter); + break; + case margb: + settings.getPageSettings().setPageMarginBottom(parameter); + break; + case paperw: + settings.getPageSettings().setPageWidth(parameter); + break; + case paperh: + settings.getPageSettings().setPageHeight(parameter); + break; + // TODO: More commands... + } + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java new file mode 100644 index 0000000..feee612 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java @@ -0,0 +1,116 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.FontTable; +import com.rtfparserkit.document.FontTable.FontFamily; +import com.rtfparserkit.rtf.Command; + +/** + * RtfContext implementation which handles RTF events inside a group inside + * of the font table section. + * + * @author stippi + */ +class FontContext extends AbstractRtfContext { + + protected final FontTable fontTable; + + private String fontName = ""; + private String alternativeName = ""; + private String fileName = ""; + private FontFamily fontFamily = FontFamily.DEFAULT; + + private enum ExpectedName { + DEFAULT, + ALTERNATIVE, + FILE + } + + private ExpectedName expectedName = ExpectedName.DEFAULT; + + FontContext(FontTable fontTable) { + this.fontTable = fontTable; + } + + @Override + public void processGroupEnd(RtfContextStack stack) { + super.processGroupEnd(stack); + } + + @Override + public void processString(String string) { + int offset = 0; + while (offset < string.length()) { + // Chop off anything after and including the first semicolon + int semicolon = string.indexOf(';', offset); + + if (semicolon == offset) { + fontTable.addFont(fontName, alternativeName, fileName, + fontFamily); + offset = semicolon + 1; + continue; + } + + int end = semicolon >= 0 ? semicolon : string.length(); + + String name = string.substring(offset, end); + + switch (expectedName) { + case DEFAULT: + fontName = name; + break; + case ALTERNATIVE: + alternativeName = name; + break; + case FILE: + fileName = name; + break; + } + + offset = end; + } + } + + @Override + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + switch (command) { + case fname: + expectedName = ExpectedName.DEFAULT; + break; + case falt: + expectedName = ExpectedName.ALTERNATIVE; + break; + case fontfile: + expectedName = ExpectedName.FILE; + break; + + case fnil: + fontFamily = FontFamily.DEFAULT; + break; + case froman: + fontFamily = FontFamily.ROMAN; + break; + case fswiss: + fontFamily = FontFamily.SWISS; + break; + case fmodern: + fontFamily = FontFamily.MODERN; + break; + case fscript: + fontFamily = FontFamily.SCRIPT; + break; + case fdecor: + fontFamily = FontFamily.DECOR; + break; + case ftech: + fontFamily = FontFamily.TECH; + break; + case fbidi: + fontFamily = FontFamily.BIDI; + break; + } + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java new file mode 100644 index 0000000..a057817 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java @@ -0,0 +1,33 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.FontTable; +import com.rtfparserkit.rtf.Command; + +/** + * Processes RTF events that may be encountered in the font table section of + * the file. Whenever a new group is started, a new FontContext is created to + * handle the events within the group which specify the font parameters. + * + * @author stippi + */ +class FontTableContext extends FontContext { + + FontTableContext(FontTable table) { + super(table); + } + + @Override + public void processGroupStart(RtfContextStack stack) { + stack.pushContext(new FontContext(fontTable)); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + stack.pushContext(new FontContext(fontTable)); + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java new file mode 100644 index 0000000..5c5d582 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java @@ -0,0 +1,45 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.rtf.Command; + +/** + * RtfContext ignoring all events. + * + * @author stippi + */ +class NullContext implements RtfContext { + + public void processGroupStart(RtfContextStack stack) { + stack.pushContext(new NullContext()); + } + + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + processGroupStart(stack); + } + + public void processGroupEnd(RtfContextStack stack) { + stack.popContext(); + } + + public void processCharacterBytes(byte[] data) { + // Ignore + } + + public void processBinaryBytes(byte[] data) { + // Ignore + } + + public void processString(String string) { + // Ignore + } + + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional) { + // Ignore + } + +} \ No newline at end of file diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java new file mode 100644 index 0000000..f55af4f --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java @@ -0,0 +1,42 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.Document; +import com.rtfparserkit.rtf.Command; + +/** + * Initial RtfContext. + * + * @author stippi + */ +class RootContext extends AbstractRtfContext { + + private final Document document; + + RootContext(Document document) { + this.document = document; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + switch (command) { + case rtf: + stack.pushContext(new DocumentContext(document)); + break; + + default: + // Unknown destinations should be ignored. + stack.pushContext(new NullContext()); + break; + } + } + + @Override + public void processGroupStart(RtfContextStack stack) { + // Unknown groups should be ignored. + stack.pushContext(new NullContext()); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java new file mode 100644 index 0000000..e718060 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java @@ -0,0 +1,30 @@ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.rtf.Command; + +/** + * Interface for delegating the handling of RTF Parser events to an object which + * knows how to handle the events based on the current "context" (location in + * the file and group hierarchy). + * + * @author stippi + */ +interface RtfContext { + + public void processGroupStart(RtfContextStack stack); + + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional); + + public void processGroupEnd(RtfContextStack stack); + + public void processCharacterBytes(byte[] data); + + public void processBinaryBytes(byte[] data); + + public void processString(String string); + + public void processCommand(Command command, int parameter, + boolean hasParameter, boolean optional); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java new file mode 100644 index 0000000..486938c --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java @@ -0,0 +1,40 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.parser.builder; + +import java.util.Stack; + +/** + * + * @author stippi + */ +class RtfContextStack { + + private final Stack stack; + private RtfContext currentContext; + + RtfContextStack(RtfContext initialContext) { + if (initialContext == null) { + throw new IllegalArgumentException( + "Initial RTF context cannot be null."); + } + stack = new Stack(); + currentContext = initialContext; + } + + RtfContext getContext() { + return currentContext; + } + + void pushContext(RtfContext context) { + stack.push(currentContext); + currentContext = context; + } + + void popContext() { + if (stack.isEmpty()) + throw new IllegalStateException("RTF context stack is empty"); + currentContext = stack.pop(); + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java new file mode 100644 index 0000000..5ebe7c5 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java @@ -0,0 +1,59 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.rtfparserkit.document.impl.ParagraphList; + +/** + * + * @author stippi + */ +public class ParagraphListTest { + + @Test + public void testEmptyParagraphList() { + ParagraphList list = new ParagraphList(); + assertEquals(1, list.countParagraphs()); + assertEquals("", list.getText()); + } + + @Test + public void testAppend() { + ParagraphList list = new ParagraphList(); + list.append("test1"); + list.append("test2"); + list.append("test3"); + assertEquals(1, list.countParagraphs()); + assertEquals("test1test2test3", list.getText()); + } + + @Test + public void testDelimiter() { + ParagraphList list = new ParagraphList(); + list.append("\n"); + assertEquals(2, list.countParagraphs()); + assertEquals("\n", list.getText()); + assertEquals("\n", list.paragraphAt(0).getText()); + assertEquals("", list.paragraphAt(1).getText()); + + list.append("\n\n"); + assertEquals(4, list.countParagraphs()); + assertEquals("\n\n\n", list.getText()); + assertEquals("\n", list.paragraphAt(2).getText()); + assertEquals("", list.paragraphAt(3).getText()); + + list = new ParagraphList(); + list.append("test1"); + list.append("test2\ntest3\n"); + assertEquals(3, list.countParagraphs()); + assertEquals("test1test2\ntest3\n", list.getText()); + assertEquals("test1test2\n", list.paragraphAt(0).getText()); + assertEquals("test3\n", list.paragraphAt(1).getText()); + assertEquals("", list.paragraphAt(2).getText()); + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java new file mode 100644 index 0000000..07306c9 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java @@ -0,0 +1,95 @@ +/** + * Copyright 2015 DramaQueen GmbH. All rights reserved. + */ +package com.rtfparserkit.document; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.rtfparserkit.document.impl.DefaultParagraph; + +/** + * + * @author stippi + */ +public class ParagraphTest { + + @Test + public void testEmptyParagraph() { + DefaultParagraph p = new DefaultParagraph(); + assertEquals("", p.getText()); + } + + @Test + public void testAppend() { + DefaultParagraph p = new DefaultParagraph(); + p.append("test1"); + p.append("test2"); + p.append("test3"); + assertEquals("test1test2test3", p.getText()); + } + + @Test + public void testDelimiter() { + DefaultParagraph p = new DefaultParagraph(); + p.end(); + assertEquals("\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + assertEquals("test", p.getText()); + + p.end(); + assertEquals("test\n", p.getText()); + } + + @Test + public void testOnlyOneDelimiter() { + DefaultParagraph p = new DefaultParagraph(); + p.end(); + expectException(p, "\n", true); + assertEquals("\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + expectException(p, "\n", false); + // Paragraph already delimited + expectException(p, "\n", true); + // Paragraph must not have changed + assertEquals("test\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + // Appended text may end with a delimiter + expectException(p, "test\n", false); + assertEquals("testtest\n", p.getText()); + // Paragraph already delimited, various cases of the text containing + // a delimiter should all raise an exception + expectException(p, "test\n", true); + expectException(p, "\n", true); + expectException(p, "\ntest", true); + expectException(p, "test\ntest", true); + // Paragraph must not have changed + assertEquals("testtest\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + // Appended text may only /end/ with a delimiter + expectException(p, "test\ntest", true); + expectException(p, "\ntest", true); + // Paragraph must not have changed + assertEquals("test", p.getText()); + } + + private void expectException(DefaultParagraph defaultParagraph, String toAppend, + boolean exceptionExpected) { + boolean exceptionRaised = false; + try { + defaultParagraph.append(toAppend); + } catch (Exception e) { + exceptionRaised = true; + } + assertEquals(exceptionExpected, exceptionRaised); + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java new file mode 100644 index 0000000..b15a9d7 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -0,0 +1,111 @@ +package com.rtfparserkit.parser.builder; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Test; + +import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.Document; +import com.rtfparserkit.document.Paragraph; +import com.rtfparserkit.document.Section; +import com.rtfparserkit.document.impl.DefaultDocument; +import com.rtfparserkit.parser.RtfStreamSource; +import com.rtfparserkit.parser.standard.StandardRtfParser; + +public class BuilderParseTest { + + @Test + public void testParagraphContents() { + DefaultDocument document = new DefaultDocument(); + parseStream("lineSeparator", document); + + Section section = document.getLastSection(); + + int paragraphCount = section.countParagraphs(); + assertEquals(5, paragraphCount); + + assertEquals("INNEN. KÜCHE - TAG\n", + section.paragraphAt(0).getText()); + assertEquals("Ein Absatz mit Line-Separator:\u2028" + + "Der geht hier auf einer neuen Zeile weiter.\n", + section.paragraphAt(1).getText()); + assertEquals("INNEN. KÜCHE - TAG\n", + section.paragraphAt(2).getText()); + assertEquals("Hier ist die zweite Szene.\n", + section.paragraphAt(3).getText()); + assertEquals("", + section.paragraphAt(4).getText()); + + assertEquals(12242, document.getPageSize().width); + assertEquals(15842, document.getPageSize().height); + + assertEquals(1425, document.getPageMargins().left); + assertEquals(360, document.getPageMargins().right); + assertEquals(950, document.getPageMargins().top); + assertEquals(1425, document.getPageMargins().bottom); + + assertEquals(2, document.getColorTable().countColors()); + } + + @Test + public void testStyles() { + + String[] files = { + "variousStyles", + "variousStylesPages", + "variousStylesGrouped", + }; + + for (String file : files) { + System.out.println("################################"); + + DefaultDocument document = new DefaultDocument(); + parseStream(file, document); + + assertEquals(1, document.countSections()); + Section section = document.sectionAt(0); + assertStyles(section); + } + } + + private void assertStyles(Section section) { + int paragraphCount = section.countParagraphs(); + assertEquals(8, paragraphCount); + + for (int i = 0; i < paragraphCount; i++) { + Paragraph paragraph = section.paragraphAt(i); + String text = paragraph.getText(); + System.out.print("[" + i + "]: " + text); + if (!text.endsWith("\n")); + System.out.println(); + for (Chunk chunk : paragraph) { + System.out.println(" '" + chunk.getString().replaceAll("\n", + "") + "' " + chunk.getStyle()); + } + } + } + + private void parseStream(String fileName, Document document) { + InputStream is = null; + try { + is = BuilderParseTest.class.getResourceAsStream("data/" + + fileName + ".rtf"); + StandardRtfParser parser = new StandardRtfParser(); + parser.parse(new RtfStreamSource(is), + new DocumentBuilder(document)); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + // Ignore + } + } + } + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/lineSeparator.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/lineSeparator.rtf new file mode 100644 index 0000000..3dccc6f --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/lineSeparator.rtf @@ -0,0 +1 @@ +{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\froman\fcharset0 Times New Roman;}{\f1\froman\fcharset0 Arial;}{\f2\froman\fcharset0 Courier;}}{\colortbl\red0\green0\blue0;\red255\green255\blue255;}{\stylesheet {\style\s0 \ql\fi0\li0\ri0\f1\fs24\cf0 Normal;}{\style\s3 \ql\fi0\li0\ri0\f1\fs26\b\cf0 heading 3;}{\style\s2 \ql\fi0\li0\ri0\f1\fs28\b\i\cf0 heading 2;}{\style\s1 \ql\fi0\li0\ri0\f1\fs32\b\cf0 heading 1;}}{\*\listtable}{\*\listoverridetable}{\*\generator iText 2.1.7 by 1T3XT}{\info}\paperw12242\paperh15842\margl1425\margr360\margt950\margb1425{\header \pard\plain\s0\qr\fi0\li0\ri0\sl320\plain\f0{\field{\*\fldinst PAGE}{\fldrslt }}\f2\fs24 . \line \par}\pgwsxn12242\pghsxn15842\marglsxn1425\margrsxn360\margtsxn950\margbsxn1425\pard\plain\s0\ql\fi-734\li734\ri0\sb480\sa240\sl240\plain\tx720\tqr\tx9580\tx9720{\f2\fs24\cf0\chcbpat1 \tab }{\f2\fs24\cf0\chcbpat1 INNEN. K\u220?CHE - TAG}\par\pard\plain\s0\qj\fi0\li734\ri864\sb240\sa240\sl240\plain\tx1920\tx3840\tx5760\tx7680\tx9600{\f2\fs24\cf0\chcbpat1 Ein Absatz mit Line-Separator:\line Der geht hier auf einer neuen Zeile weiter.}\par\pard\plain\s0\ql\fi-734\li734\ri0\sb480\sa240\sl240\plain\tx720\tqr\tx9580\tx9720{\f2\fs24\cf0\chcbpat1 \tab }{\f2\fs24\cf0\chcbpat1 INNEN. K\u220?CHE - TAG}\par\pard\plain\s0\qj\fi0\li734\ri864\sb240\sl240\plain\tx1920\tx3840\tx5760\tx7680\tx9600{\f2\fs24\cf0\chcbpat1 Hier ist die zweite Szene.}\par} \ No newline at end of file diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStyles.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStyles.rtf new file mode 100644 index 0000000..18fb1e4 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStyles.rtf @@ -0,0 +1,26 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red217\green11\blue0;\red255\green249\blue89;} +\margl1440\margr1440\vieww10800\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural + +\f0\fs24 \cf0 Normal +\b Bold +\i Bold/Italic +\b0 Italic +\i0 Normal.\ + +\fs36 Bigger Font (18). \ul Underlined +\fs24 \ulnone Normal size. \cf2 Red text. \cb3 On yellow background.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\cf0 \cb1 Centered.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qr +\cf0 Right.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qj +\cf0 Justified.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\sl480\slmult1\pardirnatural\qj +\cf0 With bigger line spacing. +\fs36 \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\cf0 \ +} \ No newline at end of file diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesGrouped.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesGrouped.rtf new file mode 100644 index 0000000..cda1463 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesGrouped.rtf @@ -0,0 +1,26 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red217\green11\blue0;\red255\green249\blue89;} +\margl1440\margr1440\vieww10800\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural + +\f0\fs24 \cf0 Normal +{\b Bold +{\i Bold/Italic +\b0 Italic} +} Normal.\ + +\fs36 Bigger Font (18). \ul Underlined +\fs24 \ulnone Normal size. \cf2 Red text. \cb3 On yellow background.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\cf0 \cb1 Centered.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qr +\cf0 Right.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qj +\cf0 Justified.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\sl480\slmult1\pardirnatural\qj +\cf0 With bigger line spacing. +\fs36 \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\cf0 \ +} \ No newline at end of file diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesPages.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesPages.rtf new file mode 100644 index 0000000..fee6f91 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/variousStylesPages.rtf @@ -0,0 +1,43 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red217\green11\blue0;} +\margl1440\margr1440\margb1800\margt1800 +\deftab720 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural + +\f0\fs24 \cf0 \expnd0\expndtw0\kerning0 +\up0 \nosupersub \ulnone \outl0\strokewidth0 \strokec0 Normal +\b \expnd0\expndtw0\kerning0 +Bold +\i \expnd0\expndtw0\kerning0 +Bold/Italic +\b0 \expnd0\expndtw0\kerning0 + Italic +\i0 \expnd0\expndtw0\kerning0 + Normal.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural + +\fs36 \expnd0\expndtw0\kerning0 +Bigger Font (18). \expnd0\expndtw0\kerning0 +\ul Underlined +\fs24 \expnd0\expndtw0\kerning0 +\ulnone Normal size. \cf2 \expnd0\expndtw0\kerning0 +\strokec2 Red text. On yellow background.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural\qc +\cf0 \expnd0\expndtw0\kerning0 +\strokec0 Centered.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural\qr +\expnd0\expndtw0\kerning0 +Right.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural\qj +\expnd0\expndtw0\kerning0 +Justified.\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\sl480\slmult1\pardirnatural\qj +\expnd0\expndtw0\kerning0 +With bigger line spacing. +\fs36 \expnd0\expndtw0\kerning0 +\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\pardirnatural +\expnd0\expndtw0\kerning0 +\ +} \ No newline at end of file From 6a29a33591c37ac9e70dca647daa9a5b3f3e96e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 1 Oct 2015 18:30:45 +0200 Subject: [PATCH 03/16] Fixed copyrights, annotation support Fixed the copyright of all added files to also be the APL 2.0. Introduced support for parsing annotations and storing them in the document model. The objects contained in a Paragraph are no longer Chunks, but Elements. Chunk inherits from Element, as does Annotation, by inheriting from DocumentPart. That means an annotation can contain any styled text, including text which itself contains annotations. --- .../com/rtfparserkit/document/Annotation.java | 39 +++++ .../src/com/rtfparserkit/document/Chunk.java | 22 ++- .../src/com/rtfparserkit/document/Color.java | 19 ++- .../com/rtfparserkit/document/ColorTable.java | 21 ++- .../com/rtfparserkit/document/Document.java | 17 +- .../rtfparserkit/document/DocumentPart.java | 27 +++- .../document/DocumentSettings.java | 18 ++- .../com/rtfparserkit/document/Element.java | 23 +++ .../src/com/rtfparserkit/document/Font.java | 18 ++- .../com/rtfparserkit/document/FontTable.java | 25 ++- .../src/com/rtfparserkit/document/Footer.java | 19 ++- .../src/com/rtfparserkit/document/Header.java | 19 ++- .../rtfparserkit/document/PageSettings.java | 18 ++- .../com/rtfparserkit/document/Paragraph.java | 31 ++-- .../com/rtfparserkit/document/Section.java | 20 ++- .../src/com/rtfparserkit/document/Style.java | 18 ++- .../com/rtfparserkit/document/StyleSheet.java | 22 ++- .../src/com/rtfparserkit/document/Text.java | 25 +++ .../document/impl/DefaultAnnotation.java | 59 +++++++ .../document/impl/DefaultChunk.java | 20 ++- .../document/impl/DefaultColor.java | 19 ++- .../document/impl/DefaultColorTable.java | 18 +++ .../document/impl/DefaultDocument.java | 56 ++++++- .../document/impl/DefaultFont.java | 18 ++- .../document/impl/DefaultFontTable.java | 2 +- .../document/impl/DefaultFooter.java | 19 ++- .../document/impl/DefaultHeader.java | 19 ++- .../document/impl/DefaultParagraph.java | 150 +++++++++++++----- .../document/impl/DefaultSection.java | 19 ++- .../document/impl/DefaultStyle.java | 18 ++- .../document/impl/DefaultStyleSheet.java | 2 +- .../document/impl/PageMargins.java | 19 ++- .../rtfparserkit/document/impl/PageSize.java | 19 ++- .../document/impl/ParagraphList.java | 90 +++++++---- .../document/impl/SectionList.java | 18 ++- .../parser/builder/AbstractRtfContext.java | 29 +++- .../parser/builder/AnnotationContext.java | 111 +++++++++++++ .../parser/builder/ColorTableContext.java | 22 ++- .../parser/builder/DocumentBuilder.java | 27 +++- .../parser/builder/DocumentContext.java | 27 +++- .../parser/builder/DocumentPartContext.java | 118 +++++++++++--- .../builder/DocumentSettingsContext.java | 18 ++- .../parser/builder/FontContext.java | 22 ++- .../parser/builder/FontTableContext.java | 20 ++- .../parser/builder/NullContext.java | 26 ++- .../parser/builder/RootContext.java | 21 ++- .../parser/builder/RtfContext.java | 21 ++- .../parser/builder/RtfContextStack.java | 32 +++- .../parser/builder/TimeContext.java | 86 ++++++++++ .../rtfparserkit/document/ParagraphTest.java | 18 +++ .../parser/builder/BuilderParseTest.java | 92 ++++++++++- .../builder/data/annotationLibreOffice.rtf | 19 +++ .../parser/builder/data/annotationSpec.rtf | 9 ++ 53 files changed, 1402 insertions(+), 282 deletions(-) create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Element.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/Text.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationLibreOffice.rtf create mode 100644 RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationSpec.rtf diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java new file mode 100644 index 0000000..82405ab --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +import java.util.Date; + +/** + * Interface for annotation elements. The annotation contents are accessible + * via the DocumentPart functionality. Note that this would mean support for + * nested annotations. + */ +public interface Annotation extends DocumentPart { + + public void setId(String id); + + public String getId(); + + public void setAuthor(String author); + + public String getAuthor(); + + public void setDate(Date date); + + public Date getDate(); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java index 60dae04..2b19df3 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java @@ -1,16 +1,26 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * A chunk of text with a certain style. - * - * @author stippi */ -public interface Chunk { +public interface Chunk extends Element { - public String getString(); + public String getText(); public Style getStyle(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Color.java b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java index f145d79..2df1b6b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Color.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java @@ -1,11 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * - * @author stippi + * Represents a color that can be placed in the ColorTable. */ public interface Color { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java index 5009d86..71a65c5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java @@ -1,12 +1,23 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * Interface for adding a color to the global color table. - * - * @author stippi + * Interface for adding a color to the global color table and retrieving + * a Color instance at a specific index. */ public interface ColorTable { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Document.java b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java index 3b4f113..1535ab6 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Document.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java @@ -1,9 +1,22 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.document; /** * Interface for getting to all relevant parts of the document model. - * - * @author stippi */ public interface Document extends DocumentPart { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java index 7fd3341..a67d820 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java @@ -1,13 +1,26 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.document; /** - * Interface for appending text to a destination. - * - * @author stippi + * Interface for appending styled text and handling paragraphs. A flattened + * String representation of all contained text can be obtained via the Text + * functionality. */ -public interface DocumentPart { - - public String getText(); +public interface DocumentPart extends Text { public int countParagraphs(); @@ -19,5 +32,7 @@ public interface DocumentPart { public void nextLine(); + public Annotation appendAnnotation(); + public Style createDefaultStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java index 3d46192..6256fdd 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java @@ -1,12 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Interface for controlling global settings of the document. - * - * @author stippi */ public interface DocumentSettings { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Element.java b/RTF Parser Kit/src/com/rtfparserkit/document/Element.java new file mode 100644 index 0000000..ccf25a7 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Element.java @@ -0,0 +1,23 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +/** + * Base type for various possible children of a Paragraph. + */ +public interface Element { + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Font.java b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java index b4b25a0..4eae3b5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Font.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java @@ -1,12 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Simple interface for storing font information. - * - * @author stippi */ public interface Font { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java index 7e7edf0..01b51bd 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java @@ -1,12 +1,23 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * Interface for adding a font definition to the global font table. - * - * @author stippi + * Interface for adding a font definition to the global font table and + * retrieving the font information at a specific index. */ public interface FontTable { @@ -23,6 +34,8 @@ public enum FontFamily { public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily); + + public int countFonts(); - public Font getFont(int index); + public Font fontAt(int index); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java index c0b4d0a..12a5aaf 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java @@ -1,11 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * - * @author stippi + * Special type of a DocumentPart representing a page footer. */ public interface Footer extends DocumentPart { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Header.java b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java index 4ba3cca..4d72daa 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Header.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java @@ -1,11 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * - * @author stippi + * Special type of a DocumentPart representing a page header. */ public interface Header extends DocumentPart { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java index 5fd4932..cdbeb3c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java @@ -1,12 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Interface for controlling page settings - * - * @author stippi */ public interface PageSettings { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java index baace2d..92ad280 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java @@ -1,18 +1,29 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** - * Interface for paragraph functionality. - * - * @author stippi + * Interface for paragraph functionality. A Paragraph contains Elements + * which currently may be of type Chunk and Annotation. */ -public interface Paragraph extends Iterable { +public interface Paragraph extends Iterable, Text { - public String getText(); - - public int countChunks(); + public int countElements(); - public Chunk chunkAt(int index); + public Element elementAt(int index); + + public Style getStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Section.java b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java index af25ee3..09a081e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Section.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java @@ -1,15 +1,25 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Interface for starting a new section in a document. A section can have * its own paper settings (for example orientation and margins). - * - * @author stippi */ -public interface Section extends DocumentPart { +public interface Section extends DocumentPart, Iterable { public Header createHeader(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java index 09f80a6..26842a8 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java @@ -1,12 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Interface for setting style parameters. - * - * @author stippi */ public interface Style { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java index aaac4be..a12aa67 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java @@ -1,17 +1,29 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document; /** * Interface for adding a style definition to a global style sheet. - * - * @author stippi */ public interface StyleSheet { public Style addStyle(); + + public int countStyles(); - public Style get(int index); + public Style styleAt(int index); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Text.java b/RTF Parser Kit/src/com/rtfparserkit/document/Text.java new file mode 100644 index 0000000..b9576ac --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Text.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +/** + * Base type for Elements which can return a flattened String for their text + * contents. + */ +public interface Text extends Element { + + public String getText(); +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java new file mode 100644 index 0000000..b8ec757 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import java.util.Calendar; +import java.util.Date; + +import com.rtfparserkit.document.Annotation; + +/** + * Default implementation for Annotation. + */ +public class DefaultAnnotation extends ParagraphList implements Annotation { + + private String id = ""; + private String author = ""; + private long date = Calendar.getInstance().getTimeInMillis(); + + public DefaultAnnotation() { + } + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAuthor() { + return author; + } + + public void setDate(Date date) { + this.date = date.getTime(); + } + + public Date getDate() { + return new Date(date); + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java index e9fb2c5..0084996 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -8,8 +20,6 @@ /** * Default Chunk implementation. - * - * @author stippi */ public class DefaultChunk implements Chunk { private final StringBuilder stringBuilder; @@ -20,7 +30,7 @@ public DefaultChunk(Style style) { this.style = style; } - public String getString() { + public String getText() { return stringBuilder.toString(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java index d3f704f..877677e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java @@ -1,13 +1,24 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Color; /** - * - * @author stippi + * Default Color implementation. After creation, DefaultColor is not mutable. */ public class DefaultColor implements Color { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java index af81889..75fd873 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -6,6 +21,9 @@ import com.rtfparserkit.document.Color; import com.rtfparserkit.document.ColorTable; +/** + * Default implementation of ColorTable. + */ public class DefaultColorTable implements ColorTable { private final List colors; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java index 7c8ce40..e25de44 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -1,8 +1,21 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; +import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.DocumentSettings; import com.rtfparserkit.document.PageSettings; @@ -11,8 +24,9 @@ import com.rtfparserkit.document.Style; /** - * - * @author stippi + * Default implementation of Document. Note that Document itself is also + * a DocumentPart. It implements relevant functionality by forwarding to the + * last Section. */ public class DefaultDocument extends SectionList implements Document { @@ -76,22 +90,43 @@ public void setPageHeight(int value) { }; } + /** + * Appends a string of text to the last Section. + * + * @param text The string to append + * @param style The Style in which the appended string is to appear. + */ public void append(String text, Style style) { getLastSection().append(text, style); } + /** + * Starts a new Paragraph at the last Section and sets the Style of the + * previous last Paragraph. + * + * @param lastStyle The Style to be set on the previous paragraph. + */ public void nextParagraph(Style lastStyle) { getLastSection().nextParagraph(lastStyle); } + /** + * Creates a new line at the last Section. + */ public void nextLine() { getLastSection().nextLine(); } + /** + * @return The default Style created by the last Section. + */ public Style createDefaultStyle() { return getLastSection().createDefaultStyle(); } + /** + * @return The total count of all paragraphs contained in all Sections. + */ public int countParagraphs() { int count = 0; for (Section section : this) @@ -99,6 +134,10 @@ public int countParagraphs() { return count; } + /** + * @param index The index of the paragraph relative to the total paragraph + * count of all Sections. + */ public Paragraph paragraphAt(int index) { int originalIndex = index; for (Section section : this) { @@ -113,4 +152,13 @@ public Paragraph paragraphAt(int index) { throw new IndexOutOfBoundsException("paragraphs in section: " + countParagraphs() + ", requested index: " + originalIndex); } + + /** + * Creates a new Annotation instance and appends it to the last Section. + * + * @return The appended annotation + */ + public Annotation appendAnnotation() { + return getLastSection().appendAnnotation(); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java index bd05d97..03d8b3c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -7,8 +19,6 @@ /** * Default Font implementation - * - * @author stippi */ public class DefaultFont implements Font { private String name; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java index f8a7a3d..3ec4c61 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -23,7 +23,7 @@ public int countFonts() { return fonts.size(); } - public Font getFont(int index) { + public Font fontAt(int index) { return fonts.get(index); } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java index 20f98ec..c5d07f5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -7,8 +19,7 @@ /** - * - * @author stippi + * Default Footer implementation. */ public class DefaultFooter extends ParagraphList implements Footer { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java index 9d8c848..50d88b6 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -7,8 +19,7 @@ /** - * - * @author stippi + * Default Header implementation */ public class DefaultHeader extends ParagraphList implements Header { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java index cd393dc..ee9e040 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -8,62 +20,84 @@ import java.util.List; import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.Element; import com.rtfparserkit.document.Paragraph; import com.rtfparserkit.document.Style; /** - * A Paragraph contains text which is formed by chunks. - * - * @author stippi + * Default Paragraph implementation */ -public class DefaultParagraph implements Iterable, Paragraph { - private final List chunks; - +public class DefaultParagraph implements Iterable, Paragraph { + private final List chunks; + private Style style; + public DefaultParagraph() { - chunks = new ArrayList(); + this(new DefaultStyle()); + } + + public DefaultParagraph(Style style) { + chunks = new ArrayList(); + this.style = style; } - public Iterator iterator() { + public Iterator iterator() { return chunks.iterator(); } public String getText() { StringBuilder builder = new StringBuilder(); - for (Chunk chunk : chunks) - builder.append(chunk.getString()); + for (Element element : chunks) { + if (element instanceof Chunk) + builder.append(((Chunk) element).getText()); + } return builder.toString(); } - public int countChunks() { + public int countElements() { return chunks.size(); } - public Chunk chunkAt(int index) { + public Element elementAt(int index) { return chunks.get(index); } - public void append(Chunk chunk) { - if (chunk == null) - throw new IllegalArgumentException("Chunk may not be null"); - chunks.add(chunk); + public Style getStyle() { + return style; } - - public Chunk getLastChunk() { - if (chunks.size() > 0) - return chunks.get(chunks.size() - 1); - return null; + + public void append(Element element) { + if (element == null) + throw new IllegalArgumentException("Element may not be null"); + chunks.add(element); } + /** + * Appends the string to the Paragraph. If the last Element of the Paragraph + * is a Chunk, the string will be appended to the Chunk. Otherwise a new + * Chunk will be created to hold the String. If the Paragraph already + * contains any Chunks, the Style of the last Chunk is used for the string. + * The paragraph may not already be delimited (end with '\n'). The appended + * string may contain a delimiter ('\n'), but it must be at the end of the + * string. + * + * @param string The string to append + */ public void append(String string) { - Style style; - Chunk defaultChunk = getLastChunk(); - if (defaultChunk == null) - style = new DefaultStyle(); - else - style = defaultChunk.getStyle(); - append(string, style); + append(string, getLastStyle()); } + /** + * Appends the string to the Paragraph. If the last Element of the Paragraph + * is a Chunk, the string will be appended to that Chunk if the Style + * matches the Style of the last Chunk. Otherwise a new Chunk with the given + * Style will be created to hold the String. + * The paragraph may not already be delimited (end with '\n'). The appended + * string may contain a delimiter ('\n'), but it must be at the end of the + * string. + * + * @param string The string to append + * @param style The Style in which the string is to appear + */ public void append(String string, Style style) { if (string == null) throw new IllegalArgumentException("String may not be null!"); @@ -78,31 +112,61 @@ public void append(String string, Style style) { appendString(string, style); } - /** - * Makes sure that the paragraph doesn't already end with '\n'. - */ - private void assertNotDelimited() { - Chunk last = getLastChunk(); - if (last != null && last.getString().endsWith("\n")) { - throw new IllegalArgumentException( - "Paragraph is already delimited."); - } - } - public void end() { - end(new DefaultStyle()); + end(getLastStyle()); } public void end(Style lastStyle) { append("\n", lastStyle); } + public Style getLastStyle() { + // Try to use the last used Style instead of the default style + Chunk lastChunk = findLastChunk(); + if (lastChunk != null) + return lastChunk.getStyle(); + + return style; + } + + /** + * Makes sure that the paragraph doesn't already end with '\n'. + */ + private void assertNotDelimited() { + for (int i = chunks.size() - 1; i >= 0; i--) { + Element element = chunks.get(i); + if (element instanceof Chunk) { + Chunk chunk = (Chunk) element; + if (chunk.getText().endsWith("\n")) { + throw new IllegalArgumentException( + "Paragraph is already delimited."); + } + break; + } + } + } + private void appendString(String string, Style style) { - Chunk chunk = getLastChunk(); + Chunk chunk = null; + if (chunks.size() > 0) { + Element last = chunks.get(chunks.size() - 1); + if (last instanceof Chunk) + chunk = (Chunk) last; + } if (chunk == null || !chunk.getStyle().equals(style)) { chunk = new DefaultChunk(style); append(chunk); } chunk.append(string); } + + private Chunk findLastChunk() { + for (int i = chunks.size() - 1; i >= 0; i--) { + Element element = chunks.get(i); + if (element instanceof Chunk) + return (Chunk) element; + } + + return null; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java index 5c00426..326a3e2 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -9,8 +21,7 @@ import com.rtfparserkit.document.Section; /** - * - * @author stippi + * Default Section implementation */ public class DefaultSection extends ParagraphList implements Section { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java index 3b4c7fd..fcaa31a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -11,8 +23,6 @@ /** * Default Style implementation - * - * @author stippi */ public class DefaultStyle implements Style { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java index 2ecec13..90eb89f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java @@ -23,7 +23,7 @@ public int countStyles() { return styles.size(); } - public DefaultStyle get(int index) { + public DefaultStyle styleAt(int index) { return styles.get(index); } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java index 7b21d80..f8d7baf 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java @@ -1,11 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; /** - * - * @author stippi + * Simple parameter storage for page margins. */ public class PageMargins { public int left; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java index a812be5..e4112a5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java @@ -1,11 +1,22 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; /** - * - * @author stippi + * Simple parameter storage for page size. */ public class PageSize { public int width; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java index 41cbdaf..37e3aa1 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -7,7 +19,7 @@ import java.util.Iterator; import java.util.List; -import com.rtfparserkit.document.Chunk; +import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.DocumentPart; import com.rtfparserkit.document.Paragraph; import com.rtfparserkit.document.Style; @@ -15,26 +27,24 @@ /** * A list of Paragraph objects. There is always at least one, empty paragraph * in the list. - * - * @author stippi */ -public class ParagraphList implements Iterable, DocumentPart { - private final List defaultParagraphs; +public class ParagraphList implements Iterable, DocumentPart { + private final List paragraphs; /** * Creates a new instance which already contains an empty initial paragraph * by calling clear(). */ public ParagraphList() { - defaultParagraphs = new ArrayList(); + paragraphs = new ArrayList(); clear(); } /** * Returns and iterator over the Paragraphs contained in this list. */ - public Iterator iterator() { - return defaultParagraphs.iterator(); + public Iterator iterator() { + return new ParagraphIterator(paragraphs.iterator()); } /** @@ -43,9 +53,8 @@ public Iterator iterator() { */ public void nextParagraph(Style lastStyle) { if (countParagraphs() > 0) - getCurrentParagraph().end(lastStyle); - DefaultParagraph next = new DefaultParagraph(); - defaultParagraphs.add(next); + getLastParagraph().end(lastStyle); + paragraphs.add(new DefaultParagraph()); } /** @@ -53,7 +62,7 @@ public void nextParagraph(Style lastStyle) { * to the current paragraph. */ public void nextLine() { - getCurrentParagraph().append("\u2028"); + getLastParagraph().append("\u2028"); } /** @@ -61,8 +70,8 @@ public void nextLine() { */ public String getText() { StringBuilder builder = new StringBuilder(); - for (DefaultParagraph defaultParagraph : defaultParagraphs) - builder.append(defaultParagraph.getText()); + for (Paragraph paragraph : paragraphs) + builder.append(paragraph.getText()); return builder.toString(); } @@ -94,28 +103,29 @@ public void append(String text, Style style) { int end = nextLineBreak > offset ? nextLineBreak : text.length(); String subString = text.substring(offset, end); - getCurrentParagraph().append(subString, style); + getLastParagraph().append(subString, style); offset = end; } } - + public void append(String string) { - Style style; - Chunk chunk = getCurrentParagraph().getLastChunk(); - if (chunk != null) - style = chunk.getStyle(); - else - style = new DefaultStyle(); + Style style = getLastParagraph().getLastStyle(); append(string, style); } + + public Annotation appendAnnotation() { + Annotation annotation = new DefaultAnnotation(); + getLastParagraph().append(annotation); + return annotation; + } /** * Removes all Paragraphs that are currently in the list and adds a new * empty Paragraph as the initial Paragraph by calling nextParagraph() */ public void clear() { - defaultParagraphs.clear(); + paragraphs.clear(); // Add the initial empty paragraph nextParagraph(new DefaultStyle()); } @@ -124,15 +134,15 @@ public void clear() { * @return The last Paragraph of the list. There is always at least * one paragraph in the list. */ - public DefaultParagraph getCurrentParagraph() { - return defaultParagraphs.get(defaultParagraphs.size() - 1); + public DefaultParagraph getLastParagraph() { + return paragraphs.get(paragraphs.size() - 1); } /** * @return The number of paragraphs in this list. */ public int countParagraphs() { - return defaultParagraphs.size(); + return paragraphs.size(); } /** @@ -144,6 +154,28 @@ public int countParagraphs() { * IndexOutOfBoundsExpception if index is out of bounds. */ public Paragraph paragraphAt(int index) { - return defaultParagraphs.get(index); + return paragraphs.get(index); + } + + private static class ParagraphIterator implements Iterator { + + private final Iterator internalIterator; + + ParagraphIterator(Iterator iterator) { + internalIterator = iterator; + } + + public boolean hasNext() { + return internalIterator.hasNext(); + } + + public Paragraph next() { + return internalIterator.next(); + } + + public void remove() { + internalIterator.remove(); + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java index 46e02a0..3ea49e9 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.document.impl; @@ -10,8 +22,6 @@ /** * A list of Section objects. There is always at least one, empty section * in the list. - * - * @author stippi */ public class SectionList implements Iterable { private final List sections; diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java index 7b4e689..a9b3ec8 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java @@ -1,10 +1,31 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; +/** + * An implementation of all methods defined by RtfContext. All methods + * throw an IllegalStateException, unless the object is configured not to + * throw exception at construction time. The idea is that derived classes + * implement exactly the needed functionality and RTF events resulting in + * calling methods which have not been overridden means something is wrong. + * The only method which is supposed to be used by sub-classes is + * processGroupEnd(), which pops the context from the provided RtfContextStack. + */ abstract class AbstractRtfContext implements RtfContext { private final boolean throwExceptions; @@ -44,8 +65,8 @@ public void processString(String string) { handleUnexpectedEvent("Unexpected string '" + string + "'"); } - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { handleUnexpectedEvent("Unexpected command '" + command + "'"); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java new file mode 100644 index 0000000..8609923 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java @@ -0,0 +1,111 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.parser.builder; + +import java.util.Date; + +import com.rtfparserkit.document.Annotation; +import com.rtfparserkit.parser.builder.TimeContext.DateListener; +import com.rtfparserkit.rtf.Command; + + +/** + * Parses the body of an Annotation. + */ +class AnnotationContext extends DocumentPartContext { + + private final Annotation annotation; + private final DocumentPartContext parent; + + AnnotationContext(Annotation annotation, DocumentPartContext parent) { + super(annotation, parent.document); + this.annotation = annotation; + this.parent = parent; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + switch (command) { + case atntime: + case atndate: + stack.pushContext(new TimeContext(new DateListener() { + public void setDate(Date date) { + annotation.setDate(date); + } + })); + break; + case atnref: + // TODO: Handle annotation references. The reference is in + // the parameter. + stack.pushContext(new AnnotationReferenceContext()); + break; + case atnparent: + stack.pushContext(new AnnotationParentContext()); + break; + case atrfstart: + stack.pushContext(new BookmarkStartContext()); + break; + case atrfend: + stack.pushContext(new BookmarkEndContext()); + break; + default: + super.processGroupStart(stack, command, parameter, hasParameter, + optional); + } + } + + @Override + public void processGroupEnd(RtfContextStack stack) { + // Inform the parent context that parsing the annotation body has + // finished. + parent.annotationFinished(); + super.processGroupEnd(stack); + } + + private class AnnotationParentContext extends AbstractRtfContext { + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + switch (command) { + case atnid: + stack.pushContext(new AnnotationIdContext()); + break; + default: + super.processGroupStart(stack, command, parameter, hasParameter, + optional); + } + } + } + + private class AnnotationIdContext extends AbstractRtfContext { + @Override + public void processString(String string) { + // TODO: The string is the ID of a parent Annotation. Do something + // with it. + } + } + + private class AnnotationReferenceContext extends AbstractRtfContext { + } + + private class BookmarkStartContext extends AbstractRtfContext { + } + + private class BookmarkEndContext extends AbstractRtfContext { + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java index 0a431ee..b9cb5b5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -10,8 +22,6 @@ * Processes RTF events that may be encountered in the color table section of * the file. Whenever a color entry is closed with ';' a new color entry is * added to the ColorTable instance which is passed on construction. - * - * @author stippi */ class ColorTableContext extends AbstractRtfContext { @@ -35,8 +45,8 @@ public void processString(String string) { } @Override - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { switch (command) { case red: red = parameter; diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java index 233e066..be71b0f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Document; @@ -5,6 +20,14 @@ import com.rtfparserkit.rtf.Command; import com.rtfparserkit.rtf.CommandType; +/** + * The main class used for building a Document model from parsing RTF events. + * The intended use is to construct an instance of DocumentBuilder with an + * instance of a Document, then pass the DocumentBuilder to + * StandardParser.parse(RtfSource, RtfListener) as the RtfListener. + * + * @author stippi + */ public class DocumentBuilder implements IRtfListener { private int level = 0; @@ -77,8 +100,8 @@ public void processCommand(Command command, int parameter, System.out.print(" (optional)"); System.out.println(); - stack.getContext().processCommand(command, parameter, hasParameter, - optional); + stack.getContext().processCommand(stack, command, parameter, + hasParameter, optional); } private String getIndentation() { diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java index f2ef202..8242118 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -7,9 +19,7 @@ import com.rtfparserkit.rtf.Command; /** - * Initial RtfContext. - * - * @author stippi + * RtfContext for handling the {\rtf group. */ class DocumentContext extends DocumentPartContext { @@ -54,8 +64,8 @@ public void processGroupStart(RtfContextStack stack) { } @Override - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { switch (command) { case margl: document.getDocumentSettings() @@ -83,7 +93,8 @@ public void processCommand(Command command, int parameter, break; default: - super.processCommand(command, parameter, hasParameter, optional); + super.processCommand(stack, command, parameter, hasParameter, + optional); } } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 977a067..1e45386 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -1,59 +1,81 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; -import com.rtfparserkit.document.ColorTable; +import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.DocumentPart; -import com.rtfparserkit.document.FontTable; import com.rtfparserkit.document.Style; import com.rtfparserkit.document.Style.Alignment; import com.rtfparserkit.document.Style.UnderlineStyle; -import com.rtfparserkit.document.StyleSheet; import com.rtfparserkit.rtf.Command; /** - * - * @author stippi + * RtfContext for processing RTF events which have a main styled text + * destination. */ class DocumentPartContext extends AbstractRtfContext { private final DocumentPart documentPart; - private final ColorTable colorTable; - private final FontTable fontTable; - private final StyleSheet styleSheet; + protected final Document document; private final Style style; + private Annotation currentAnnotation; + DocumentPartContext(DocumentPart part, Document document) { documentPart = part; - this.colorTable = document.getColorTable(); - this.fontTable = document.getFontTable(); - this.styleSheet = document.getStyleSheet(); + this.document = document; style = part.createDefaultStyle(); } DocumentPartContext(DocumentPartContext parent) { documentPart = parent.documentPart; - colorTable = parent.colorTable; - fontTable = parent.fontTable; - styleSheet = parent.styleSheet; + document = parent.document; style = parent.style.createDerivedStyle(); } @Override public void processGroupStart(RtfContextStack stack) { - // TODO: Push new style context stack.pushContext(new DocumentPartContext(this)); } @Override public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { - // TODO: Push new style context - stack.pushContext(new DocumentPartContext(this)); + switch (command) { + case atnid: + // A new Annotation started + if (currentAnnotation != null) { + stack.handleError("An annotation has already" + + "started, but encountered another annotation ID."); + } + currentAnnotation = documentPart.appendAnnotation(); + stack.pushContext(new AnnotationIdContext()); + break; + case atnauthor: + stack.pushContext(new AnnotationAuthorContext()); + break; + case annotation: + stack.pushContext(new AnnotationContext(currentAnnotation, this)); + break; + default: + stack.pushContext(new DocumentPartContext(this)); + } } - + @Override public void processCharacterBytes(byte[] data) { // Ignore @@ -70,9 +92,10 @@ public void processString(String string) { } @Override - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { switch (command) { + // Paragraph control case par: documentPart.nextParagraph(style.createFlattenedStyle()); break; @@ -80,12 +103,24 @@ public void processCommand(Command command, int parameter, documentPart.nextLine(); break; + // Special characters + case chatn: + // This denotes a special character that is associated with an + // annotation. In most text processing applications, the text + // cursor can be "before" and "after" an annotation within the text. + // deleting this text position deletes the annotation. + // Before \chatn, there should have been an annotation started by + // \atnid and we have already appended an Annotation object to + // the DocumentPart. At the latest, this will happen with the + // next \annotation group. + break; + // Text styles case plain: style.resetFontToDefaults(); break; case f: - style.setFont(fontTable.getFont(parameter)); + style.setFont(document.getFontTable().fontAt(parameter)); break; case fs: style.setFontSize(fromHalfPoints(parameter)); @@ -175,10 +210,12 @@ public void processCommand(Command command, int parameter, setUnderlined(UnderlineStyle.WAVE, hasParameter, parameter); break; case cb: - style.setBackgroundColor(colorTable.colorAt(parameter)); + style.setBackgroundColor( + document.getColorTable().colorAt(parameter)); break; case cf: - style.setForegroundColor(colorTable.colorAt(parameter)); + style.setForegroundColor( + document.getColorTable().colorAt(parameter)); break; // Alignment @@ -226,7 +263,7 @@ public void processCommand(Command command, int parameter, break; } } - + private void setUnderlined(UnderlineStyle underline, boolean hasParamter, int parameter) { if (!hasParamter || parameter == 0) @@ -242,4 +279,33 @@ private static float fromTwips(int value) { private static float fromHalfPoints(int value) { return (float) value / 2.0f; } + + private String append(String string, String toAppend) { + return string != null ? string + toAppend : toAppend; + } + + void annotationFinished() { + currentAnnotation = null; + } + + private class AnnotationAuthorContext extends AbstractRtfContext { + @Override + public void processString(String string) { + if (currentAnnotation != null) { + currentAnnotation.setAuthor( + append(currentAnnotation.getAuthor(), string)); + } + } + } + + private class AnnotationIdContext extends AbstractRtfContext { + @Override + public void processString(String string) { + if (currentAnnotation != null) { + currentAnnotation.setId( + append(currentAnnotation.getId(), string)); + } + } + } + } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java index b3eedee..0c91a2a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -8,8 +20,6 @@ /** * RtfContext implementing the storing of global settings to the document. - * - * @author stippi */ class DocumentSettingsContext extends AbstractRtfContext { diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java index feee612..f8e736a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -10,8 +22,6 @@ /** * RtfContext implementation which handles RTF events inside a group inside * of the font table section. - * - * @author stippi */ class FontContext extends AbstractRtfContext { @@ -74,8 +84,8 @@ public void processString(String string) { } @Override - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { switch (command) { case fname: expectedName = ExpectedName.DEFAULT; diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java index a057817..5e5994f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -10,8 +22,8 @@ * Processes RTF events that may be encountered in the font table section of * the file. Whenever a new group is started, a new FontContext is created to * handle the events within the group which specify the font parameters. - * - * @author stippi + * Note that FontTableContext inherits from FontContext, since RTF files may + * or may not have the \font elements within a group. */ class FontTableContext extends FontContext { diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java index 5c5d582..b1de0cc 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java @@ -1,14 +1,26 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; /** - * RtfContext ignoring all events. - * - * @author stippi + * RtfContext ignoring all events. Used when text and other comments should not + * end up in a known destination. Groups within a null destination will also + * be completely ignored. */ class NullContext implements RtfContext { @@ -37,8 +49,8 @@ public void processString(String string) { // Ignore } - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { // Ignore } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java index f55af4f..f792435 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java @@ -1,5 +1,17 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; @@ -7,9 +19,8 @@ import com.rtfparserkit.rtf.Command; /** - * Initial RtfContext. - * - * @author stippi + * Initial RtfContext. Pushes a DocumentContext upon encountering a group + * starting with \rtf. */ class RootContext extends AbstractRtfContext { diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java index e718060..dc3cc7a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; @@ -6,8 +21,6 @@ * Interface for delegating the handling of RTF Parser events to an object which * knows how to handle the events based on the current "context" (location in * the file and group hierarchy). - * - * @author stippi */ interface RtfContext { @@ -24,7 +37,7 @@ public void processGroupStart(RtfContextStack stack, Command command, public void processString(String string); - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional); + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java index 486938c..ac41110 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java @@ -1,13 +1,25 @@ -/** - * Copyright 2015 DramaQueen GmbH. All rights reserved. +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.rtfparserkit.parser.builder; import java.util.Stack; /** - * - * @author stippi + * RtfContextStack manages a stack of RtfContext instances and has the notion + * of the current RtfContext (not part of the stack storage). */ class RtfContextStack { @@ -33,8 +45,16 @@ void pushContext(RtfContext context) { } void popContext() { - if (stack.isEmpty()) - throw new IllegalStateException("RTF context stack is empty"); + if (stack.isEmpty()) { + handleError("RTF context stack is empty"); + return; + } currentContext = stack.pop(); } + + void handleError(String error) { + // TODO: Allow setting an error handler + throw new IllegalStateException(error); + //System.out.println(error); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java new file mode 100644 index 0000000..3dc03fb --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.parser.builder; + +import java.util.Calendar; +import java.util.Date; + +import com.rtfparserkit.rtf.Command; + +/** + * Context for parsing a time. When the current group is ended, it informs + * a DateListener provided at construction time about the Date that has been + * parsed. + */ +class TimeContext extends AbstractRtfContext { + + public interface DateListener { + public void setDate(Date date); + } + + private Calendar calendar = Calendar.getInstance(); + + private final DateListener dateListener; + + TimeContext(DateListener listener) { + dateListener = listener; + } + + @Override + public void processGroupEnd(RtfContextStack stack) { + dateListener.setDate(calendar.getTime()); + super.processGroupEnd(stack); + } + + @Override + public void processString(String string) { + try { + long time = Long.parseLong(string); + calendar.setTimeInMillis(time * 1000); + } catch (Exception e) { + // Ignore + } + } + + @Override + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + switch (command) { + case yr: + calendar.set(Calendar.YEAR, parameter); + break; + case mo: + calendar.set(Calendar.MONTH, parameter); + break; + case dy: + calendar.set(Calendar.DAY_OF_MONTH, parameter); + break; + case hr: + calendar.set(Calendar.HOUR, parameter); + break; + case min: + calendar.set(Calendar.MINUTE, parameter); + break; + case sec: + calendar.set(Calendar.SECOND, parameter); + break; + + default: + super.processCommand(stack, command, parameter, hasParameter, + optional); + } + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java index 07306c9..97c1e62 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java @@ -7,6 +7,7 @@ import org.junit.Test; +import com.rtfparserkit.document.impl.DefaultAnnotation; import com.rtfparserkit.document.impl.DefaultParagraph; /** @@ -81,6 +82,23 @@ public void testOnlyOneDelimiter() { // Paragraph must not have changed assertEquals("test", p.getText()); } + + @Test + public void testAnnotation() { + DefaultParagraph p = new DefaultParagraph(); + p.append("test"); + p.append(new DefaultAnnotation()); + p.append("test"); + + assertEquals(3, p.countElements()); + + p = new DefaultParagraph(); + p.append("test"); + p.append(new DefaultAnnotation()); + p.end(); + + assertEquals(3, p.countElements()); + } private void expectException(DefaultParagraph defaultParagraph, String toAppend, boolean exceptionExpected) { diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java index b15a9d7..51a15c5 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -1,14 +1,18 @@ package com.rtfparserkit.parser.builder; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import org.junit.Test; +import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.Chunk; import com.rtfparserkit.document.Document; +import com.rtfparserkit.document.Element; import com.rtfparserkit.document.Paragraph; import com.rtfparserkit.document.Section; import com.rtfparserkit.document.impl.DefaultDocument; @@ -70,6 +74,39 @@ public void testStyles() { assertStyles(section); } } + + @Test + public void testAnnotations() { + DefaultDocument document = new DefaultDocument(); + parseStream("annotationSpec", document); + + Section section = document.sectionAt(0); + + assertEquals(1, section.countParagraphs()); + + Paragraph paragraph = section.paragraphAt(0); + + assertEquals(3, paragraph.countElements()); + + Element element = paragraph.elementAt(0); + assertTrue(element instanceof Chunk); + Chunk chunk = (Chunk) element; + assertEquals("An example of a paradigm might be Darwinian biology.", + chunk.getText()); + + element = paragraph.elementAt(1); + assertTrue(element instanceof Annotation); + Annotation annotation = (Annotation) element; + assertEquals("How about some examples that deal with social science? " + + "That is what this paper is about.", annotation.getText()); + assertEquals("JD", annotation.getId()); + assertEquals("John Doe", annotation.getAuthor()); + + element = paragraph.elementAt(2); + assertTrue(element instanceof Chunk); + chunk = (Chunk) element; + assertEquals(" ", chunk.getText()); + } private void assertStyles(Section section) { int paragraphCount = section.countParagraphs(); @@ -77,15 +114,54 @@ private void assertStyles(Section section) { for (int i = 0; i < paragraphCount; i++) { Paragraph paragraph = section.paragraphAt(i); - String text = paragraph.getText(); - System.out.print("[" + i + "]: " + text); - if (!text.endsWith("\n")); - System.out.println(); - for (Chunk chunk : paragraph) { - System.out.println(" '" + chunk.getString().replaceAll("\n", - "") + "' " + chunk.getStyle()); + + if (i == 0) + assertNormalBoldItalic(paragraph); +// else { + String text = paragraph.getText(); + System.out.print("[" + i + "]: " + text); + if (!text.endsWith("\n")) + System.out.println(); + for (Element element : paragraph) { + if (element instanceof Chunk) { + Chunk chunk = (Chunk) element; + System.out.println(" '" + + chunk.getText().replaceAll("\n", + "") + "' " + chunk.getStyle()); + } + } } - } +// } + } + + private void assertNormalBoldItalic(Paragraph paragraph) { + int chunks = paragraph.countElements(); + assertEquals(5, chunks); + + Chunk chunk = (Chunk) paragraph.elementAt(0); + assertEquals("Normal ", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(1); + assertEquals("Bold ", chunk.getText()); + assertTrue(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(2); + assertEquals("Bold/Italic", chunk.getText()); + assertTrue(chunk.getStyle().getBold()); + assertTrue(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(3); + assertEquals(" Italic", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertTrue(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(4); + assertEquals(" Normal.\n", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); } private void parseStream(String fileName, Document document) { diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationLibreOffice.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationLibreOffice.rtf new file mode 100644 index 0000000..a173ff5 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationLibreOffice.rtf @@ -0,0 +1,19 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Times New Roman;}{\f4\fswiss\fprq2\fcharset0 Arial;}{\f5\fnil\fprq2\fcharset0 Arial Unicode MS;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af5\langfe2052\dbch\af5\afs24\alang1081\loch\f3\fs24\lang1031 Standard;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af5\dbch\af5\afs28\loch\f4\fs28 \u220\'dcberschrift;} +{\s16\sbasedon0\snext16\sb0\sa120 Textk\u246\'f6rper;} +{\s17\sbasedon16\snext17\sb0\sa120 Liste;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\afs24\ai\fs24 Beschriftung;} +{\s19\sbasedon0\snext19\noline Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af5\langfe2052\dbch\af5\afs24\alang1081\loch\f3\fs24\lang1031\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803{\rtlch \ltrch\loch +This }{\rtlch \ltrch\loch +{\*\atnid Unbekannter Autor}{\*\atnauthor Unbekannter Autor}\chatn{\*\annotation{\*\atndate -2026238962}These are the comment contents.}}{\rtlch \ltrch\loch +word is commented.} +\par } \ No newline at end of file diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationSpec.rtf b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationSpec.rtf new file mode 100644 index 0000000..104d529 --- /dev/null +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/data/annotationSpec.rtf @@ -0,0 +1,9 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red217\green11\blue0;\red255\green249\blue89;} +\margl1440\margr1440\vieww10800\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural + +{\insrsid8729657 An example of a paradigm might be Darwinian biology.} +{\cs15\v\fs16\insrsid8729657 {\*\atnid JD}{\*\atnauthor John Doe}\chatn {\*\annotation{\*\atndate 1180187342}\pard\plain \s16\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\cs15\fs16\insrsid8729657 \chatn }{\insrsid9244585 How about some examples that deal with social science? That is what this paper is about.}}} +} \ No newline at end of file From 4e12ae15ff7b60d4a889d387a3679923d4118773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 2 Oct 2015 09:54:52 +0200 Subject: [PATCH 04/16] Updated Readme Now mentions the existence of the new DocumentBuilder parser and that it is probably the parser to use. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d28ee6..129b4d5 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ The idea is to provide a "kit" of components which can either be used "as-is", f What's currently included? -------------------------- * Raw RTF Parser - parses RTF, sends events representing content to a listener. Performs minimal processing - you get the RTF commands and data exactly as they appear in the file. -* Standard RTF Parser - parses RTF, sends events representing content to a listener. Handles character encoding, Unicode and so on, so you don't have to. This is probably the parser you want to use. +* Standard RTF Parser - parses RTF, sends events representing content to a listener. Handles character encoding, Unicode and so on, so you don't have to. +* Document Builder RTF Parser - parses RTF and constructs a document object model via an implementation of the Document interface. You can either use the provided DefaultDocument implementation, or provide your own. This is probably the parser you want to use. * Text Converter - demonstrates very simple text extraction from an RTF file What's planned? --------------- * HTML converter -* Parsing to an RTF document object model -* RTF generation from an RTF document object model +* RTF generation from the RTF document object model That's a lot of stuff! ---------------------- From a241478560ef77c158dbd8391ded023151a95f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 2 Oct 2015 12:25:35 +0200 Subject: [PATCH 05/16] Work on StyleSheet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Style is now split up into a base interface Style. It defines all properties and Styles can have a name and return the overridden properties. The first derived interface is CharacterStyle and it defines setters and getters for just the character style related properties. The second derived interface is ParagraphStyle which also inherits CharacterStyle. It has an additional method for creating a derived CharacterStyle that has a ParagraphStyle as its parent. StyleSheet no longer directly holds styles. Rather it defines getters for instances of CharacterStyleTable and ParagraphStyleTable. The 2007 spec also knows table and section style tables which are not yet implemented. Work in DocumentBuilder towards implementing parsing the styles in the style sheet section. Currently it only creates the styles, sets their names and puts them into the correct table with their correct ID. Also new is ignoring unknown groups. These are detected by a group directly followed by an Command.optionalcommand, i.e. a command not in the Command table. The complete group is ignored by the Document Builder, which fixes some unwanted text ending up in the document. LibreOffice apparently uses a new version of the spec which has some section descriptions that we don’t understand which is no longer a problem. --- .../rtfparserkit/document/CharacterStyle.java | 85 +++++ .../document/CharacterStyleTable.java | 32 ++ .../src/com/rtfparserkit/document/Chunk.java | 2 +- .../rtfparserkit/document/DocumentPart.java | 6 +- .../com/rtfparserkit/document/Paragraph.java | 2 +- .../rtfparserkit/document/ParagraphStyle.java | 74 ++++ .../document/ParagraphStyleTable.java | 32 ++ .../src/com/rtfparserkit/document/Style.java | 131 ++----- .../com/rtfparserkit/document/StyleSheet.java | 12 +- .../document/impl/DefaultCharacterStyle.java | 255 +++++++++++++ .../impl/DefaultCharacterStyleTable.java | 31 ++ .../document/impl/DefaultChunk.java | 8 +- .../document/impl/DefaultDocument.java | 8 +- .../document/impl/DefaultParagraph.java | 18 +- .../document/impl/DefaultParagraphStyle.java | 218 +++++++++++ .../impl/DefaultParagraphStyleTable.java | 31 ++ .../document/impl/DefaultStyle.java | 352 +----------------- .../document/impl/DefaultStyleSheet.java | 46 ++- .../document/impl/ParagraphList.java | 14 +- .../document/impl/StyleTable.java | 48 +++ .../parser/builder/CharacterStyleContext.java | 59 +++ .../parser/builder/DocumentBuilder.java | 54 ++- .../parser/builder/DocumentContext.java | 3 + .../parser/builder/DocumentPartContext.java | 10 +- .../parser/builder/ParagraphStyleContext.java | 59 +++ .../parser/builder/StyleSheetContext.java | 72 ++++ .../parser/builder/BuilderParseTest.java | 30 +- 27 files changed, 1170 insertions(+), 522 deletions(-) create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java create mode 100644 RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java new file mode 100644 index 0000000..fd9dcbc --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + + +/** + * Interface for storing paragraph style parameters. + */ +public interface CharacterStyle extends Style { + + public enum UnderlineStyle { + NONE, + SINGLE, + DOUBLE, + WORD, + DOTTED, + DASHED, + DASH_DOTTED, + DASH_DOT_DOTTED, + LONG_DASHED, + THICK, + THICK_DOTTED, + THICK_DASHED, + THICK_DASH_DOTTED, + THICK_DASH_DOT_DOTTED, + THICK_LONG_DASHED, + WAVE, + HEAVY_WAVE, + DOUBLE_WAVE + } + + public CharacterStyle createDerivedStyle(); + + public CharacterStyle createFlattenedStyle(); + + public void setFont(Font font); + + public Font getFont(); + + public void setFontSize(float value); + + public float getFontSize(); + + public void setBold(boolean bold); + + public boolean getBold(); + + public void setItalic(boolean italic); + + public boolean getItalic(); + + public void setCaps(boolean caps); + + public boolean getCaps(); + + public void setStrikeOut(boolean strikeOut); + + public boolean getStrikeOut(); + + public void setUnderlined(UnderlineStyle style); + + public UnderlineStyle getUnderlined(); + + public void setBackgroundColor(Color color); + + public Color getBackgroundColor(); + + public void setForegroundColor(Color color); + + public Color getForegroundColor(); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java new file mode 100644 index 0000000..9b1c1d7 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +/** + * Interface for style table in which character styles can be + * retrieved by their ID. + */ +public interface CharacterStyleTable extends Iterable { + + public CharacterStyle createStyle(); + + public void addStyle(int id, CharacterStyle style); + + public CharacterStyle styleFor(int id); + + public int countStyles(); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java index 2b19df3..cf3f6de 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java @@ -22,7 +22,7 @@ public interface Chunk extends Element { public String getText(); - public Style getStyle(); + public ParagraphStyle getStyle(); public void append(String string); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java index a67d820..389456d 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java @@ -26,13 +26,13 @@ public interface DocumentPart extends Text { public Paragraph paragraphAt(int index); - public void append(String text, Style style); + public void append(String text, ParagraphStyle style); - public void nextParagraph(Style lastStyle); + public void nextParagraph(ParagraphStyle lastStyle); public void nextLine(); public Annotation appendAnnotation(); - public Style createDefaultStyle(); + public ParagraphStyle createDefaultStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java index 92ad280..9a21663 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java @@ -25,5 +25,5 @@ public interface Paragraph extends Iterable, Text { public Element elementAt(int index); - public Style getStyle(); + public ParagraphStyle getStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java new file mode 100644 index 0000000..f2313fa --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +/** + * Interface for storing paragraph style parameters. + */ +public interface ParagraphStyle extends CharacterStyle { + + public enum Alignment { + LEFT, + RIGHT, + CENTER, + JUSTIFIED, + DISTRIBUTED, + } + + public enum TabAlignment { + LEFT, + CENTER, + RIGHT, + DECIMAL, + } + + public ParagraphStyle createDerivedStyle(); + + public CharacterStyle createDerivedCharacterStyle(); + + public ParagraphStyle createFlattenedStyle(); + + public void setAlignment(Alignment alignment); + + public Alignment getAlignment(); + + public void setSpacingTop(float value); + + public float getSpacingTop(); + + public void setSpacingBottom(float value); + + public float getSpacingBottom(); + + public void setFirstLineIndent(float value); + + public float getFirstLineIndent(); + + public void setLeftIndent(float value); + + public float getLeftIndent(); + + public void setRightIndent(float value); + + public float getRightIndent(); + + public void setLineSpacing(float value); + + public float getLineSpacing(); + + public void addTab(float position, TabAlignment aligment); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java new file mode 100644 index 0000000..d31bf61 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document; + +/** + * Interface for style table in which paragraph styles can be + * retrieved by their ID. + */ +public interface ParagraphStyleTable extends Iterable { + + public ParagraphStyle createStyle(); + + public void addStyle(int id, ParagraphStyle style); + + public ParagraphStyle styleFor(int id); + + public int countStyles(); + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java index 26842a8..238a69a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java @@ -15,120 +15,41 @@ */ package com.rtfparserkit.document; +import java.util.EnumSet; + /** - * Interface for setting style parameters. + * Interface style base class. Also defines a bunch of properties. */ public interface Style { - public enum Alignment { - LEFT, - RIGHT, - CENTER, - JUSTIFIED, - DISTRIBUTED, - } - - public enum TabAlignment { - LEFT, - CENTER, - RIGHT, - DECIMAL, + public enum Property { + ALIGNMENT, + SPACING_TOP, + SPACING_BOTTOM, + FIRST_LINE_INDENT, + LEFT_INDENT, + RIGHT_INDENT, + LINE_SPACING, + TABS, + FONT, + FONT_SIZE, + BOLD, + ITALIC, + UNDERLINED, + STRIKE_OUT, + CAPS, + BACKGROUND_COLOR, + FOREGROUND_COLOR } - public enum UnderlineStyle { - NONE, - SINGLE, - DOUBLE, - WORD, - DOTTED, - DASHED, - DASH_DOTTED, - DASH_DOT_DOTTED, - LONG_DASHED, - THICK, - THICK_DOTTED, - THICK_DASHED, - THICK_DASH_DOTTED, - THICK_DASH_DOT_DOTTED, - THICK_LONG_DASHED, - WAVE, - HEAVY_WAVE, - DOUBLE_WAVE - } - - public void resetToDefaults(); - - public void resetFontToDefaults(); - - public Style createDerivedStyle(); - - public Style createFlattenedStyle(); - - public boolean equals(Style other); + public void setName(String name); - public void setAlignment(Alignment alignment); - - public Alignment getAlignment(); - - public void setSpacingTop(float value); - - public float getSpacingTop(); - - public void setSpacingBottom(float value); - - public float getSpacingBottom(); - - public void setFirstLineIndent(float value); + public String getName(); - public float getFirstLineIndent(); - - public void setLeftIndent(float value); - - public float getLeftIndent(); - - public void setRightIndent(float value); - - public float getRightIndent(); + public EnumSet getOverriddenProperties(); - public void setLineSpacing(float value); - - public float getLineSpacing(); - - public void addTab(float position, TabAlignment aligment); - - public void setFont(Font font); - - public Font getFont(); - - public void setFontSize(float value); - - public float getFontSize(); - - public void setBold(boolean bold); - - public boolean getBold(); - - public void setItalic(boolean italic); - - public boolean getItalic(); - - public void setUnderlined(UnderlineStyle style); - - public UnderlineStyle getUnderlined(); - - public void setStrikeOut(boolean strikeOut); - - public boolean getStrikeOut(); - - public void setCaps(boolean caps); - - public boolean getCaps(); - - public void setBackgroundColor(Color color); - - public Color getBackgroundColor(); + public void resetToDefaults(); - public void setForegroundColor(Color color); + public boolean equals(Style other); - public Color getForegroundColor(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java index a12aa67..5b7b42e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java @@ -16,14 +16,16 @@ package com.rtfparserkit.document; /** - * Interface for adding a style definition to a global style sheet. + * Interface for adding a style definition to a global style sheet. The style + * sheet contains four style tables: Paragraph styles, character styles, + * section styles and table styles. Each have their own index name space. */ public interface StyleSheet { - public Style addStyle(); - - public int countStyles(); + public ParagraphStyleTable getParagraphStyleTable(); - public Style styleAt(int index); + public CharacterStyleTable getCharacterStyleTable(); + // TODO: Section style table + // TODO: Table style table } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java new file mode 100644 index 0000000..d79da3f --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java @@ -0,0 +1,255 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import java.util.EnumSet; + +import com.rtfparserkit.document.CharacterStyle; +import com.rtfparserkit.document.Color; +import com.rtfparserkit.document.Font; +import com.rtfparserkit.document.Style; + +/** + * Default CharacterStyle implementation + */ +public class DefaultCharacterStyle extends DefaultStyle + implements CharacterStyle { + + private final CharacterStyle parent; + + private Font font; + private float fontSize; + private boolean bold; + private boolean italic; + private UnderlineStyle underlineStyle; + private boolean strikeOut; + private boolean caps; + private Color backgroundColor; + private Color foregroundColor; + // TODO: Support more RTF properties + + static private final EnumSet CHARACTER_STYLE_PROPERTIES + = EnumSet.of( + Property.FONT, + Property.FONT_SIZE, + Property.BOLD, + Property.ITALIC, + Property.UNDERLINED, + Property.STRIKE_OUT, + Property.CAPS, + Property.BACKGROUND_COLOR, + Property.FOREGROUND_COLOR + ); + + public DefaultCharacterStyle() { + parent = null; + resetToDefaults(); + } + + public DefaultCharacterStyle(CharacterStyle other) { + parent = other; + } + + public void resetToDefaults() { + // TODO: Mechanics should probably be changed. Instead of having a + // method resetFontToDefaults() here, the StyleSheet should have methods + // to set and get the default style. And Style should have a method + // to set(Style other) to copy the values from the parameter. + // Then \plain can be handled by copying the default style. The problem + // is that there are RTF commands which define the default style values. + font = new DefaultFont("default"); + fontSize = 12.0f; + bold = false; + italic = false; + underlineStyle = UnderlineStyle.NONE; + strikeOut = false; + caps = false; + backgroundColor = DefaultColor.WHITE; + foregroundColor = DefaultColor.BLACK; + + overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); + } + + public CharacterStyle createDerivedStyle() { + return new DefaultCharacterStyle(this); + } + + public CharacterStyle createFlattenedStyle() { + DefaultCharacterStyle style = new DefaultCharacterStyle(); + style.copyFrom(this); + return style; + } + + protected void copyFrom(CharacterStyle style) { + font = style.getFont(); + fontSize = style.getFontSize(); + bold = style.getBold(); + italic = style.getItalic(); + underlineStyle = style.getUnderlined(); + strikeOut = style.getStrikeOut(); + caps = style.getCaps(); + backgroundColor = style.getBackgroundColor(); + foregroundColor = style.getForegroundColor(); + + overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); + } + + @Override + public boolean equals(Style object) { + if (object == this) + return true; + if (object == null || !(object instanceof DefaultCharacterStyle)) + return false; + if (!super.equals(object)) + return false; + + DefaultCharacterStyle other = (DefaultCharacterStyle) object; + return parent == other.parent + && (font != null ? font.equals(other.font) : other.font == null) + && fontSize == other.fontSize + && bold == other.bold + && italic == other.italic + && underlineStyle == other.underlineStyle + && strikeOut == other.strikeOut + && caps == other.caps + && backgroundColor == other.backgroundColor + && foregroundColor == other.foregroundColor; + } + + public void setFont(Font font) { + this.font = font; + overriddenProperties.add(Property.FONT); + } + + public Font getFont() { + if (overriddenProperties.contains(Property.BOLD)) + return font; + else + return parent.getFont(); + } + + public void setFontSize(float value) { + this.fontSize = value; + overriddenProperties.add(Property.FONT_SIZE); + } + + public float getFontSize() { + if (overriddenProperties.contains(Property.FONT_SIZE)) + return fontSize; + else + return parent.getFontSize(); + } + + public void setBold(boolean bold) { + this.bold = bold; + overriddenProperties.add(Property.BOLD); + } + + public boolean getBold() { + if (overriddenProperties.contains(Property.BOLD)) + return bold; + else + return parent.getBold(); + } + + public void setItalic(boolean italic) { + this.italic = italic; + overriddenProperties.add(Property.ITALIC); + } + + public boolean getItalic() { + if (overriddenProperties.contains(Property.ITALIC)) + return italic; + else + return parent.getItalic(); + } + + public void setUnderlined(UnderlineStyle style) { + this.underlineStyle = style; + overriddenProperties.add(Property.UNDERLINED); + } + + public UnderlineStyle getUnderlined() { + if (overriddenProperties.contains(Property.UNDERLINED)) + return underlineStyle; + else + return parent.getUnderlined(); + } + + public void setStrikeOut(boolean strikeOut) { + this.strikeOut = strikeOut; + overriddenProperties.add(Property.STRIKE_OUT); + } + + public boolean getStrikeOut() { + if (overriddenProperties.contains(Property.STRIKE_OUT)) + return strikeOut; + else + return parent.getStrikeOut(); + } + + public void setCaps(boolean caps) { + this.caps = caps; + overriddenProperties.add(Property.CAPS); + } + + public boolean getCaps() { + if (overriddenProperties.contains(Property.CAPS)) + return caps; + else + return parent.getCaps(); + } + + public void setBackgroundColor(Color color) { + if (color instanceof DefaultColor) { + backgroundColor = (DefaultColor) color; + overriddenProperties.add(Property.BACKGROUND_COLOR); + } + } + + public Color getBackgroundColor() { + if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) + return backgroundColor; + else + return parent.getBackgroundColor(); + } + + public void setForegroundColor(Color color) { + if (color instanceof DefaultColor) { + foregroundColor = (DefaultColor) color; + overriddenProperties.add(Property.FOREGROUND_COLOR); + } + } + + public Color getForegroundColor() { + if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) + return foregroundColor; + else + return parent.getForegroundColor(); + } + + @Override + public String toString() { + return "DefaultCharacterStyle(" + + (font != null ? font.getName() : "") + "@" + fontSize + ", " + + (bold ? "bold, " : "") + + (italic ? "italic, " : "") + + (underlineStyle != UnderlineStyle.NONE ? ("underline: " + underlineStyle.name() + ", ") : "") + + "fg: " + foregroundColor + ", " + + "bg: " + backgroundColor + + ")"; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java new file mode 100644 index 0000000..6f623e6 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.CharacterStyle; +import com.rtfparserkit.document.CharacterStyleTable; + +/** + * Default CharacterStyleTable implementation. + */ +public class DefaultCharacterStyleTable extends StyleTable + implements CharacterStyleTable { + + public CharacterStyle createStyle() { + return new DefaultCharacterStyle(); + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java index 0084996..9ed65c9 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -16,16 +16,16 @@ package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Chunk; -import com.rtfparserkit.document.Style; +import com.rtfparserkit.document.ParagraphStyle; /** * Default Chunk implementation. */ public class DefaultChunk implements Chunk { private final StringBuilder stringBuilder; - private final Style style; + private final ParagraphStyle style; - public DefaultChunk(Style style) { + public DefaultChunk(ParagraphStyle style) { stringBuilder = new StringBuilder(); this.style = style; } @@ -34,7 +34,7 @@ public String getText() { return stringBuilder.toString(); } - public Style getStyle() { + public ParagraphStyle getStyle() { return style; } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java index e25de44..43d877c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -21,7 +21,7 @@ import com.rtfparserkit.document.PageSettings; import com.rtfparserkit.document.Paragraph; import com.rtfparserkit.document.Section; -import com.rtfparserkit.document.Style; +import com.rtfparserkit.document.ParagraphStyle; /** * Default implementation of Document. Note that Document itself is also @@ -96,7 +96,7 @@ public void setPageHeight(int value) { * @param text The string to append * @param style The Style in which the appended string is to appear. */ - public void append(String text, Style style) { + public void append(String text, ParagraphStyle style) { getLastSection().append(text, style); } @@ -106,7 +106,7 @@ public void append(String text, Style style) { * * @param lastStyle The Style to be set on the previous paragraph. */ - public void nextParagraph(Style lastStyle) { + public void nextParagraph(ParagraphStyle lastStyle) { getLastSection().nextParagraph(lastStyle); } @@ -120,7 +120,7 @@ public void nextLine() { /** * @return The default Style created by the last Section. */ - public Style createDefaultStyle() { + public ParagraphStyle createDefaultStyle() { return getLastSection().createDefaultStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java index ee9e040..3469c1f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -22,20 +22,20 @@ import com.rtfparserkit.document.Chunk; import com.rtfparserkit.document.Element; import com.rtfparserkit.document.Paragraph; -import com.rtfparserkit.document.Style; +import com.rtfparserkit.document.ParagraphStyle; /** * Default Paragraph implementation */ public class DefaultParagraph implements Iterable, Paragraph { private final List chunks; - private Style style; + private ParagraphStyle style; public DefaultParagraph() { - this(new DefaultStyle()); + this(new DefaultParagraphStyle()); } - public DefaultParagraph(Style style) { + public DefaultParagraph(ParagraphStyle style) { chunks = new ArrayList(); this.style = style; } @@ -61,7 +61,7 @@ public Element elementAt(int index) { return chunks.get(index); } - public Style getStyle() { + public ParagraphStyle getStyle() { return style; } @@ -98,7 +98,7 @@ public void append(String string) { * @param string The string to append * @param style The Style in which the string is to appear */ - public void append(String string, Style style) { + public void append(String string, ParagraphStyle style) { if (string == null) throw new IllegalArgumentException("String may not be null!"); if (style == null) @@ -116,11 +116,11 @@ public void end() { end(getLastStyle()); } - public void end(Style lastStyle) { + public void end(ParagraphStyle lastStyle) { append("\n", lastStyle); } - public Style getLastStyle() { + public ParagraphStyle getLastStyle() { // Try to use the last used Style instead of the default style Chunk lastChunk = findLastChunk(); if (lastChunk != null) @@ -146,7 +146,7 @@ private void assertNotDelimited() { } } - private void appendString(String string, Style style) { + private void appendString(String string, ParagraphStyle style) { Chunk chunk = null; if (chunks.size() > 0) { Element last = chunks.get(chunks.size() - 1); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java new file mode 100644 index 0000000..c2ea551 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java @@ -0,0 +1,218 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import java.util.EnumSet; + +import com.rtfparserkit.document.CharacterStyle; +import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.document.Style; + +/** + * Default ParagraphStyle implementation + */ +public class DefaultParagraphStyle extends DefaultCharacterStyle + implements ParagraphStyle { + + private final ParagraphStyle parent; + + private Alignment alignment; + private float spacingTop; + private float spacingBottom; + private float firstLineIndent; + private float leftIndent; + private float rightIndent; + private float lineSpacing; + // TODO: Support more RTF properties + + public DefaultParagraphStyle() { + parent = null; + resetToDefaults(); + } + + public DefaultParagraphStyle(ParagraphStyle other) { + super(other); + parent = other; + } + + @Override + public void resetToDefaults() { + super.resetToDefaults(); + + alignment = Alignment.LEFT; + spacingTop = 0; + spacingBottom = 0; + firstLineIndent = 0; + leftIndent = 0; + rightIndent = 0; + lineSpacing = 0; + + overriddenProperties = EnumSet.allOf(Property.class); + } + + @Override + public ParagraphStyle createDerivedStyle() { + return new DefaultParagraphStyle(this); + } + + public CharacterStyle createDerivedCharacterStyle() { + return new DefaultCharacterStyle(this); + } + + @Override + public ParagraphStyle createFlattenedStyle() { + DefaultParagraphStyle style = new DefaultParagraphStyle(); + style.copyFrom(this); + return style; + } + + protected void copyFrom(ParagraphStyle style) { + super.copyFrom(style); + + alignment = style.getAlignment(); + spacingTop = style.getSpacingTop(); + spacingBottom = style.getSpacingBottom(); + firstLineIndent = style.getFirstLineIndent(); + leftIndent = style.getLeftIndent(); + rightIndent = style.getRightIndent(); + lineSpacing = style.getLineSpacing(); + + overriddenProperties = EnumSet.allOf(Property.class); + } + + @Override + public boolean equals(Style object) { + if (object == this) + return true; + if (object == null || !(object instanceof DefaultParagraphStyle)) + return false; + if (!super.equals(object)) + return false; + + DefaultParagraphStyle other = (DefaultParagraphStyle) object; + return parent == other.parent + && alignment == other.alignment + && spacingTop == other.spacingTop + && spacingBottom == other.spacingBottom + && firstLineIndent == other.firstLineIndent + && leftIndent == other.leftIndent + && rightIndent == other.rightIndent + && lineSpacing == other.lineSpacing; + } + + public void setAlignment(Alignment alignment) { + this.alignment = alignment; + overriddenProperties.add(Property.ALIGNMENT); + } + + public Alignment getAlignment() { + if (overriddenProperties.contains(Property.ALIGNMENT)) + return alignment; + else + return parent.getAlignment(); + } + + public void setSpacingTop(float value) { + spacingTop = value; + overriddenProperties.add(Property.SPACING_TOP); + } + + public float getSpacingTop() { + if (overriddenProperties.contains(Property.SPACING_TOP)) + return spacingTop; + else + return parent.getSpacingTop(); + } + + public void setSpacingBottom(float value) { + spacingBottom = value; + overriddenProperties.add(Property.SPACING_BOTTOM); + } + + public float getSpacingBottom() { + if (overriddenProperties.contains(Property.SPACING_BOTTOM)) + return spacingBottom; + else + return parent.getSpacingBottom(); + } + + public void setFirstLineIndent(float value) { + firstLineIndent = value; + overriddenProperties.add(Property.FIRST_LINE_INDENT); + } + + public float getFirstLineIndent() { + if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) + return firstLineIndent; + else + return parent.getFirstLineIndent(); + } + + public void setLeftIndent(float value) { + leftIndent = value; + overriddenProperties.add(Property.LEFT_INDENT); + } + + public float getLeftIndent() { + if (overriddenProperties.contains(Property.LEFT_INDENT)) + return leftIndent; + else + return parent.getLeftIndent(); + } + + public void setRightIndent(float value) { + rightIndent = value; + overriddenProperties.add(Property.RIGHT_INDENT); + } + + public float getRightIndent() { + if (overriddenProperties.contains(Property.RIGHT_INDENT)) + return rightIndent; + else + return parent.getRightIndent(); + } + + public void setLineSpacing(float value) { + lineSpacing = value; + overriddenProperties.add(Property.LINE_SPACING); + } + + public float getLineSpacing() { + if (overriddenProperties.contains(Property.LINE_SPACING)) + return lineSpacing; + else + return parent.getLineSpacing(); + } + + public void addTab(float position, TabAlignment aligment) { + // TODO Auto-generated method stub + } + + @Override + public String toString() { + return "ParagraphStyle(" + + alignment.name() + ", " + + (getFont() != null ? getFont().getName() : "") + + "@" + getFontSize() + ", " + + (getBold() ? "bold, " : "") + + (getItalic() ? "italic, " : "") + + (getUnderlined() != UnderlineStyle.NONE + ? ("underline: " + getUnderlined().name() + ", ") : "") + + "fg: " + getForegroundColor() + ", " + + "bg: " + getBackgroundColor() + + ")"; + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java new file mode 100644 index 0000000..7839df3 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.document.ParagraphStyleTable; + +/** + * Default ParagraphStyleTable implementation. + */ +public class DefaultParagraphStyleTable extends StyleTable + implements ParagraphStyleTable { + + public ParagraphStyle createStyle() { + return new DefaultParagraphStyle(); + } + +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java index fcaa31a..b98e4cf 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java @@ -17,366 +17,40 @@ import java.util.EnumSet; -import com.rtfparserkit.document.Color; -import com.rtfparserkit.document.Font; import com.rtfparserkit.document.Style; /** * Default Style implementation */ -public class DefaultStyle implements Style { +abstract class DefaultStyle implements Style { - public enum Property { - ALIGNMENT, SPACING_TOP, SPACING_BOTTOM, FIRST_LINE_INDENT, LEFT_INDENT, - RIGHT_INDENT, LINE_SPACING, TABS, FONT, FONT_SIZE, BOLD, ITALIC, - UNDERLINED, STRIKE_OUT, CAPS, BACKGROUND_COLOR, FOREGROUND_COLOR - } - - private final Style parent; - private EnumSet overriddenProperties; - - private Alignment alignment; - private float spacingTop; - private float spacingBottom; - private float firstLineIndent; - private float leftIndent; - private float rightIndent; - private float lineSpacing; - private Font font; - private float fontSize; - // TODO: ... - private boolean bold; - private boolean italic; - private UnderlineStyle underlineStyle; - private boolean strikeOut; - private boolean caps; - private Color backgroundColor; - private Color foregroundColor; + private String name; + protected EnumSet overriddenProperties; - public DefaultStyle() { - parent = null; - resetToDefaults(); - } - - public DefaultStyle(Style other) { - parent = other; + protected DefaultStyle() { overriddenProperties = EnumSet.noneOf(Property.class); } - public void resetToDefaults() { - alignment = Alignment.LEFT; - spacingTop = 0; - spacingBottom = 0; - firstLineIndent = 0; - leftIndent = 0; - rightIndent = 0; - lineSpacing = 0; - // TODO: ... - overriddenProperties = EnumSet.allOf(Property.class); - - resetFontToDefaults(); + public void setName(String name) { + this.name = name; } - public void resetFontToDefaults() { - // TODO: Mechanics should probably be changed. Instead of having a - // method resetFontToDefaults() here, the StyleSheet should have methods - // to set and get the default style. And Style should have a method - // to set(Style other) to copy the values from the parameter. - // Then \plain can be handled by copying the default style. The problem - // is that there are RTF commands which define the default style values. - font = new DefaultFont("default"); - fontSize = 12.0f; - bold = false; - italic = false; - underlineStyle = UnderlineStyle.NONE; - strikeOut = false; - caps = false; - backgroundColor = DefaultColor.WHITE; - foregroundColor = DefaultColor.BLACK; - - overriddenProperties.addAll(EnumSet.of( - Property.FONT, - Property.FONT_SIZE, - Property.BOLD, - Property.ITALIC, - Property.UNDERLINED, - Property.STRIKE_OUT, - Property.CAPS, - Property.BACKGROUND_COLOR, - Property.FOREGROUND_COLOR - )); + public String getName() { + return name; } - public Style createDerivedStyle() { - return new DefaultStyle(this); + public EnumSet getOverriddenProperties() { + return overriddenProperties; } - - public Style createFlattenedStyle() { - DefaultStyle style = new DefaultStyle(); - style.copyFrom(this); - return style; - } - - private void copyFrom(Style style) { - alignment = style.getAlignment(); - spacingTop = style.getSpacingTop(); - spacingBottom = style.getSpacingBottom(); - firstLineIndent = style.getFirstLineIndent(); - leftIndent = style.getLeftIndent(); - rightIndent = style.getRightIndent(); - lineSpacing = style.getLineSpacing(); - // TODO: ... - font = style.getFont(); - fontSize = style.getFontSize(); - bold = style.getBold(); - italic = style.getItalic(); - underlineStyle = style.getUnderlined(); - strikeOut = style.getStrikeOut(); - caps = style.getCaps(); - backgroundColor = style.getBackgroundColor(); - foregroundColor = style.getForegroundColor(); - overriddenProperties = EnumSet.allOf(Property.class); - } - public boolean equals(Style object) { if (object == this) return true; - if (object == null || object.getClass() != DefaultStyle.class) + if (object == null || !(object instanceof DefaultStyle)) return false; DefaultStyle other = (DefaultStyle) object; - return parent == other.parent - && overriddenProperties.equals(other.overriddenProperties) - && alignment == other.alignment - && spacingTop == other.spacingTop - && spacingBottom == other.spacingBottom - && firstLineIndent == other.firstLineIndent - && leftIndent == other.leftIndent - && rightIndent == other.rightIndent - && lineSpacing == other.lineSpacing - // TODO: ... - && (font != null ? font.equals(other.font) : other.font == null) - && fontSize == other.fontSize - && bold == other.bold - && italic == other.italic - && underlineStyle == other.underlineStyle - && strikeOut == other.strikeOut - && caps == other.caps - && backgroundColor == other.backgroundColor - && foregroundColor == other.foregroundColor; - } - - public void setAlignment(Alignment alignment) { - this.alignment = alignment; - overriddenProperties.add(Property.ALIGNMENT); - } - - public Alignment getAlignment() { - if (overriddenProperties.contains(Property.ALIGNMENT)) - return alignment; - else - return parent.getAlignment(); - } - - public void setSpacingTop(float value) { - spacingTop = value; - overriddenProperties.add(Property.SPACING_TOP); - } - - public float getSpacingTop() { - if (overriddenProperties.contains(Property.SPACING_TOP)) - return spacingTop; - else - return parent.getSpacingTop(); - } - - public void setSpacingBottom(float value) { - spacingBottom = value; - overriddenProperties.add(Property.SPACING_BOTTOM); - } - - public float getSpacingBottom() { - if (overriddenProperties.contains(Property.SPACING_BOTTOM)) - return spacingBottom; - else - return parent.getSpacingBottom(); - } - - public void setFirstLineIndent(float value) { - firstLineIndent = value; - overriddenProperties.add(Property.FIRST_LINE_INDENT); - } - - public float getFirstLineIndent() { - if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) - return firstLineIndent; - else - return parent.getFirstLineIndent(); - } - - public void setLeftIndent(float value) { - leftIndent = value; - overriddenProperties.add(Property.LEFT_INDENT); - } - - public float getLeftIndent() { - if (overriddenProperties.contains(Property.LEFT_INDENT)) - return leftIndent; - else - return parent.getLeftIndent(); - } - - public void setRightIndent(float value) { - rightIndent = value; - overriddenProperties.add(Property.RIGHT_INDENT); - } - - public float getRightIndent() { - if (overriddenProperties.contains(Property.RIGHT_INDENT)) - return rightIndent; - else - return parent.getRightIndent(); - } - - public void setLineSpacing(float value) { - lineSpacing = value; - overriddenProperties.add(Property.LINE_SPACING); - } - - public float getLineSpacing() { - if (overriddenProperties.contains(Property.LINE_SPACING)) - return lineSpacing; - else - return parent.getLineSpacing(); - } - - public void addTab(float position, TabAlignment aligment) { - // TODO Auto-generated method stub - } - - public void setFont(Font font) { - this.font = font; - overriddenProperties.add(Property.FONT); - } - - public Font getFont() { - if (overriddenProperties.contains(Property.BOLD)) - return font; - else - return parent.getFont(); - } - - public void setFontSize(float value) { - this.fontSize = value; - overriddenProperties.add(Property.FONT_SIZE); - } - - public float getFontSize() { - if (overriddenProperties.contains(Property.FONT_SIZE)) - return fontSize; - else - return parent.getFontSize(); - } - - public void setBold(boolean bold) { - this.bold = bold; - overriddenProperties.add(Property.BOLD); - } - - public boolean getBold() { - if (overriddenProperties.contains(Property.BOLD)) - return bold; - else - return parent.getBold(); - } - - public void setItalic(boolean italic) { - this.italic = italic; - overriddenProperties.add(Property.ITALIC); - } - - public boolean getItalic() { - if (overriddenProperties.contains(Property.ITALIC)) - return italic; - else - return parent.getItalic(); - } - - public void setUnderlined(UnderlineStyle style) { - this.underlineStyle = style; - overriddenProperties.add(Property.UNDERLINED); - } - - public UnderlineStyle getUnderlined() { - if (overriddenProperties.contains(Property.UNDERLINED)) - return underlineStyle; - else - return parent.getUnderlined(); - } - - public void setStrikeOut(boolean strikeOut) { - this.strikeOut = strikeOut; - overriddenProperties.add(Property.STRIKE_OUT); - } - - public boolean getStrikeOut() { - if (overriddenProperties.contains(Property.STRIKE_OUT)) - return strikeOut; - else - return parent.getStrikeOut(); - } - - public void setCaps(boolean caps) { - this.caps = caps; - overriddenProperties.add(Property.CAPS); - } - - public boolean getCaps() { - if (overriddenProperties.contains(Property.CAPS)) - return caps; - else - return parent.getCaps(); - } - - public void setBackgroundColor(Color color) { - if (color instanceof DefaultColor) { - backgroundColor = (DefaultColor) color; - overriddenProperties.add(Property.BACKGROUND_COLOR); - } - } - - public Color getBackgroundColor() { - if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) - return backgroundColor; - else - return parent.getBackgroundColor(); - } - - public void setForegroundColor(Color color) { - if (color instanceof DefaultColor) { - foregroundColor = (DefaultColor) color; - overriddenProperties.add(Property.FOREGROUND_COLOR); - } - } - - public Color getForegroundColor() { - if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) - return foregroundColor; - else - return parent.getForegroundColor(); - } - - @Override - public String toString() { - return "DefaultStyle(" - + alignment.name() + ", " - + (font != null ? font.getName() : "") + "@" + fontSize + ", " - + (bold ? "bold, " : "") - + (italic ? "italic, " : "") - + (underlineStyle != UnderlineStyle.NONE ? ("underline: " + underlineStyle.name() + ", ") : "") - + "fg: " + foregroundColor + ", " - + "bg: " + backgroundColor - + ")"; + return (name != null ? name.equals(other.name) : other.name == null) + && overriddenProperties.equals(other.overriddenProperties); } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java index 90eb89f..fa4cc12 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java @@ -1,29 +1,39 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.rtfparserkit.document.impl; -import java.util.ArrayList; -import java.util.List; - +import com.rtfparserkit.document.CharacterStyleTable; +import com.rtfparserkit.document.ParagraphStyleTable; import com.rtfparserkit.document.StyleSheet; -public class DefaultStyleSheet implements StyleSheet { +class DefaultStyleSheet implements StyleSheet { - private final List styles; - - public DefaultStyleSheet() { - styles = new ArrayList(); + private final ParagraphStyleTable paragraphStyleTable; + private final CharacterStyleTable characterStyleTable; + + DefaultStyleSheet() { + paragraphStyleTable = new DefaultParagraphStyleTable(); + characterStyleTable = new DefaultCharacterStyleTable(); } - public DefaultStyle addStyle() { - DefaultStyle style = new DefaultStyle(); - styles.add(style); - return style; + public ParagraphStyleTable getParagraphStyleTable() { + return paragraphStyleTable; } - public int countStyles() { - return styles.size(); - } - - public DefaultStyle styleAt(int index) { - return styles.get(index); + public CharacterStyleTable getCharacterStyleTable() { + return characterStyleTable; } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java index 37e3aa1..21cc46a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -22,7 +22,7 @@ import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.DocumentPart; import com.rtfparserkit.document.Paragraph; -import com.rtfparserkit.document.Style; +import com.rtfparserkit.document.ParagraphStyle; /** * A list of Paragraph objects. There is always at least one, empty paragraph @@ -51,7 +51,7 @@ public Iterator iterator() { * Finalizes the current paragraph by appending a line-break character '\n'. * Starts the next paragraph by appending a new empty Paragraph to the list. */ - public void nextParagraph(Style lastStyle) { + public void nextParagraph(ParagraphStyle lastStyle) { if (countParagraphs() > 0) getLastParagraph().end(lastStyle); paragraphs.add(new DefaultParagraph()); @@ -75,8 +75,8 @@ public String getText() { return builder.toString(); } - public Style createDefaultStyle() { - return new DefaultStyle(); + public ParagraphStyle createDefaultStyle() { + return new DefaultParagraphStyle(); } /** @@ -91,7 +91,7 @@ public Style createDefaultStyle() { * * @see #nextParagraph() */ - public void append(String text, Style style) { + public void append(String text, ParagraphStyle style) { int offset = 0; while (offset < text.length()) { int nextLineBreak = text.indexOf('\n', offset); @@ -110,7 +110,7 @@ public void append(String text, Style style) { } public void append(String string) { - Style style = getLastParagraph().getLastStyle(); + ParagraphStyle style = getLastParagraph().getLastStyle(); append(string, style); } @@ -127,7 +127,7 @@ public Annotation appendAnnotation() { public void clear() { paragraphs.clear(); // Add the initial empty paragraph - nextParagraph(new DefaultStyle()); + nextParagraph(new DefaultParagraphStyle()); } /** diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java new file mode 100644 index 0000000..627ebf7 --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.document.impl; + +import java.util.HashMap; +import java.util.Iterator; + +import com.rtfparserkit.document.Style; + +/** + * A table of Style objects. Styles can be added and retrieved by ID. + */ +class StyleTable implements Iterable { + private final HashMap styles; + + StyleTable() { + styles = new HashMap(); + } + + public Iterator iterator() { + return styles.values().iterator(); + } + + public void addStyle(int id, E style) { + styles.put(id, style); + } + + public int countStyles() { + return styles.size(); + } + + public E styleFor(int id) { + return styles.get(id); + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java new file mode 100644 index 0000000..1d1b80d --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.CharacterStyle; +import com.rtfparserkit.rtf.Command; + +/** + * RtfContext for parsing a style definition group located in the style sheet + * section of an RTF document. + */ +class CharacterStyleContext extends AbstractRtfContext { + + private final CharacterStyle style; + + CharacterStyleContext(CharacterStyle style) { + this.style = style; + } + + @Override + public void processGroupStart(RtfContextStack stack) { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processString(String string) { + int semicolon = string.indexOf(';'); + int end = semicolon >= 0 ? semicolon : string.length(); + string = string.substring(0, end); + style.setName(string); + } + + @Override + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // TODO: Implement + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java index be71b0f..55bd0c2 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java @@ -32,6 +32,7 @@ public class DocumentBuilder implements IRtfListener { private int level = 0; private boolean atGroupStart = false; + private boolean debugEvents = false; private final RtfContextStack stack; @@ -39,6 +40,10 @@ public DocumentBuilder(Document document) { stack = new RtfContextStack(new RootContext(document)); } + public void setDebugEvents(boolean debug) { + debugEvents = debug; + } + public void processDocumentStart() { } @@ -51,7 +56,8 @@ public void processGroupStart() { public void processGroupEnd() { handleDelayedGroupStart(); - System.out.println(getIndentation() + "processGroupEnd()"); + if (debugEvents) + System.out.println(getIndentation() + "processGroupEnd()"); stack.getContext().processGroupEnd(stack); level--; atGroupStart = false; @@ -59,19 +65,22 @@ public void processGroupEnd() { public void processCharacterBytes(byte[] data) { handleDelayedGroupStart(); - System.out.println(getIndentation() + "processCharacterBytes()"); + if (debugEvents) + System.out.println(getIndentation() + "processCharacterBytes()"); stack.getContext().processCharacterBytes(data); } public void processBinaryBytes(byte[] data) { handleDelayedGroupStart(); - System.out.println(getIndentation() + "processBinaryBytes()"); + if (debugEvents) + System.out.println(getIndentation() + "processBinaryBytes()"); stack.getContext().processBinaryBytes(data); } public void processString(String string) { handleDelayedGroupStart(); - System.out.println(getIndentation() + "processString(" + string + ")"); + if (debugEvents) + System.out.println(getIndentation() + "processString(" + string + ")"); stack.getContext().processString(string); } @@ -79,9 +88,23 @@ public void processCommand(Command command, int parameter, boolean hasParameter, boolean optional) { if (atGroupStart) { // Handle delayed group start. - if (command.getCommandType() == CommandType.Destination) { - System.out.println(getIndentation() + "processGroupStart(" - + command + ")"); + if (command == Command.optionalcommand) { + // Optional group with an unknown command, completely ignore + // this. + if (debugEvents) { + System.out.println(getIndentation() + "processGroupStart(" + + command + ")"); + } + level++; + stack.pushContext(new NullContext()); + // Do not handle this command as processCommand() a second time. + groupStarted(); + return; + } if (command.getCommandType() == CommandType.Destination) { + if (debugEvents) { + System.out.println(getIndentation() + "processGroupStart(" + + command + ")"); + } level++; stack.getContext().processGroupStart(stack, command, parameter, hasParameter, optional); @@ -93,12 +116,14 @@ public void processCommand(Command command, int parameter, } } - System.out.print(getIndentation() + "processCommand() " + command); - if (hasParameter) - System.out.print(", parameter: " + parameter); - if (optional) - System.out.print(" (optional)"); - System.out.println(); + if (debugEvents) { + System.out.print(getIndentation() + "processCommand() " + command); + if (hasParameter) + System.out.print(", parameter: " + parameter); + if (optional) + System.out.print(" (optional)"); + System.out.println(); + } stack.getContext().processCommand(stack, command, parameter, hasParameter, optional); @@ -115,7 +140,8 @@ private String getIndentation() { private void handleDelayedGroupStart() { if (atGroupStart) { - System.out.println(getIndentation() + "processGroupStart()"); + if (debugEvents) + System.out.println(getIndentation() + "processGroupStart()"); level++; stack.getContext().processGroupStart(stack); groupStarted(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java index 8242118..c990363 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java @@ -50,6 +50,9 @@ public void processGroupStart(RtfContextStack stack, Command command, case fonttbl: stack.pushContext(new FontTableContext(document.getFontTable())); break; + case stylesheet: + stack.pushContext(new StyleSheetContext(document.getStyleSheet())); + break; default: // Unknown destinations should be ignored. diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 1e45386..096c647 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -18,9 +18,9 @@ import com.rtfparserkit.document.Annotation; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.DocumentPart; -import com.rtfparserkit.document.Style; -import com.rtfparserkit.document.Style.Alignment; -import com.rtfparserkit.document.Style.UnderlineStyle; +import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.document.ParagraphStyle.Alignment; +import com.rtfparserkit.document.CharacterStyle.UnderlineStyle; import com.rtfparserkit.rtf.Command; /** @@ -31,7 +31,7 @@ class DocumentPartContext extends AbstractRtfContext { private final DocumentPart documentPart; protected final Document document; - private final Style style; + private final ParagraphStyle style; private Annotation currentAnnotation; @@ -117,7 +117,7 @@ public void processCommand(RtfContextStack stack, Command command, // Text styles case plain: - style.resetFontToDefaults(); + style.resetToDefaults(); break; case f: style.setFont(document.getFontTable().fontAt(parameter)); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java new file mode 100644 index 0000000..ce3b94d --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.rtf.Command; + +/** + * RtfContext for parsing a style definition group located in the style sheet + * section of an RTF document. + */ +class ParagraphStyleContext extends AbstractRtfContext { + + private final ParagraphStyle style; + + ParagraphStyleContext(ParagraphStyle style) { + this.style = style; + } + + @Override + public void processGroupStart(RtfContextStack stack) { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processString(String string) { + int semicolon = string.indexOf(';'); + int end = semicolon >= 0 ? semicolon : string.length(); + string = string.substring(0, end); + style.setName(string); + } + + @Override + public void processCommand(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // TODO: Implement + } +} diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java new file mode 100644 index 0000000..fe048fb --- /dev/null +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Stephan Aßmus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rtfparserkit.parser.builder; + +import com.rtfparserkit.document.CharacterStyle; +import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.document.StyleSheet; +import com.rtfparserkit.rtf.Command; + +/** + * Processes RTF events that may be encountered in the style sheet section of + * the file. + */ +class StyleSheetContext extends NullContext { + + private final StyleSheet styleSheet; + + StyleSheetContext(StyleSheet styleSheet) { + this.styleSheet = styleSheet; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, + int parameter, boolean hasParameter, boolean optional) { + // The Style Sheet should only contain style definition groups. These + // can start with one of these commands, + switch (command) { + case s: + { + // Paragraph style + ParagraphStyle style = styleSheet.getParagraphStyleTable() + .createStyle(); + styleSheet.getParagraphStyleTable().addStyle(parameter, style); + stack.pushContext(new ParagraphStyleContext(style)); + break; + } + case cs: + { + // Character style + CharacterStyle style = styleSheet.getCharacterStyleTable() + .createStyle(); + styleSheet.getCharacterStyleTable().addStyle(parameter, style); + stack.pushContext(new CharacterStyleContext(style)); + break; + } + case ds: + // TODO: Section style + stack.pushContext(new NullContext()); + break; + case ts: + // TODO: Table style + stack.pushContext(new NullContext()); + break; + default: + stack.pushContext(new NullContext()); + break; + } + } +} diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java index 51a15c5..274658b 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -22,9 +22,9 @@ public class BuilderParseTest { @Test - public void testParagraphContents() { + public void testParagraphContentsIText() { DefaultDocument document = new DefaultDocument(); - parseStream("lineSeparator", document); + parseStream("lineSeparator", document, false); Section section = document.getLastSection(); @@ -54,6 +54,20 @@ public void testParagraphContents() { assertEquals(2, document.getColorTable().countColors()); } + @Test + public void testParagraphContentsLibreOffice() { + DefaultDocument document = new DefaultDocument(); + parseStream("annotationLibreOffice", document, true); + + Section section = document.getLastSection(); + + int paragraphCount = section.countParagraphs(); + assertEquals(2, paragraphCount); + + assertEquals("This word is commented.\n", + section.paragraphAt(0).getText()); + } + @Test public void testStyles() { @@ -67,7 +81,7 @@ public void testStyles() { System.out.println("################################"); DefaultDocument document = new DefaultDocument(); - parseStream(file, document); + parseStream(file, document, false); assertEquals(1, document.countSections()); Section section = document.sectionAt(0); @@ -78,7 +92,7 @@ public void testStyles() { @Test public void testAnnotations() { DefaultDocument document = new DefaultDocument(); - parseStream("annotationSpec", document); + parseStream("annotationSpec", document, false); Section section = document.sectionAt(0); @@ -164,14 +178,16 @@ private void assertNormalBoldItalic(Paragraph paragraph) { assertFalse(chunk.getStyle().getItalic()); } - private void parseStream(String fileName, Document document) { + private void parseStream(String fileName, Document document, + boolean debug) { InputStream is = null; try { is = BuilderParseTest.class.getResourceAsStream("data/" + fileName + ".rtf"); StandardRtfParser parser = new StandardRtfParser(); - parser.parse(new RtfStreamSource(is), - new DocumentBuilder(document)); + DocumentBuilder builder = new DocumentBuilder(document); + builder.setDebugEvents(debug); + parser.parse(new RtfStreamSource(is), builder); } catch (IOException e) { e.printStackTrace(); } finally { From 1008919e8d55da42e78bf3444b43110fc6306705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 21:33:33 +0200 Subject: [PATCH 06/16] Auto formatting cleanup. --- .../com/rtfparserkit/document/Annotation.java | 28 +- .../rtfparserkit/document/CharacterStyle.java | 111 ++-- .../document/CharacterStyleTable.java | 18 +- .../src/com/rtfparserkit/document/Chunk.java | 12 +- .../src/com/rtfparserkit/document/Color.java | 16 +- .../com/rtfparserkit/document/ColorTable.java | 14 +- .../com/rtfparserkit/document/Document.java | 36 +- .../rtfparserkit/document/DocumentPart.java | 26 +- .../document/DocumentSettings.java | 7 +- .../com/rtfparserkit/document/Element.java | 4 +- .../src/com/rtfparserkit/document/Font.java | 11 +- .../com/rtfparserkit/document/FontTable.java | 29 +- .../src/com/rtfparserkit/document/Footer.java | 4 +- .../src/com/rtfparserkit/document/Header.java | 4 +- .../rtfparserkit/document/PageSettings.java | 28 +- .../com/rtfparserkit/document/Paragraph.java | 11 +- .../rtfparserkit/document/ParagraphStyle.java | 101 ++-- .../document/ParagraphStyleTable.java | 18 +- .../com/rtfparserkit/document/Section.java | 20 +- .../src/com/rtfparserkit/document/Style.java | 49 +- .../com/rtfparserkit/document/StyleSheet.java | 12 +- .../src/com/rtfparserkit/document/Text.java | 6 +- .../document/impl/DefaultAnnotation.java | 73 +-- .../document/impl/DefaultCharacterStyle.java | 456 +++++++-------- .../impl/DefaultCharacterStyleTable.java | 12 +- .../document/impl/DefaultChunk.java | 42 +- .../document/impl/DefaultColor.java | 82 +-- .../document/impl/DefaultColorTable.java | 44 +- .../document/impl/DefaultDocument.java | 291 +++++----- .../document/impl/DefaultFont.java | 56 +- .../document/impl/DefaultFontTable.java | 45 +- .../document/impl/DefaultFooter.java | 5 +- .../document/impl/DefaultHeader.java | 5 +- .../document/impl/DefaultParagraph.java | 308 +++++----- .../document/impl/DefaultParagraphStyle.java | 390 ++++++------- .../impl/DefaultParagraphStyleTable.java | 12 +- .../document/impl/DefaultSection.java | 142 +++-- .../document/impl/DefaultStyle.java | 68 ++- .../document/impl/DefaultStyleSheet.java | 33 +- .../document/impl/PageMargins.java | 12 +- .../rtfparserkit/document/impl/PageSize.java | 8 +- .../document/impl/ParagraphList.java | 322 ++++++----- .../document/impl/SectionList.java | 146 ++--- .../document/impl/StyleTable.java | 51 +- .../parser/builder/AbstractRtfContext.java | 88 +-- .../parser/builder/AnnotationContext.java | 165 +++--- .../parser/builder/CharacterStyleContext.java | 73 +-- .../parser/builder/ColorTableContext.java | 79 +-- .../parser/builder/DocumentBuilder.java | 266 +++++---- .../parser/builder/DocumentContext.java | 145 +++-- .../parser/builder/DocumentPartContext.java | 541 +++++++++--------- .../builder/DocumentSettingsContext.java | 70 ++- .../parser/builder/FontContext.java | 211 +++---- .../parser/builder/FontTableContext.java | 30 +- .../parser/builder/NullContext.java | 71 +-- .../parser/builder/ParagraphStyleContext.java | 73 +-- .../parser/builder/RootContext.java | 61 +- .../parser/builder/RtfContext.java | 20 +- .../parser/builder/RtfContextStack.java | 80 +-- .../parser/builder/StyleSheetContext.java | 88 +-- .../parser/builder/TimeContext.java | 115 ++-- .../document/ParagraphListTest.java | 91 +-- .../rtfparserkit/document/ParagraphTest.java | 202 +++---- .../parser/builder/BuilderParseTest.java | 367 ++++++------ 64 files changed, 3157 insertions(+), 2847 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java index 82405ab..69c43cf 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Annotation.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; import java.util.Date; @@ -22,18 +23,19 @@ * via the DocumentPart functionality. Note that this would mean support for * nested annotations. */ -public interface Annotation extends DocumentPart { - - public void setId(String id); - - public String getId(); - - public void setAuthor(String author); - - public String getAuthor(); - - public void setDate(Date date); - - public Date getDate(); +public interface Annotation extends DocumentPart +{ + + public void setId(String id); + + public String getId(); + + public void setAuthor(String author); + + public String getAuthor(); + + public void setDate(Date date); + + public Date getDate(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java index fd9dcbc..79fcbc8 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java @@ -13,73 +13,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.rtfparserkit.document; +package com.rtfparserkit.document; /** * Interface for storing paragraph style parameters. */ -public interface CharacterStyle extends Style { - - public enum UnderlineStyle { - NONE, - SINGLE, - DOUBLE, - WORD, - DOTTED, - DASHED, - DASH_DOTTED, - DASH_DOT_DOTTED, - LONG_DASHED, - THICK, - THICK_DOTTED, - THICK_DASHED, - THICK_DASH_DOTTED, - THICK_DASH_DOT_DOTTED, - THICK_LONG_DASHED, - WAVE, - HEAVY_WAVE, - DOUBLE_WAVE - } - - public CharacterStyle createDerivedStyle(); - - public CharacterStyle createFlattenedStyle(); - - public void setFont(Font font); - - public Font getFont(); - - public void setFontSize(float value); - - public float getFontSize(); - - public void setBold(boolean bold); - - public boolean getBold(); - - public void setItalic(boolean italic); - - public boolean getItalic(); - - public void setCaps(boolean caps); - - public boolean getCaps(); - - public void setStrikeOut(boolean strikeOut); - - public boolean getStrikeOut(); - - public void setUnderlined(UnderlineStyle style); - - public UnderlineStyle getUnderlined(); - - public void setBackgroundColor(Color color); - - public Color getBackgroundColor(); - - public void setForegroundColor(Color color); - - public Color getForegroundColor(); +public interface CharacterStyle extends Style +{ + + public enum UnderlineStyle + { + NONE, SINGLE, DOUBLE, WORD, DOTTED, DASHED, DASH_DOTTED, DASH_DOT_DOTTED, LONG_DASHED, THICK, THICK_DOTTED, THICK_DASHED, THICK_DASH_DOTTED, THICK_DASH_DOT_DOTTED, THICK_LONG_DASHED, WAVE, HEAVY_WAVE, DOUBLE_WAVE + } + + public CharacterStyle createDerivedStyle(); + + public CharacterStyle createFlattenedStyle(); + + public void setFont(Font font); + + public Font getFont(); + + public void setFontSize(float value); + + public float getFontSize(); + + public void setBold(boolean bold); + + public boolean getBold(); + + public void setItalic(boolean italic); + + public boolean getItalic(); + + public void setCaps(boolean caps); + + public boolean getCaps(); + + public void setStrikeOut(boolean strikeOut); + + public boolean getStrikeOut(); + + public void setUnderlined(UnderlineStyle style); + + public UnderlineStyle getUnderlined(); + + public void setBackgroundColor(Color color); + + public Color getBackgroundColor(); + + public void setForegroundColor(Color color); + + public Color getForegroundColor(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java index 9b1c1d7..2113f6b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyleTable.java @@ -13,20 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for style table in which character styles can be * retrieved by their ID. */ -public interface CharacterStyleTable extends Iterable { +public interface CharacterStyleTable extends Iterable +{ + + public CharacterStyle createStyle(); + + public void addStyle(int id, CharacterStyle style); + + public CharacterStyle styleFor(int id); - public CharacterStyle createStyle(); - - public void addStyle(int id, CharacterStyle style); - - public CharacterStyle styleFor(int id); - - public int countStyles(); + public int countStyles(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java index cf3f6de..6e64d44 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * A chunk of text with a certain style. */ -public interface Chunk extends Element { +public interface Chunk extends Element +{ + + public String getText(); - public String getText(); - - public ParagraphStyle getStyle(); + public ParagraphStyle getStyle(); - public void append(String string); + public void append(String string); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Color.java b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java index 2df1b6b..162db98 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Color.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Color.java @@ -13,17 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Represents a color that can be placed in the ColorTable. */ -public interface Color { +public interface Color +{ + + public int getRed(); + + public int getGreen(); + + public int getBlue(); - public int getRed(); - - public int getGreen(); - - public int getBlue(); - } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java index 71a65c5..13cdcad 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ColorTable.java @@ -13,17 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for adding a color to the global color table and retrieving * a Color instance at a specific index. */ -public interface ColorTable { +public interface ColorTable +{ + + public void addColor(int red, int green, int blue); + + public int countColors(); - public void addColor(int red, int green, int blue); - - public int countColors(); - - public Color colorAt(int index); + public Color colorAt(int index); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Document.java b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java index 1535ab6..546b23f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Document.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Document.java @@ -13,26 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for getting to all relevant parts of the document model. */ -public interface Document extends DocumentPart { - - public FontTable getFontTable(); - - public ColorTable getColorTable(); - - public StyleSheet getStyleSheet(); - - public DocumentSettings getDocumentSettings(); - - public int countSections(); - - public Section sectionAt(int index); - - public void nextSection(); - - public Section getLastSection(); +public interface Document extends DocumentPart +{ + + public FontTable getFontTable(); + + public ColorTable getColorTable(); + + public StyleSheet getStyleSheet(); + + public DocumentSettings getDocumentSettings(); + + public int countSections(); + + public Section sectionAt(int index); + + public void nextSection(); + + public Section getLastSection(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java index 389456d..8498ea1 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** @@ -20,19 +21,20 @@ * String representation of all contained text can be obtained via the Text * functionality. */ -public interface DocumentPart extends Text { +public interface DocumentPart extends Text +{ + + public int countParagraphs(); + + public Paragraph paragraphAt(int index); + + public void append(String text, ParagraphStyle style); + + public void nextParagraph(ParagraphStyle lastStyle); - public int countParagraphs(); - - public Paragraph paragraphAt(int index); + public void nextLine(); - public void append(String text, ParagraphStyle style); - - public void nextParagraph(ParagraphStyle lastStyle); - - public void nextLine(); + public Annotation appendAnnotation(); - public Annotation appendAnnotation(); - - public ParagraphStyle createDefaultStyle(); + public ParagraphStyle createDefaultStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java index 6256fdd..46b3c31 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentSettings.java @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for controlling global settings of the document. */ -public interface DocumentSettings { - - public PageSettings getPageSettings(); +public interface DocumentSettings +{ + public PageSettings getPageSettings(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Element.java b/RTF Parser Kit/src/com/rtfparserkit/document/Element.java index ccf25a7..8a1bda3 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Element.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Element.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Base type for various possible children of a Paragraph. */ -public interface Element { +public interface Element +{ } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Font.java b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java index 4eae3b5..3ebb181 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Font.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Font.java @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Simple interface for storing font information. */ -public interface Font { - - public void setName(String name); +public interface Font +{ + public void setName(String name); - public String getName(); + public String getName(); - public boolean equals(Font other); + public boolean equals(Font other); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java index 01b51bd..3d5b632 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java @@ -13,29 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for adding a font definition to the global font table and * retrieving the font information at a specific index. */ -public interface FontTable { +public interface FontTable +{ + + public enum FontFamily + { + DEFAULT, ROMAN, SWISS, MODERN, SCRIPT, DECOR, TECH, BIDI + } + + public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily); - public enum FontFamily { - DEFAULT, - ROMAN, - SWISS, - MODERN, - SCRIPT, - DECOR, - TECH, - BIDI - } - - public void addFont(String name, String alternativeName, String fileName, - FontFamily fontFamily); - - public int countFonts(); + public int countFonts(); - public Font fontAt(int index); + public Font fontAt(int index); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java index 12a5aaf..d8e1a5f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Footer.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Special type of a DocumentPart representing a page footer. */ -public interface Footer extends DocumentPart { +public interface Footer extends DocumentPart +{ } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Header.java b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java index 4d72daa..aebc18e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Header.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Header.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Special type of a DocumentPart representing a page header. */ -public interface Header extends DocumentPart { +public interface Header extends DocumentPart +{ } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java index cdbeb3c..06f19fd 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java @@ -13,22 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for controlling page settings */ -public interface PageSettings { - - public void setPageMarginLeft(int value); - - public void setPageMarginRight(int value); - - public void setPageMarginTop(int value); - - public void setPageMarginBottom(int value); - - public void setPageWidth(int value); - - public void setPageHeight(int value); +public interface PageSettings +{ + + public void setPageMarginLeft(int value); + + public void setPageMarginRight(int value); + + public void setPageMarginTop(int value); + + public void setPageMarginBottom(int value); + + public void setPageWidth(int value); + + public void setPageHeight(int value); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java index 9a21663..0cef010 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Paragraph.java @@ -13,17 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for paragraph functionality. A Paragraph contains Elements * which currently may be of type Chunk and Annotation. */ -public interface Paragraph extends Iterable, Text { +public interface Paragraph extends Iterable, Text +{ + public int countElements(); - public int countElements(); - - public Element elementAt(int index); + public Element elementAt(int index); - public ParagraphStyle getStyle(); + public ParagraphStyle getStyle(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java index f2313fa..8057b8d 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java @@ -13,62 +13,59 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for storing paragraph style parameters. */ -public interface ParagraphStyle extends CharacterStyle { - - public enum Alignment { - LEFT, - RIGHT, - CENTER, - JUSTIFIED, - DISTRIBUTED, - } - - public enum TabAlignment { - LEFT, - CENTER, - RIGHT, - DECIMAL, - } - - public ParagraphStyle createDerivedStyle(); - - public CharacterStyle createDerivedCharacterStyle(); - - public ParagraphStyle createFlattenedStyle(); - - public void setAlignment(Alignment alignment); - - public Alignment getAlignment(); - - public void setSpacingTop(float value); - - public float getSpacingTop(); - - public void setSpacingBottom(float value); - - public float getSpacingBottom(); - - public void setFirstLineIndent(float value); - - public float getFirstLineIndent(); - - public void setLeftIndent(float value); - - public float getLeftIndent(); - - public void setRightIndent(float value); - - public float getRightIndent(); - - public void setLineSpacing(float value); - - public float getLineSpacing(); - - public void addTab(float position, TabAlignment aligment); +public interface ParagraphStyle extends CharacterStyle +{ + + public enum Alignment + { + LEFT, RIGHT, CENTER, JUSTIFIED, DISTRIBUTED, + } + + public enum TabAlignment + { + LEFT, CENTER, RIGHT, DECIMAL, + } + + public ParagraphStyle createDerivedStyle(); + + public CharacterStyle createDerivedCharacterStyle(); + + public ParagraphStyle createFlattenedStyle(); + + public void setAlignment(Alignment alignment); + + public Alignment getAlignment(); + + public void setSpacingTop(float value); + + public float getSpacingTop(); + + public void setSpacingBottom(float value); + + public float getSpacingBottom(); + + public void setFirstLineIndent(float value); + + public float getFirstLineIndent(); + + public void setLeftIndent(float value); + + public float getLeftIndent(); + + public void setRightIndent(float value); + + public float getRightIndent(); + + public void setLineSpacing(float value); + + public float getLineSpacing(); + + public void addTab(float position, TabAlignment aligment); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java index d31bf61..11abfce 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyleTable.java @@ -13,20 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for style table in which paragraph styles can be * retrieved by their ID. */ -public interface ParagraphStyleTable extends Iterable { +public interface ParagraphStyleTable extends Iterable +{ + + public ParagraphStyle createStyle(); + + public void addStyle(int id, ParagraphStyle style); + + public ParagraphStyle styleFor(int id); - public ParagraphStyle createStyle(); - - public void addStyle(int id, ParagraphStyle style); - - public ParagraphStyle styleFor(int id); - - public int countStyles(); + public int countStyles(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Section.java b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java index 09a081e..fd80187 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Section.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Section.java @@ -13,21 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Interface for starting a new section in a document. A section can have * its own paper settings (for example orientation and margins). */ -public interface Section extends DocumentPart, Iterable { +public interface Section extends DocumentPart, Iterable +{ + + public Header createHeader(); + + public Footer createFooter(); + + public Header getHeader(); - public Header createHeader(); - - public Footer createFooter(); + public Footer getFooter(); - public Header getHeader(); - - public Footer getFooter(); - - public PageSettings getPageSettings(); + public PageSettings getPageSettings(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java index 238a69a..5f6dce5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; import java.util.EnumSet; @@ -20,36 +21,22 @@ /** * Interface style base class. Also defines a bunch of properties. */ -public interface Style { - - public enum Property { - ALIGNMENT, - SPACING_TOP, - SPACING_BOTTOM, - FIRST_LINE_INDENT, - LEFT_INDENT, - RIGHT_INDENT, - LINE_SPACING, - TABS, - FONT, - FONT_SIZE, - BOLD, - ITALIC, - UNDERLINED, - STRIKE_OUT, - CAPS, - BACKGROUND_COLOR, - FOREGROUND_COLOR - } - - public void setName(String name); - - public String getName(); - - public EnumSet getOverriddenProperties(); - - public void resetToDefaults(); - - public boolean equals(Style other); +public interface Style +{ + + public enum Property + { + ALIGNMENT, SPACING_TOP, SPACING_BOTTOM, FIRST_LINE_INDENT, LEFT_INDENT, RIGHT_INDENT, LINE_SPACING, TABS, FONT, FONT_SIZE, BOLD, ITALIC, UNDERLINED, STRIKE_OUT, CAPS, BACKGROUND_COLOR, FOREGROUND_COLOR + } + + public void setName(String name); + + public String getName(); + + public EnumSet getOverriddenProperties(); + + public void resetToDefaults(); + + public boolean equals(Style other); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java index 5b7b42e..4e70cc1 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/StyleSheet.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** @@ -20,12 +21,13 @@ * sheet contains four style tables: Paragraph styles, character styles, * section styles and table styles. Each have their own index name space. */ -public interface StyleSheet { +public interface StyleSheet +{ - public ParagraphStyleTable getParagraphStyleTable(); + public ParagraphStyleTable getParagraphStyleTable(); - public CharacterStyleTable getCharacterStyleTable(); + public CharacterStyleTable getCharacterStyleTable(); - // TODO: Section style table - // TODO: Table style table + // TODO: Section style table + // TODO: Table style table } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Text.java b/RTF Parser Kit/src/com/rtfparserkit/document/Text.java index b9576ac..44b821f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Text.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Text.java @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document; /** * Base type for Elements which can return a flattened String for their text * contents. */ -public interface Text extends Element { +public interface Text extends Element +{ - public String getText(); + public String getText(); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java index b8ec757..2f95e0a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.Calendar; @@ -23,37 +24,45 @@ /** * Default implementation for Annotation. */ -public class DefaultAnnotation extends ParagraphList implements Annotation { - - private String id = ""; - private String author = ""; - private long date = Calendar.getInstance().getTimeInMillis(); - - public DefaultAnnotation() { - } - - public void setId(String id) { - this.id = id; - } - - public String getId() { - return id; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getAuthor() { - return author; - } - - public void setDate(Date date) { - this.date = date.getTime(); - } - - public Date getDate() { - return new Date(date); - } +public class DefaultAnnotation extends ParagraphList implements Annotation +{ + + private String id = ""; + private String author = ""; + private long date = Calendar.getInstance().getTimeInMillis(); + + public DefaultAnnotation() + { + } + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setAuthor(String author) + { + this.author = author; + } + + public String getAuthor() + { + return author; + } + + public void setDate(Date date) + { + this.date = date.getTime(); + } + + public Date getDate() + { + return new Date(date); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java index d79da3f..7c85a8b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.EnumSet; @@ -25,231 +26,232 @@ /** * Default CharacterStyle implementation */ -public class DefaultCharacterStyle extends DefaultStyle - implements CharacterStyle { - - private final CharacterStyle parent; - - private Font font; - private float fontSize; - private boolean bold; - private boolean italic; - private UnderlineStyle underlineStyle; - private boolean strikeOut; - private boolean caps; - private Color backgroundColor; - private Color foregroundColor; - // TODO: Support more RTF properties - - static private final EnumSet CHARACTER_STYLE_PROPERTIES - = EnumSet.of( - Property.FONT, - Property.FONT_SIZE, - Property.BOLD, - Property.ITALIC, - Property.UNDERLINED, - Property.STRIKE_OUT, - Property.CAPS, - Property.BACKGROUND_COLOR, - Property.FOREGROUND_COLOR - ); - - public DefaultCharacterStyle() { - parent = null; - resetToDefaults(); - } - - public DefaultCharacterStyle(CharacterStyle other) { - parent = other; - } - - public void resetToDefaults() { - // TODO: Mechanics should probably be changed. Instead of having a - // method resetFontToDefaults() here, the StyleSheet should have methods - // to set and get the default style. And Style should have a method - // to set(Style other) to copy the values from the parameter. - // Then \plain can be handled by copying the default style. The problem - // is that there are RTF commands which define the default style values. - font = new DefaultFont("default"); - fontSize = 12.0f; - bold = false; - italic = false; - underlineStyle = UnderlineStyle.NONE; - strikeOut = false; - caps = false; - backgroundColor = DefaultColor.WHITE; - foregroundColor = DefaultColor.BLACK; - - overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); - } - - public CharacterStyle createDerivedStyle() { - return new DefaultCharacterStyle(this); - } - - public CharacterStyle createFlattenedStyle() { - DefaultCharacterStyle style = new DefaultCharacterStyle(); - style.copyFrom(this); - return style; - } - - protected void copyFrom(CharacterStyle style) { - font = style.getFont(); - fontSize = style.getFontSize(); - bold = style.getBold(); - italic = style.getItalic(); - underlineStyle = style.getUnderlined(); - strikeOut = style.getStrikeOut(); - caps = style.getCaps(); - backgroundColor = style.getBackgroundColor(); - foregroundColor = style.getForegroundColor(); - - overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); - } - - @Override - public boolean equals(Style object) { - if (object == this) - return true; - if (object == null || !(object instanceof DefaultCharacterStyle)) - return false; - if (!super.equals(object)) - return false; - - DefaultCharacterStyle other = (DefaultCharacterStyle) object; - return parent == other.parent - && (font != null ? font.equals(other.font) : other.font == null) - && fontSize == other.fontSize - && bold == other.bold - && italic == other.italic - && underlineStyle == other.underlineStyle - && strikeOut == other.strikeOut - && caps == other.caps - && backgroundColor == other.backgroundColor - && foregroundColor == other.foregroundColor; - } - - public void setFont(Font font) { - this.font = font; - overriddenProperties.add(Property.FONT); - } - - public Font getFont() { - if (overriddenProperties.contains(Property.BOLD)) - return font; - else - return parent.getFont(); - } - - public void setFontSize(float value) { - this.fontSize = value; - overriddenProperties.add(Property.FONT_SIZE); - } - - public float getFontSize() { - if (overriddenProperties.contains(Property.FONT_SIZE)) - return fontSize; - else - return parent.getFontSize(); - } - - public void setBold(boolean bold) { - this.bold = bold; - overriddenProperties.add(Property.BOLD); - } - - public boolean getBold() { - if (overriddenProperties.contains(Property.BOLD)) - return bold; - else - return parent.getBold(); - } - - public void setItalic(boolean italic) { - this.italic = italic; - overriddenProperties.add(Property.ITALIC); - } - - public boolean getItalic() { - if (overriddenProperties.contains(Property.ITALIC)) - return italic; - else - return parent.getItalic(); - } - - public void setUnderlined(UnderlineStyle style) { - this.underlineStyle = style; - overriddenProperties.add(Property.UNDERLINED); - } - - public UnderlineStyle getUnderlined() { - if (overriddenProperties.contains(Property.UNDERLINED)) - return underlineStyle; - else - return parent.getUnderlined(); - } - - public void setStrikeOut(boolean strikeOut) { - this.strikeOut = strikeOut; - overriddenProperties.add(Property.STRIKE_OUT); - } - - public boolean getStrikeOut() { - if (overriddenProperties.contains(Property.STRIKE_OUT)) - return strikeOut; - else - return parent.getStrikeOut(); - } - - public void setCaps(boolean caps) { - this.caps = caps; - overriddenProperties.add(Property.CAPS); - } - - public boolean getCaps() { - if (overriddenProperties.contains(Property.CAPS)) - return caps; - else - return parent.getCaps(); - } - - public void setBackgroundColor(Color color) { - if (color instanceof DefaultColor) { - backgroundColor = (DefaultColor) color; - overriddenProperties.add(Property.BACKGROUND_COLOR); - } - } - - public Color getBackgroundColor() { - if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) - return backgroundColor; - else - return parent.getBackgroundColor(); - } - - public void setForegroundColor(Color color) { - if (color instanceof DefaultColor) { - foregroundColor = (DefaultColor) color; - overriddenProperties.add(Property.FOREGROUND_COLOR); - } - } - - public Color getForegroundColor() { - if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) - return foregroundColor; - else - return parent.getForegroundColor(); - } - - @Override - public String toString() { - return "DefaultCharacterStyle(" - + (font != null ? font.getName() : "") + "@" + fontSize + ", " - + (bold ? "bold, " : "") - + (italic ? "italic, " : "") - + (underlineStyle != UnderlineStyle.NONE ? ("underline: " + underlineStyle.name() + ", ") : "") - + "fg: " + foregroundColor + ", " - + "bg: " + backgroundColor - + ")"; - } +public class DefaultCharacterStyle extends DefaultStyle implements CharacterStyle +{ + + private final CharacterStyle parent; + + private Font font; + private float fontSize; + private boolean bold; + private boolean italic; + private UnderlineStyle underlineStyle; + private boolean strikeOut; + private boolean caps; + private Color backgroundColor; + private Color foregroundColor; + // TODO: Support more RTF properties + + static private final EnumSet CHARACTER_STYLE_PROPERTIES = EnumSet.of(Property.FONT, Property.FONT_SIZE, Property.BOLD, Property.ITALIC, Property.UNDERLINED, Property.STRIKE_OUT, Property.CAPS, Property.BACKGROUND_COLOR, Property.FOREGROUND_COLOR); + + public DefaultCharacterStyle() + { + parent = null; + resetToDefaults(); + } + + public DefaultCharacterStyle(CharacterStyle other) + { + parent = other; + } + + public void resetToDefaults() + { + // TODO: Mechanics should probably be changed. Instead of having a + // method resetFontToDefaults() here, the StyleSheet should have methods + // to set and get the default style. And Style should have a method + // to set(Style other) to copy the values from the parameter. + // Then \plain can be handled by copying the default style. The problem + // is that there are RTF commands which define the default style values. + font = new DefaultFont("default"); + fontSize = 12.0f; + bold = false; + italic = false; + underlineStyle = UnderlineStyle.NONE; + strikeOut = false; + caps = false; + backgroundColor = DefaultColor.WHITE; + foregroundColor = DefaultColor.BLACK; + + overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); + } + + public CharacterStyle createDerivedStyle() + { + return new DefaultCharacterStyle(this); + } + + public CharacterStyle createFlattenedStyle() + { + DefaultCharacterStyle style = new DefaultCharacterStyle(); + style.copyFrom(this); + return style; + } + + protected void copyFrom(CharacterStyle style) + { + font = style.getFont(); + fontSize = style.getFontSize(); + bold = style.getBold(); + italic = style.getItalic(); + underlineStyle = style.getUnderlined(); + strikeOut = style.getStrikeOut(); + caps = style.getCaps(); + backgroundColor = style.getBackgroundColor(); + foregroundColor = style.getForegroundColor(); + + overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); + } + + @Override + public boolean equals(Style object) + { + if (object == this) + return true; + if (object == null || !(object instanceof DefaultCharacterStyle)) + return false; + if (!super.equals(object)) + return false; + + DefaultCharacterStyle other = (DefaultCharacterStyle) object; + return parent == other.parent && (font != null ? font.equals(other.font) : other.font == null) && fontSize == other.fontSize && bold == other.bold && italic == other.italic && underlineStyle == other.underlineStyle && strikeOut == other.strikeOut && caps == other.caps && backgroundColor == other.backgroundColor && foregroundColor == other.foregroundColor; + } + + public void setFont(Font font) + { + this.font = font; + overriddenProperties.add(Property.FONT); + } + + public Font getFont() + { + if (overriddenProperties.contains(Property.BOLD)) + return font; + else + return parent.getFont(); + } + + public void setFontSize(float value) + { + this.fontSize = value; + overriddenProperties.add(Property.FONT_SIZE); + } + + public float getFontSize() + { + if (overriddenProperties.contains(Property.FONT_SIZE)) + return fontSize; + else + return parent.getFontSize(); + } + + public void setBold(boolean bold) + { + this.bold = bold; + overriddenProperties.add(Property.BOLD); + } + + public boolean getBold() + { + if (overriddenProperties.contains(Property.BOLD)) + return bold; + else + return parent.getBold(); + } + + public void setItalic(boolean italic) + { + this.italic = italic; + overriddenProperties.add(Property.ITALIC); + } + + public boolean getItalic() + { + if (overriddenProperties.contains(Property.ITALIC)) + return italic; + else + return parent.getItalic(); + } + + public void setUnderlined(UnderlineStyle style) + { + this.underlineStyle = style; + overriddenProperties.add(Property.UNDERLINED); + } + + public UnderlineStyle getUnderlined() + { + if (overriddenProperties.contains(Property.UNDERLINED)) + return underlineStyle; + else + return parent.getUnderlined(); + } + + public void setStrikeOut(boolean strikeOut) + { + this.strikeOut = strikeOut; + overriddenProperties.add(Property.STRIKE_OUT); + } + + public boolean getStrikeOut() + { + if (overriddenProperties.contains(Property.STRIKE_OUT)) + return strikeOut; + else + return parent.getStrikeOut(); + } + + public void setCaps(boolean caps) + { + this.caps = caps; + overriddenProperties.add(Property.CAPS); + } + + public boolean getCaps() + { + if (overriddenProperties.contains(Property.CAPS)) + return caps; + else + return parent.getCaps(); + } + + public void setBackgroundColor(Color color) + { + if (color instanceof DefaultColor) + { + backgroundColor = (DefaultColor) color; + overriddenProperties.add(Property.BACKGROUND_COLOR); + } + } + + public Color getBackgroundColor() + { + if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) + return backgroundColor; + else + return parent.getBackgroundColor(); + } + + public void setForegroundColor(Color color) + { + if (color instanceof DefaultColor) + { + foregroundColor = (DefaultColor) color; + overriddenProperties.add(Property.FOREGROUND_COLOR); + } + } + + public Color getForegroundColor() + { + if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) + return foregroundColor; + else + return parent.getForegroundColor(); + } + + @Override + public String toString() + { + return "DefaultCharacterStyle(" + (font != null ? font.getName() : "") + "@" + fontSize + ", " + (bold ? "bold, " : "") + (italic ? "italic, " : "") + (underlineStyle != UnderlineStyle.NONE ? ("underline: " + underlineStyle.name() + ", ") : "") + "fg: " + foregroundColor + ", " + "bg: " + backgroundColor + ")"; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java index 6f623e6..4c1c44c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.CharacterStyle; @@ -21,11 +22,12 @@ /** * Default CharacterStyleTable implementation. */ -public class DefaultCharacterStyleTable extends StyleTable - implements CharacterStyleTable { +public class DefaultCharacterStyleTable extends StyleTableimplements CharacterStyleTable +{ - public CharacterStyle createStyle() { - return new DefaultCharacterStyle(); - } + public CharacterStyle createStyle() + { + return new DefaultCharacterStyle(); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java index 9ed65c9..bf70109 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Chunk; @@ -21,24 +22,29 @@ /** * Default Chunk implementation. */ -public class DefaultChunk implements Chunk { - private final StringBuilder stringBuilder; - private final ParagraphStyle style; +public class DefaultChunk implements Chunk +{ + private final StringBuilder stringBuilder; + private final ParagraphStyle style; + + public DefaultChunk(ParagraphStyle style) + { + stringBuilder = new StringBuilder(); + this.style = style; + } + + public String getText() + { + return stringBuilder.toString(); + } - public DefaultChunk(ParagraphStyle style) { - stringBuilder = new StringBuilder(); - this.style = style; - } - - public String getText() { - return stringBuilder.toString(); - } - - public ParagraphStyle getStyle() { - return style; - } + public ParagraphStyle getStyle() + { + return style; + } - public void append(String string) { - stringBuilder.append(string); - } + public void append(String string) + { + stringBuilder.append(string); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java index 877677e..208e809 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Color; @@ -20,41 +21,48 @@ /** * Default Color implementation. After creation, DefaultColor is not mutable. */ -public class DefaultColor implements Color { - - private final int red; - private final int green; - private final int blue; - - static final DefaultColor BLACK = new DefaultColor(0, 0, 0); - static final DefaultColor WHITE = new DefaultColor(255, 255, 255); - - public DefaultColor(int red, int green, int blue) { - this.red = red; - this.green = green; - this.blue = blue; - } - - public DefaultColor(Color other) { - this.red = other.getRed(); - this.green = other.getGreen(); - this.blue = other.getBlue(); - } - - public int getRed() { - return red; - } - - public int getGreen() { - return green; - } - - public int getBlue() { - return blue; - } - - @Override - public String toString() { - return "(r" + red + "g" + green + "b" + blue + ")"; - } +public class DefaultColor implements Color +{ + + private final int red; + private final int green; + private final int blue; + + static final DefaultColor BLACK = new DefaultColor(0, 0, 0); + static final DefaultColor WHITE = new DefaultColor(255, 255, 255); + + public DefaultColor(int red, int green, int blue) + { + this.red = red; + this.green = green; + this.blue = blue; + } + + public DefaultColor(Color other) + { + this.red = other.getRed(); + this.green = other.getGreen(); + this.blue = other.getBlue(); + } + + public int getRed() + { + return red; + } + + public int getGreen() + { + return green; + } + + public int getBlue() + { + return blue; + } + + @Override + public String toString() + { + return "(r" + red + "g" + green + "b" + blue + ")"; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java index 75fd873..b001a6e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -24,23 +25,28 @@ /** * Default implementation of ColorTable. */ -public class DefaultColorTable implements ColorTable { - - private final List colors; - - public DefaultColorTable() { - colors = new ArrayList(); - } - - public void addColor(int red, int green, int blue) { - colors.add(new DefaultColor(red, green, blue)); - } - - public int countColors() { - return colors.size(); - } - - public Color colorAt(int index) { - return colors.get(index); - } +public class DefaultColorTable implements ColorTable +{ + + private final List colors; + + public DefaultColorTable() + { + colors = new ArrayList(); + } + + public void addColor(int red, int green, int blue) + { + colors.add(new DefaultColor(red, green, blue)); + } + + public int countColors() + { + return colors.size(); + } + + public Color colorAt(int index) + { + return colors.get(index); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java index 43d877c..ca75c72 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Annotation; @@ -28,137 +29,161 @@ * a DocumentPart. It implements relevant functionality by forwarding to the * last Section. */ -public class DefaultDocument extends SectionList implements Document { - - private final DefaultColorTable colors = new DefaultColorTable(); - private final DefaultFontTable fonts = new DefaultFontTable(); - private final DefaultStyleSheet styles = new DefaultStyleSheet(); - - private final PageMargins pageMargins = new PageMargins(); - private final PageSize pageSize = new PageSize(); - - public DefaultFontTable getFontTable() { - return fonts; - } - - public DefaultColorTable getColorTable() { - return colors; - } - - public DefaultStyleSheet getStyleSheet() { - return styles; - } - - public PageMargins getPageMargins() { - return pageMargins; - } - - public PageSize getPageSize() { - return pageSize; - } - - public DocumentSettings getDocumentSettings() { - return new DocumentSettings() { - - public PageSettings getPageSettings() { - return new PageSettings() { - public void setPageMarginLeft(int value) { - pageMargins.left = value; - } - - public void setPageMarginRight(int value) { - pageMargins.right = value; - } - - public void setPageMarginTop(int value) { - pageMargins.top = value; - } - - public void setPageMarginBottom(int value) { - pageMargins.bottom = value; - } - - public void setPageWidth(int value) { - pageSize.width = value; - } - - public void setPageHeight(int value) { - pageSize.height = value; - } - }; - } - }; - } - - /** - * Appends a string of text to the last Section. - * - * @param text The string to append - * @param style The Style in which the appended string is to appear. - */ - public void append(String text, ParagraphStyle style) { - getLastSection().append(text, style); - } - - /** - * Starts a new Paragraph at the last Section and sets the Style of the - * previous last Paragraph. - * - * @param lastStyle The Style to be set on the previous paragraph. - */ - public void nextParagraph(ParagraphStyle lastStyle) { - getLastSection().nextParagraph(lastStyle); - } - - /** - * Creates a new line at the last Section. - */ - public void nextLine() { - getLastSection().nextLine(); - } - - /** - * @return The default Style created by the last Section. - */ - public ParagraphStyle createDefaultStyle() { - return getLastSection().createDefaultStyle(); - } - - /** - * @return The total count of all paragraphs contained in all Sections. - */ - public int countParagraphs() { - int count = 0; - for (Section section : this) - count += section.countParagraphs(); - return count; - } - - /** - * @param index The index of the paragraph relative to the total paragraph - * count of all Sections. - */ - public Paragraph paragraphAt(int index) { - int originalIndex = index; - for (Section section : this) { - int paragrapgsInSection = section.countParagraphs(); - if (index > paragrapgsInSection) { - index -= paragrapgsInSection; - continue; - } - return section.paragraphAt(index); - } - - throw new IndexOutOfBoundsException("paragraphs in section: " - + countParagraphs() + ", requested index: " + originalIndex); - } - - /** - * Creates a new Annotation instance and appends it to the last Section. - * - * @return The appended annotation - */ - public Annotation appendAnnotation() { - return getLastSection().appendAnnotation(); - } +public class DefaultDocument extends SectionList implements Document +{ + + private final DefaultColorTable colors = new DefaultColorTable(); + private final DefaultFontTable fonts = new DefaultFontTable(); + private final DefaultStyleSheet styles = new DefaultStyleSheet(); + + private final PageMargins pageMargins = new PageMargins(); + private final PageSize pageSize = new PageSize(); + + public DefaultFontTable getFontTable() + { + return fonts; + } + + public DefaultColorTable getColorTable() + { + return colors; + } + + public DefaultStyleSheet getStyleSheet() + { + return styles; + } + + public PageMargins getPageMargins() + { + return pageMargins; + } + + public PageSize getPageSize() + { + return pageSize; + } + + public DocumentSettings getDocumentSettings() + { + return new DocumentSettings() + { + + public PageSettings getPageSettings() + { + return new PageSettings() + { + public void setPageMarginLeft(int value) + { + pageMargins.left = value; + } + + public void setPageMarginRight(int value) + { + pageMargins.right = value; + } + + public void setPageMarginTop(int value) + { + pageMargins.top = value; + } + + public void setPageMarginBottom(int value) + { + pageMargins.bottom = value; + } + + public void setPageWidth(int value) + { + pageSize.width = value; + } + + public void setPageHeight(int value) + { + pageSize.height = value; + } + }; + } + }; + } + + /** + * Appends a string of text to the last Section. + * + * @param text The string to append + * @param style The Style in which the appended string is to appear. + */ + public void append(String text, ParagraphStyle style) + { + getLastSection().append(text, style); + } + + /** + * Starts a new Paragraph at the last Section and sets the Style of the + * previous last Paragraph. + * + * @param lastStyle The Style to be set on the previous paragraph. + */ + public void nextParagraph(ParagraphStyle lastStyle) + { + getLastSection().nextParagraph(lastStyle); + } + + /** + * Creates a new line at the last Section. + */ + public void nextLine() + { + getLastSection().nextLine(); + } + + /** + * @return The default Style created by the last Section. + */ + public ParagraphStyle createDefaultStyle() + { + return getLastSection().createDefaultStyle(); + } + + /** + * @return The total count of all paragraphs contained in all Sections. + */ + public int countParagraphs() + { + int count = 0; + for (Section section : this) + count += section.countParagraphs(); + return count; + } + + /** + * @param index The index of the paragraph relative to the total paragraph + * count of all Sections. + */ + public Paragraph paragraphAt(int index) + { + int originalIndex = index; + for (Section section : this) + { + int paragrapgsInSection = section.countParagraphs(); + if (index > paragrapgsInSection) + { + index -= paragrapgsInSection; + continue; + } + return section.paragraphAt(index); + } + + throw new IndexOutOfBoundsException("paragraphs in section: " + countParagraphs() + ", requested index: " + originalIndex); + } + + /** + * Creates a new Annotation instance and appends it to the last Section. + * + * @return The appended annotation + */ + public Annotation appendAnnotation() + { + return getLastSection().appendAnnotation(); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java index 03d8b3c..e278824 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Font; @@ -20,30 +21,35 @@ /** * Default Font implementation */ -public class DefaultFont implements Font { - private String name; - - public DefaultFont(String fontName) { - name = fontName; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public boolean equals(Font object) { - if (object == this) - return true; - if (object == null || object.getClass() != DefaultFont.class) - return false; - DefaultFont other = (DefaultFont) object; - return name.equals(other.name); - } - - // TODO: Hold all necessary data. +public class DefaultFont implements Font +{ + private String name; + + public DefaultFont(String fontName) + { + name = fontName; + } + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public boolean equals(Font object) + { + if (object == this) + return true; + if (object == null || object.getClass() != DefaultFont.class) + return false; + DefaultFont other = (DefaultFont) object; + return name.equals(other.name); + } + + // TODO: Hold all necessary data. } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java index 3ec4c61..c488ce7 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -1,3 +1,4 @@ + package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -6,24 +7,28 @@ import com.rtfparserkit.document.Font; import com.rtfparserkit.document.FontTable; -public class DefaultFontTable implements FontTable { - - private final List fonts; - - public DefaultFontTable() { - fonts = new ArrayList(); - } - - public void addFont(String name, String alternativeName, String fileName, - FontFamily fontFamily) { - fonts.add(new DefaultFont(name)); - } - - public int countFonts() { - return fonts.size(); - } - - public Font fontAt(int index) { - return fonts.get(index); - } +public class DefaultFontTable implements FontTable +{ + + private final List fonts; + + public DefaultFontTable() + { + fonts = new ArrayList(); + } + + public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily) + { + fonts.add(new DefaultFont(name)); + } + + public int countFonts() + { + return fonts.size(); + } + + public Font fontAt(int index) + { + return fonts.get(index); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java index c5d07f5..8aef754 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFooter.java @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Footer; - /** * Default Footer implementation. */ -public class DefaultFooter extends ParagraphList implements Footer { +public class DefaultFooter extends ParagraphList implements Footer +{ } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java index 50d88b6..36ed356 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultHeader.java @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Header; - /** * Default Header implementation */ -public class DefaultHeader extends ParagraphList implements Header { +public class DefaultHeader extends ParagraphList implements Header +{ } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java index 3469c1f..ab186d9 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -27,146 +28,169 @@ /** * Default Paragraph implementation */ -public class DefaultParagraph implements Iterable, Paragraph { - private final List chunks; - private ParagraphStyle style; - - public DefaultParagraph() { - this(new DefaultParagraphStyle()); - } - - public DefaultParagraph(ParagraphStyle style) { - chunks = new ArrayList(); - this.style = style; - } - - public Iterator iterator() { - return chunks.iterator(); - } - - public String getText() { - StringBuilder builder = new StringBuilder(); - for (Element element : chunks) { - if (element instanceof Chunk) - builder.append(((Chunk) element).getText()); - } - return builder.toString(); - } - - public int countElements() { - return chunks.size(); - } - - public Element elementAt(int index) { - return chunks.get(index); - } - - public ParagraphStyle getStyle() { - return style; - } - - public void append(Element element) { - if (element == null) - throw new IllegalArgumentException("Element may not be null"); - chunks.add(element); - } - - /** - * Appends the string to the Paragraph. If the last Element of the Paragraph - * is a Chunk, the string will be appended to the Chunk. Otherwise a new - * Chunk will be created to hold the String. If the Paragraph already - * contains any Chunks, the Style of the last Chunk is used for the string. - * The paragraph may not already be delimited (end with '\n'). The appended - * string may contain a delimiter ('\n'), but it must be at the end of the - * string. - * - * @param string The string to append - */ - public void append(String string) { - append(string, getLastStyle()); - } - - /** - * Appends the string to the Paragraph. If the last Element of the Paragraph - * is a Chunk, the string will be appended to that Chunk if the Style - * matches the Style of the last Chunk. Otherwise a new Chunk with the given - * Style will be created to hold the String. - * The paragraph may not already be delimited (end with '\n'). The appended - * string may contain a delimiter ('\n'), but it must be at the end of the - * string. - * - * @param string The string to append - * @param style The Style in which the string is to appear - */ - public void append(String string, ParagraphStyle style) { - if (string == null) - throw new IllegalArgumentException("String may not be null!"); - if (style == null) - throw new IllegalArgumentException("Style may not be null!"); - int firstLineBreak = string.indexOf('\n'); - if (firstLineBreak >= 0 && firstLineBreak != string.length() - 1) { - throw new IllegalArgumentException("String must not contain a " - + "line-break (\\n) unless right at the end."); - } - assertNotDelimited(); - appendString(string, style); - } - - public void end() { - end(getLastStyle()); - } - - public void end(ParagraphStyle lastStyle) { - append("\n", lastStyle); - } - - public ParagraphStyle getLastStyle() { - // Try to use the last used Style instead of the default style - Chunk lastChunk = findLastChunk(); - if (lastChunk != null) - return lastChunk.getStyle(); - - return style; - } - - /** - * Makes sure that the paragraph doesn't already end with '\n'. - */ - private void assertNotDelimited() { - for (int i = chunks.size() - 1; i >= 0; i--) { - Element element = chunks.get(i); - if (element instanceof Chunk) { - Chunk chunk = (Chunk) element; - if (chunk.getText().endsWith("\n")) { - throw new IllegalArgumentException( - "Paragraph is already delimited."); - } - break; - } - } - } - - private void appendString(String string, ParagraphStyle style) { - Chunk chunk = null; - if (chunks.size() > 0) { - Element last = chunks.get(chunks.size() - 1); - if (last instanceof Chunk) - chunk = (Chunk) last; - } - if (chunk == null || !chunk.getStyle().equals(style)) { - chunk = new DefaultChunk(style); - append(chunk); - } - chunk.append(string); - } - - private Chunk findLastChunk() { - for (int i = chunks.size() - 1; i >= 0; i--) { - Element element = chunks.get(i); - if (element instanceof Chunk) - return (Chunk) element; - } - - return null; - } +public class DefaultParagraph implements Iterable, Paragraph +{ + private final List chunks; + private ParagraphStyle style; + + public DefaultParagraph() + { + this(new DefaultParagraphStyle()); + } + + public DefaultParagraph(ParagraphStyle style) + { + chunks = new ArrayList(); + this.style = style; + } + + public Iterator iterator() + { + return chunks.iterator(); + } + + public String getText() + { + StringBuilder builder = new StringBuilder(); + for (Element element : chunks) + { + if (element instanceof Chunk) + builder.append(((Chunk) element).getText()); + } + return builder.toString(); + } + + public int countElements() + { + return chunks.size(); + } + + public Element elementAt(int index) + { + return chunks.get(index); + } + + public ParagraphStyle getStyle() + { + return style; + } + + public void append(Element element) + { + if (element == null) + throw new IllegalArgumentException("Element may not be null"); + chunks.add(element); + } + + /** + * Appends the string to the Paragraph. If the last Element of the Paragraph + * is a Chunk, the string will be appended to the Chunk. Otherwise a new + * Chunk will be created to hold the String. If the Paragraph already + * contains any Chunks, the Style of the last Chunk is used for the string. + * The paragraph may not already be delimited (end with '\n'). The appended + * string may contain a delimiter ('\n'), but it must be at the end of the + * string. + * + * @param string The string to append + */ + public void append(String string) + { + append(string, getLastStyle()); + } + + /** + * Appends the string to the Paragraph. If the last Element of the Paragraph + * is a Chunk, the string will be appended to that Chunk if the Style + * matches the Style of the last Chunk. Otherwise a new Chunk with the given + * Style will be created to hold the String. + * The paragraph may not already be delimited (end with '\n'). The appended + * string may contain a delimiter ('\n'), but it must be at the end of the + * string. + * + * @param string The string to append + * @param style The Style in which the string is to appear + */ + public void append(String string, ParagraphStyle style) + { + if (string == null) + throw new IllegalArgumentException("String may not be null!"); + if (style == null) + throw new IllegalArgumentException("Style may not be null!"); + int firstLineBreak = string.indexOf('\n'); + if (firstLineBreak >= 0 && firstLineBreak != string.length() - 1) + { + throw new IllegalArgumentException("String must not contain a " + "line-break (\\n) unless right at the end."); + } + assertNotDelimited(); + appendString(string, style); + } + + public void end() + { + end(getLastStyle()); + } + + public void end(ParagraphStyle lastStyle) + { + append("\n", lastStyle); + } + + public ParagraphStyle getLastStyle() + { + // Try to use the last used Style instead of the default style + Chunk lastChunk = findLastChunk(); + if (lastChunk != null) + return lastChunk.getStyle(); + + return style; + } + + /** + * Makes sure that the paragraph doesn't already end with '\n'. + */ + private void assertNotDelimited() + { + for (int i = chunks.size() - 1; i >= 0; i--) + { + Element element = chunks.get(i); + if (element instanceof Chunk) + { + Chunk chunk = (Chunk) element; + if (chunk.getText().endsWith("\n")) + { + throw new IllegalArgumentException("Paragraph is already delimited."); + } + break; + } + } + } + + private void appendString(String string, ParagraphStyle style) + { + Chunk chunk = null; + if (chunks.size() > 0) + { + Element last = chunks.get(chunks.size() - 1); + if (last instanceof Chunk) + chunk = (Chunk) last; + } + if (chunk == null || !chunk.getStyle().equals(style)) + { + chunk = new DefaultChunk(style); + append(chunk); + } + chunk.append(string); + } + + private Chunk findLastChunk() + { + for (int i = chunks.size() - 1; i >= 0; i--) + { + Element element = chunks.get(i); + if (element instanceof Chunk) + return (Chunk) element; + } + + return null; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java index c2ea551..8ae2012 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.EnumSet; @@ -24,195 +25,202 @@ /** * Default ParagraphStyle implementation */ -public class DefaultParagraphStyle extends DefaultCharacterStyle - implements ParagraphStyle { - - private final ParagraphStyle parent; - - private Alignment alignment; - private float spacingTop; - private float spacingBottom; - private float firstLineIndent; - private float leftIndent; - private float rightIndent; - private float lineSpacing; - // TODO: Support more RTF properties - - public DefaultParagraphStyle() { - parent = null; - resetToDefaults(); - } - - public DefaultParagraphStyle(ParagraphStyle other) { - super(other); - parent = other; - } - - @Override - public void resetToDefaults() { - super.resetToDefaults(); - - alignment = Alignment.LEFT; - spacingTop = 0; - spacingBottom = 0; - firstLineIndent = 0; - leftIndent = 0; - rightIndent = 0; - lineSpacing = 0; - - overriddenProperties = EnumSet.allOf(Property.class); - } - - @Override - public ParagraphStyle createDerivedStyle() { - return new DefaultParagraphStyle(this); - } - - public CharacterStyle createDerivedCharacterStyle() { - return new DefaultCharacterStyle(this); - } - - @Override - public ParagraphStyle createFlattenedStyle() { - DefaultParagraphStyle style = new DefaultParagraphStyle(); - style.copyFrom(this); - return style; - } - - protected void copyFrom(ParagraphStyle style) { - super.copyFrom(style); - - alignment = style.getAlignment(); - spacingTop = style.getSpacingTop(); - spacingBottom = style.getSpacingBottom(); - firstLineIndent = style.getFirstLineIndent(); - leftIndent = style.getLeftIndent(); - rightIndent = style.getRightIndent(); - lineSpacing = style.getLineSpacing(); - - overriddenProperties = EnumSet.allOf(Property.class); - } - - @Override - public boolean equals(Style object) { - if (object == this) - return true; - if (object == null || !(object instanceof DefaultParagraphStyle)) - return false; - if (!super.equals(object)) - return false; - - DefaultParagraphStyle other = (DefaultParagraphStyle) object; - return parent == other.parent - && alignment == other.alignment - && spacingTop == other.spacingTop - && spacingBottom == other.spacingBottom - && firstLineIndent == other.firstLineIndent - && leftIndent == other.leftIndent - && rightIndent == other.rightIndent - && lineSpacing == other.lineSpacing; - } - - public void setAlignment(Alignment alignment) { - this.alignment = alignment; - overriddenProperties.add(Property.ALIGNMENT); - } - - public Alignment getAlignment() { - if (overriddenProperties.contains(Property.ALIGNMENT)) - return alignment; - else - return parent.getAlignment(); - } - - public void setSpacingTop(float value) { - spacingTop = value; - overriddenProperties.add(Property.SPACING_TOP); - } - - public float getSpacingTop() { - if (overriddenProperties.contains(Property.SPACING_TOP)) - return spacingTop; - else - return parent.getSpacingTop(); - } - - public void setSpacingBottom(float value) { - spacingBottom = value; - overriddenProperties.add(Property.SPACING_BOTTOM); - } - - public float getSpacingBottom() { - if (overriddenProperties.contains(Property.SPACING_BOTTOM)) - return spacingBottom; - else - return parent.getSpacingBottom(); - } - - public void setFirstLineIndent(float value) { - firstLineIndent = value; - overriddenProperties.add(Property.FIRST_LINE_INDENT); - } - - public float getFirstLineIndent() { - if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) - return firstLineIndent; - else - return parent.getFirstLineIndent(); - } - - public void setLeftIndent(float value) { - leftIndent = value; - overriddenProperties.add(Property.LEFT_INDENT); - } - - public float getLeftIndent() { - if (overriddenProperties.contains(Property.LEFT_INDENT)) - return leftIndent; - else - return parent.getLeftIndent(); - } - - public void setRightIndent(float value) { - rightIndent = value; - overriddenProperties.add(Property.RIGHT_INDENT); - } - - public float getRightIndent() { - if (overriddenProperties.contains(Property.RIGHT_INDENT)) - return rightIndent; - else - return parent.getRightIndent(); - } - - public void setLineSpacing(float value) { - lineSpacing = value; - overriddenProperties.add(Property.LINE_SPACING); - } - - public float getLineSpacing() { - if (overriddenProperties.contains(Property.LINE_SPACING)) - return lineSpacing; - else - return parent.getLineSpacing(); - } - - public void addTab(float position, TabAlignment aligment) { - // TODO Auto-generated method stub - } - - @Override - public String toString() { - return "ParagraphStyle(" - + alignment.name() + ", " - + (getFont() != null ? getFont().getName() : "") - + "@" + getFontSize() + ", " - + (getBold() ? "bold, " : "") - + (getItalic() ? "italic, " : "") - + (getUnderlined() != UnderlineStyle.NONE - ? ("underline: " + getUnderlined().name() + ", ") : "") - + "fg: " + getForegroundColor() + ", " - + "bg: " + getBackgroundColor() - + ")"; - } +public class DefaultParagraphStyle extends DefaultCharacterStyle implements ParagraphStyle +{ + + private final ParagraphStyle parent; + + private Alignment alignment; + private float spacingTop; + private float spacingBottom; + private float firstLineIndent; + private float leftIndent; + private float rightIndent; + private float lineSpacing; + // TODO: Support more RTF properties + + public DefaultParagraphStyle() + { + parent = null; + resetToDefaults(); + } + + public DefaultParagraphStyle(ParagraphStyle other) + { + super(other); + parent = other; + } + + @Override + public void resetToDefaults() + { + super.resetToDefaults(); + + alignment = Alignment.LEFT; + spacingTop = 0; + spacingBottom = 0; + firstLineIndent = 0; + leftIndent = 0; + rightIndent = 0; + lineSpacing = 0; + + overriddenProperties = EnumSet.allOf(Property.class); + } + + @Override + public ParagraphStyle createDerivedStyle() + { + return new DefaultParagraphStyle(this); + } + + public CharacterStyle createDerivedCharacterStyle() + { + return new DefaultCharacterStyle(this); + } + + @Override + public ParagraphStyle createFlattenedStyle() + { + DefaultParagraphStyle style = new DefaultParagraphStyle(); + style.copyFrom(this); + return style; + } + + protected void copyFrom(ParagraphStyle style) + { + super.copyFrom(style); + + alignment = style.getAlignment(); + spacingTop = style.getSpacingTop(); + spacingBottom = style.getSpacingBottom(); + firstLineIndent = style.getFirstLineIndent(); + leftIndent = style.getLeftIndent(); + rightIndent = style.getRightIndent(); + lineSpacing = style.getLineSpacing(); + + overriddenProperties = EnumSet.allOf(Property.class); + } + + @Override + public boolean equals(Style object) + { + if (object == this) + return true; + if (object == null || !(object instanceof DefaultParagraphStyle)) + return false; + if (!super.equals(object)) + return false; + + DefaultParagraphStyle other = (DefaultParagraphStyle) object; + return parent == other.parent && alignment == other.alignment && spacingTop == other.spacingTop && spacingBottom == other.spacingBottom && firstLineIndent == other.firstLineIndent && leftIndent == other.leftIndent && rightIndent == other.rightIndent && lineSpacing == other.lineSpacing; + } + + public void setAlignment(Alignment alignment) + { + this.alignment = alignment; + overriddenProperties.add(Property.ALIGNMENT); + } + + public Alignment getAlignment() + { + if (overriddenProperties.contains(Property.ALIGNMENT)) + return alignment; + else + return parent.getAlignment(); + } + + public void setSpacingTop(float value) + { + spacingTop = value; + overriddenProperties.add(Property.SPACING_TOP); + } + + public float getSpacingTop() + { + if (overriddenProperties.contains(Property.SPACING_TOP)) + return spacingTop; + else + return parent.getSpacingTop(); + } + + public void setSpacingBottom(float value) + { + spacingBottom = value; + overriddenProperties.add(Property.SPACING_BOTTOM); + } + + public float getSpacingBottom() + { + if (overriddenProperties.contains(Property.SPACING_BOTTOM)) + return spacingBottom; + else + return parent.getSpacingBottom(); + } + + public void setFirstLineIndent(float value) + { + firstLineIndent = value; + overriddenProperties.add(Property.FIRST_LINE_INDENT); + } + + public float getFirstLineIndent() + { + if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) + return firstLineIndent; + else + return parent.getFirstLineIndent(); + } + + public void setLeftIndent(float value) + { + leftIndent = value; + overriddenProperties.add(Property.LEFT_INDENT); + } + + public float getLeftIndent() + { + if (overriddenProperties.contains(Property.LEFT_INDENT)) + return leftIndent; + else + return parent.getLeftIndent(); + } + + public void setRightIndent(float value) + { + rightIndent = value; + overriddenProperties.add(Property.RIGHT_INDENT); + } + + public float getRightIndent() + { + if (overriddenProperties.contains(Property.RIGHT_INDENT)) + return rightIndent; + else + return parent.getRightIndent(); + } + + public void setLineSpacing(float value) + { + lineSpacing = value; + overriddenProperties.add(Property.LINE_SPACING); + } + + public float getLineSpacing() + { + if (overriddenProperties.contains(Property.LINE_SPACING)) + return lineSpacing; + else + return parent.getLineSpacing(); + } + + public void addTab(float position, TabAlignment aligment) + { + // TODO Auto-generated method stub + } + + @Override + public String toString() + { + return "ParagraphStyle(" + alignment.name() + ", " + (getFont() != null ? getFont().getName() : "") + "@" + getFontSize() + ", " + (getBold() ? "bold, " : "") + (getItalic() ? "italic, " : "") + (getUnderlined() != UnderlineStyle.NONE ? ("underline: " + getUnderlined().name() + ", ") : "") + "fg: " + getForegroundColor() + ", " + "bg: " + getBackgroundColor() + ")"; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java index 7839df3..adc7c55 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.ParagraphStyle; @@ -21,11 +22,12 @@ /** * Default ParagraphStyleTable implementation. */ -public class DefaultParagraphStyleTable extends StyleTable - implements ParagraphStyleTable { +public class DefaultParagraphStyleTable extends StyleTableimplements ParagraphStyleTable +{ - public ParagraphStyle createStyle() { - return new DefaultParagraphStyle(); - } + public ParagraphStyle createStyle() + { + return new DefaultParagraphStyle(); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java index 326a3e2..261aac2 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Footer; @@ -23,68 +24,83 @@ /** * Default Section implementation */ -public class DefaultSection extends ParagraphList implements Section { - - private DefaultHeader header; - private DefaultFooter footer; - private final PageMargins pageMargins = new PageMargins(); - private final PageSize pageSize = new PageSize(); - - public Header createHeader() { - if (header == null) - header = new DefaultHeader(); - return header; - } - - public Header getHeader() { - return header; - } - - public Footer createFooter() { - if (footer == null) - footer = new DefaultFooter(); - return footer; - } - - public Footer getFooter() { - return footer; - } - - public PageMargins getPageMargins() { - return pageMargins; - } - - public PageSize getPageSize() { - return pageSize; - } - - public PageSettings getPageSettings() { - return new PageSettings() { - - public void setPageMarginLeft(int value) { - pageMargins.left = value; - } - - public void setPageMarginRight(int value) { - pageMargins.right = value; - } - - public void setPageMarginTop(int value) { - pageMargins.top = value; - } - - public void setPageMarginBottom(int value) { - pageMargins.bottom = value; - } - - public void setPageWidth(int value) { - pageSize.width = value; - } - - public void setPageHeight(int value) { - pageSize.height = value; - } - }; - } +public class DefaultSection extends ParagraphList implements Section +{ + + private DefaultHeader header; + private DefaultFooter footer; + private final PageMargins pageMargins = new PageMargins(); + private final PageSize pageSize = new PageSize(); + + public Header createHeader() + { + if (header == null) + header = new DefaultHeader(); + return header; + } + + public Header getHeader() + { + return header; + } + + public Footer createFooter() + { + if (footer == null) + footer = new DefaultFooter(); + return footer; + } + + public Footer getFooter() + { + return footer; + } + + public PageMargins getPageMargins() + { + return pageMargins; + } + + public PageSize getPageSize() + { + return pageSize; + } + + public PageSettings getPageSettings() + { + return new PageSettings() + { + + public void setPageMarginLeft(int value) + { + pageMargins.left = value; + } + + public void setPageMarginRight(int value) + { + pageMargins.right = value; + } + + public void setPageMarginTop(int value) + { + pageMargins.top = value; + } + + public void setPageMarginBottom(int value) + { + pageMargins.bottom = value; + } + + public void setPageWidth(int value) + { + pageSize.width = value; + } + + public void setPageHeight(int value) + { + pageSize.height = value; + } + }; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java index b98e4cf..27d74a5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.EnumSet; @@ -22,35 +23,40 @@ /** * Default Style implementation */ -abstract class DefaultStyle implements Style { - - private String name; - protected EnumSet overriddenProperties; - - protected DefaultStyle() { - overriddenProperties = EnumSet.noneOf(Property.class); - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public EnumSet getOverriddenProperties() { - return overriddenProperties; - } - - public boolean equals(Style object) { - if (object == this) - return true; - if (object == null || !(object instanceof DefaultStyle)) - return false; - - DefaultStyle other = (DefaultStyle) object; - return (name != null ? name.equals(other.name) : other.name == null) - && overriddenProperties.equals(other.overriddenProperties); - } +abstract class DefaultStyle implements Style +{ + + private String name; + protected EnumSet overriddenProperties; + + protected DefaultStyle() + { + overriddenProperties = EnumSet.noneOf(Property.class); + } + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public EnumSet getOverriddenProperties() + { + return overriddenProperties; + } + + public boolean equals(Style object) + { + if (object == this) + return true; + if (object == null || !(object instanceof DefaultStyle)) + return false; + + DefaultStyle other = (DefaultStyle) object; + return (name != null ? name.equals(other.name) : other.name == null) && overriddenProperties.equals(other.overriddenProperties); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java index fa4cc12..7f58cb4 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java @@ -13,27 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import com.rtfparserkit.document.CharacterStyleTable; import com.rtfparserkit.document.ParagraphStyleTable; import com.rtfparserkit.document.StyleSheet; -class DefaultStyleSheet implements StyleSheet { +class DefaultStyleSheet implements StyleSheet +{ + + private final ParagraphStyleTable paragraphStyleTable; + private final CharacterStyleTable characterStyleTable; - private final ParagraphStyleTable paragraphStyleTable; - private final CharacterStyleTable characterStyleTable; + DefaultStyleSheet() + { + paragraphStyleTable = new DefaultParagraphStyleTable(); + characterStyleTable = new DefaultCharacterStyleTable(); + } - DefaultStyleSheet() { - paragraphStyleTable = new DefaultParagraphStyleTable(); - characterStyleTable = new DefaultCharacterStyleTable(); - } - - public ParagraphStyleTable getParagraphStyleTable() { - return paragraphStyleTable; - } + public ParagraphStyleTable getParagraphStyleTable() + { + return paragraphStyleTable; + } - public CharacterStyleTable getCharacterStyleTable() { - return characterStyleTable; - } + public CharacterStyleTable getCharacterStyleTable() + { + return characterStyleTable; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java index f8d7baf..d229d17 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageMargins.java @@ -13,14 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; /** * Simple parameter storage for page margins. */ -public class PageMargins { - public int left; - public int right; - public int top; - public int bottom; +public class PageMargins +{ + public int left; + public int right; + public int top; + public int bottom; } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java index e4112a5..283405b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/PageSize.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; /** * Simple parameter storage for page size. */ -public class PageSize { - public int width; - public int height; +public class PageSize +{ + public int width; + public int height; } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java index 21cc46a..16d3081 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -28,154 +29,175 @@ * A list of Paragraph objects. There is always at least one, empty paragraph * in the list. */ -public class ParagraphList implements Iterable, DocumentPart { - private final List paragraphs; - - /** - * Creates a new instance which already contains an empty initial paragraph - * by calling clear(). - */ - public ParagraphList() { - paragraphs = new ArrayList(); - clear(); - } - - /** - * Returns and iterator over the Paragraphs contained in this list. - */ - public Iterator iterator() { - return new ParagraphIterator(paragraphs.iterator()); - } - - /** - * Finalizes the current paragraph by appending a line-break character '\n'. - * Starts the next paragraph by appending a new empty Paragraph to the list. - */ - public void nextParagraph(ParagraphStyle lastStyle) { - if (countParagraphs() > 0) - getLastParagraph().end(lastStyle); - paragraphs.add(new DefaultParagraph()); - } - - /** - * Implements nextLine() by appending the Unicode character "Line Separator" - * to the current paragraph. - */ - public void nextLine() { - getLastParagraph().append("\u2028"); - } - - /** - * @return The concatenated text of all contained Paragraphs. - */ - public String getText() { - StringBuilder builder = new StringBuilder(); - for (Paragraph paragraph : paragraphs) - builder.append(paragraph.getText()); - return builder.toString(); - } - - public ParagraphStyle createDefaultStyle() { - return new DefaultParagraphStyle(); - } - - /** - * Implements handleText() by separating the given text at line-breaks - * (calling nextParagraph() at '\n') and appending the chunks between - * line-breaks to the currently last Paragraph. This makes sure that all - * paragraphs in this list are normalized in that the last paragraph never - * contains a line-break, while all preceding paragraphs contain exactly - * one line-break which is at the very end of the paragraph. - * - * @param text The string to append. - * - * @see #nextParagraph() - */ - public void append(String text, ParagraphStyle style) { - int offset = 0; - while (offset < text.length()) { - int nextLineBreak = text.indexOf('\n', offset); - if (nextLineBreak == offset) { - nextParagraph(style); - offset++; - continue; - } - - int end = nextLineBreak > offset ? nextLineBreak : text.length(); - String subString = text.substring(offset, end); - getLastParagraph().append(subString, style); - - offset = end; - } - } - - public void append(String string) { - ParagraphStyle style = getLastParagraph().getLastStyle(); - append(string, style); - } - - public Annotation appendAnnotation() { - Annotation annotation = new DefaultAnnotation(); - getLastParagraph().append(annotation); - return annotation; - } - - /** - * Removes all Paragraphs that are currently in the list and adds a new - * empty Paragraph as the initial Paragraph by calling nextParagraph() - */ - public void clear() { - paragraphs.clear(); - // Add the initial empty paragraph - nextParagraph(new DefaultParagraphStyle()); - } - - /** - * @return The last Paragraph of the list. There is always at least - * one paragraph in the list. - */ - public DefaultParagraph getLastParagraph() { - return paragraphs.get(paragraphs.size() - 1); - } - - /** - * @return The number of paragraphs in this list. - */ - public int countParagraphs() { - return paragraphs.size(); - } - - /** - * Return the Paragraph at the specified index. - * - * @param index The index of the desired paragraph. The index must be - * >= 0 and < countParagraphs(). - * @return The paragraph at the given index. Throws an - * IndexOutOfBoundsExpception if index is out of bounds. - */ - public Paragraph paragraphAt(int index) { - return paragraphs.get(index); - } - - private static class ParagraphIterator implements Iterator { - - private final Iterator internalIterator; - - ParagraphIterator(Iterator iterator) { - internalIterator = iterator; - } - - public boolean hasNext() { - return internalIterator.hasNext(); - } - - public Paragraph next() { - return internalIterator.next(); - } - - public void remove() { - internalIterator.remove(); - } - - } +public class ParagraphList implements Iterable, DocumentPart +{ + private final List paragraphs; + + /** + * Creates a new instance which already contains an empty initial paragraph + * by calling clear(). + */ + public ParagraphList() + { + paragraphs = new ArrayList(); + clear(); + } + + /** + * Returns and iterator over the Paragraphs contained in this list. + */ + public Iterator iterator() + { + return new ParagraphIterator(paragraphs.iterator()); + } + + /** + * Finalizes the current paragraph by appending a line-break character '\n'. + * Starts the next paragraph by appending a new empty Paragraph to the list. + */ + public void nextParagraph(ParagraphStyle lastStyle) + { + if (countParagraphs() > 0) + getLastParagraph().end(lastStyle); + paragraphs.add(new DefaultParagraph()); + } + + /** + * Implements nextLine() by appending the Unicode character "Line Separator" + * to the current paragraph. + */ + public void nextLine() + { + getLastParagraph().append("\u2028"); + } + + /** + * @return The concatenated text of all contained Paragraphs. + */ + public String getText() + { + StringBuilder builder = new StringBuilder(); + for (Paragraph paragraph : paragraphs) + builder.append(paragraph.getText()); + return builder.toString(); + } + + public ParagraphStyle createDefaultStyle() + { + return new DefaultParagraphStyle(); + } + + /** + * Implements handleText() by separating the given text at line-breaks + * (calling nextParagraph() at '\n') and appending the chunks between + * line-breaks to the currently last Paragraph. This makes sure that all + * paragraphs in this list are normalized in that the last paragraph never + * contains a line-break, while all preceding paragraphs contain exactly + * one line-break which is at the very end of the paragraph. + * + * @param text The string to append. + * + * @see #nextParagraph() + */ + public void append(String text, ParagraphStyle style) + { + int offset = 0; + while (offset < text.length()) + { + int nextLineBreak = text.indexOf('\n', offset); + if (nextLineBreak == offset) + { + nextParagraph(style); + offset++; + continue; + } + + int end = nextLineBreak > offset ? nextLineBreak : text.length(); + String subString = text.substring(offset, end); + getLastParagraph().append(subString, style); + + offset = end; + } + } + + public void append(String string) + { + ParagraphStyle style = getLastParagraph().getLastStyle(); + append(string, style); + } + + public Annotation appendAnnotation() + { + Annotation annotation = new DefaultAnnotation(); + getLastParagraph().append(annotation); + return annotation; + } + + /** + * Removes all Paragraphs that are currently in the list and adds a new + * empty Paragraph as the initial Paragraph by calling nextParagraph() + */ + public void clear() + { + paragraphs.clear(); + // Add the initial empty paragraph + nextParagraph(new DefaultParagraphStyle()); + } + + /** + * @return The last Paragraph of the list. There is always at least + * one paragraph in the list. + */ + public DefaultParagraph getLastParagraph() + { + return paragraphs.get(paragraphs.size() - 1); + } + + /** + * @return The number of paragraphs in this list. + */ + public int countParagraphs() + { + return paragraphs.size(); + } + + /** + * Return the Paragraph at the specified index. + * + * @param index The index of the desired paragraph. The index must be + * >= 0 and < countParagraphs(). + * @return The paragraph at the given index. Throws an + * IndexOutOfBoundsExpception if index is out of bounds. + */ + public Paragraph paragraphAt(int index) + { + return paragraphs.get(index); + } + + private static class ParagraphIterator implements Iterator + { + + private final Iterator internalIterator; + + ParagraphIterator(Iterator iterator) + { + internalIterator = iterator; + } + + public boolean hasNext() + { + return internalIterator.hasNext(); + } + + public Paragraph next() + { + return internalIterator.next(); + } + + public void remove() + { + internalIterator.remove(); + } + + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java index 3ea49e9..fa14517 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.ArrayList; @@ -23,77 +24,86 @@ * A list of Section objects. There is always at least one, empty section * in the list. */ -public class SectionList implements Iterable { - private final List sections; - - /** - * Creates a new instance which already contains an empty initial section - * by calling clear(). - */ - public SectionList() { - sections = new ArrayList(); - clear(); - } +public class SectionList implements Iterable +{ + private final List sections; + + /** + * Creates a new instance which already contains an empty initial section + * by calling clear(). + */ + public SectionList() + { + sections = new ArrayList(); + clear(); + } + + /** + * Returns and iterator over the Sections contained in this list. + */ + public Iterator iterator() + { + return sections.iterator(); + } + + /** + * Starts the next Section by appending a new empty Section to the list. + */ + public void nextSection() + { + DefaultSection next = new DefaultSection(); + sections.add(next); + } - /** - * Returns and iterator over the Sections contained in this list. - */ - public Iterator iterator() { - return sections.iterator(); - } + /** + * Removes all Sections that are currently in the list and adds a new + * empty Section as the initial Section by calling nextSection() + */ + public void clear() + { + sections.clear(); + // Add the initial empty section + nextSection(); + } - /** - * Starts the next Section by appending a new empty Section to the list. - */ - public void nextSection() { - DefaultSection next = new DefaultSection(); - sections.add(next); - } + /** + * @return The last Paragraph of the list. There is always at least + * one paragraph in the list. + */ + public DefaultSection getLastSection() + { + return sections.get(sections.size() - 1); + } - /** - * Removes all Sections that are currently in the list and adds a new - * empty Section as the initial Section by calling nextSection() - */ - public void clear() { - sections.clear(); - // Add the initial empty section - nextSection(); - } + /** + * @return The number of paragraphs in this list. + */ + public int countSections() + { + return sections.size(); + } - /** - * @return The last Paragraph of the list. There is always at least - * one paragraph in the list. - */ - public DefaultSection getLastSection() { - return sections.get(sections.size() - 1); - } - - /** - * @return The number of paragraphs in this list. - */ - public int countSections() { - return sections.size(); - } + /** + * Return the Section at the specified index. + * + * @param index The index of the desired section. The index must be + * >= 0 and < countSections(). + * @return The Section at the given index. Throws an + * IndexOutOfBoundsExpception if index is out of bounds. + */ + public DefaultSection sectionAt(int index) + { + return sections.get(index); + } - /** - * Return the Section at the specified index. - * - * @param index The index of the desired section. The index must be - * >= 0 and < countSections(). - * @return The Section at the given index. Throws an - * IndexOutOfBoundsExpception if index is out of bounds. - */ - public DefaultSection sectionAt(int index) { - return sections.get(index); - } - - /** - * @return The concatenated text of all contained Sections. - */ - public String getText() { - StringBuilder builder = new StringBuilder(); - for (DefaultSection section : sections) - builder.append(section.getText()); - return builder.toString(); - } + /** + * @return The concatenated text of all contained Sections. + */ + public String getText() + { + StringBuilder builder = new StringBuilder(); + for (DefaultSection section : sections) + builder.append(section.getText()); + return builder.toString(); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java index 627ebf7..311f618 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.document.impl; import java.util.HashMap; @@ -23,26 +24,32 @@ /** * A table of Style objects. Styles can be added and retrieved by ID. */ -class StyleTable implements Iterable { - private final HashMap styles; - - StyleTable() { - styles = new HashMap(); - } - - public Iterator iterator() { - return styles.values().iterator(); - } - - public void addStyle(int id, E style) { - styles.put(id, style); - } - - public int countStyles() { - return styles.size(); - } - - public E styleFor(int id) { - return styles.get(id); - } +class StyleTable implements Iterable +{ + private final HashMap styles; + + StyleTable() + { + styles = new HashMap(); + } + + public Iterator iterator() + { + return styles.values().iterator(); + } + + public void addStyle(int id, E style) + { + styles.put(id, style); + } + + public int countStyles() + { + return styles.size(); + } + + public E styleFor(int id) + { + return styles.get(id); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java index a9b3ec8..29be458 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; @@ -26,52 +27,61 @@ * The only method which is supposed to be used by sub-classes is * processGroupEnd(), which pops the context from the provided RtfContextStack. */ -abstract class AbstractRtfContext implements RtfContext { - - private final boolean throwExceptions; - - protected AbstractRtfContext() { - this(true); - } +abstract class AbstractRtfContext implements RtfContext +{ + + private final boolean throwExceptions; + + protected AbstractRtfContext() + { + this(true); + } - protected AbstractRtfContext(boolean throwExceptions) { - this.throwExceptions = throwExceptions; - } + protected AbstractRtfContext(boolean throwExceptions) + { + this.throwExceptions = throwExceptions; + } - public void processGroupStart(RtfContextStack stack) { - handleUnexpectedEvent("Unexpected anonymous group start"); - stack.pushContext(this); - } + public void processGroupStart(RtfContextStack stack) + { + handleUnexpectedEvent("Unexpected anonymous group start"); + stack.pushContext(this); + } - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - handleUnexpectedEvent("Unexpected destination group start"); - stack.pushContext(this); - } + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + handleUnexpectedEvent("Unexpected destination group start"); + stack.pushContext(this); + } - public void processGroupEnd(RtfContextStack stack) { - stack.popContext(); - } + public void processGroupEnd(RtfContextStack stack) + { + stack.popContext(); + } - public void processCharacterBytes(byte[] data) { - handleUnexpectedEvent("Unexpected character bytes"); - } + public void processCharacterBytes(byte[] data) + { + handleUnexpectedEvent("Unexpected character bytes"); + } - public void processBinaryBytes(byte[] data) { - handleUnexpectedEvent("Unexpected binary bytes"); - } + public void processBinaryBytes(byte[] data) + { + handleUnexpectedEvent("Unexpected binary bytes"); + } - public void processString(String string) { - handleUnexpectedEvent("Unexpected string '" + string + "'"); - } + public void processString(String string) + { + handleUnexpectedEvent("Unexpected string '" + string + "'"); + } - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - handleUnexpectedEvent("Unexpected command '" + command + "'"); - } + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + handleUnexpectedEvent("Unexpected command '" + command + "'"); + } - private void handleUnexpectedEvent(String eventInfo) { - if (throwExceptions) - throw new IllegalStateException(eventInfo); - } + private void handleUnexpectedEvent(String eventInfo) + { + if (throwExceptions) + throw new IllegalStateException(eventInfo); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java index 8609923..0f0c2fc 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import java.util.Date; @@ -21,91 +22,101 @@ import com.rtfparserkit.parser.builder.TimeContext.DateListener; import com.rtfparserkit.rtf.Command; - /** * Parses the body of an Annotation. */ -class AnnotationContext extends DocumentPartContext { +class AnnotationContext extends DocumentPartContext +{ + + private final Annotation annotation; + private final DocumentPartContext parent; + + AnnotationContext(Annotation annotation, DocumentPartContext parent) + { + super(annotation, parent.document); + this.annotation = annotation; + this.parent = parent; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case atntime: + case atndate: + stack.pushContext(new TimeContext(new DateListener() + { + public void setDate(Date date) + { + annotation.setDate(date); + } + })); + break; + case atnref: + // TODO: Handle annotation references. The reference is in + // the parameter. + stack.pushContext(new AnnotationReferenceContext()); + break; + case atnparent: + stack.pushContext(new AnnotationParentContext()); + break; + case atrfstart: + stack.pushContext(new BookmarkStartContext()); + break; + case atrfend: + stack.pushContext(new BookmarkEndContext()); + break; + default: + super.processGroupStart(stack, command, parameter, hasParameter, optional); + } + } - private final Annotation annotation; - private final DocumentPartContext parent; - - AnnotationContext(Annotation annotation, DocumentPartContext parent) { - super(annotation, parent.document); - this.annotation = annotation; - this.parent = parent; - } - - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case atntime: - case atndate: - stack.pushContext(new TimeContext(new DateListener() { - public void setDate(Date date) { - annotation.setDate(date); - } - })); - break; - case atnref: - // TODO: Handle annotation references. The reference is in - // the parameter. - stack.pushContext(new AnnotationReferenceContext()); - break; - case atnparent: - stack.pushContext(new AnnotationParentContext()); - break; - case atrfstart: - stack.pushContext(new BookmarkStartContext()); - break; - case atrfend: - stack.pushContext(new BookmarkEndContext()); - break; - default: - super.processGroupStart(stack, command, parameter, hasParameter, - optional); - } - } + @Override + public void processGroupEnd(RtfContextStack stack) + { + // Inform the parent context that parsing the annotation body has + // finished. + parent.annotationFinished(); + super.processGroupEnd(stack); + } - @Override - public void processGroupEnd(RtfContextStack stack) { - // Inform the parent context that parsing the annotation body has - // finished. - parent.annotationFinished(); - super.processGroupEnd(stack); - } + private class AnnotationParentContext extends AbstractRtfContext + { + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case atnid: + stack.pushContext(new AnnotationIdContext()); + break; + default: + super.processGroupStart(stack, command, parameter, hasParameter, optional); + } + } + } - private class AnnotationParentContext extends AbstractRtfContext { - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case atnid: - stack.pushContext(new AnnotationIdContext()); - break; - default: - super.processGroupStart(stack, command, parameter, hasParameter, - optional); - } - } - } + private class AnnotationIdContext extends AbstractRtfContext + { + @Override + public void processString(String string) + { + // TODO: The string is the ID of a parent Annotation. Do something + // with it. + } + } - private class AnnotationIdContext extends AbstractRtfContext { - @Override - public void processString(String string) { - // TODO: The string is the ID of a parent Annotation. Do something - // with it. - } - } + private class AnnotationReferenceContext extends AbstractRtfContext + { + } - private class AnnotationReferenceContext extends AbstractRtfContext { - } + private class BookmarkStartContext extends AbstractRtfContext + { + } - private class BookmarkStartContext extends AbstractRtfContext { - } + private class BookmarkEndContext extends AbstractRtfContext + { + } - private class BookmarkEndContext extends AbstractRtfContext { - } - } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java index 1d1b80d..8faa2b2 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/CharacterStyleContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.CharacterStyle; @@ -22,38 +23,42 @@ * RtfContext for parsing a style definition group located in the style sheet * section of an RTF document. */ -class CharacterStyleContext extends AbstractRtfContext { - - private final CharacterStyle style; - - CharacterStyleContext(CharacterStyle style) { - this.style = style; - } - - @Override - public void processGroupStart(RtfContextStack stack) { - // TODO: Implement - stack.pushContext(new NullContext()); - } - - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // TODO: Implement - stack.pushContext(new NullContext()); - } - - @Override - public void processString(String string) { - int semicolon = string.indexOf(';'); - int end = semicolon >= 0 ? semicolon : string.length(); - string = string.substring(0, end); - style.setName(string); - } - - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // TODO: Implement - } +class CharacterStyleContext extends AbstractRtfContext +{ + + private final CharacterStyle style; + + CharacterStyleContext(CharacterStyle style) + { + this.style = style; + } + + @Override + public void processGroupStart(RtfContextStack stack) + { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processString(String string) + { + int semicolon = string.indexOf(';'); + int end = semicolon >= 0 ? semicolon : string.length(); + string = string.substring(0, end); + style.setName(string); + } + + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // TODO: Implement + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java index b9cb5b5..6e3e7a5 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ColorTableContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.ColorTable; @@ -23,44 +24,50 @@ * the file. Whenever a color entry is closed with ';' a new color entry is * added to the ColorTable instance which is passed on construction. */ -class ColorTableContext extends AbstractRtfContext { +class ColorTableContext extends AbstractRtfContext +{ + + private final ColorTable table; + + private int red; + private int green; + private int blue; - private final ColorTable table; - - private int red; - private int green; - private int blue; - - ColorTableContext(ColorTable table) { - this.table = table; - } + ColorTableContext(ColorTable table) + { + this.table = table; + } - @Override - public void processString(String string) { - if (";".equals(string)) { - table.addColor(red, green, blue); - } else { - throw new IllegalStateException("Unexpected string in color table"); - } - } + @Override + public void processString(String string) + { + if (";".equals(string)) + { + table.addColor(red, green, blue); + } + else + { + throw new IllegalStateException("Unexpected string in color table"); + } + } - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case red: - red = parameter; - break; - case green: - green = parameter; - break; - case blue: - blue = parameter; - break; - default: - throw new IllegalStateException( - "Unexpected command in color table"); - } - } + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case red: + red = parameter; + break; + case green: + green = parameter; + break; + case blue: + blue = parameter; + break; + default: + throw new IllegalStateException("Unexpected command in color table"); + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java index 55bd0c2..270a056 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Document; @@ -28,127 +29,146 @@ * * @author stippi */ -public class DocumentBuilder implements IRtfListener { - - private int level = 0; - private boolean atGroupStart = false; - private boolean debugEvents = false; - - private final RtfContextStack stack; - - public DocumentBuilder(Document document) { - stack = new RtfContextStack(new RootContext(document)); - } - - public void setDebugEvents(boolean debug) { - debugEvents = debug; - } - - public void processDocumentStart() { - } - - public void processDocumentEnd() { - } - - public void processGroupStart() { - atGroupStart = true; - } - - public void processGroupEnd() { - handleDelayedGroupStart(); - if (debugEvents) - System.out.println(getIndentation() + "processGroupEnd()"); - stack.getContext().processGroupEnd(stack); - level--; - atGroupStart = false; - } - - public void processCharacterBytes(byte[] data) { - handleDelayedGroupStart(); - if (debugEvents) - System.out.println(getIndentation() + "processCharacterBytes()"); - stack.getContext().processCharacterBytes(data); - } - - public void processBinaryBytes(byte[] data) { - handleDelayedGroupStart(); - if (debugEvents) - System.out.println(getIndentation() + "processBinaryBytes()"); - stack.getContext().processBinaryBytes(data); - } - - public void processString(String string) { - handleDelayedGroupStart(); - if (debugEvents) - System.out.println(getIndentation() + "processString(" + string + ")"); - stack.getContext().processString(string); - } - - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { - if (atGroupStart) { - // Handle delayed group start. - if (command == Command.optionalcommand) { - // Optional group with an unknown command, completely ignore - // this. - if (debugEvents) { - System.out.println(getIndentation() + "processGroupStart(" - + command + ")"); - } - level++; - stack.pushContext(new NullContext()); - // Do not handle this command as processCommand() a second time. - groupStarted(); - return; - } if (command.getCommandType() == CommandType.Destination) { - if (debugEvents) { - System.out.println(getIndentation() + "processGroupStart(" - + command + ")"); - } - level++; - stack.getContext().processGroupStart(stack, command, parameter, - hasParameter, optional); - // Do not handle this command as processCommand() a second time. - groupStarted(); - return; - } else { - handleDelayedGroupStart(); - } - } - - if (debugEvents) { - System.out.print(getIndentation() + "processCommand() " + command); - if (hasParameter) - System.out.print(", parameter: " + parameter); - if (optional) - System.out.print(" (optional)"); - System.out.println(); - } - - stack.getContext().processCommand(stack, command, parameter, - hasParameter, optional); - } - - private String getIndentation() { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < level; i++) - builder.append(" "); - builder.append(stack.getContext().getClass().getSimpleName()); - builder.append('.'); - return builder.toString(); - } - - private void handleDelayedGroupStart() { - if (atGroupStart) { - if (debugEvents) - System.out.println(getIndentation() + "processGroupStart()"); - level++; - stack.getContext().processGroupStart(stack); - groupStarted(); - } - } - - private void groupStarted() { - atGroupStart = false; - } +public class DocumentBuilder implements IRtfListener +{ + + private int level = 0; + private boolean atGroupStart = false; + private boolean debugEvents = false; + + private final RtfContextStack stack; + + public DocumentBuilder(Document document) + { + stack = new RtfContextStack(new RootContext(document)); + } + + public void setDebugEvents(boolean debug) + { + debugEvents = debug; + } + + public void processDocumentStart() + { + } + + public void processDocumentEnd() + { + } + + public void processGroupStart() + { + atGroupStart = true; + } + + public void processGroupEnd() + { + handleDelayedGroupStart(); + if (debugEvents) + System.out.println(getIndentation() + "processGroupEnd()"); + stack.getContext().processGroupEnd(stack); + level--; + atGroupStart = false; + } + + public void processCharacterBytes(byte[] data) + { + handleDelayedGroupStart(); + if (debugEvents) + System.out.println(getIndentation() + "processCharacterBytes()"); + stack.getContext().processCharacterBytes(data); + } + + public void processBinaryBytes(byte[] data) + { + handleDelayedGroupStart(); + if (debugEvents) + System.out.println(getIndentation() + "processBinaryBytes()"); + stack.getContext().processBinaryBytes(data); + } + + public void processString(String string) + { + handleDelayedGroupStart(); + if (debugEvents) + System.out.println(getIndentation() + "processString(" + string + ")"); + stack.getContext().processString(string); + } + + public void processCommand(Command command, int parameter, boolean hasParameter, boolean optional) + { + if (atGroupStart) + { + // Handle delayed group start. + if (command == Command.optionalcommand) + { + // Optional group with an unknown command, completely ignore + // this. + if (debugEvents) + { + System.out.println(getIndentation() + "processGroupStart(" + command + ")"); + } + level++; + stack.pushContext(new NullContext()); + // Do not handle this command as processCommand() a second time. + groupStarted(); + return; + } + if (command.getCommandType() == CommandType.Destination) + { + if (debugEvents) + { + System.out.println(getIndentation() + "processGroupStart(" + command + ")"); + } + level++; + stack.getContext().processGroupStart(stack, command, parameter, hasParameter, optional); + // Do not handle this command as processCommand() a second time. + groupStarted(); + return; + } + else + { + handleDelayedGroupStart(); + } + } + + if (debugEvents) + { + System.out.print(getIndentation() + "processCommand() " + command); + if (hasParameter) + System.out.print(", parameter: " + parameter); + if (optional) + System.out.print(" (optional)"); + System.out.println(); + } + + stack.getContext().processCommand(stack, command, parameter, hasParameter, optional); + } + + private String getIndentation() + { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < level; i++) + builder.append(" "); + builder.append(stack.getContext().getClass().getSimpleName()); + builder.append('.'); + return builder.toString(); + } + + private void handleDelayedGroupStart() + { + if (atGroupStart) + { + if (debugEvents) + System.out.println(getIndentation() + "processGroupStart()"); + level++; + stack.getContext().processGroupStart(stack); + groupStarted(); + } + } + + private void groupStarted() + { + atGroupStart = false; + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java index c990363..6db0040 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Document; @@ -21,83 +22,77 @@ /** * RtfContext for handling the {\rtf group. */ -class DocumentContext extends DocumentPartContext { +class DocumentContext extends DocumentPartContext +{ + + private final Document document; + + DocumentContext(Document document) + { + super(document, document); + this.document = document; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case header: + stack.pushContext(new DocumentPartContext(document.getLastSection().createHeader(), document)); + break; + case footer: + stack.pushContext(new DocumentPartContext(document.getLastSection().createFooter(), document)); + break; + case colortbl: + stack.pushContext(new ColorTableContext(document.getColorTable())); + break; + case fonttbl: + stack.pushContext(new FontTableContext(document.getFontTable())); + break; + case stylesheet: + stack.pushContext(new StyleSheetContext(document.getStyleSheet())); + break; - private final Document document; - - DocumentContext(Document document) { - super(document, document); - this.document = document; - } + default: + // Unknown destinations should be ignored. + stack.pushContext(new NullContext()); + break; + } + } - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case header: - stack.pushContext(new DocumentPartContext( - document.getLastSection().createHeader(), - document)); - break; - case footer: - stack.pushContext(new DocumentPartContext( - document.getLastSection().createFooter(), - document)); - break; - case colortbl: - stack.pushContext(new ColorTableContext(document.getColorTable())); - break; - case fonttbl: - stack.pushContext(new FontTableContext(document.getFontTable())); - break; - case stylesheet: - stack.pushContext(new StyleSheetContext(document.getStyleSheet())); - break; + @Override + public void processGroupStart(RtfContextStack stack) + { + stack.pushContext(new DocumentPartContext(document, document)); + } - default: - // Unknown destinations should be ignored. - stack.pushContext(new NullContext()); - break; - } - } - - @Override - public void processGroupStart(RtfContextStack stack) { - stack.pushContext(new DocumentPartContext(document, document)); - } + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case margl: + document.getDocumentSettings().getPageSettings().setPageMarginLeft(parameter); + break; + case margr: + document.getDocumentSettings().getPageSettings().setPageMarginRight(parameter); + break; + case margt: + document.getDocumentSettings().getPageSettings().setPageMarginTop(parameter); + break; + case margb: + document.getDocumentSettings().getPageSettings().setPageMarginBottom(parameter); + break; + case paperw: + document.getDocumentSettings().getPageSettings().setPageWidth(parameter); + break; + case paperh: + document.getDocumentSettings().getPageSettings().setPageHeight(parameter); + break; - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case margl: - document.getDocumentSettings() - .getPageSettings().setPageMarginLeft(parameter); - break; - case margr: - document.getDocumentSettings() - .getPageSettings().setPageMarginRight(parameter); - break; - case margt: - document.getDocumentSettings() - .getPageSettings().setPageMarginTop(parameter); - break; - case margb: - document.getDocumentSettings() - .getPageSettings().setPageMarginBottom(parameter); - break; - case paperw: - document.getDocumentSettings() - .getPageSettings().setPageWidth(parameter); - break; - case paperh: - document.getDocumentSettings() - .getPageSettings().setPageHeight(parameter); - break; - - default: - super.processCommand(stack, command, parameter, hasParameter, - optional); - } - } + default: + super.processCommand(stack, command, parameter, hasParameter, optional); + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 096c647..65c1b6f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Annotation; @@ -27,285 +28,295 @@ * RtfContext for processing RTF events which have a main styled text * destination. */ -class DocumentPartContext extends AbstractRtfContext { +class DocumentPartContext extends AbstractRtfContext +{ + + private final DocumentPart documentPart; + protected final Document document; + private final ParagraphStyle style; + + private Annotation currentAnnotation; + + DocumentPartContext(DocumentPart part, Document document) + { + documentPart = part; + this.document = document; + style = part.createDefaultStyle(); + } + + DocumentPartContext(DocumentPartContext parent) + { + documentPart = parent.documentPart; + document = parent.document; + style = parent.style.createDerivedStyle(); + } + + @Override + public void processGroupStart(RtfContextStack stack) + { + stack.pushContext(new DocumentPartContext(this)); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case atnid: + // A new Annotation started + if (currentAnnotation != null) + { + stack.handleError("An annotation has already" + "started, but encountered another annotation ID."); + } + currentAnnotation = documentPart.appendAnnotation(); + stack.pushContext(new AnnotationIdContext()); + break; + case atnauthor: + stack.pushContext(new AnnotationAuthorContext()); + break; + case annotation: + stack.pushContext(new AnnotationContext(currentAnnotation, this)); + break; + default: + stack.pushContext(new DocumentPartContext(this)); + } + } + + @Override + public void processCharacterBytes(byte[] data) + { + // Ignore + } + + @Override + public void processBinaryBytes(byte[] data) + { + // Ignore + } - private final DocumentPart documentPart; - protected final Document document; - private final ParagraphStyle style; - - private Annotation currentAnnotation; - - DocumentPartContext(DocumentPart part, Document document) { - documentPart = part; - this.document = document; - style = part.createDefaultStyle(); - } + @Override + public void processString(String string) + { + documentPart.append(string, style.createFlattenedStyle()); + } - DocumentPartContext(DocumentPartContext parent) { - documentPart = parent.documentPart; - document = parent.document; - style = parent.style.createDerivedStyle(); - } + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + // Paragraph control + case par: + documentPart.nextParagraph(style.createFlattenedStyle()); + break; + case line: + documentPart.nextLine(); + break; - @Override - public void processGroupStart(RtfContextStack stack) { - stack.pushContext(new DocumentPartContext(this)); - } + // Special characters + case chatn: + // This denotes a special character that is associated with an + // annotation. In most text processing applications, the text + // cursor can be "before" and "after" an annotation within the text. + // deleting this text position deletes the annotation. + // Before \chatn, there should have been an annotation started by + // \atnid and we have already appended an Annotation object to + // the DocumentPart. At the latest, this will happen with the + // next \annotation group. + break; - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case atnid: - // A new Annotation started - if (currentAnnotation != null) { - stack.handleError("An annotation has already" - + "started, but encountered another annotation ID."); - } - currentAnnotation = documentPart.appendAnnotation(); - stack.pushContext(new AnnotationIdContext()); - break; - case atnauthor: - stack.pushContext(new AnnotationAuthorContext()); - break; - case annotation: - stack.pushContext(new AnnotationContext(currentAnnotation, this)); - break; - default: - stack.pushContext(new DocumentPartContext(this)); - } - } - - @Override - public void processCharacterBytes(byte[] data) { - // Ignore - } + // Text styles + case plain: + style.resetToDefaults(); + break; + case f: + style.setFont(document.getFontTable().fontAt(parameter)); + break; + case fs: + style.setFontSize(fromHalfPoints(parameter)); + break; + case b: + if (!hasParameter) + style.setBold(true); + else + style.setBold(parameter != 0); + break; + case i: + if (!hasParameter) + style.setItalic(true); + else + style.setItalic(parameter != 0); + break; + case caps: + if (!hasParameter) + style.setCaps(true); + else + style.setCaps(parameter != 0); + break; + case strike: + case striked: + if (!hasParameter) + style.setStrikeOut(true); + else + style.setStrikeOut(parameter != 0); + break; + case ul: + setUnderlined(UnderlineStyle.SINGLE, hasParameter, parameter); + break; + case uld: + setUnderlined(UnderlineStyle.DOTTED, hasParameter, parameter); + break; + case uldash: + setUnderlined(UnderlineStyle.DASHED, hasParameter, parameter); + break; + case uldashd: + setUnderlined(UnderlineStyle.DASH_DOTTED, hasParameter, parameter); + break; + case uldashdd: + setUnderlined(UnderlineStyle.DASH_DOT_DOTTED, hasParameter, parameter); + break; + case uldb: + setUnderlined(UnderlineStyle.DOUBLE, hasParameter, parameter); + break; + case ulhwave: + setUnderlined(UnderlineStyle.HEAVY_WAVE, hasParameter, parameter); + break; + case ulldash: + setUnderlined(UnderlineStyle.LONG_DASHED, hasParameter, parameter); + break; + case ulnone: + style.setUnderlined(UnderlineStyle.NONE); + break; + case ulth: + setUnderlined(UnderlineStyle.THICK, hasParameter, parameter); + break; + case ulthd: + setUnderlined(UnderlineStyle.THICK_DOTTED, hasParameter, parameter); + break; + case ulthdash: + setUnderlined(UnderlineStyle.THICK_DASHED, hasParameter, parameter); + break; + case ulthdashd: + setUnderlined(UnderlineStyle.THICK_DASH_DOTTED, hasParameter, parameter); + break; + case ulthdashdd: + setUnderlined(UnderlineStyle.THICK_DASH_DOT_DOTTED, hasParameter, parameter); + break; + case ulthldash: + setUnderlined(UnderlineStyle.THICK_LONG_DASHED, hasParameter, parameter); + break; + case ululdbwave: + setUnderlined(UnderlineStyle.DOUBLE_WAVE, hasParameter, parameter); + break; + case ulw: + setUnderlined(UnderlineStyle.WORD, hasParameter, parameter); + break; + case ulwave: + setUnderlined(UnderlineStyle.WAVE, hasParameter, parameter); + break; + case cb: + style.setBackgroundColor(document.getColorTable().colorAt(parameter)); + break; + case cf: + style.setForegroundColor(document.getColorTable().colorAt(parameter)); + break; - @Override - public void processBinaryBytes(byte[] data) { - // Ignore - } + // Alignment + case qc: + style.setAlignment(Alignment.CENTER); + break; + case qj: + style.setAlignment(Alignment.JUSTIFIED); + break; + case ql: + style.setAlignment(Alignment.LEFT); + break; + case qr: + style.setAlignment(Alignment.RIGHT); + break; + case qd: + style.setAlignment(Alignment.DISTRIBUTED); + break; - @Override - public void processString(String string) { - documentPart.append(string, style.createFlattenedStyle()); - } + // Indents + case fi: + style.setFirstLineIndent(fromTwips(parameter)); + break; + case li: + style.setLeftIndent(fromTwips(parameter)); + break; + case ri: + style.setRightIndent(fromTwips(parameter)); + break; - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - // Paragraph control - case par: - documentPart.nextParagraph(style.createFlattenedStyle()); - break; - case line: - documentPart.nextLine(); - break; - - // Special characters - case chatn: - // This denotes a special character that is associated with an - // annotation. In most text processing applications, the text - // cursor can be "before" and "after" an annotation within the text. - // deleting this text position deletes the annotation. - // Before \chatn, there should have been an annotation started by - // \atnid and we have already appended an Annotation object to - // the DocumentPart. At the latest, this will happen with the - // next \annotation group. - break; - - // Text styles - case plain: - style.resetToDefaults(); - break; - case f: - style.setFont(document.getFontTable().fontAt(parameter)); - break; - case fs: - style.setFontSize(fromHalfPoints(parameter)); - break; - case b: - if (!hasParameter) - style.setBold(true); - else - style.setBold(parameter != 0); - break; - case i: - if (!hasParameter) - style.setItalic(true); - else - style.setItalic(parameter != 0); - break; - case caps: - if (!hasParameter) - style.setCaps(true); - else - style.setCaps(parameter != 0); - break; - case strike: - case striked: - if (!hasParameter) - style.setStrikeOut(true); - else - style.setStrikeOut(parameter != 0); - break; - case ul: - setUnderlined(UnderlineStyle.SINGLE, hasParameter, parameter); - break; - case uld: - setUnderlined(UnderlineStyle.DOTTED, hasParameter, parameter); - break; - case uldash: - setUnderlined(UnderlineStyle.DASHED, hasParameter, parameter); - break; - case uldashd: - setUnderlined(UnderlineStyle.DASH_DOTTED, hasParameter, parameter); - break; - case uldashdd: - setUnderlined(UnderlineStyle.DASH_DOT_DOTTED, hasParameter, - parameter); - break; - case uldb: - setUnderlined(UnderlineStyle.DOUBLE, hasParameter, parameter); - break; - case ulhwave: - setUnderlined(UnderlineStyle.HEAVY_WAVE, hasParameter, parameter); - break; - case ulldash: - setUnderlined(UnderlineStyle.LONG_DASHED, hasParameter, parameter); - break; - case ulnone: - style.setUnderlined(UnderlineStyle.NONE); - break; - case ulth: - setUnderlined(UnderlineStyle.THICK, hasParameter, parameter); - break; - case ulthd: - setUnderlined(UnderlineStyle.THICK_DOTTED, hasParameter, parameter); - break; - case ulthdash: - setUnderlined(UnderlineStyle.THICK_DASHED, hasParameter, parameter); - break; - case ulthdashd: - setUnderlined(UnderlineStyle.THICK_DASH_DOTTED, hasParameter, - parameter); - break; - case ulthdashdd: - setUnderlined(UnderlineStyle.THICK_DASH_DOT_DOTTED, hasParameter, - parameter); - break; - case ulthldash: - setUnderlined(UnderlineStyle.THICK_LONG_DASHED, hasParameter, - parameter); - break; - case ululdbwave: - setUnderlined(UnderlineStyle.DOUBLE_WAVE, hasParameter, parameter); - break; - case ulw: - setUnderlined(UnderlineStyle.WORD, hasParameter, - parameter); - break; - case ulwave: - setUnderlined(UnderlineStyle.WAVE, hasParameter, parameter); - break; - case cb: - style.setBackgroundColor( - document.getColorTable().colorAt(parameter)); - break; - case cf: - style.setForegroundColor( - document.getColorTable().colorAt(parameter)); - break; - - // Alignment - case qc: - style.setAlignment(Alignment.CENTER); - break; - case qj: - style.setAlignment(Alignment.JUSTIFIED); - break; - case ql: - style.setAlignment(Alignment.LEFT); - break; - case qr: - style.setAlignment(Alignment.RIGHT); - break; - case qd: - style.setAlignment(Alignment.DISTRIBUTED); - break; + // spacing + case sb: + style.setSpacingTop(fromTwips(parameter)); + break; + case sa: + style.setSpacingBottom(fromTwips(parameter)); + break; + case sl: + style.setLineSpacing(fromTwips(parameter)); + break; - // Indents - case fi: - style.setFirstLineIndent(fromTwips(parameter)); - break; - case li: - style.setLeftIndent(fromTwips(parameter)); - break; - case ri: - style.setRightIndent(fromTwips(parameter)); - break; + default: + // System.out.println("DocumentPartContext.processCommand(" + // + command + ") not handled!"); + break; + } + } - // spacing - case sb: - style.setSpacingTop(fromTwips(parameter)); - break; - case sa: - style.setSpacingBottom(fromTwips(parameter)); - break; - case sl: - style.setLineSpacing(fromTwips(parameter)); - break; - - default: -// System.out.println("DocumentPartContext.processCommand(" -// + command + ") not handled!"); - break; - } - } + private void setUnderlined(UnderlineStyle underline, boolean hasParamter, int parameter) + { + if (!hasParamter || parameter == 0) + style.setUnderlined(UnderlineStyle.NONE); + else + style.setUnderlined(underline); + } - private void setUnderlined(UnderlineStyle underline, boolean hasParamter, - int parameter) { - if (!hasParamter || parameter == 0) - style.setUnderlined(UnderlineStyle.NONE); - else - style.setUnderlined(underline); - } + private static float fromTwips(int value) + { + return (float) value / 20.0f; + } - private static float fromTwips(int value) { - return (float) value / 20.0f; - } + private static float fromHalfPoints(int value) + { + return (float) value / 2.0f; + } - private static float fromHalfPoints(int value) { - return (float) value / 2.0f; - } + private String append(String string, String toAppend) + { + return string != null ? string + toAppend : toAppend; + } - private String append(String string, String toAppend) { - return string != null ? string + toAppend : toAppend; - } - - void annotationFinished() { - currentAnnotation = null; - } + void annotationFinished() + { + currentAnnotation = null; + } - private class AnnotationAuthorContext extends AbstractRtfContext { - @Override - public void processString(String string) { - if (currentAnnotation != null) { - currentAnnotation.setAuthor( - append(currentAnnotation.getAuthor(), string)); - } - } - } + private class AnnotationAuthorContext extends AbstractRtfContext + { + @Override + public void processString(String string) + { + if (currentAnnotation != null) + { + currentAnnotation.setAuthor(append(currentAnnotation.getAuthor(), string)); + } + } + } - private class AnnotationIdContext extends AbstractRtfContext { - @Override - public void processString(String string) { - if (currentAnnotation != null) { - currentAnnotation.setId( - append(currentAnnotation.getId(), string)); - } - } - } + private class AnnotationIdContext extends AbstractRtfContext + { + @Override + public void processString(String string) + { + if (currentAnnotation != null) + { + currentAnnotation.setId(append(currentAnnotation.getId(), string)); + } + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java index 0c91a2a..6fd6148 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentSettingsContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.DocumentSettings; @@ -21,37 +22,44 @@ /** * RtfContext implementing the storing of global settings to the document. */ -class DocumentSettingsContext extends AbstractRtfContext { +class DocumentSettingsContext extends AbstractRtfContext +{ + + private final DocumentSettings settings; + + DocumentSettingsContext(DocumentSettings settings) + { + this.settings = settings; + } - private final DocumentSettings settings; - - DocumentSettingsContext(DocumentSettings settings) { - this.settings = settings; - } - - public void processCommand(Command command, int parameter, - boolean hasParameter, boolean optional) { - switch (command) { - case margl: - settings.getPageSettings().setPageMarginLeft(parameter); - break; - case margr: - settings.getPageSettings().setPageMarginRight(parameter); - break; - case margt: - settings.getPageSettings().setPageMarginTop(parameter); - break; - case margb: - settings.getPageSettings().setPageMarginBottom(parameter); - break; - case paperw: - settings.getPageSettings().setPageWidth(parameter); - break; - case paperh: - settings.getPageSettings().setPageHeight(parameter); - break; - // TODO: More commands... - } - } + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case margl: + settings.getPageSettings().setPageMarginLeft(parameter); + break; + case margr: + settings.getPageSettings().setPageMarginRight(parameter); + break; + case margt: + settings.getPageSettings().setPageMarginTop(parameter); + break; + case margb: + settings.getPageSettings().setPageMarginBottom(parameter); + break; + case paperw: + settings.getPageSettings().setPageWidth(parameter); + break; + case paperh: + settings.getPageSettings().setPageHeight(parameter); + break; + // TODO: More commands... + default: + super.processCommand(stack, command, parameter, hasParameter, optional); + break; + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java index f8e736a..5a09d36 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.FontTable; @@ -23,104 +24,114 @@ * RtfContext implementation which handles RTF events inside a group inside * of the font table section. */ -class FontContext extends AbstractRtfContext { - - protected final FontTable fontTable; - - private String fontName = ""; - private String alternativeName = ""; - private String fileName = ""; - private FontFamily fontFamily = FontFamily.DEFAULT; - - private enum ExpectedName { - DEFAULT, - ALTERNATIVE, - FILE - } - - private ExpectedName expectedName = ExpectedName.DEFAULT; - - FontContext(FontTable fontTable) { - this.fontTable = fontTable; - } - - @Override - public void processGroupEnd(RtfContextStack stack) { - super.processGroupEnd(stack); - } - - @Override - public void processString(String string) { - int offset = 0; - while (offset < string.length()) { - // Chop off anything after and including the first semicolon - int semicolon = string.indexOf(';', offset); - - if (semicolon == offset) { - fontTable.addFont(fontName, alternativeName, fileName, - fontFamily); - offset = semicolon + 1; - continue; - } - - int end = semicolon >= 0 ? semicolon : string.length(); - - String name = string.substring(offset, end); - - switch (expectedName) { - case DEFAULT: - fontName = name; - break; - case ALTERNATIVE: - alternativeName = name; - break; - case FILE: - fileName = name; - break; - } - - offset = end; - } - } - - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case fname: - expectedName = ExpectedName.DEFAULT; - break; - case falt: - expectedName = ExpectedName.ALTERNATIVE; - break; - case fontfile: - expectedName = ExpectedName.FILE; - break; - - case fnil: - fontFamily = FontFamily.DEFAULT; - break; - case froman: - fontFamily = FontFamily.ROMAN; - break; - case fswiss: - fontFamily = FontFamily.SWISS; - break; - case fmodern: - fontFamily = FontFamily.MODERN; - break; - case fscript: - fontFamily = FontFamily.SCRIPT; - break; - case fdecor: - fontFamily = FontFamily.DECOR; - break; - case ftech: - fontFamily = FontFamily.TECH; - break; - case fbidi: - fontFamily = FontFamily.BIDI; - break; - } - } +class FontContext extends AbstractRtfContext +{ + + protected final FontTable fontTable; + + private String fontName = ""; + private String alternativeName = ""; + private String fileName = ""; + private FontFamily fontFamily = FontFamily.DEFAULT; + + private enum ExpectedName + { + DEFAULT, ALTERNATIVE, FILE + } + + private ExpectedName expectedName = ExpectedName.DEFAULT; + + FontContext(FontTable fontTable) + { + this.fontTable = fontTable; + } + + @Override + public void processGroupEnd(RtfContextStack stack) + { + super.processGroupEnd(stack); + } + + @Override + public void processString(String string) + { + int offset = 0; + while (offset < string.length()) + { + // Chop off anything after and including the first semicolon + int semicolon = string.indexOf(';', offset); + + if (semicolon == offset) + { + fontTable.addFont(fontName, alternativeName, fileName, fontFamily); + offset = semicolon + 1; + continue; + } + + int end = semicolon >= 0 ? semicolon : string.length(); + + String name = string.substring(offset, end); + + switch (expectedName) + { + case DEFAULT: + fontName = name; + break; + case ALTERNATIVE: + alternativeName = name; + break; + case FILE: + fileName = name; + break; + } + + offset = end; + } + } + + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case fname: + expectedName = ExpectedName.DEFAULT; + break; + case falt: + expectedName = ExpectedName.ALTERNATIVE; + break; + case fontfile: + expectedName = ExpectedName.FILE; + break; + + case fnil: + fontFamily = FontFamily.DEFAULT; + break; + case froman: + fontFamily = FontFamily.ROMAN; + break; + case fswiss: + fontFamily = FontFamily.SWISS; + break; + case fmodern: + fontFamily = FontFamily.MODERN; + break; + case fscript: + fontFamily = FontFamily.SCRIPT; + break; + case fdecor: + fontFamily = FontFamily.DECOR; + break; + case ftech: + fontFamily = FontFamily.TECH; + break; + case fbidi: + fontFamily = FontFamily.BIDI; + break; + + default: + super.processCommand(stack, command, parameter, hasParameter, optional); + break; + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java index 5e5994f..bd9c50b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.FontTable; @@ -25,21 +26,24 @@ * Note that FontTableContext inherits from FontContext, since RTF files may * or may not have the \font elements within a group. */ -class FontTableContext extends FontContext { +class FontTableContext extends FontContext +{ - FontTableContext(FontTable table) { - super(table); - } + FontTableContext(FontTable table) + { + super(table); + } - @Override - public void processGroupStart(RtfContextStack stack) { - stack.pushContext(new FontContext(fontTable)); - } + @Override + public void processGroupStart(RtfContextStack stack) + { + stack.pushContext(new FontContext(fontTable)); + } - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - stack.pushContext(new FontContext(fontTable)); - } + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + stack.pushContext(new FontContext(fontTable)); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java index b1de0cc..5275480 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; @@ -22,36 +23,42 @@ * end up in a known destination. Groups within a null destination will also * be completely ignored. */ -class NullContext implements RtfContext { - - public void processGroupStart(RtfContextStack stack) { - stack.pushContext(new NullContext()); - } - - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - processGroupStart(stack); - } - - public void processGroupEnd(RtfContextStack stack) { - stack.popContext(); - } - - public void processCharacterBytes(byte[] data) { - // Ignore - } - - public void processBinaryBytes(byte[] data) { - // Ignore - } - - public void processString(String string) { - // Ignore - } - - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // Ignore - } - +class NullContext implements RtfContext +{ + + public void processGroupStart(RtfContextStack stack) + { + stack.pushContext(new NullContext()); + } + + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + processGroupStart(stack); + } + + public void processGroupEnd(RtfContextStack stack) + { + stack.popContext(); + } + + public void processCharacterBytes(byte[] data) + { + // Ignore + } + + public void processBinaryBytes(byte[] data) + { + // Ignore + } + + public void processString(String string) + { + // Ignore + } + + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // Ignore + } + } \ No newline at end of file diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java index ce3b94d..35bd3c8 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/ParagraphStyleContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.ParagraphStyle; @@ -22,38 +23,42 @@ * RtfContext for parsing a style definition group located in the style sheet * section of an RTF document. */ -class ParagraphStyleContext extends AbstractRtfContext { - - private final ParagraphStyle style; - - ParagraphStyleContext(ParagraphStyle style) { - this.style = style; - } - - @Override - public void processGroupStart(RtfContextStack stack) { - // TODO: Implement - stack.pushContext(new NullContext()); - } - - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // TODO: Implement - stack.pushContext(new NullContext()); - } - - @Override - public void processString(String string) { - int semicolon = string.indexOf(';'); - int end = semicolon >= 0 ? semicolon : string.length(); - string = string.substring(0, end); - style.setName(string); - } - - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // TODO: Implement - } +class ParagraphStyleContext extends AbstractRtfContext +{ + + private final ParagraphStyle style; + + ParagraphStyleContext(ParagraphStyle style) + { + this.style = style; + } + + @Override + public void processGroupStart(RtfContextStack stack) + { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // TODO: Implement + stack.pushContext(new NullContext()); + } + + @Override + public void processString(String string) + { + int semicolon = string.indexOf(';'); + int end = semicolon >= 0 ? semicolon : string.length(); + string = string.substring(0, end); + style.setName(string); + } + + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // TODO: Implement + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java index f792435..68d4560 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RootContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Document; @@ -22,32 +23,36 @@ * Initial RtfContext. Pushes a DocumentContext upon encountering a group * starting with \rtf. */ -class RootContext extends AbstractRtfContext { - - private final Document document; - - RootContext(Document document) { - this.document = document; - } - - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case rtf: - stack.pushContext(new DocumentContext(document)); - break; - - default: - // Unknown destinations should be ignored. - stack.pushContext(new NullContext()); - break; - } - } - - @Override - public void processGroupStart(RtfContextStack stack) { - // Unknown groups should be ignored. - stack.pushContext(new NullContext()); - } +class RootContext extends AbstractRtfContext +{ + + private final Document document; + + RootContext(Document document) + { + this.document = document; + } + + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case rtf: + stack.pushContext(new DocumentContext(document)); + break; + + default: + // Unknown destinations should be ignored. + stack.pushContext(new NullContext()); + break; + } + } + + @Override + public void processGroupStart(RtfContextStack stack) + { + // Unknown groups should be ignored. + stack.pushContext(new NullContext()); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java index dc3cc7a..bdff5c3 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.rtf.Command; @@ -22,22 +23,21 @@ * knows how to handle the events based on the current "context" (location in * the file and group hierarchy). */ -interface RtfContext { +interface RtfContext +{ - public void processGroupStart(RtfContextStack stack); + public void processGroupStart(RtfContextStack stack); - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional); + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional); - public void processGroupEnd(RtfContextStack stack); + public void processGroupEnd(RtfContextStack stack); - public void processCharacterBytes(byte[] data); + public void processCharacterBytes(byte[] data); - public void processBinaryBytes(byte[] data); + public void processBinaryBytes(byte[] data); - public void processString(String string); + public void processString(String string); - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional); + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java index ac41110..84302ee 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/RtfContextStack.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import java.util.Stack; @@ -21,40 +22,47 @@ * RtfContextStack manages a stack of RtfContext instances and has the notion * of the current RtfContext (not part of the stack storage). */ -class RtfContextStack { - - private final Stack stack; - private RtfContext currentContext; - - RtfContextStack(RtfContext initialContext) { - if (initialContext == null) { - throw new IllegalArgumentException( - "Initial RTF context cannot be null."); - } - stack = new Stack(); - currentContext = initialContext; - } - - RtfContext getContext() { - return currentContext; - } - - void pushContext(RtfContext context) { - stack.push(currentContext); - currentContext = context; - } - - void popContext() { - if (stack.isEmpty()) { - handleError("RTF context stack is empty"); - return; - } - currentContext = stack.pop(); - } - - void handleError(String error) { - // TODO: Allow setting an error handler - throw new IllegalStateException(error); - //System.out.println(error); - } +class RtfContextStack +{ + + private final Stack stack; + private RtfContext currentContext; + + RtfContextStack(RtfContext initialContext) + { + if (initialContext == null) + { + throw new IllegalArgumentException("Initial RTF context cannot be null."); + } + stack = new Stack(); + currentContext = initialContext; + } + + RtfContext getContext() + { + return currentContext; + } + + void pushContext(RtfContext context) + { + stack.push(currentContext); + currentContext = context; + } + + void popContext() + { + if (stack.isEmpty()) + { + handleError("RTF context stack is empty"); + return; + } + currentContext = stack.pop(); + } + + void handleError(String error) + { + // TODO: Allow setting an error handler + throw new IllegalStateException(error); + //System.out.println(error); + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java index fe048fb..a31e06e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/StyleSheetContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.CharacterStyle; @@ -24,49 +25,50 @@ * Processes RTF events that may be encountered in the style sheet section of * the file. */ -class StyleSheetContext extends NullContext { +class StyleSheetContext extends NullContext +{ + + private final StyleSheet styleSheet; - private final StyleSheet styleSheet; - - StyleSheetContext(StyleSheet styleSheet) { - this.styleSheet = styleSheet; - } + StyleSheetContext(StyleSheet styleSheet) + { + this.styleSheet = styleSheet; + } - @Override - public void processGroupStart(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - // The Style Sheet should only contain style definition groups. These - // can start with one of these commands, - switch (command) { - case s: - { - // Paragraph style - ParagraphStyle style = styleSheet.getParagraphStyleTable() - .createStyle(); - styleSheet.getParagraphStyleTable().addStyle(parameter, style); - stack.pushContext(new ParagraphStyleContext(style)); - break; - } - case cs: - { - // Character style - CharacterStyle style = styleSheet.getCharacterStyleTable() - .createStyle(); - styleSheet.getCharacterStyleTable().addStyle(parameter, style); - stack.pushContext(new CharacterStyleContext(style)); - break; - } - case ds: - // TODO: Section style - stack.pushContext(new NullContext()); - break; - case ts: - // TODO: Table style - stack.pushContext(new NullContext()); - break; - default: - stack.pushContext(new NullContext()); - break; - } - } + @Override + public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + // The Style Sheet should only contain style definition groups. These + // can start with one of these commands, + switch (command) + { + case s: + { + // Paragraph style + ParagraphStyle style = styleSheet.getParagraphStyleTable().createStyle(); + styleSheet.getParagraphStyleTable().addStyle(parameter, style); + stack.pushContext(new ParagraphStyleContext(style)); + break; + } + case cs: + { + // Character style + CharacterStyle style = styleSheet.getCharacterStyleTable().createStyle(); + styleSheet.getCharacterStyleTable().addStyle(parameter, style); + stack.pushContext(new CharacterStyleContext(style)); + break; + } + case ds: + // TODO: Section style + stack.pushContext(new NullContext()); + break; + case ts: + // TODO: Table style + stack.pushContext(new NullContext()); + break; + default: + stack.pushContext(new NullContext()); + break; + } + } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java index 3dc03fb..31b5044 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/TimeContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.rtfparserkit.parser.builder; import java.util.Calendar; @@ -25,62 +26,70 @@ * a DateListener provided at construction time about the Date that has been * parsed. */ -class TimeContext extends AbstractRtfContext { - - public interface DateListener { - public void setDate(Date date); - } +class TimeContext extends AbstractRtfContext +{ + + public interface DateListener + { + public void setDate(Date date); + } + + private Calendar calendar = Calendar.getInstance(); + + private final DateListener dateListener; - private Calendar calendar = Calendar.getInstance(); + TimeContext(DateListener listener) + { + dateListener = listener; + } - private final DateListener dateListener; - - TimeContext(DateListener listener) { - dateListener = listener; - } - - @Override - public void processGroupEnd(RtfContextStack stack) { - dateListener.setDate(calendar.getTime()); - super.processGroupEnd(stack); - } + @Override + public void processGroupEnd(RtfContextStack stack) + { + dateListener.setDate(calendar.getTime()); + super.processGroupEnd(stack); + } - @Override - public void processString(String string) { - try { - long time = Long.parseLong(string); - calendar.setTimeInMillis(time * 1000); - } catch (Exception e) { - // Ignore - } - } + @Override + public void processString(String string) + { + try + { + long time = Long.parseLong(string); + calendar.setTimeInMillis(time * 1000); + } + catch (Exception e) + { + // Ignore + } + } - @Override - public void processCommand(RtfContextStack stack, Command command, - int parameter, boolean hasParameter, boolean optional) { - switch (command) { - case yr: - calendar.set(Calendar.YEAR, parameter); - break; - case mo: - calendar.set(Calendar.MONTH, parameter); - break; - case dy: - calendar.set(Calendar.DAY_OF_MONTH, parameter); - break; - case hr: - calendar.set(Calendar.HOUR, parameter); - break; - case min: - calendar.set(Calendar.MINUTE, parameter); - break; - case sec: - calendar.set(Calendar.SECOND, parameter); - break; + @Override + public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) + { + switch (command) + { + case yr: + calendar.set(Calendar.YEAR, parameter); + break; + case mo: + calendar.set(Calendar.MONTH, parameter); + break; + case dy: + calendar.set(Calendar.DAY_OF_MONTH, parameter); + break; + case hr: + calendar.set(Calendar.HOUR, parameter); + break; + case min: + calendar.set(Calendar.MINUTE, parameter); + break; + case sec: + calendar.set(Calendar.SECOND, parameter); + break; - default: - super.processCommand(stack, command, parameter, hasParameter, - optional); - } - } + default: + super.processCommand(stack, command, parameter, hasParameter, optional); + } + } } diff --git a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java index 5ebe7c5..e02f145 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphListTest.java @@ -1,6 +1,7 @@ /** * Copyright 2015 DramaQueen GmbH. All rights reserved. */ + package com.rtfparserkit.document; import static org.junit.Assert.assertEquals; @@ -13,47 +14,51 @@ * * @author stippi */ -public class ParagraphListTest { - - @Test - public void testEmptyParagraphList() { - ParagraphList list = new ParagraphList(); - assertEquals(1, list.countParagraphs()); - assertEquals("", list.getText()); - } - - @Test - public void testAppend() { - ParagraphList list = new ParagraphList(); - list.append("test1"); - list.append("test2"); - list.append("test3"); - assertEquals(1, list.countParagraphs()); - assertEquals("test1test2test3", list.getText()); - } - - @Test - public void testDelimiter() { - ParagraphList list = new ParagraphList(); - list.append("\n"); - assertEquals(2, list.countParagraphs()); - assertEquals("\n", list.getText()); - assertEquals("\n", list.paragraphAt(0).getText()); - assertEquals("", list.paragraphAt(1).getText()); - - list.append("\n\n"); - assertEquals(4, list.countParagraphs()); - assertEquals("\n\n\n", list.getText()); - assertEquals("\n", list.paragraphAt(2).getText()); - assertEquals("", list.paragraphAt(3).getText()); - - list = new ParagraphList(); - list.append("test1"); - list.append("test2\ntest3\n"); - assertEquals(3, list.countParagraphs()); - assertEquals("test1test2\ntest3\n", list.getText()); - assertEquals("test1test2\n", list.paragraphAt(0).getText()); - assertEquals("test3\n", list.paragraphAt(1).getText()); - assertEquals("", list.paragraphAt(2).getText()); - } +public class ParagraphListTest +{ + + @Test + public void testEmptyParagraphList() + { + ParagraphList list = new ParagraphList(); + assertEquals(1, list.countParagraphs()); + assertEquals("", list.getText()); + } + + @Test + public void testAppend() + { + ParagraphList list = new ParagraphList(); + list.append("test1"); + list.append("test2"); + list.append("test3"); + assertEquals(1, list.countParagraphs()); + assertEquals("test1test2test3", list.getText()); + } + + @Test + public void testDelimiter() + { + ParagraphList list = new ParagraphList(); + list.append("\n"); + assertEquals(2, list.countParagraphs()); + assertEquals("\n", list.getText()); + assertEquals("\n", list.paragraphAt(0).getText()); + assertEquals("", list.paragraphAt(1).getText()); + + list.append("\n\n"); + assertEquals(4, list.countParagraphs()); + assertEquals("\n\n\n", list.getText()); + assertEquals("\n", list.paragraphAt(2).getText()); + assertEquals("", list.paragraphAt(3).getText()); + + list = new ParagraphList(); + list.append("test1"); + list.append("test2\ntest3\n"); + assertEquals(3, list.countParagraphs()); + assertEquals("test1test2\ntest3\n", list.getText()); + assertEquals("test1test2\n", list.paragraphAt(0).getText()); + assertEquals("test3\n", list.paragraphAt(1).getText()); + assertEquals("", list.paragraphAt(2).getText()); + } } diff --git a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java index 97c1e62..58e0cc1 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/document/ParagraphTest.java @@ -1,6 +1,7 @@ /** * Copyright 2015 DramaQueen GmbH. All rights reserved. */ + package com.rtfparserkit.document; import static org.junit.Assert.assertEquals; @@ -14,100 +15,109 @@ * * @author stippi */ -public class ParagraphTest { - - @Test - public void testEmptyParagraph() { - DefaultParagraph p = new DefaultParagraph(); - assertEquals("", p.getText()); - } - - @Test - public void testAppend() { - DefaultParagraph p = new DefaultParagraph(); - p.append("test1"); - p.append("test2"); - p.append("test3"); - assertEquals("test1test2test3", p.getText()); - } - - @Test - public void testDelimiter() { - DefaultParagraph p = new DefaultParagraph(); - p.end(); - assertEquals("\n", p.getText()); - - p = new DefaultParagraph(); - p.append("test"); - assertEquals("test", p.getText()); - - p.end(); - assertEquals("test\n", p.getText()); - } - - @Test - public void testOnlyOneDelimiter() { - DefaultParagraph p = new DefaultParagraph(); - p.end(); - expectException(p, "\n", true); - assertEquals("\n", p.getText()); - - p = new DefaultParagraph(); - p.append("test"); - expectException(p, "\n", false); - // Paragraph already delimited - expectException(p, "\n", true); - // Paragraph must not have changed - assertEquals("test\n", p.getText()); - - p = new DefaultParagraph(); - p.append("test"); - // Appended text may end with a delimiter - expectException(p, "test\n", false); - assertEquals("testtest\n", p.getText()); - // Paragraph already delimited, various cases of the text containing - // a delimiter should all raise an exception - expectException(p, "test\n", true); - expectException(p, "\n", true); - expectException(p, "\ntest", true); - expectException(p, "test\ntest", true); - // Paragraph must not have changed - assertEquals("testtest\n", p.getText()); - - p = new DefaultParagraph(); - p.append("test"); - // Appended text may only /end/ with a delimiter - expectException(p, "test\ntest", true); - expectException(p, "\ntest", true); - // Paragraph must not have changed - assertEquals("test", p.getText()); - } - - @Test - public void testAnnotation() { - DefaultParagraph p = new DefaultParagraph(); - p.append("test"); - p.append(new DefaultAnnotation()); - p.append("test"); - - assertEquals(3, p.countElements()); - - p = new DefaultParagraph(); - p.append("test"); - p.append(new DefaultAnnotation()); - p.end(); - - assertEquals(3, p.countElements()); - } - - private void expectException(DefaultParagraph defaultParagraph, String toAppend, - boolean exceptionExpected) { - boolean exceptionRaised = false; - try { - defaultParagraph.append(toAppend); - } catch (Exception e) { - exceptionRaised = true; - } - assertEquals(exceptionExpected, exceptionRaised); - } +public class ParagraphTest +{ + + @Test + public void testEmptyParagraph() + { + DefaultParagraph p = new DefaultParagraph(); + assertEquals("", p.getText()); + } + + @Test + public void testAppend() + { + DefaultParagraph p = new DefaultParagraph(); + p.append("test1"); + p.append("test2"); + p.append("test3"); + assertEquals("test1test2test3", p.getText()); + } + + @Test + public void testDelimiter() + { + DefaultParagraph p = new DefaultParagraph(); + p.end(); + assertEquals("\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + assertEquals("test", p.getText()); + + p.end(); + assertEquals("test\n", p.getText()); + } + + @Test + public void testOnlyOneDelimiter() + { + DefaultParagraph p = new DefaultParagraph(); + p.end(); + expectException(p, "\n", true); + assertEquals("\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + expectException(p, "\n", false); + // Paragraph already delimited + expectException(p, "\n", true); + // Paragraph must not have changed + assertEquals("test\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + // Appended text may end with a delimiter + expectException(p, "test\n", false); + assertEquals("testtest\n", p.getText()); + // Paragraph already delimited, various cases of the text containing + // a delimiter should all raise an exception + expectException(p, "test\n", true); + expectException(p, "\n", true); + expectException(p, "\ntest", true); + expectException(p, "test\ntest", true); + // Paragraph must not have changed + assertEquals("testtest\n", p.getText()); + + p = new DefaultParagraph(); + p.append("test"); + // Appended text may only /end/ with a delimiter + expectException(p, "test\ntest", true); + expectException(p, "\ntest", true); + // Paragraph must not have changed + assertEquals("test", p.getText()); + } + + @Test + public void testAnnotation() + { + DefaultParagraph p = new DefaultParagraph(); + p.append("test"); + p.append(new DefaultAnnotation()); + p.append("test"); + + assertEquals(3, p.countElements()); + + p = new DefaultParagraph(); + p.append("test"); + p.append(new DefaultAnnotation()); + p.end(); + + assertEquals(3, p.countElements()); + } + + private void expectException(DefaultParagraph defaultParagraph, String toAppend, boolean exceptionExpected) + { + boolean exceptionRaised = false; + try + { + defaultParagraph.append(toAppend); + } + catch (Exception e) + { + exceptionRaised = true; + } + assertEquals(exceptionExpected, exceptionRaised); + } } diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java index 274658b..a7fa848 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -1,3 +1,4 @@ + package com.rtfparserkit.parser.builder; import static org.junit.Assert.assertEquals; @@ -19,185 +20,189 @@ import com.rtfparserkit.parser.RtfStreamSource; import com.rtfparserkit.parser.standard.StandardRtfParser; -public class BuilderParseTest { - - @Test - public void testParagraphContentsIText() { - DefaultDocument document = new DefaultDocument(); - parseStream("lineSeparator", document, false); - - Section section = document.getLastSection(); - - int paragraphCount = section.countParagraphs(); - assertEquals(5, paragraphCount); - - assertEquals("INNEN. KÜCHE - TAG\n", - section.paragraphAt(0).getText()); - assertEquals("Ein Absatz mit Line-Separator:\u2028" - + "Der geht hier auf einer neuen Zeile weiter.\n", - section.paragraphAt(1).getText()); - assertEquals("INNEN. KÜCHE - TAG\n", - section.paragraphAt(2).getText()); - assertEquals("Hier ist die zweite Szene.\n", - section.paragraphAt(3).getText()); - assertEquals("", - section.paragraphAt(4).getText()); - - assertEquals(12242, document.getPageSize().width); - assertEquals(15842, document.getPageSize().height); - - assertEquals(1425, document.getPageMargins().left); - assertEquals(360, document.getPageMargins().right); - assertEquals(950, document.getPageMargins().top); - assertEquals(1425, document.getPageMargins().bottom); - - assertEquals(2, document.getColorTable().countColors()); - } - - @Test - public void testParagraphContentsLibreOffice() { - DefaultDocument document = new DefaultDocument(); - parseStream("annotationLibreOffice", document, true); - - Section section = document.getLastSection(); - - int paragraphCount = section.countParagraphs(); - assertEquals(2, paragraphCount); - - assertEquals("This word is commented.\n", - section.paragraphAt(0).getText()); - } - - @Test - public void testStyles() { - - String[] files = { - "variousStyles", - "variousStylesPages", - "variousStylesGrouped", - }; - - for (String file : files) { - System.out.println("################################"); - - DefaultDocument document = new DefaultDocument(); - parseStream(file, document, false); - - assertEquals(1, document.countSections()); - Section section = document.sectionAt(0); - assertStyles(section); - } - } - - @Test - public void testAnnotations() { - DefaultDocument document = new DefaultDocument(); - parseStream("annotationSpec", document, false); - - Section section = document.sectionAt(0); - - assertEquals(1, section.countParagraphs()); - - Paragraph paragraph = section.paragraphAt(0); - - assertEquals(3, paragraph.countElements()); - - Element element = paragraph.elementAt(0); - assertTrue(element instanceof Chunk); - Chunk chunk = (Chunk) element; - assertEquals("An example of a paradigm might be Darwinian biology.", - chunk.getText()); - - element = paragraph.elementAt(1); - assertTrue(element instanceof Annotation); - Annotation annotation = (Annotation) element; - assertEquals("How about some examples that deal with social science? " - + "That is what this paper is about.", annotation.getText()); - assertEquals("JD", annotation.getId()); - assertEquals("John Doe", annotation.getAuthor()); - - element = paragraph.elementAt(2); - assertTrue(element instanceof Chunk); - chunk = (Chunk) element; - assertEquals(" ", chunk.getText()); - } - - private void assertStyles(Section section) { - int paragraphCount = section.countParagraphs(); - assertEquals(8, paragraphCount); - - for (int i = 0; i < paragraphCount; i++) { - Paragraph paragraph = section.paragraphAt(i); - - if (i == 0) - assertNormalBoldItalic(paragraph); -// else { - String text = paragraph.getText(); - System.out.print("[" + i + "]: " + text); - if (!text.endsWith("\n")) - System.out.println(); - for (Element element : paragraph) { - if (element instanceof Chunk) { - Chunk chunk = (Chunk) element; - System.out.println(" '" - + chunk.getText().replaceAll("\n", - "") + "' " + chunk.getStyle()); - } - } - } -// } - } - - private void assertNormalBoldItalic(Paragraph paragraph) { - int chunks = paragraph.countElements(); - assertEquals(5, chunks); - - Chunk chunk = (Chunk) paragraph.elementAt(0); - assertEquals("Normal ", chunk.getText()); - assertFalse(chunk.getStyle().getBold()); - assertFalse(chunk.getStyle().getItalic()); - - chunk = (Chunk) paragraph.elementAt(1); - assertEquals("Bold ", chunk.getText()); - assertTrue(chunk.getStyle().getBold()); - assertFalse(chunk.getStyle().getItalic()); - - chunk = (Chunk) paragraph.elementAt(2); - assertEquals("Bold/Italic", chunk.getText()); - assertTrue(chunk.getStyle().getBold()); - assertTrue(chunk.getStyle().getItalic()); - - chunk = (Chunk) paragraph.elementAt(3); - assertEquals(" Italic", chunk.getText()); - assertFalse(chunk.getStyle().getBold()); - assertTrue(chunk.getStyle().getItalic()); - - chunk = (Chunk) paragraph.elementAt(4); - assertEquals(" Normal.\n", chunk.getText()); - assertFalse(chunk.getStyle().getBold()); - assertFalse(chunk.getStyle().getItalic()); - } - - private void parseStream(String fileName, Document document, - boolean debug) { - InputStream is = null; - try { - is = BuilderParseTest.class.getResourceAsStream("data/" - + fileName + ".rtf"); - StandardRtfParser parser = new StandardRtfParser(); - DocumentBuilder builder = new DocumentBuilder(document); - builder.setDebugEvents(debug); - parser.parse(new RtfStreamSource(is), builder); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - // Ignore - } - } - } - } +public class BuilderParseTest +{ + + @Test + public void testParagraphContentsIText() + { + DefaultDocument document = new DefaultDocument(); + parseStream("lineSeparator", document, false); + + Section section = document.getLastSection(); + + int paragraphCount = section.countParagraphs(); + assertEquals(5, paragraphCount); + + assertEquals("INNEN. KÜCHE - TAG\n", section.paragraphAt(0).getText()); + assertEquals("Ein Absatz mit Line-Separator:\u2028" + "Der geht hier auf einer neuen Zeile weiter.\n", section.paragraphAt(1).getText()); + assertEquals("INNEN. KÜCHE - TAG\n", section.paragraphAt(2).getText()); + assertEquals("Hier ist die zweite Szene.\n", section.paragraphAt(3).getText()); + assertEquals("", section.paragraphAt(4).getText()); + + assertEquals(12242, document.getPageSize().width); + assertEquals(15842, document.getPageSize().height); + + assertEquals(1425, document.getPageMargins().left); + assertEquals(360, document.getPageMargins().right); + assertEquals(950, document.getPageMargins().top); + assertEquals(1425, document.getPageMargins().bottom); + + assertEquals(2, document.getColorTable().countColors()); + } + + @Test + public void testParagraphContentsLibreOffice() + { + DefaultDocument document = new DefaultDocument(); + parseStream("annotationLibreOffice", document, true); + + Section section = document.getLastSection(); + + int paragraphCount = section.countParagraphs(); + assertEquals(2, paragraphCount); + + assertEquals("This word is commented.\n", section.paragraphAt(0).getText()); + } + + @Test + public void testStyles() + { + + String[] files = {"variousStyles", "variousStylesPages", "variousStylesGrouped",}; + + for (String file : files) + { + System.out.println("################################"); + + DefaultDocument document = new DefaultDocument(); + parseStream(file, document, false); + + assertEquals(1, document.countSections()); + Section section = document.sectionAt(0); + assertStyles(section); + } + } + + @Test + public void testAnnotations() + { + DefaultDocument document = new DefaultDocument(); + parseStream("annotationSpec", document, false); + + Section section = document.sectionAt(0); + + assertEquals(1, section.countParagraphs()); + + Paragraph paragraph = section.paragraphAt(0); + + assertEquals(3, paragraph.countElements()); + + Element element = paragraph.elementAt(0); + assertTrue(element instanceof Chunk); + Chunk chunk = (Chunk) element; + assertEquals("An example of a paradigm might be Darwinian biology.", chunk.getText()); + + element = paragraph.elementAt(1); + assertTrue(element instanceof Annotation); + Annotation annotation = (Annotation) element; + assertEquals("How about some examples that deal with social science? " + "That is what this paper is about.", annotation.getText()); + assertEquals("JD", annotation.getId()); + assertEquals("John Doe", annotation.getAuthor()); + + element = paragraph.elementAt(2); + assertTrue(element instanceof Chunk); + chunk = (Chunk) element; + assertEquals(" ", chunk.getText()); + } + + private void assertStyles(Section section) + { + int paragraphCount = section.countParagraphs(); + assertEquals(8, paragraphCount); + + for (int i = 0; i < paragraphCount; i++) + { + Paragraph paragraph = section.paragraphAt(i); + + if (i == 0) + assertNormalBoldItalic(paragraph); + // else { + String text = paragraph.getText(); + System.out.print("[" + i + "]: " + text); + if (!text.endsWith("\n")) + System.out.println(); + for (Element element : paragraph) + { + if (element instanceof Chunk) + { + Chunk chunk = (Chunk) element; + System.out.println(" '" + chunk.getText().replaceAll("\n", "") + "' " + chunk.getStyle()); + } + } + } + // } + } + + private void assertNormalBoldItalic(Paragraph paragraph) + { + int chunks = paragraph.countElements(); + assertEquals(5, chunks); + + Chunk chunk = (Chunk) paragraph.elementAt(0); + assertEquals("Normal ", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(1); + assertEquals("Bold ", chunk.getText()); + assertTrue(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(2); + assertEquals("Bold/Italic", chunk.getText()); + assertTrue(chunk.getStyle().getBold()); + assertTrue(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(3); + assertEquals(" Italic", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertTrue(chunk.getStyle().getItalic()); + + chunk = (Chunk) paragraph.elementAt(4); + assertEquals(" Normal.\n", chunk.getText()); + assertFalse(chunk.getStyle().getBold()); + assertFalse(chunk.getStyle().getItalic()); + } + + private void parseStream(String fileName, Document document, boolean debug) + { + InputStream is = null; + try + { + is = BuilderParseTest.class.getResourceAsStream("data/" + fileName + ".rtf"); + StandardRtfParser parser = new StandardRtfParser(); + DocumentBuilder builder = new DocumentBuilder(document); + builder.setDebugEvents(debug); + parser.parse(new RtfStreamSource(is), builder); + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + if (is != null) + { + try + { + is.close(); + } + catch (Exception e) + { + // Ignore + } + } + } + } } From 368a39c2b2ad1367d7f498df2209583341b74757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 21:47:25 +0200 Subject: [PATCH 07/16] Give the project files a default encoding (UTF-8) My name contains a German umlaut, and I guess it is helpful in general to have a defined encoding. --- RTF Parser Kit/.settings/org.eclipse.core.resources.prefs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 RTF Parser Kit/.settings/org.eclipse.core.resources.prefs diff --git a/RTF Parser Kit/.settings/org.eclipse.core.resources.prefs b/RTF Parser Kit/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/RTF Parser Kit/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 From 6bb3b9b40ac447ee4aaef0f0d6ac881b8e7ad820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 21:52:49 +0200 Subject: [PATCH 08/16] Added @Override annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to conform with the rest of the project setup and eliminate the warnings. --- .../rtfparserkit/document/ParagraphStyle.java | 2 ++ .../document/impl/DefaultAnnotation.java | 6 ++++++ .../document/impl/DefaultCharacterStyle.java | 21 +++++++++++++++++++ .../impl/DefaultCharacterStyleTable.java | 1 + .../document/impl/DefaultChunk.java | 3 +++ .../document/impl/DefaultColor.java | 3 +++ .../document/impl/DefaultColorTable.java | 3 +++ .../document/impl/DefaultDocument.java | 20 +++++++++++++++++- .../document/impl/DefaultFont.java | 3 +++ .../document/impl/DefaultFontTable.java | 3 +++ .../document/impl/DefaultParagraph.java | 5 +++++ .../document/impl/DefaultParagraphStyle.java | 16 ++++++++++++++ .../impl/DefaultParagraphStyleTable.java | 1 + .../document/impl/DefaultSection.java | 11 ++++++++++ .../document/impl/DefaultStyle.java | 4 ++++ .../document/impl/DefaultStyleSheet.java | 2 ++ .../document/impl/ParagraphList.java | 12 +++++++++++ .../document/impl/SectionList.java | 1 + .../document/impl/StyleTable.java | 1 + .../parser/builder/AbstractRtfContext.java | 7 +++++++ .../parser/builder/AnnotationContext.java | 1 + .../parser/builder/DocumentBuilder.java | 8 +++++++ .../parser/builder/NullContext.java | 7 +++++++ 23 files changed, 140 insertions(+), 1 deletion(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java index 8057b8d..76f7392 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java @@ -32,10 +32,12 @@ public enum TabAlignment LEFT, CENTER, RIGHT, DECIMAL, } + @Override public ParagraphStyle createDerivedStyle(); public CharacterStyle createDerivedCharacterStyle(); + @Override public ParagraphStyle createFlattenedStyle(); public void setAlignment(Alignment alignment); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java index 2f95e0a..7745acd 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java @@ -35,31 +35,37 @@ public DefaultAnnotation() { } + @Override public void setId(String id) { this.id = id; } + @Override public String getId() { return id; } + @Override public void setAuthor(String author) { this.author = author; } + @Override public String getAuthor() { return author; } + @Override public void setDate(Date date) { this.date = date.getTime(); } + @Override public Date getDate() { return new Date(date); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java index 7c85a8b..d9ea5e1 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java @@ -55,6 +55,7 @@ public DefaultCharacterStyle(CharacterStyle other) parent = other; } + @Override public void resetToDefaults() { // TODO: Mechanics should probably be changed. Instead of having a @@ -76,11 +77,13 @@ public void resetToDefaults() overriddenProperties.addAll(CHARACTER_STYLE_PROPERTIES); } + @Override public CharacterStyle createDerivedStyle() { return new DefaultCharacterStyle(this); } + @Override public CharacterStyle createFlattenedStyle() { DefaultCharacterStyle style = new DefaultCharacterStyle(); @@ -117,12 +120,14 @@ public boolean equals(Style object) return parent == other.parent && (font != null ? font.equals(other.font) : other.font == null) && fontSize == other.fontSize && bold == other.bold && italic == other.italic && underlineStyle == other.underlineStyle && strikeOut == other.strikeOut && caps == other.caps && backgroundColor == other.backgroundColor && foregroundColor == other.foregroundColor; } + @Override public void setFont(Font font) { this.font = font; overriddenProperties.add(Property.FONT); } + @Override public Font getFont() { if (overriddenProperties.contains(Property.BOLD)) @@ -131,12 +136,14 @@ public Font getFont() return parent.getFont(); } + @Override public void setFontSize(float value) { this.fontSize = value; overriddenProperties.add(Property.FONT_SIZE); } + @Override public float getFontSize() { if (overriddenProperties.contains(Property.FONT_SIZE)) @@ -145,12 +152,14 @@ public float getFontSize() return parent.getFontSize(); } + @Override public void setBold(boolean bold) { this.bold = bold; overriddenProperties.add(Property.BOLD); } + @Override public boolean getBold() { if (overriddenProperties.contains(Property.BOLD)) @@ -159,12 +168,14 @@ public boolean getBold() return parent.getBold(); } + @Override public void setItalic(boolean italic) { this.italic = italic; overriddenProperties.add(Property.ITALIC); } + @Override public boolean getItalic() { if (overriddenProperties.contains(Property.ITALIC)) @@ -173,12 +184,14 @@ public boolean getItalic() return parent.getItalic(); } + @Override public void setUnderlined(UnderlineStyle style) { this.underlineStyle = style; overriddenProperties.add(Property.UNDERLINED); } + @Override public UnderlineStyle getUnderlined() { if (overriddenProperties.contains(Property.UNDERLINED)) @@ -187,12 +200,14 @@ public UnderlineStyle getUnderlined() return parent.getUnderlined(); } + @Override public void setStrikeOut(boolean strikeOut) { this.strikeOut = strikeOut; overriddenProperties.add(Property.STRIKE_OUT); } + @Override public boolean getStrikeOut() { if (overriddenProperties.contains(Property.STRIKE_OUT)) @@ -201,12 +216,14 @@ public boolean getStrikeOut() return parent.getStrikeOut(); } + @Override public void setCaps(boolean caps) { this.caps = caps; overriddenProperties.add(Property.CAPS); } + @Override public boolean getCaps() { if (overriddenProperties.contains(Property.CAPS)) @@ -215,6 +232,7 @@ public boolean getCaps() return parent.getCaps(); } + @Override public void setBackgroundColor(Color color) { if (color instanceof DefaultColor) @@ -224,6 +242,7 @@ public void setBackgroundColor(Color color) } } + @Override public Color getBackgroundColor() { if (overriddenProperties.contains(Property.BACKGROUND_COLOR)) @@ -232,6 +251,7 @@ public Color getBackgroundColor() return parent.getBackgroundColor(); } + @Override public void setForegroundColor(Color color) { if (color instanceof DefaultColor) @@ -241,6 +261,7 @@ public void setForegroundColor(Color color) } } + @Override public Color getForegroundColor() { if (overriddenProperties.contains(Property.FOREGROUND_COLOR)) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java index 4c1c44c..062c1c9 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java @@ -25,6 +25,7 @@ public class DefaultCharacterStyleTable extends StyleTableimplements CharacterStyleTable { + @Override public CharacterStyle createStyle() { return new DefaultCharacterStyle(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java index bf70109..58fce8e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -33,16 +33,19 @@ public DefaultChunk(ParagraphStyle style) this.style = style; } + @Override public String getText() { return stringBuilder.toString(); } + @Override public ParagraphStyle getStyle() { return style; } + @Override public void append(String string) { stringBuilder.append(string); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java index 208e809..bba44ef 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColor.java @@ -45,16 +45,19 @@ public DefaultColor(Color other) this.blue = other.getBlue(); } + @Override public int getRed() { return red; } + @Override public int getGreen() { return green; } + @Override public int getBlue() { return blue; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java index b001a6e..62139b0 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultColorTable.java @@ -35,16 +35,19 @@ public DefaultColorTable() colors = new ArrayList(); } + @Override public void addColor(int red, int green, int blue) { colors.add(new DefaultColor(red, green, blue)); } + @Override public int countColors() { return colors.size(); } + @Override public Color colorAt(int index) { return colors.get(index); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java index ca75c72..132b1c2 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -21,8 +21,8 @@ import com.rtfparserkit.document.DocumentSettings; import com.rtfparserkit.document.PageSettings; import com.rtfparserkit.document.Paragraph; -import com.rtfparserkit.document.Section; import com.rtfparserkit.document.ParagraphStyle; +import com.rtfparserkit.document.Section; /** * Default implementation of Document. Note that Document itself is also @@ -39,16 +39,19 @@ public class DefaultDocument extends SectionList implements Document private final PageMargins pageMargins = new PageMargins(); private final PageSize pageSize = new PageSize(); + @Override public DefaultFontTable getFontTable() { return fonts; } + @Override public DefaultColorTable getColorTable() { return colors; } + @Override public DefaultStyleSheet getStyleSheet() { return styles; @@ -64,40 +67,48 @@ public PageSize getPageSize() return pageSize; } + @Override public DocumentSettings getDocumentSettings() { return new DocumentSettings() { + @Override public PageSettings getPageSettings() { return new PageSettings() { + @Override public void setPageMarginLeft(int value) { pageMargins.left = value; } + @Override public void setPageMarginRight(int value) { pageMargins.right = value; } + @Override public void setPageMarginTop(int value) { pageMargins.top = value; } + @Override public void setPageMarginBottom(int value) { pageMargins.bottom = value; } + @Override public void setPageWidth(int value) { pageSize.width = value; } + @Override public void setPageHeight(int value) { pageSize.height = value; @@ -113,6 +124,7 @@ public void setPageHeight(int value) * @param text The string to append * @param style The Style in which the appended string is to appear. */ + @Override public void append(String text, ParagraphStyle style) { getLastSection().append(text, style); @@ -124,6 +136,7 @@ public void append(String text, ParagraphStyle style) * * @param lastStyle The Style to be set on the previous paragraph. */ + @Override public void nextParagraph(ParagraphStyle lastStyle) { getLastSection().nextParagraph(lastStyle); @@ -132,6 +145,7 @@ public void nextParagraph(ParagraphStyle lastStyle) /** * Creates a new line at the last Section. */ + @Override public void nextLine() { getLastSection().nextLine(); @@ -140,6 +154,7 @@ public void nextLine() /** * @return The default Style created by the last Section. */ + @Override public ParagraphStyle createDefaultStyle() { return getLastSection().createDefaultStyle(); @@ -148,6 +163,7 @@ public ParagraphStyle createDefaultStyle() /** * @return The total count of all paragraphs contained in all Sections. */ + @Override public int countParagraphs() { int count = 0; @@ -160,6 +176,7 @@ public int countParagraphs() * @param index The index of the paragraph relative to the total paragraph * count of all Sections. */ + @Override public Paragraph paragraphAt(int index) { int originalIndex = index; @@ -182,6 +199,7 @@ public Paragraph paragraphAt(int index) * * @return The appended annotation */ + @Override public Annotation appendAnnotation() { return getLastSection().appendAnnotation(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java index e278824..b7b6e34 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFont.java @@ -30,16 +30,19 @@ public DefaultFont(String fontName) name = fontName; } + @Override public void setName(String name) { this.name = name; } + @Override public String getName() { return name; } + @Override public boolean equals(Font object) { if (object == this) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java index c488ce7..c1b671f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -17,16 +17,19 @@ public DefaultFontTable() fonts = new ArrayList(); } + @Override public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily) { fonts.add(new DefaultFont(name)); } + @Override public int countFonts() { return fonts.size(); } + @Override public Font fontAt(int index) { return fonts.get(index); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java index ab186d9..40266c6 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -44,11 +44,13 @@ public DefaultParagraph(ParagraphStyle style) this.style = style; } + @Override public Iterator iterator() { return chunks.iterator(); } + @Override public String getText() { StringBuilder builder = new StringBuilder(); @@ -60,16 +62,19 @@ public String getText() return builder.toString(); } + @Override public int countElements() { return chunks.size(); } + @Override public Element elementAt(int index) { return chunks.get(index); } + @Override public ParagraphStyle getStyle() { return style; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java index 8ae2012..2773152 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java @@ -73,6 +73,7 @@ public ParagraphStyle createDerivedStyle() return new DefaultParagraphStyle(this); } + @Override public CharacterStyle createDerivedCharacterStyle() { return new DefaultCharacterStyle(this); @@ -115,12 +116,14 @@ public boolean equals(Style object) return parent == other.parent && alignment == other.alignment && spacingTop == other.spacingTop && spacingBottom == other.spacingBottom && firstLineIndent == other.firstLineIndent && leftIndent == other.leftIndent && rightIndent == other.rightIndent && lineSpacing == other.lineSpacing; } + @Override public void setAlignment(Alignment alignment) { this.alignment = alignment; overriddenProperties.add(Property.ALIGNMENT); } + @Override public Alignment getAlignment() { if (overriddenProperties.contains(Property.ALIGNMENT)) @@ -129,12 +132,14 @@ public Alignment getAlignment() return parent.getAlignment(); } + @Override public void setSpacingTop(float value) { spacingTop = value; overriddenProperties.add(Property.SPACING_TOP); } + @Override public float getSpacingTop() { if (overriddenProperties.contains(Property.SPACING_TOP)) @@ -143,12 +148,14 @@ public float getSpacingTop() return parent.getSpacingTop(); } + @Override public void setSpacingBottom(float value) { spacingBottom = value; overriddenProperties.add(Property.SPACING_BOTTOM); } + @Override public float getSpacingBottom() { if (overriddenProperties.contains(Property.SPACING_BOTTOM)) @@ -157,12 +164,14 @@ public float getSpacingBottom() return parent.getSpacingBottom(); } + @Override public void setFirstLineIndent(float value) { firstLineIndent = value; overriddenProperties.add(Property.FIRST_LINE_INDENT); } + @Override public float getFirstLineIndent() { if (overriddenProperties.contains(Property.FIRST_LINE_INDENT)) @@ -171,12 +180,14 @@ public float getFirstLineIndent() return parent.getFirstLineIndent(); } + @Override public void setLeftIndent(float value) { leftIndent = value; overriddenProperties.add(Property.LEFT_INDENT); } + @Override public float getLeftIndent() { if (overriddenProperties.contains(Property.LEFT_INDENT)) @@ -185,12 +196,14 @@ public float getLeftIndent() return parent.getLeftIndent(); } + @Override public void setRightIndent(float value) { rightIndent = value; overriddenProperties.add(Property.RIGHT_INDENT); } + @Override public float getRightIndent() { if (overriddenProperties.contains(Property.RIGHT_INDENT)) @@ -199,12 +212,14 @@ public float getRightIndent() return parent.getRightIndent(); } + @Override public void setLineSpacing(float value) { lineSpacing = value; overriddenProperties.add(Property.LINE_SPACING); } + @Override public float getLineSpacing() { if (overriddenProperties.contains(Property.LINE_SPACING)) @@ -213,6 +228,7 @@ public float getLineSpacing() return parent.getLineSpacing(); } + @Override public void addTab(float position, TabAlignment aligment) { // TODO Auto-generated method stub diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java index adc7c55..4fc22da 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyleTable.java @@ -25,6 +25,7 @@ public class DefaultParagraphStyleTable extends StyleTableimplements ParagraphStyleTable { + @Override public ParagraphStyle createStyle() { return new DefaultParagraphStyle(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java index 261aac2..4b8c20f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultSection.java @@ -32,6 +32,7 @@ public class DefaultSection extends ParagraphList implements Section private final PageMargins pageMargins = new PageMargins(); private final PageSize pageSize = new PageSize(); + @Override public Header createHeader() { if (header == null) @@ -39,11 +40,13 @@ public Header createHeader() return header; } + @Override public Header getHeader() { return header; } + @Override public Footer createFooter() { if (footer == null) @@ -51,6 +54,7 @@ public Footer createFooter() return footer; } + @Override public Footer getFooter() { return footer; @@ -66,36 +70,43 @@ public PageSize getPageSize() return pageSize; } + @Override public PageSettings getPageSettings() { return new PageSettings() { + @Override public void setPageMarginLeft(int value) { pageMargins.left = value; } + @Override public void setPageMarginRight(int value) { pageMargins.right = value; } + @Override public void setPageMarginTop(int value) { pageMargins.top = value; } + @Override public void setPageMarginBottom(int value) { pageMargins.bottom = value; } + @Override public void setPageWidth(int value) { pageSize.width = value; } + @Override public void setPageHeight(int value) { pageSize.height = value; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java index 27d74a5..c5ca84f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyle.java @@ -34,21 +34,25 @@ protected DefaultStyle() overriddenProperties = EnumSet.noneOf(Property.class); } + @Override public void setName(String name) { this.name = name; } + @Override public String getName() { return name; } + @Override public EnumSet getOverriddenProperties() { return overriddenProperties; } + @Override public boolean equals(Style object) { if (object == this) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java index 7f58cb4..8a4201c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultStyleSheet.java @@ -32,11 +32,13 @@ class DefaultStyleSheet implements StyleSheet characterStyleTable = new DefaultCharacterStyleTable(); } + @Override public ParagraphStyleTable getParagraphStyleTable() { return paragraphStyleTable; } + @Override public CharacterStyleTable getCharacterStyleTable() { return characterStyleTable; diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java index 16d3081..e6e9893 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -46,6 +46,7 @@ public ParagraphList() /** * Returns and iterator over the Paragraphs contained in this list. */ + @Override public Iterator iterator() { return new ParagraphIterator(paragraphs.iterator()); @@ -55,6 +56,7 @@ public Iterator iterator() * Finalizes the current paragraph by appending a line-break character '\n'. * Starts the next paragraph by appending a new empty Paragraph to the list. */ + @Override public void nextParagraph(ParagraphStyle lastStyle) { if (countParagraphs() > 0) @@ -66,6 +68,7 @@ public void nextParagraph(ParagraphStyle lastStyle) * Implements nextLine() by appending the Unicode character "Line Separator" * to the current paragraph. */ + @Override public void nextLine() { getLastParagraph().append("\u2028"); @@ -74,6 +77,7 @@ public void nextLine() /** * @return The concatenated text of all contained Paragraphs. */ + @Override public String getText() { StringBuilder builder = new StringBuilder(); @@ -82,6 +86,7 @@ public String getText() return builder.toString(); } + @Override public ParagraphStyle createDefaultStyle() { return new DefaultParagraphStyle(); @@ -99,6 +104,7 @@ public ParagraphStyle createDefaultStyle() * * @see #nextParagraph() */ + @Override public void append(String text, ParagraphStyle style) { int offset = 0; @@ -126,6 +132,7 @@ public void append(String string) append(string, style); } + @Override public Annotation appendAnnotation() { Annotation annotation = new DefaultAnnotation(); @@ -156,6 +163,7 @@ public DefaultParagraph getLastParagraph() /** * @return The number of paragraphs in this list. */ + @Override public int countParagraphs() { return paragraphs.size(); @@ -169,6 +177,7 @@ public int countParagraphs() * @return The paragraph at the given index. Throws an * IndexOutOfBoundsExpception if index is out of bounds. */ + @Override public Paragraph paragraphAt(int index) { return paragraphs.get(index); @@ -184,16 +193,19 @@ private static class ParagraphIterator implements Iterator internalIterator = iterator; } + @Override public boolean hasNext() { return internalIterator.hasNext(); } + @Override public Paragraph next() { return internalIterator.next(); } + @Override public void remove() { internalIterator.remove(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java index fa14517..52b6b1a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/SectionList.java @@ -41,6 +41,7 @@ public SectionList() /** * Returns and iterator over the Sections contained in this list. */ + @Override public Iterator iterator() { return sections.iterator(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java index 311f618..342df97 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/StyleTable.java @@ -33,6 +33,7 @@ class StyleTable implements Iterable styles = new HashMap(); } + @Override public Iterator iterator() { return styles.values().iterator(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java index 29be458..d5c2e76 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AbstractRtfContext.java @@ -42,38 +42,45 @@ protected AbstractRtfContext(boolean throwExceptions) this.throwExceptions = throwExceptions; } + @Override public void processGroupStart(RtfContextStack stack) { handleUnexpectedEvent("Unexpected anonymous group start"); stack.pushContext(this); } + @Override public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { handleUnexpectedEvent("Unexpected destination group start"); stack.pushContext(this); } + @Override public void processGroupEnd(RtfContextStack stack) { stack.popContext(); } + @Override public void processCharacterBytes(byte[] data) { handleUnexpectedEvent("Unexpected character bytes"); } + @Override public void processBinaryBytes(byte[] data) { handleUnexpectedEvent("Unexpected binary bytes"); } + @Override public void processString(String string) { handleUnexpectedEvent("Unexpected string '" + string + "'"); } + @Override public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { handleUnexpectedEvent("Unexpected command '" + command + "'"); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java index 0f0c2fc..8543719 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/AnnotationContext.java @@ -47,6 +47,7 @@ public void processGroupStart(RtfContextStack stack, Command command, int parame case atndate: stack.pushContext(new TimeContext(new DateListener() { + @Override public void setDate(Date date) { annotation.setDate(date); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java index 270a056..593b58b 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentBuilder.java @@ -48,19 +48,23 @@ public void setDebugEvents(boolean debug) debugEvents = debug; } + @Override public void processDocumentStart() { } + @Override public void processDocumentEnd() { } + @Override public void processGroupStart() { atGroupStart = true; } + @Override public void processGroupEnd() { handleDelayedGroupStart(); @@ -71,6 +75,7 @@ public void processGroupEnd() atGroupStart = false; } + @Override public void processCharacterBytes(byte[] data) { handleDelayedGroupStart(); @@ -79,6 +84,7 @@ public void processCharacterBytes(byte[] data) stack.getContext().processCharacterBytes(data); } + @Override public void processBinaryBytes(byte[] data) { handleDelayedGroupStart(); @@ -87,6 +93,7 @@ public void processBinaryBytes(byte[] data) stack.getContext().processBinaryBytes(data); } + @Override public void processString(String string) { handleDelayedGroupStart(); @@ -95,6 +102,7 @@ public void processString(String string) stack.getContext().processString(string); } + @Override public void processCommand(Command command, int parameter, boolean hasParameter, boolean optional) { if (atGroupStart) diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java index 5275480..aed2e57 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/NullContext.java @@ -26,36 +26,43 @@ class NullContext implements RtfContext { + @Override public void processGroupStart(RtfContextStack stack) { stack.pushContext(new NullContext()); } + @Override public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { processGroupStart(stack); } + @Override public void processGroupEnd(RtfContextStack stack) { stack.popContext(); } + @Override public void processCharacterBytes(byte[] data) { // Ignore } + @Override public void processBinaryBytes(byte[] data) { // Ignore } + @Override public void processString(String string) { // Ignore } + @Override public void processCommand(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { // Ignore From 3208923a9cacb3f17a2ee88f9656dff652a9ff19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 22:29:21 +0200 Subject: [PATCH 09/16] Coding style corrections --- RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java | 1 - .../src/com/rtfparserkit/document/impl/DefaultAnnotation.java | 2 -- .../rtfparserkit/document/impl/DefaultCharacterStyleTable.java | 2 -- 3 files changed, 5 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java index 06f19fd..c62d494 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/PageSettings.java @@ -21,7 +21,6 @@ */ public interface PageSettings { - public void setPageMarginLeft(int value); public void setPageMarginRight(int value); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java index 7745acd..329221a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultAnnotation.java @@ -26,7 +26,6 @@ */ public class DefaultAnnotation extends ParagraphList implements Annotation { - private String id = ""; private String author = ""; private long date = Calendar.getInstance().getTimeInMillis(); @@ -70,5 +69,4 @@ public Date getDate() { return new Date(date); } - } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java index 062c1c9..3f418fc 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyleTable.java @@ -24,11 +24,9 @@ */ public class DefaultCharacterStyleTable extends StyleTableimplements CharacterStyleTable { - @Override public CharacterStyle createStyle() { return new DefaultCharacterStyle(); } - } From 7de3742188f31d0cedfa11f9740d01743e6a40ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 22:31:06 +0200 Subject: [PATCH 10/16] CharacterStyle versus ParagraphStyle API changes A Chunk in a Paragraph just needs to know a CharacterStyle. Changed where ParagraphStyle was passed in the API, but a CharacterStyle should be used instead. --- RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java | 2 +- .../src/com/rtfparserkit/document/DocumentPart.java | 4 ++-- .../src/com/rtfparserkit/document/impl/DefaultChunk.java | 8 ++++---- .../com/rtfparserkit/document/impl/DefaultDocument.java | 5 +++-- .../com/rtfparserkit/document/impl/DefaultParagraph.java | 9 +++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java index 6e64d44..36c7604 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Chunk.java @@ -24,7 +24,7 @@ public interface Chunk extends Element public String getText(); - public ParagraphStyle getStyle(); + public CharacterStyle getStyle(); public void append(String string); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java index 8498ea1..82baf8c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/DocumentPart.java @@ -28,9 +28,9 @@ public interface DocumentPart extends Text public Paragraph paragraphAt(int index); - public void append(String text, ParagraphStyle style); + public void append(String text, CharacterStyle style); - public void nextParagraph(ParagraphStyle lastStyle); + public void nextParagraph(CharacterStyle lastStyle); public void nextLine(); diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java index 58fce8e..3a7a4d1 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultChunk.java @@ -16,8 +16,8 @@ package com.rtfparserkit.document.impl; +import com.rtfparserkit.document.CharacterStyle; import com.rtfparserkit.document.Chunk; -import com.rtfparserkit.document.ParagraphStyle; /** * Default Chunk implementation. @@ -25,9 +25,9 @@ public class DefaultChunk implements Chunk { private final StringBuilder stringBuilder; - private final ParagraphStyle style; + private final CharacterStyle style; - public DefaultChunk(ParagraphStyle style) + public DefaultChunk(CharacterStyle style) { stringBuilder = new StringBuilder(); this.style = style; @@ -40,7 +40,7 @@ public String getText() } @Override - public ParagraphStyle getStyle() + public CharacterStyle getStyle() { return style; } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java index 132b1c2..e13163e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultDocument.java @@ -17,6 +17,7 @@ package com.rtfparserkit.document.impl; import com.rtfparserkit.document.Annotation; +import com.rtfparserkit.document.CharacterStyle; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.DocumentSettings; import com.rtfparserkit.document.PageSettings; @@ -125,7 +126,7 @@ public void setPageHeight(int value) * @param style The Style in which the appended string is to appear. */ @Override - public void append(String text, ParagraphStyle style) + public void append(String text, CharacterStyle style) { getLastSection().append(text, style); } @@ -137,7 +138,7 @@ public void append(String text, ParagraphStyle style) * @param lastStyle The Style to be set on the previous paragraph. */ @Override - public void nextParagraph(ParagraphStyle lastStyle) + public void nextParagraph(CharacterStyle lastStyle) { getLastSection().nextParagraph(lastStyle); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java index 40266c6..b0f7087 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraph.java @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.List; +import com.rtfparserkit.document.CharacterStyle; import com.rtfparserkit.document.Chunk; import com.rtfparserkit.document.Element; import com.rtfparserkit.document.Paragraph; @@ -115,7 +116,7 @@ public void append(String string) * @param string The string to append * @param style The Style in which the string is to appear */ - public void append(String string, ParagraphStyle style) + public void append(String string, CharacterStyle style) { if (string == null) throw new IllegalArgumentException("String may not be null!"); @@ -135,12 +136,12 @@ public void end() end(getLastStyle()); } - public void end(ParagraphStyle lastStyle) + public void end(CharacterStyle lastStyle) { append("\n", lastStyle); } - public ParagraphStyle getLastStyle() + public CharacterStyle getLastStyle() { // Try to use the last used Style instead of the default style Chunk lastChunk = findLastChunk(); @@ -170,7 +171,7 @@ private void assertNotDelimited() } } - private void appendString(String string, ParagraphStyle style) + private void appendString(String string, CharacterStyle style) { Chunk chunk = null; if (chunks.size() > 0) From b6c6fd28d9065c3cef333481590d4dbf23509bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 4 Oct 2015 22:32:53 +0200 Subject: [PATCH 11/16] Flesh out Style related API Allow to get the parent and make a Style an exact copy of another Style via setTo(). This is supposed to make it easier to use a specific style from the style sheet once parsing that is implemented. --- .../rtfparserkit/document/CharacterStyle.java | 5 ++-- .../rtfparserkit/document/ParagraphStyle.java | 5 ++-- .../src/com/rtfparserkit/document/Style.java | 4 ++- .../document/impl/DefaultCharacterStyle.java | 26 +++++++++++++++++-- .../document/impl/DefaultParagraphStyle.java | 26 +++++++++++++++++-- .../document/impl/ParagraphList.java | 7 ++--- 6 files changed, 61 insertions(+), 12 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java index 79fcbc8..f924a17 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/CharacterStyle.java @@ -21,7 +21,6 @@ */ public interface CharacterStyle extends Style { - public enum UnderlineStyle { NONE, SINGLE, DOUBLE, WORD, DOTTED, DASHED, DASH_DOTTED, DASH_DOT_DOTTED, LONG_DASHED, THICK, THICK_DOTTED, THICK_DASHED, THICK_DASH_DOTTED, THICK_DASH_DOT_DOTTED, THICK_LONG_DASHED, WAVE, HEAVY_WAVE, DOUBLE_WAVE @@ -31,6 +30,9 @@ public enum UnderlineStyle public CharacterStyle createFlattenedStyle(); + @Override + public CharacterStyle getParent(); + public void setFont(Font font); public Font getFont(); @@ -66,5 +68,4 @@ public enum UnderlineStyle public void setForegroundColor(Color color); public Color getForegroundColor(); - } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java index 76f7392..aabc3a6 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/ParagraphStyle.java @@ -21,7 +21,6 @@ */ public interface ParagraphStyle extends CharacterStyle { - public enum Alignment { LEFT, RIGHT, CENTER, JUSTIFIED, DISTRIBUTED, @@ -40,6 +39,9 @@ public enum TabAlignment @Override public ParagraphStyle createFlattenedStyle(); + @Override + public ParagraphStyle getParent(); + public void setAlignment(Alignment alignment); public Alignment getAlignment(); @@ -69,5 +71,4 @@ public enum TabAlignment public float getLineSpacing(); public void addTab(float position, TabAlignment aligment); - } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java index 5f6dce5..0263e4c 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/Style.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/Style.java @@ -23,7 +23,6 @@ */ public interface Style { - public enum Property { ALIGNMENT, SPACING_TOP, SPACING_BOTTOM, FIRST_LINE_INDENT, LEFT_INDENT, RIGHT_INDENT, LINE_SPACING, TABS, FONT, FONT_SIZE, BOLD, ITALIC, UNDERLINED, STRIKE_OUT, CAPS, BACKGROUND_COLOR, FOREGROUND_COLOR @@ -33,10 +32,13 @@ public enum Property public String getName(); + public Style getParent(); + public EnumSet getOverriddenProperties(); public void resetToDefaults(); public boolean equals(Style other); + public void setTo(Style other); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java index d9ea5e1..22808fc 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultCharacterStyle.java @@ -28,8 +28,7 @@ */ public class DefaultCharacterStyle extends DefaultStyle implements CharacterStyle { - - private final CharacterStyle parent; + private CharacterStyle parent; private Font font; private float fontSize; @@ -55,6 +54,12 @@ public DefaultCharacterStyle(CharacterStyle other) parent = other; } + @Override + public CharacterStyle getParent() + { + return parent; + } + @Override public void resetToDefaults() { @@ -120,6 +125,23 @@ public boolean equals(Style object) return parent == other.parent && (font != null ? font.equals(other.font) : other.font == null) && fontSize == other.fontSize && bold == other.bold && italic == other.italic && underlineStyle == other.underlineStyle && strikeOut == other.strikeOut && caps == other.caps && backgroundColor == other.backgroundColor && foregroundColor == other.foregroundColor; } + @Override + public void setTo(Style other) + { + if (other == this) + return; + if (other == null) + throw new IllegalArgumentException("Style must not be null"); + if (!(other instanceof CharacterStyle)) + throw new IllegalArgumentException("Incompatible type of Style"); + + CharacterStyle style = (CharacterStyle) other; + + copyFrom(style); + parent = style.getParent(); + overriddenProperties = style.getOverriddenProperties(); + } + @Override public void setFont(Font font) { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java index 2773152..df1740f 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultParagraphStyle.java @@ -27,8 +27,7 @@ */ public class DefaultParagraphStyle extends DefaultCharacterStyle implements ParagraphStyle { - - private final ParagraphStyle parent; + private ParagraphStyle parent; private Alignment alignment; private float spacingTop; @@ -51,6 +50,12 @@ public DefaultParagraphStyle(ParagraphStyle other) parent = other; } + @Override + public ParagraphStyle getParent() + { + return parent; + } + @Override public void resetToDefaults() { @@ -116,6 +121,23 @@ public boolean equals(Style object) return parent == other.parent && alignment == other.alignment && spacingTop == other.spacingTop && spacingBottom == other.spacingBottom && firstLineIndent == other.firstLineIndent && leftIndent == other.leftIndent && rightIndent == other.rightIndent && lineSpacing == other.lineSpacing; } + @Override + public void setTo(Style other) + { + if (other == this) + return; + if (other == null) + throw new IllegalArgumentException("Style must not be null"); + if (!(other instanceof CharacterStyle)) + throw new IllegalArgumentException("Incompatible type of Style"); + + ParagraphStyle style = (ParagraphStyle) other; + + copyFrom(style); + parent = style.getParent(); + overriddenProperties = style.getOverriddenProperties(); + } + @Override public void setAlignment(Alignment alignment) { diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java index e6e9893..7df785d 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/ParagraphList.java @@ -21,6 +21,7 @@ import java.util.List; import com.rtfparserkit.document.Annotation; +import com.rtfparserkit.document.CharacterStyle; import com.rtfparserkit.document.DocumentPart; import com.rtfparserkit.document.Paragraph; import com.rtfparserkit.document.ParagraphStyle; @@ -57,7 +58,7 @@ public Iterator iterator() * Starts the next paragraph by appending a new empty Paragraph to the list. */ @Override - public void nextParagraph(ParagraphStyle lastStyle) + public void nextParagraph(CharacterStyle lastStyle) { if (countParagraphs() > 0) getLastParagraph().end(lastStyle); @@ -105,7 +106,7 @@ public ParagraphStyle createDefaultStyle() * @see #nextParagraph() */ @Override - public void append(String text, ParagraphStyle style) + public void append(String text, CharacterStyle style) { int offset = 0; while (offset < text.length()) @@ -128,7 +129,7 @@ public void append(String text, ParagraphStyle style) public void append(String string) { - ParagraphStyle style = getLastParagraph().getLastStyle(); + CharacterStyle style = getLastParagraph().getLastStyle(); append(string, style); } From 0a92e687e0786bccbcad6ef8021f22a0c3fb36bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 5 Oct 2015 22:43:51 +0200 Subject: [PATCH 12/16] Fixed FontContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing some warnings has introduced a bug, FontContext was not handling \f and called the super class in the default case, which throws an exception on „unexpected“ commands. Also changed FontTable interface to store and look up fonts by id rather than index. --- .../com/rtfparserkit/document/FontTable.java | 4 +- .../document/impl/DefaultFontTable.java | 15 +++---- .../parser/builder/DocumentPartContext.java | 2 +- .../parser/builder/FontContext.java | 14 +++++- .../parser/builder/FontTableContext.java | 10 ++++- .../parser/builder/BuilderParseTest.java | 45 +++++++++---------- 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java index 3d5b632..20bf0fb 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java @@ -28,9 +28,9 @@ public enum FontFamily DEFAULT, ROMAN, SWISS, MODERN, SCRIPT, DECOR, TECH, BIDI } - public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily); + public void addFont(int id, String name, String alternativeName, String fileName, FontFamily fontFamily); public int countFonts(); - public Font fontAt(int index); + public Font fontFor(int id); } diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java index c1b671f..87e7652 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -1,8 +1,7 @@ package com.rtfparserkit.document.impl; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; import com.rtfparserkit.document.Font; import com.rtfparserkit.document.FontTable; @@ -10,17 +9,17 @@ public class DefaultFontTable implements FontTable { - private final List fonts; + private final HashMap fonts; public DefaultFontTable() { - fonts = new ArrayList(); + fonts = new HashMap(); } @Override - public void addFont(String name, String alternativeName, String fileName, FontFamily fontFamily) + public void addFont(int id, String name, String alternativeName, String fileName, FontFamily fontFamily) { - fonts.add(new DefaultFont(name)); + fonts.put(id, new DefaultFont(name)); } @Override @@ -30,8 +29,8 @@ public int countFonts() } @Override - public Font fontAt(int index) + public Font fontFor(int id) { - return fonts.get(index); + return fonts.get(id); } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 65c1b6f..de5f724 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -130,7 +130,7 @@ public void processCommand(RtfContextStack stack, Command command, int parameter style.resetToDefaults(); break; case f: - style.setFont(document.getFontTable().fontAt(parameter)); + style.setFont(document.getFontTable().fontFor(parameter)); break; case fs: style.setFontSize(fromHalfPoints(parameter)); diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java index 5a09d36..915b74e 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontContext.java @@ -29,6 +29,7 @@ class FontContext extends AbstractRtfContext protected final FontTable fontTable; + private int id = 0; private String fontName = ""; private String alternativeName = ""; private String fileName = ""; @@ -46,6 +47,12 @@ private enum ExpectedName this.fontTable = fontTable; } + FontContext(int id, FontTable fontTable) + { + this(fontTable); + this.id = id; + } + @Override public void processGroupEnd(RtfContextStack stack) { @@ -63,7 +70,7 @@ public void processString(String string) if (semicolon == offset) { - fontTable.addFont(fontName, alternativeName, fileName, fontFamily); + fontTable.addFont(id, fontName, alternativeName, fileName, fontFamily); offset = semicolon + 1; continue; } @@ -94,6 +101,10 @@ public void processCommand(RtfContextStack stack, Command command, int parameter { switch (command) { + case f: + id = parameter; + break; + case fname: expectedName = ExpectedName.DEFAULT; break; @@ -130,7 +141,6 @@ public void processCommand(RtfContextStack stack, Command command, int parameter break; default: - super.processCommand(stack, command, parameter, hasParameter, optional); break; } } diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java index bd9c50b..30b0ab6 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/FontTableContext.java @@ -43,7 +43,15 @@ public void processGroupStart(RtfContextStack stack) @Override public void processGroupStart(RtfContextStack stack, Command command, int parameter, boolean hasParameter, boolean optional) { - stack.pushContext(new FontContext(fontTable)); + switch (command) + { + case f: + stack.pushContext(new FontContext(parameter, fontTable)); + break; + default: + super.processGroupStart(stack, command, parameter, hasParameter, optional); + break; + } } } diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java index a7fa848..d85cdc1 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -35,7 +35,7 @@ public void testParagraphContentsIText() assertEquals(5, paragraphCount); assertEquals("INNEN. KÜCHE - TAG\n", section.paragraphAt(0).getText()); - assertEquals("Ein Absatz mit Line-Separator:\u2028" + "Der geht hier auf einer neuen Zeile weiter.\n", section.paragraphAt(1).getText()); + assertEquals("Ein Absatz mit Line-Separator:\u2028Der geht hier auf einer neuen Zeile weiter.\n", section.paragraphAt(1).getText()); assertEquals("INNEN. KÜCHE - TAG\n", section.paragraphAt(2).getText()); assertEquals("Hier ist die zweite Szene.\n", section.paragraphAt(3).getText()); assertEquals("", section.paragraphAt(4).getText()); @@ -65,25 +65,6 @@ public void testParagraphContentsLibreOffice() assertEquals("This word is commented.\n", section.paragraphAt(0).getText()); } - @Test - public void testStyles() - { - - String[] files = {"variousStyles", "variousStylesPages", "variousStylesGrouped",}; - - for (String file : files) - { - System.out.println("################################"); - - DefaultDocument document = new DefaultDocument(); - parseStream(file, document, false); - - assertEquals(1, document.countSections()); - Section section = document.sectionAt(0); - assertStyles(section); - } - } - @Test public void testAnnotations() { @@ -106,7 +87,7 @@ public void testAnnotations() element = paragraph.elementAt(1); assertTrue(element instanceof Annotation); Annotation annotation = (Annotation) element; - assertEquals("How about some examples that deal with social science? " + "That is what this paper is about.", annotation.getText()); + assertEquals("How about some examples that deal with social science? That is what this paper is about.", annotation.getText()); assertEquals("JD", annotation.getId()); assertEquals("John Doe", annotation.getAuthor()); @@ -116,6 +97,24 @@ public void testAnnotations() assertEquals(" ", chunk.getText()); } + @Test + public void testStyles() + { + String[] files = {"variousStyles", "variousStylesPages", "variousStylesGrouped",}; + + for (String file : files) + { + System.out.println("################################"); + + DefaultDocument document = new DefaultDocument(); + parseStream(file, document, false); + + assertEquals(1, document.countSections()); + Section section = document.sectionAt(0); + assertStyles(section); + } + } + private void assertStyles(Section section) { int paragraphCount = section.countParagraphs(); @@ -127,7 +126,7 @@ private void assertStyles(Section section) if (i == 0) assertNormalBoldItalic(paragraph); - // else { + // else { String text = paragraph.getText(); System.out.print("[" + i + "]: " + text); if (!text.endsWith("\n")) @@ -141,7 +140,7 @@ private void assertStyles(Section section) } } } - // } + // } } private void assertNormalBoldItalic(Paragraph paragraph) From 526ddeb9c9f45d1598c5bbdf895029f8938cc575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 5 Oct 2015 22:46:29 +0200 Subject: [PATCH 13/16] FontTable can iterate over contained Fonts --- .../src/com/rtfparserkit/document/FontTable.java | 2 +- .../rtfparserkit/document/impl/DefaultFontTable.java | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java index 20bf0fb..cd1aa2a 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/FontTable.java @@ -20,7 +20,7 @@ * Interface for adding a font definition to the global font table and * retrieving the font information at a specific index. */ -public interface FontTable +public interface FontTable extends Iterable { public enum FontFamily diff --git a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java index 87e7652..686c29d 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java +++ b/RTF Parser Kit/src/com/rtfparserkit/document/impl/DefaultFontTable.java @@ -2,18 +2,18 @@ package com.rtfparserkit.document.impl; import java.util.HashMap; +import java.util.Iterator; import com.rtfparserkit.document.Font; import com.rtfparserkit.document.FontTable; public class DefaultFontTable implements FontTable { - - private final HashMap fonts; + private final HashMap fonts; public DefaultFontTable() { - fonts = new HashMap(); + fonts = new HashMap(); } @Override @@ -33,4 +33,10 @@ public Font fontFor(int id) { return fonts.get(id); } + + @Override + public Iterator iterator() + { + return fonts.values().iterator(); + } } From 652aa6219d613f685431994ba0ecd808c359b866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 5 Oct 2015 22:50:58 +0200 Subject: [PATCH 14/16] Coding style --- .../com/rtfparserkit/parser/builder/DocumentPartContext.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index de5f724..44cd739 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -17,11 +17,11 @@ package com.rtfparserkit.parser.builder; import com.rtfparserkit.document.Annotation; +import com.rtfparserkit.document.CharacterStyle.UnderlineStyle; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.DocumentPart; import com.rtfparserkit.document.ParagraphStyle; import com.rtfparserkit.document.ParagraphStyle.Alignment; -import com.rtfparserkit.document.CharacterStyle.UnderlineStyle; import com.rtfparserkit.rtf.Command; /** @@ -30,7 +30,6 @@ */ class DocumentPartContext extends AbstractRtfContext { - private final DocumentPart documentPart; protected final Document document; private final ParagraphStyle style; @@ -66,7 +65,7 @@ public void processGroupStart(RtfContextStack stack, Command command, int parame // A new Annotation started if (currentAnnotation != null) { - stack.handleError("An annotation has already" + "started, but encountered another annotation ID."); + stack.handleError("An annotation has already started, but encountered another annotation ID."); } currentAnnotation = documentPart.appendAnnotation(); stack.pushContext(new AnnotationIdContext()); From c5a851f0c4e0399936ca948f3b6386c3246cc693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 5 Oct 2015 23:16:43 +0200 Subject: [PATCH 15/16] Fix handling underlined commands Parameter evaluation was reversed. Extended unit test to check parsing of the second paragraph of the test document. --- .../parser/builder/DocumentPartContext.java | 6 +- .../parser/builder/BuilderParseTest.java | 81 +++++++++++++++---- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 44cd739..291a839 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -268,10 +268,10 @@ public void processCommand(RtfContextStack stack, Command command, int parameter private void setUnderlined(UnderlineStyle underline, boolean hasParamter, int parameter) { - if (!hasParamter || parameter == 0) - style.setUnderlined(UnderlineStyle.NONE); - else + if (!hasParamter || parameter != 0) style.setUnderlined(underline); + else + style.setUnderlined(UnderlineStyle.NONE); } private static float fromTwips(int value) diff --git a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java index d85cdc1..90dc3d8 100644 --- a/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java +++ b/RTF Parser Kit/test/com/rtfparserkit/parser/builder/BuilderParseTest.java @@ -11,6 +11,7 @@ import org.junit.Test; import com.rtfparserkit.document.Annotation; +import com.rtfparserkit.document.CharacterStyle.UnderlineStyle; import com.rtfparserkit.document.Chunk; import com.rtfparserkit.document.Document; import com.rtfparserkit.document.Element; @@ -100,7 +101,8 @@ public void testAnnotations() @Test public void testStyles() { - String[] files = {"variousStyles", "variousStylesPages", "variousStylesGrouped",}; + // NOTE: Pages did not write the foreground/background colors + String[] files = {"variousStyles", /*"variousStylesPages",*/ "variousStylesGrouped",}; for (String file : files) { @@ -124,23 +126,29 @@ private void assertStyles(Section section) { Paragraph paragraph = section.paragraphAt(i); - if (i == 0) - assertNormalBoldItalic(paragraph); - // else { - String text = paragraph.getText(); - System.out.print("[" + i + "]: " + text); - if (!text.endsWith("\n")) - System.out.println(); - for (Element element : paragraph) + switch (i) { - if (element instanceof Chunk) - { - Chunk chunk = (Chunk) element; - System.out.println(" '" + chunk.getText().replaceAll("\n", "") + "' " + chunk.getStyle()); - } + case 0: + assertNormalBoldItalic(paragraph); + break; + case 1: + assertFontSizesAndColors(paragraph); + break; + default: + String text = paragraph.getText(); + System.out.print("[" + i + "]: " + text); + if (!text.endsWith("\n")) + System.out.println(); + for (Element element : paragraph) + { + if (element instanceof Chunk) + { + Chunk chunk = (Chunk) element; + System.out.println(" '" + chunk.getText().replaceAll("\n", "") + "' " + chunk.getStyle()); + } + } } } - // } } private void assertNormalBoldItalic(Paragraph paragraph) @@ -174,6 +182,49 @@ private void assertNormalBoldItalic(Paragraph paragraph) assertFalse(chunk.getStyle().getItalic()); } + private void assertFontSizesAndColors(Paragraph paragraph) + { + int chunks = paragraph.countElements(); + assertEquals(5, chunks); + + Chunk chunk = (Chunk) paragraph.elementAt(0); + assertEquals("Bigger Font (18). ", chunk.getText()); + assertEquals(18.0f, chunk.getStyle().getFontSize(), 0.0f); + assertEquals("Helvetica", chunk.getStyle().getFont().getName()); + assertEquals(UnderlineStyle.NONE, chunk.getStyle().getUnderlined()); + + chunk = (Chunk) paragraph.elementAt(1); + assertEquals("Underlined", chunk.getText()); + assertEquals(18.0f, chunk.getStyle().getFontSize(), 0.0f); + assertEquals(UnderlineStyle.SINGLE, chunk.getStyle().getUnderlined()); + + chunk = (Chunk) paragraph.elementAt(2); + assertEquals(" Normal size. ", chunk.getText()); + assertEquals(12.0f, chunk.getStyle().getFontSize(), 0.0f); + assertEquals(UnderlineStyle.NONE, chunk.getStyle().getUnderlined()); + assertEquals(0, chunk.getStyle().getForegroundColor().getRed()); + assertEquals(0, chunk.getStyle().getForegroundColor().getGreen()); + assertEquals(0, chunk.getStyle().getForegroundColor().getBlue()); + + chunk = (Chunk) paragraph.elementAt(3); + assertEquals("Red text. ", chunk.getText()); + assertEquals(217, chunk.getStyle().getForegroundColor().getRed()); + assertEquals(11, chunk.getStyle().getForegroundColor().getGreen()); + assertEquals(0, chunk.getStyle().getForegroundColor().getBlue()); + assertEquals(255, chunk.getStyle().getBackgroundColor().getRed()); + assertEquals(255, chunk.getStyle().getBackgroundColor().getGreen()); + assertEquals(255, chunk.getStyle().getBackgroundColor().getBlue()); + + chunk = (Chunk) paragraph.elementAt(4); + assertEquals("On yellow background.\n", chunk.getText()); + assertEquals(217, chunk.getStyle().getForegroundColor().getRed()); + assertEquals(11, chunk.getStyle().getForegroundColor().getGreen()); + assertEquals(0, chunk.getStyle().getForegroundColor().getBlue()); + assertEquals(255, chunk.getStyle().getBackgroundColor().getRed()); + assertEquals(249, chunk.getStyle().getBackgroundColor().getGreen()); + assertEquals(89, chunk.getStyle().getBackgroundColor().getBlue()); + } + private void parseStream(String fileName, Document document, boolean debug) { InputStream is = null; From 4fb04b74eabb96bfc2558904cc70846bd7f31841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 19 May 2016 10:28:40 +0200 Subject: [PATCH 16/16] Ignore groups with an unknown command... ... instead of directing the text to the document destination. Fixes for example bookmark titles arriving in the text. --- .../com/rtfparserkit/parser/builder/DocumentPartContext.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java index 291a839..65b1043 100644 --- a/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java +++ b/RTF Parser Kit/src/com/rtfparserkit/parser/builder/DocumentPartContext.java @@ -77,7 +77,8 @@ public void processGroupStart(RtfContextStack stack, Command command, int parame stack.pushContext(new AnnotationContext(currentAnnotation, this)); break; default: - stack.pushContext(new DocumentPartContext(this)); + // Ignore groups with unknown command + stack.pushContext(new NullContext()); } }