From abbe6d25210bc00b031c1b9b75b0cd4adf4f3a28 Mon Sep 17 00:00:00 2001 From: DC* Date: Fri, 28 Aug 2020 22:30:49 -0300 Subject: [PATCH 1/7] - Maven project structure - Android release compilation complains about 'res' reserved keyword - Remove unused artifacts --- .gitignore | 4 + META-INF/MANIFEST.MF | 3 - Makefile | 15 - build.gradle | 109 +++ build.txt | 3 - build.xml | 149 --- gradle/gradle-witness.jar | Bin 0 -> 23967 bytes gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 56177 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 ++++ gradlew.bat | 84 ++ src/build.sh | 10 - .../plugins/Sharesite/ActivelinkCreator.java | 0 .../java}/plugins/Sharesite/Database.java | 0 .../java}/plugins/Sharesite/Freesite.java | 6 +- .../java}/plugins/Sharesite/Inserter.java | 0 .../java}/plugins/Sharesite/Plugin.java | 5 +- .../plugins/Sharesite/common/FileStorage.java | 0 .../plugins/Sharesite/common/Logger.java | 0 .../plugins/Sharesite/common/MapToData.java | 0 .../plugins/Sharesite/common/SmartMap.java | 0 .../plugins/Sharesite/webui/EditToadlet.java | 0 .../plugins/Sharesite/webui/HomeToadlet.java | 0 .../Sharesite/webui/PreviewToadlet.java | 0 .../plugins/Sharesite/webui/WebInterface.java | 0 .../java/resources}/l10n/lang_en.l10n | 0 .../java/resources}/templates/activelink.png | Bin .../java/resources}/templates/content.txt | 0 .../main/java/resources}/templates/index.html | 0 .../main/java/resources}/templates/style.css | 0 src/net/java/textilej/TextileJPlugin.java | 266 ------ src/net/java/textilej/parser/Attributes.java | 63 -- .../java/textilej/parser/DocumentBuilder.java | 294 ------ src/net/java/textilej/parser/IdGenerator.java | 49 - .../java/textilej/parser/ImageAttributes.java | 51 - .../java/textilej/parser/LinkAttributes.java | 57 -- .../java/textilej/parser/ListAttributes.java | 16 - src/net/java/textilej/parser/Locator.java | 47 - .../java/textilej/parser/MarkupParser.java | 114 --- .../java/textilej/parser/QuoteAttributes.java | 20 - .../java/textilej/parser/TableAttributes.java | 65 -- .../textilej/parser/TableCellAttributes.java | 41 - .../textilej/parser/TableRowAttributes.java | 27 - .../java/textilej/parser/TextileParser.java | 93 -- .../builder/AbstractXmlDocumentBuilder.java | 108 --- .../builder/DocBookDocumentBuilder.java | 554 ----------- .../builder/EventLoggingDocumentBuilder.java | 98 -- .../parser/builder/HtmlDocumentBuilder.java | 895 ------------------ .../builder/MultiplexingDocumentBuilder.java | 143 --- .../java/textilej/parser/markup/Block.java | 92 -- .../textilej/parser/markup/ContentState.java | 136 --- .../java/textilej/parser/markup/Dialect.java | 408 -------- .../parser/markup/PatternBasedElement.java | 36 - .../markup/PatternBasedElementProcessor.java | 127 --- .../textilej/parser/markup/Processor.java | 48 - .../parser/markup/block/GlossaryBlock.java | 52 - .../markup/confluence/ConfluenceDialect.java | 124 --- .../AbstractConfluenceDelimitedBlock.java | 87 -- .../markup/confluence/block/CodeBlock.java | 56 -- .../block/ExtendedPreformattedBlock.java | 45 - .../confluence/block/ExtendedQuoteBlock.java | 71 -- .../markup/confluence/block/HeadingBlock.java | 70 -- .../markup/confluence/block/ListBlock.java | 162 ---- .../confluence/block/ParagraphBlock.java | 87 -- .../confluence/block/ParameterizedBlock.java | 23 - .../markup/confluence/block/QuoteBlock.java | 69 -- .../markup/confluence/block/TableBlock.java | 99 -- .../block/TableOfContentsBlock.java | 104 -- .../markup/confluence/block/TextBoxBlock.java | 104 -- .../phrase/ImagePhraseModifier.java | 39 - .../phrase/SimplePhraseModifier.java | 11 - .../phrase/SimpleWrappedPhraseModifier.java | 74 -- .../token/AnchorReplacementToken.java | 37 - .../token/HyperlinkReplacementToken.java | 41 - .../markup/mediawiki/MediaWikiDialect.java | 153 --- .../markup/mediawiki/block/HeadingBlock.java | 52 - .../markup/mediawiki/block/ListBlock.java | 250 ----- .../mediawiki/block/ParagraphBlock.java | 105 -- .../mediawiki/block/PreformattedBlock.java | 42 - .../markup/mediawiki/block/TableBlock.java | 245 ----- .../phrase/EscapePhraseModifier.java | 29 - .../phrase/SimplePhraseModifier.java | 22 - .../phrase/SimpleWrappedPhraseModifier.java | 82 -- .../EntityReferenceReplacementToken.java | 40 - .../HyperlinkExternalReplacementToken.java | 42 - .../HyperlinkInternalReplacementToken.java | 59 -- .../token/HyperlinkReplacementToken.java | 38 - .../token/ImageReplacementToken.java | 72 -- .../mediawiki/token/LineBreakToken.java | 29 - .../token/TemplateReplacementToken.java | 74 -- .../phrase/HtmlCommentPhraseModifier.java | 26 - .../phrase/HtmlEndTagPhraseModifier.java | 26 - .../phrase/HtmlStartTagPhraseModifier.java | 26 - .../LimitedHtmlEndTagPhraseModifier.java | 41 - .../LimitedHtmlStartTagPhraseModifier.java | 41 - .../LiteralPhraseModifierProcessor.java | 24 - .../parser/markup/textile/Textile.java | 115 --- .../markup/textile/TextileContentState.java | 34 - .../parser/markup/textile/TextileDialect.java | 135 --- .../markup/textile/block/CodeBlock.java | 79 -- .../markup/textile/block/FootnoteBlock.java | 87 -- .../markup/textile/block/HeadingBlock.java | 78 -- .../markup/textile/block/ListBlock.java | 159 ---- .../markup/textile/block/ParagraphBlock.java | 102 -- .../textile/block/PreformattedBlock.java | 79 -- .../markup/textile/block/QuoteBlock.java | 103 -- .../markup/textile/block/TableBlock.java | 141 --- .../textile/block/TableOfContentsBlock.java | 110 --- .../textile/block/TextileGlossaryBlock.java | 46 - .../phrase/EscapeTextilePhraseModifier.java | 31 - .../phrase/ImageTextilePhraseModifier.java | 73 -- .../phrase/SimpleTextilePhraseModifier.java | 109 --- .../FootnoteReferenceReplacementToken.java | 36 - .../token/HyperlinkReplacementToken.java | 66 -- .../validation/BlockWhitespaceRule.java | 42 - .../markup/token/AcronymReplacementToken.java | 34 - .../EntityReferenceReplacementToken.java | 11 - .../EntityReplacementTokenProcessor.java | 18 - .../token/EntityWrappingReplacementToken.java | 55 -- .../ImpliedHyperlinkReplacementToken.java | 30 - .../LineBreakReplacementTokenProcessor.java | 12 - .../LiteralReplacementTokenProcessor.java | 18 - ...atternEntityReferenceReplacementToken.java | 31 - .../PatternLineBreakReplacementToken.java | 29 - .../token/PatternLiteralReplacementToken.java | 31 - .../parser/markup/trac/TracWikiDialect.java | 89 -- .../markup/trac/block/HeadingBlock.java | 53 -- .../parser/markup/trac/block/ListBlock.java | 173 ---- .../markup/trac/block/ParagraphBlock.java | 67 -- .../markup/trac/block/PreformattedBlock.java | 55 -- .../parser/markup/trac/block/QuoteBlock.java | 112 --- .../parser/markup/trac/block/TableBlock.java | 94 -- .../trac/phrase/EscapePhraseModifier.java | 53 -- .../trac/phrase/SimplePhraseModifier.java | 22 - .../phrase/SimpleWrappedPhraseModifier.java | 81 -- .../markup/trac/token/BangEscapeToken.java | 31 - .../trac/token/HyperlinkReplacementToken.java | 41 - .../markup/trac/token/LineBreakToken.java | 29 - .../textilej/parser/outline/OutlineItem.java | 179 ---- .../parser/outline/OutlineParser.java | 204 ---- .../textilej/parser/util/MarkupToDocbook.java | 61 -- .../parser/util/MarkupToEclipseToc.java | 93 -- .../java/textilej/parser/util/Matcher.java | 7 - .../textilej/parser/util/MatcherAdaper.java | 24 - .../parser/util/TextileToDocbook.java | 90 -- .../parser/util/TextileToEclipseToc.java | 103 -- .../textilej/util/DefaultXmlStreamWriter.java | 505 ---------- .../util/FormattingXMLStreamWriter.java | 241 ----- .../util/IgnoreDtdEntityResolver.java | 28 - .../textilej/util/LocationTrackingReader.java | 180 ---- src/net/java/textilej/util/LocatorImpl.java | 47 - .../textilej/util/LoggingXMLStreamWriter.java | 164 ---- .../java/textilej/util/XmlStreamWriter.java | 73 -- .../util/anttask/TextileToDocbookTask.java | 226 ----- .../anttask/TextileToEclipseHelpTask.java | 100 -- .../util/anttask/TextileToHtmlTask.java | 317 ------- .../textilej/util/anttask/tasks.properties | 4 - .../textilej/validation/MarkupValidator.java | 94 -- .../validation/ValidationProblem.java | 100 -- .../textilej/validation/ValidationRule.java | 21 - 160 files changed, 379 insertions(+), 12562 deletions(-) create mode 100644 .gitignore delete mode 100644 META-INF/MANIFEST.MF delete mode 100644 Makefile create mode 100644 build.gradle delete mode 100644 build.txt delete mode 100644 build.xml create mode 100644 gradle/gradle-witness.jar create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 src/build.sh rename src/{ => main/java}/plugins/Sharesite/ActivelinkCreator.java (100%) rename src/{ => main/java}/plugins/Sharesite/Database.java (100%) rename src/{ => main/java}/plugins/Sharesite/Freesite.java (98%) rename src/{ => main/java}/plugins/Sharesite/Inserter.java (100%) rename src/{ => main/java}/plugins/Sharesite/Plugin.java (97%) rename src/{ => main/java}/plugins/Sharesite/common/FileStorage.java (100%) rename src/{ => main/java}/plugins/Sharesite/common/Logger.java (100%) rename src/{ => main/java}/plugins/Sharesite/common/MapToData.java (100%) rename src/{ => main/java}/plugins/Sharesite/common/SmartMap.java (100%) rename src/{ => main/java}/plugins/Sharesite/webui/EditToadlet.java (100%) rename src/{ => main/java}/plugins/Sharesite/webui/HomeToadlet.java (100%) rename src/{ => main/java}/plugins/Sharesite/webui/PreviewToadlet.java (100%) rename src/{ => main/java}/plugins/Sharesite/webui/WebInterface.java (100%) rename src/{plugins/Sharesite => main/java/resources}/l10n/lang_en.l10n (100%) rename {rez => src/main/java/resources}/templates/activelink.png (100%) rename {rez => src/main/java/resources}/templates/content.txt (100%) rename {rez => src/main/java/resources}/templates/index.html (100%) rename {rez => src/main/java/resources}/templates/style.css (100%) delete mode 100644 src/net/java/textilej/TextileJPlugin.java delete mode 100644 src/net/java/textilej/parser/Attributes.java delete mode 100644 src/net/java/textilej/parser/DocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/IdGenerator.java delete mode 100644 src/net/java/textilej/parser/ImageAttributes.java delete mode 100644 src/net/java/textilej/parser/LinkAttributes.java delete mode 100644 src/net/java/textilej/parser/ListAttributes.java delete mode 100644 src/net/java/textilej/parser/Locator.java delete mode 100644 src/net/java/textilej/parser/MarkupParser.java delete mode 100644 src/net/java/textilej/parser/QuoteAttributes.java delete mode 100644 src/net/java/textilej/parser/TableAttributes.java delete mode 100644 src/net/java/textilej/parser/TableCellAttributes.java delete mode 100644 src/net/java/textilej/parser/TableRowAttributes.java delete mode 100644 src/net/java/textilej/parser/TextileParser.java delete mode 100644 src/net/java/textilej/parser/builder/AbstractXmlDocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/builder/DocBookDocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/builder/EventLoggingDocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/builder/HtmlDocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/builder/MultiplexingDocumentBuilder.java delete mode 100644 src/net/java/textilej/parser/markup/Block.java delete mode 100644 src/net/java/textilej/parser/markup/ContentState.java delete mode 100644 src/net/java/textilej/parser/markup/Dialect.java delete mode 100644 src/net/java/textilej/parser/markup/PatternBasedElement.java delete mode 100644 src/net/java/textilej/parser/markup/PatternBasedElementProcessor.java delete mode 100644 src/net/java/textilej/parser/markup/Processor.java delete mode 100644 src/net/java/textilej/parser/markup/block/GlossaryBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/ConfluenceDialect.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/AbstractConfluenceDelimitedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/CodeBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/ExtendedPreformattedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/ExtendedQuoteBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/HeadingBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/ListBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/ParagraphBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/ParameterizedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/QuoteBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/TableBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/TableOfContentsBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/block/TextBoxBlock.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/phrase/ImagePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/phrase/SimplePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/phrase/SimpleWrappedPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/token/AnchorReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/confluence/token/HyperlinkReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/MediaWikiDialect.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/block/HeadingBlock.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/block/ListBlock.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/block/ParagraphBlock.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/block/PreformattedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/block/TableBlock.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/phrase/EscapePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/phrase/SimplePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/phrase/SimpleWrappedPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/EntityReferenceReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkExternalReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkInternalReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/ImageReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/LineBreakToken.java delete mode 100644 src/net/java/textilej/parser/markup/mediawiki/token/TemplateReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/HtmlCommentPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/HtmlEndTagPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/HtmlStartTagPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/LimitedHtmlEndTagPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/LimitedHtmlStartTagPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/phrase/LiteralPhraseModifierProcessor.java delete mode 100644 src/net/java/textilej/parser/markup/textile/Textile.java delete mode 100644 src/net/java/textilej/parser/markup/textile/TextileContentState.java delete mode 100644 src/net/java/textilej/parser/markup/textile/TextileDialect.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/CodeBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/FootnoteBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/HeadingBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/ListBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/ParagraphBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/PreformattedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/QuoteBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/TableBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/TableOfContentsBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/block/TextileGlossaryBlock.java delete mode 100644 src/net/java/textilej/parser/markup/textile/phrase/EscapeTextilePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/textile/phrase/ImageTextilePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/textile/phrase/SimpleTextilePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/textile/token/FootnoteReferenceReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/textile/token/HyperlinkReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/textile/validation/BlockWhitespaceRule.java delete mode 100644 src/net/java/textilej/parser/markup/token/AcronymReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/EntityReferenceReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/EntityReplacementTokenProcessor.java delete mode 100644 src/net/java/textilej/parser/markup/token/EntityWrappingReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/ImpliedHyperlinkReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/LineBreakReplacementTokenProcessor.java delete mode 100644 src/net/java/textilej/parser/markup/token/LiteralReplacementTokenProcessor.java delete mode 100644 src/net/java/textilej/parser/markup/token/PatternEntityReferenceReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/PatternLineBreakReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/token/PatternLiteralReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/trac/TracWikiDialect.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/HeadingBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/ListBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/ParagraphBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/PreformattedBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/QuoteBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/block/TableBlock.java delete mode 100644 src/net/java/textilej/parser/markup/trac/phrase/EscapePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/trac/phrase/SimplePhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/trac/phrase/SimpleWrappedPhraseModifier.java delete mode 100644 src/net/java/textilej/parser/markup/trac/token/BangEscapeToken.java delete mode 100644 src/net/java/textilej/parser/markup/trac/token/HyperlinkReplacementToken.java delete mode 100644 src/net/java/textilej/parser/markup/trac/token/LineBreakToken.java delete mode 100644 src/net/java/textilej/parser/outline/OutlineItem.java delete mode 100644 src/net/java/textilej/parser/outline/OutlineParser.java delete mode 100644 src/net/java/textilej/parser/util/MarkupToDocbook.java delete mode 100644 src/net/java/textilej/parser/util/MarkupToEclipseToc.java delete mode 100644 src/net/java/textilej/parser/util/Matcher.java delete mode 100644 src/net/java/textilej/parser/util/MatcherAdaper.java delete mode 100644 src/net/java/textilej/parser/util/TextileToDocbook.java delete mode 100644 src/net/java/textilej/parser/util/TextileToEclipseToc.java delete mode 100644 src/net/java/textilej/util/DefaultXmlStreamWriter.java delete mode 100644 src/net/java/textilej/util/FormattingXMLStreamWriter.java delete mode 100644 src/net/java/textilej/util/IgnoreDtdEntityResolver.java delete mode 100644 src/net/java/textilej/util/LocationTrackingReader.java delete mode 100644 src/net/java/textilej/util/LocatorImpl.java delete mode 100644 src/net/java/textilej/util/LoggingXMLStreamWriter.java delete mode 100644 src/net/java/textilej/util/XmlStreamWriter.java delete mode 100644 src/net/java/textilej/util/anttask/TextileToDocbookTask.java delete mode 100644 src/net/java/textilej/util/anttask/TextileToEclipseHelpTask.java delete mode 100644 src/net/java/textilej/util/anttask/TextileToHtmlTask.java delete mode 100644 src/net/java/textilej/util/anttask/tasks.properties delete mode 100644 src/net/java/textilej/validation/MarkupValidator.java delete mode 100644 src/net/java/textilej/validation/ValidationProblem.java delete mode 100644 src/net/java/textilej/validation/ValidationRule.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05b98a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +.gradle +build/ +dist diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF deleted file mode 100644 index 20f7a4d..0000000 --- a/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Plugin-Main-Class: plugins.Sharesite.Plugin - diff --git a/Makefile b/Makefile deleted file mode 100644 index 1bc9f9b..0000000 --- a/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -SOURCES:=$(shell find src/ -name *.java) $(shell find src/ -name *.l10n) - -all: dist/.dist-updated - -check-syntax: $(SOURCES) - ant - -check: build.xml $(SOURCES) - ant - -dist/.dist-updated: build.xml build.txt $(SOURCES) - @mkdir -p dist/ - ant clean && ant dist && touch $@ - - diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..6cb2881 --- /dev/null +++ b/build.gradle @@ -0,0 +1,109 @@ +buildscript { + dependencies { + classpath files('gradle/gradle-witness.jar') + } +} + +apply plugin: 'java' +apply plugin: 'witness' +apply plugin: 'maven-publish' + +compileJava { + sourceCompatibility = 1.7 + targetCompatibility = 1.7 +} + +version = "0.4.7" + +repositories { + mavenLocal() + maven { url "http://4thline.org/m2" } + maven { url 'https://mvn.freenetproject.org' } + jcenter() +} + +dependencies { + implementation group: 'net.java', name: 'textile-j', version: '2.2' + implementation group: 'org.freenetproject', name: 'fred', version: 'build+' +} + +dependencyVerification { + verify = [] +} + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributes; + +Date getMTime(String file) { + return new Date(Files.readAttributes(Paths.get(file), BasicFileAttributes.class).lastModifiedTime().toMillis()); +} + +jar { + manifest { + attributes 'Plugin-Main-Class': 'plugins.Sharesite.Plugin', + 'Required-Node-Version': '1472', + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-Date': getMTime("src/main/java/plugins/Sharesite/Plugin.java"), + 'Built-JDK': System.getProperty('java.version') + } + + from("src/main/java") { + include "**/*.l10n" + include "**/*.png" + include "**/*.txt" + include "**/*.html" + include "**/*.css" + } + + preserveFileTimestamps = false + reproducibleFileOrder = true + duplicatesStrategy = "exclude" + archiveName = 'freenet-Sharesite.jar' +} + +def jars = [] +gradle.addListener(new TaskExecutionListener() { +void afterExecute(Task task, TaskState state) { + if(task in AbstractArchiveTask) { + jars << task.outputs.files.singleFile + } +} + +void beforeExecute(Task task) { } +}) +gradle.addBuildListener(new BuildAdapter() { + void buildFinished(BuildResult result) { + if(jars) { + def hash = { + File file -> def sha256 = java.security.MessageDigest.getInstance('SHA-256') + file.eachByte(1024 * 4) { buffer, len -> sha256.update(buffer, 0, len) } + println "SHA-256 of ${file.name}: ${sha256.digest().encodeHex().toString()}" + } + + jars.each { hash(it) } + } + } +}) + +publishing { + publications { + mavenJava(MavenPublication) { + groupId 'org.freenetproject.plugins' + artifactId "Sharesite" + version version + from components.java + } + } + repositories { + maven { + url "s3://mvn.freenetproject.org/" + credentials(AwsCredentials) { + accessKey System.getenv('AWS_ACCESS_KEY_ID') + secretKey System.getenv('AWS_SECRET_ACCESS_KEY') + } + } + } +} diff --git a/build.txt b/build.txt deleted file mode 100644 index 45b9843..0000000 --- a/build.txt +++ /dev/null @@ -1,3 +0,0 @@ -#Build Number for ANT. Do not edit! -#Sat Dec 01 23:09:28 CET 2018 -build.number=79 diff --git a/build.xml b/build.xml deleted file mode 100644 index 23a9500..0000000 --- a/build.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gradle/gradle-witness.jar b/gradle/gradle-witness.jar new file mode 100644 index 0000000000000000000000000000000000000000..1006badec20c807813445f66c246554bd131963e GIT binary patch literal 23967 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 z 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 OPy1D^?J61x>3;w)FvMd3 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..94336fcae912db8a11d55634156fa011f4686124 GIT binary patch literal 56177 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 i;x|p)^~-yfPOPa3(|vBayXKz \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/build.sh b/src/build.sh deleted file mode 100644 index 69be927..0000000 --- a/src/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# It is assumed the Java Compiler from OpenJDK 7 is used. -# The produced jar file will run on both Java 6 and Java 7. - -rm plugins/Sharesite/*.class plugins/Sharesite/*/*.class -rm Sharesite*.jar - -javac -cp ../freenet-ext.jar:../freenet.jar -source 1.6 -target 1.6 plugins/Sharesite/*.java plugins/Sharesite/*/*.java -zip -r Sharesite.jar * diff --git a/src/plugins/Sharesite/ActivelinkCreator.java b/src/main/java/plugins/Sharesite/ActivelinkCreator.java similarity index 100% rename from src/plugins/Sharesite/ActivelinkCreator.java rename to src/main/java/plugins/Sharesite/ActivelinkCreator.java diff --git a/src/plugins/Sharesite/Database.java b/src/main/java/plugins/Sharesite/Database.java similarity index 100% rename from src/plugins/Sharesite/Database.java rename to src/main/java/plugins/Sharesite/Database.java diff --git a/src/plugins/Sharesite/Freesite.java b/src/main/java/plugins/Sharesite/Freesite.java similarity index 98% rename from src/plugins/Sharesite/Freesite.java rename to src/main/java/plugins/Sharesite/Freesite.java index 977c3c6..64ab0b3 100644 --- a/src/plugins/Sharesite/Freesite.java +++ b/src/main/java/plugins/Sharesite/Freesite.java @@ -56,8 +56,8 @@ public Freesite(int uniqueKey) { description = "Write a short description shown in search results here."; activelinkUri = ""; - String csstemplate = "/templates/style.css"; - String texttemplate = "/templates/content.txt"; + String csstemplate = "resources/templates/style.css"; + String texttemplate = "resources/templates/content.txt"; try ( InputStream is = Plugin.class.getClassLoader().getResourceAsStream(csstemplate); @@ -245,7 +245,7 @@ public synchronized String getHTML() throws Exception { String insertDate = dateFormat.format(calendar.getTime()); // Pass through the HTML file, substituting in the real content - String template = "/templates/index.html"; + String template = "resources/templates/index.html"; InputStream is = Plugin.class.getClassLoader().getResourceAsStream(template); if (is == null) throw new Exception("Couldn't load \"" + template + "\""); diff --git a/src/plugins/Sharesite/Inserter.java b/src/main/java/plugins/Sharesite/Inserter.java similarity index 100% rename from src/plugins/Sharesite/Inserter.java rename to src/main/java/plugins/Sharesite/Inserter.java diff --git a/src/plugins/Sharesite/Plugin.java b/src/main/java/plugins/Sharesite/Plugin.java similarity index 97% rename from src/plugins/Sharesite/Plugin.java rename to src/main/java/plugins/Sharesite/Plugin.java index 8d8a1f5..26c7483 100644 --- a/src/plugins/Sharesite/Plugin.java +++ b/src/main/java/plugins/Sharesite/Plugin.java @@ -14,8 +14,6 @@ import freenet.pluginmanager.PluginRespirator; import freenet.support.Ticker; -import java.awt.GraphicsEnvironment; - /** * This is the main class, the first one executed by Freenet. * Only one instance exists, and can be accessed from anywhere using @@ -41,6 +39,7 @@ public class Plugin implements FredPlugin, FredPluginVersioned, FredPluginRealVe public Plugin() { instance = this; + setLanguage(LANGUAGE.ENGLISH); } @Override @@ -99,7 +98,7 @@ public void setLanguage(LANGUAGE newLanguage) { @Override public String getL10nFilesBasePath() { - return "plugins/Sharesite/l10n/"; + return "resources/l10n/"; } @Override diff --git a/src/plugins/Sharesite/common/FileStorage.java b/src/main/java/plugins/Sharesite/common/FileStorage.java similarity index 100% rename from src/plugins/Sharesite/common/FileStorage.java rename to src/main/java/plugins/Sharesite/common/FileStorage.java diff --git a/src/plugins/Sharesite/common/Logger.java b/src/main/java/plugins/Sharesite/common/Logger.java similarity index 100% rename from src/plugins/Sharesite/common/Logger.java rename to src/main/java/plugins/Sharesite/common/Logger.java diff --git a/src/plugins/Sharesite/common/MapToData.java b/src/main/java/plugins/Sharesite/common/MapToData.java similarity index 100% rename from src/plugins/Sharesite/common/MapToData.java rename to src/main/java/plugins/Sharesite/common/MapToData.java diff --git a/src/plugins/Sharesite/common/SmartMap.java b/src/main/java/plugins/Sharesite/common/SmartMap.java similarity index 100% rename from src/plugins/Sharesite/common/SmartMap.java rename to src/main/java/plugins/Sharesite/common/SmartMap.java diff --git a/src/plugins/Sharesite/webui/EditToadlet.java b/src/main/java/plugins/Sharesite/webui/EditToadlet.java similarity index 100% rename from src/plugins/Sharesite/webui/EditToadlet.java rename to src/main/java/plugins/Sharesite/webui/EditToadlet.java diff --git a/src/plugins/Sharesite/webui/HomeToadlet.java b/src/main/java/plugins/Sharesite/webui/HomeToadlet.java similarity index 100% rename from src/plugins/Sharesite/webui/HomeToadlet.java rename to src/main/java/plugins/Sharesite/webui/HomeToadlet.java diff --git a/src/plugins/Sharesite/webui/PreviewToadlet.java b/src/main/java/plugins/Sharesite/webui/PreviewToadlet.java similarity index 100% rename from src/plugins/Sharesite/webui/PreviewToadlet.java rename to src/main/java/plugins/Sharesite/webui/PreviewToadlet.java diff --git a/src/plugins/Sharesite/webui/WebInterface.java b/src/main/java/plugins/Sharesite/webui/WebInterface.java similarity index 100% rename from src/plugins/Sharesite/webui/WebInterface.java rename to src/main/java/plugins/Sharesite/webui/WebInterface.java diff --git a/src/plugins/Sharesite/l10n/lang_en.l10n b/src/main/java/resources/l10n/lang_en.l10n similarity index 100% rename from src/plugins/Sharesite/l10n/lang_en.l10n rename to src/main/java/resources/l10n/lang_en.l10n diff --git a/rez/templates/activelink.png b/src/main/java/resources/templates/activelink.png similarity index 100% rename from rez/templates/activelink.png rename to src/main/java/resources/templates/activelink.png diff --git a/rez/templates/content.txt b/src/main/java/resources/templates/content.txt similarity index 100% rename from rez/templates/content.txt rename to src/main/java/resources/templates/content.txt diff --git a/rez/templates/index.html b/src/main/java/resources/templates/index.html similarity index 100% rename from rez/templates/index.html rename to src/main/java/resources/templates/index.html diff --git a/rez/templates/style.css b/src/main/java/resources/templates/style.css similarity index 100% rename from rez/templates/style.css rename to src/main/java/resources/templates/style.css diff --git a/src/net/java/textilej/TextileJPlugin.java b/src/net/java/textilej/TextileJPlugin.java deleted file mode 100644 index df21b25..0000000 --- a/src/net/java/textilej/TextileJPlugin.java +++ /dev/null @@ -1,266 +0,0 @@ -package net.java.textilej; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.validation.MarkupValidator; -import net.java.textilej.validation.ValidationRule; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.osgi.framework.BundleContext; - - -public class TextileJPlugin extends Plugin { - - private static final String EXTENSION_MARKUP_DIALECT = "markupDialect"; - - private static final String EXTENSION_VALIDATION_RULES = "markupValidationRule"; - - private static TextileJPlugin plugin; - - private SortedMap> dialectByName; - private Map> dialectByFileExtension; - - private Map> validationRulesByDialectName; - - public TextileJPlugin() { - } - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - @Override - public void stop(BundleContext context) throws Exception { - if (plugin == this) { - plugin = null; - } - super.stop(context); - } - - public static TextileJPlugin getDefault() { - return plugin; - } - - /** - * Get a dialect by name. - * - * @param name the name of the dialect to retrieve - * - * @return the dialect or null if there is no dialect known by the given name - * - * @see #getDialectNames() - */ - public Dialect getDialect(String name) { - if (dialectByName == null) { - initializeDialects(); - } - Class dialectClass = dialectByName.get(name); - if (dialectClass != null) { - return instantiateDialect(name, dialectClass); - } - return null; - } - - private Dialect instantiateDialect(String name, Class dialectClass) { - try { - Dialect dialect = dialectClass.newInstance(); - dialect.setName(name); - return dialect; - } catch (Exception e) { - log(IStatus.ERROR,String.format("Cannot instantiate dialect '%' (class '%s'): %s",name,dialectClass.getName(),e.getMessage()),e); - } - return null; - } - - /** - * Get a dialect for a file. A dialect is selected based on the registered dialects and their - * expected file extensions. - * - * @param name the name of the file for which a dialect is desired - * - * @return the dialect, or null if no dialect is registered for the specified file name - */ - public Dialect getDialectForFilename(String name) { - if (dialectByFileExtension == null) { - initializeDialects(); - } - int lastIndexOfDot = name.lastIndexOf('.'); - String extension = lastIndexOfDot==-1?name:name.substring(lastIndexOfDot+1); - Class dialectClass = dialectByFileExtension.get(extension); - if (dialectClass != null) { - String dialectName = null; - for (Map.Entry> ent: dialectByName.entrySet()) { - if (ent.getValue() == dialectClass) { - dialectName = ent.getKey(); - break; - } - } - return instantiateDialect(dialectName, dialectClass); - } - return null; - } - - /** - * Get the names of all dialects - * - * @see #getDialect(String) - */ - public Set getDialectNames() { - if (dialectByName == null) { - initializeDialects(); - } - return dialectByName.keySet(); - } - - /** - * Get a markup validator by dialect name. - * - * @param name the name of the dialect for which a validator is desired - * - * @return the markup validator - * - * @see #getDialectNames() - */ - public MarkupValidator getMarkupValidator(String name) { - MarkupValidator markupValidator = new MarkupValidator(); - - if (validationRulesByDialectName == null) { - initializeValidationRules(); - } - List rules = validationRulesByDialectName.get(name); - if (rules != null) { - markupValidator.getRules().addAll(rules); - } - - return markupValidator; - } - - private void initializeValidationRules() { - initializeDialects(); - synchronized (this) { - if (validationRulesByDialectName == null) { - Map> validationRulesByDialectName = new HashMap>(); - - IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(getPluginId(), EXTENSION_VALIDATION_RULES); - if (extensionPoint != null) { - IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements(); - for (IConfigurationElement element: configurationElements) { - try { - String markupLanguage = element.getAttribute("markupLanguage"); - if (markupLanguage == null || markupLanguage.length() == 0) { - throw new Exception("Must specify markupLanguage"); - } - if (!dialectByName.containsKey(markupLanguage)) { - throw new Exception(String.format("'%s' is not a valid markupLanguage",dialectByName)); - } - Object extension; - try { - extension = element.createExecutableExtension("class"); - } catch (CoreException e) { - getLog().log(e.getStatus()); - continue; - } - if (!(extension instanceof ValidationRule)) { - throw new Exception(String.format("%s is not a validation rule",extension.getClass().getName())); - } - List rules = validationRulesByDialectName.get(markupLanguage); - if (rules == null) { - rules = new ArrayList(); - validationRulesByDialectName.put(markupLanguage, rules); - } - rules.add((ValidationRule) extension); - } catch (Exception e) { - log(IStatus.ERROR,String.format("Plugin '%s' extension '%s' invalid: %s",element.getDeclaringExtension().getContributor().getName(),EXTENSION_VALIDATION_RULES,e.getMessage()),e); - } - } - } - - this.validationRulesByDialectName = validationRulesByDialectName; - } - } - } - - private void initializeDialects() { - synchronized (this) { - if (this.dialectByName == null) { - SortedMap> dialectByName = new TreeMap>(); - Map> dialectByFileExtension = new HashMap>(); - - IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(getPluginId(), EXTENSION_MARKUP_DIALECT); - if (extensionPoint != null) { - IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements(); - for (IConfigurationElement element: configurationElements) { - String name = element.getAttribute("name"); - if (name == null || name.length() == 0) { - log(IStatus.ERROR,String.format(EXTENSION_MARKUP_DIALECT+"/@name must be specified by plugin '%s'",element.getDeclaringExtension().getContributor().getName())); - continue; - } - Object dialect; - try { - dialect = element.createExecutableExtension("class"); - } catch (CoreException e) { - getLog().log(e.getStatus()); - continue; - } - if (!(dialect instanceof Dialect)) { - log(IStatus.ERROR,String.format("%s is not a dialect",dialect.getClass().getName())); - continue; - } - Dialect d = (Dialect) dialect; - { - Class previous = dialectByName.put(name, d.getClass()); - if (previous != null) { - log(IStatus.ERROR,String.format(EXTENSION_MARKUP_DIALECT+"/@name '%s' specified by plugin '%s' is ignored: name '%s' is already registered",name,element.getDeclaringExtension().getContributor().getName(),name)); - dialectByName.put(name, previous); - continue; - } - } - String fileExtensions = element.getAttribute("fileExtensions"); - if (fileExtensions != null) { - String[] parts = fileExtensions.split("\\s*,\\s*"); - for (String part: parts) { - if (part.length() != 0) { - Class previous = dialectByFileExtension.put(part, d.getClass()); - if (previous != null) { - log(IStatus.ERROR,String.format(EXTENSION_MARKUP_DIALECT+"/@fileExtensions '%s' specified by plugin '%s' is ignored: extension '%s' is already registered",part,element.getDeclaringExtension().getContributor().getName(),part)); - dialectByFileExtension.put(part, previous); - continue; - } - } - } - } - } - } - - this.dialectByFileExtension = dialectByFileExtension; - this.dialectByName = dialectByName; - } - } - } - - public void log(int severity, String message) { - log(severity,message,null); - } - - public void log(int severity, String message, Throwable t) { - getLog().log(new Status(severity,getPluginId(),message,t)); - } - - public String getPluginId() { - return getBundle().getSymbolicName(); - } -} diff --git a/src/net/java/textilej/parser/Attributes.java b/src/net/java/textilej/parser/Attributes.java deleted file mode 100644 index 0973f5d..0000000 --- a/src/net/java/textilej/parser/Attributes.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * - */ -package net.java.textilej.parser; - -/** - * Attributes for a markup element - * - * @author dgreen - */ -public class Attributes { - - private String cssClass; - private String id; - private String cssStyle; - private String language; - private String title; - - public Attributes() {} - - - public Attributes(String id, String cssClass, String cssStyle, - String language) { - this.id = id; - this.cssClass = cssClass; - this.cssStyle = cssStyle; - this.language = language; - } - - public String getCssClass() { - return cssClass; - } - public void setCssClass(String cssClass) { - this.cssClass = cssClass; - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getCssStyle() { - return cssStyle; - } - public void setCssStyle(String cssStyle) { - this.cssStyle = cssStyle; - } - public String getLanguage() { - return language; - } - public void setLanguage(String language) { - this.language = language; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - -} \ No newline at end of file diff --git a/src/net/java/textilej/parser/DocumentBuilder.java b/src/net/java/textilej/parser/DocumentBuilder.java deleted file mode 100644 index 686326a..0000000 --- a/src/net/java/textilej/parser/DocumentBuilder.java +++ /dev/null @@ -1,294 +0,0 @@ -package net.java.textilej.parser; - - -/** - * The 'Builder' design pattern, for documents. Implementations can build a specific kind of document - * (such as HTML, or DocBook). - *

- * Note that many methods take {@link Attributes} to specify attributes of the element, - * however most of these methods may take a more specific subclass of {@link Attributes}. - *

- * - * - * @author dgreen - * - */ -public abstract class DocumentBuilder { - - protected Locator locator; - - public enum BlockType { - PARAGRAPH, - /** - * A text box that contains a helpful tip - */ - TIP, - /** - * A text box that contains a warning - */ - WARNING, - /** - * A text box that contains information - */ - INFORMATION, - /** - * A text box that contains a note - */ - NOTE, - /** - * A text box - */ - PANEL, - FOOTNOTE, - QUOTE, - CODE, - PREFORMATTED, - NUMERIC_LIST, - BULLETED_LIST, - LIST_ITEM, - TABLE, - TABLE_ROW, - TABLE_CELL_HEADER, - TABLE_CELL_NORMAL, - DEFINITION_LIST, - DEFINITION_TERM, - DEFINITION_ITEM; - - } - - public enum SpanType { - EMPHASIS, - STRONG, - ITALIC, - BOLD, - CITATION, - DELETED, - INSERTED, - SUPERSCRIPT, - SUBSCRIPT, - SPAN, - CODE, - MONOSPACE, - UNDERLINED - } - - /** - * Begin a document. Calling this method is optional for some builders, however if called then it must be matched by a - * corresponding call to {@link #endDocument()}. - * - * @see #endDocument() - */ - public abstract void beginDocument(); - - /** - * End a document. - * - * @see #endDocument() - */ - public abstract void endDocument(); - - /** - * Begin a block of the specified type. - * - * Builder implementations may do a best-effort application of the provided attributes. - * Note that the provided attributes *may* be a subclass of the {@link Attributes} class, in which case the builder may attempt - * to apply the attributes specified. Builders may choose to ignore attributes, and should fail silently if the given attributes - * are not as expected. - * - * Each call to this method must be matched by a corresponding call to {@link #endBlock()}. - * - * @param type - * @param attributes the attributes to apply to the block. Callers may choose to specify a more specialized set of attributes by - * providing a subclass instance. - * - * @see #endBlock() - */ - public abstract void beginBlock(BlockType type,Attributes attributes); - - /** - * End a block that was {@link #beginBlock(net.java.textilej.parser.DocumentBuilder.BlockType, Attributes) started}. - */ - public abstract void endBlock(); - - /** - * Begin a span of the specified type. - * - * Builder implementations may do a best-effort application of the provided attributes. - * - * Each call to this method must be matched by a corresponding call to {@link #endSpan()}. - * - * @param type - * @param attributes the attributes to apply to the span - * - * @see #endSpan() - */ - public abstract void beginSpan(SpanType type,Attributes attributes); - - /** - * End a span that was {@link #beginSpan(net.java.textilej.parser.DocumentBuilder.SpanType, Attributes) started}. - * - * @see #beginSpan(net.java.textilej.parser.DocumentBuilder.SpanType, Attributes) - */ - public abstract void endSpan(); - - /** - * Begin a heading of the specified level (usually 1-6). - * - * Builder implementations may do a best-effort application of the provided attributes. - * - * Each call to this method must be matched by a corresponding call to {@link #endHeading()}. - * - * @param level the level of the heading, usually 1-6 - * @param attributes the attributes to apply to the heading - * - * @see #endHeading() - */ - public abstract void beginHeading(int level,Attributes attributes); - - /** - * End a span that was {@link #beginHeading(int, Attributes) started}. - * - * @see #beginHeading(int, Attributes) - */ - public abstract void endHeading(); - - /** - * Emit the given text as characters where special characters are encoded according to the output format rules. - * - * @param text the text to emit. - */ - public abstract void characters(String text); - - /** - * An XML entity reference. - * - * @param entity the entity - */ - public abstract void entityReference(String entity); - - /** - * Build the image with the given attributes - * - * @param attributes the attributes, which may be an {@link ImageAttributes}. - * @param url the URL to the image, possibly relative - */ - public abstract void image(Attributes attributes,String url); - - /** - * Create a hyperlink to the given url - * - * @param attributes the attributes of the link - * @param hrefOrHashName the url (which may be internal to the page if prefixed with a hash '#') - * @param text the text of the hyperlink - */ - public abstract void link(Attributes attributes,String hrefOrHashName,String text); - - /** - * Create a hyperlink to the given url - * - * @param attributes the attributes of the link - * @param hrefOrHashName the url (which may be internal to the page if prefixed with a hash '#') - * @param text the text of the hyperlink - * @param title the title or alternative text which is typically displayed on mouse hover - * - * @deprecated please use {@link #link(Attributes, String, String)} instead and place the title in the {@link Attributes#getTitle() attributes title}. - */ - @Deprecated - public final void link(Attributes attributes,String hrefOrHashName,String text,String title) { - attributes.setTitle(title); - link(attributes,hrefOrHashName,text); - } - - /** - * Create a hyperlink whose visual representation is an image. Implementations must apply - * the attributes to the image tag. For example, if the builder constructs HTML, the - * builder would emit <a href="..."><img src="..."/></a>. In this case if the attributes define - * a css class then the resulting HTML should look like this: <a href="..."><img src="..." class="..."/></a> - * - * @param linkAttributes the attributes of the link, which may be {@link LinkAttributes} - * @param imageAttributes the attributes of the image , which may be {@link ImageAttributes} - * @param href the url (which may be internal to the page if prefixed with a hash '#') - * @param imageUrl the url of the image, which may be relative - */ - public abstract void imageLink(Attributes linkAttributes, Attributes imageAttributes, String href, String imageUrl); - - /** - * Create a hyperlink whose visual representation is an image. Implementations must apply - * the attributes to the image tag. For example, if the builder constructs HTML, the - * builder would emit <a href="..."><img src="..."/></a>. In this case if the attributes define - * a css class then the resulting HTML should look like this: <a href="..."><img src="..." class="..."/></a> - * - * @param attributes the attributes of the image, which may be {@link ImageAttributes} - * @param href the url (which may be internal to the page if prefixed with a hash '#') - * @param imageUrl the url of the image, which may be relative - * - * @see #imageLink(Attributes, Attributes, String, String) - */ - public final void imageLink(Attributes attributes,String href,String imageUrl) { - imageLink(new LinkAttributes(),attributes,href,imageUrl); - } - - - /** - * @see #link(Attributes, String, String) - */ - public final void link(String hrefOrHashName,String text) { - link(new LinkAttributes(), hrefOrHashName, text); - } - /** - * @see #link(Attributes, String, String, String) - * - * @deprecated use {@link #link(Attributes, String, String)} instead and place the title in the {@link Attributes#getTitle() attributes title}. - */ - @Deprecated - public final void link(String hrefOrHashName,String text,String title) { - Attributes attributes = new LinkAttributes(); - attributes.setTitle(title); - link(attributes, hrefOrHashName, text); - } - /** - * @see #imageLink(Attributes, String, String) - */ - public final void imageLink(String href,String imageUrl) { - imageLink(new LinkAttributes(), new ImageAttributes(), href, imageUrl); - } - - - /** - * Emit an acronym - * - * @param text the acronym to emit - * @param definition the definition of the acronym, which is typically displayed on mouse hover - */ - public abstract void acronym(String text,String definition); - - /** - * Create a line break (eg: br in html). Not all builders need support line breaks. - */ - public abstract void lineBreak(); - /** - * Create unescaped characters, usually with some embedded HTML markup. Note that using this method - * causes the output to be HTML-centric - * - * @param literal the literal characters to emit - */ - public abstract void charactersUnescaped(String literal); - - /** - * Set the locator for the current session - * - * @param locator the locator that provides information about the current location in the markup - */ - public void setLocator(Locator locator) { - this.locator = locator; - } - - /** - * The locator for the current session - */ - public Locator getLocator() { - return locator; - } - - -} diff --git a/src/net/java/textilej/parser/IdGenerator.java b/src/net/java/textilej/parser/IdGenerator.java deleted file mode 100644 index 9901596..0000000 --- a/src/net/java/textilej/parser/IdGenerator.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.java.textilej.parser; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class IdGenerator { - - private Map idGenerators = new HashMap(); - private Set anchorNames = new HashSet(); - - public String newId(String type, String text) { - if (type == null) { - type = ""; - } - Integer current = idGenerators.get(type); - if (current == null) { - current = 0; - } - current = current + 1; - - idGenerators.put(type, current); - - String id = null; - if (text != null) { - id = convertToAnchor(text.trim()); - if (id.length() == 0) { - id = type+'-'+current; - } - } else { - id = type+'-'+current; - } - String template = id; - int suffix = 1; - while (!anchorNames.add(id)) { - id = template + (++suffix); - } - return id; - } - - private String convertToAnchor(String text) { - String anchor = text.replaceAll("[^a-zA-Z0-9]", ""); - if (anchor.length() > 0 && Character.isDigit(anchor.charAt(0))) { - anchor = 'a'+anchor; - } - return anchor; - } -} diff --git a/src/net/java/textilej/parser/ImageAttributes.java b/src/net/java/textilej/parser/ImageAttributes.java deleted file mode 100644 index 84d96b5..0000000 --- a/src/net/java/textilej/parser/ImageAttributes.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.java.textilej.parser; - -/** - * Attributes for images. - * - * @author dgreen - */ -public class ImageAttributes extends Attributes { - - public enum Align { - Left, Right, Top, Texttop, Middle, Absmiddle, Baseline, Bottom, Absbottom, Center - } - - private int width = -1; - private int height = -1; - private int border = 0; - private Align align = null; - private String alt; - - - public String getAlt() { - return alt; - } - public void setAlt(String alt) { - this.alt = alt; - } - public int getWidth() { - return width; - } - public void setWidth(int width) { - this.width = width; - } - public int getHeight() { - return height; - } - public void setHeight(int height) { - this.height = height; - } - public int getBorder() { - return border; - } - public void setBorder(int border) { - this.border = border; - } - public Align getAlign() { - return align; - } - public void setAlign(Align align) { - this.align = align; - } -} diff --git a/src/net/java/textilej/parser/LinkAttributes.java b/src/net/java/textilej/parser/LinkAttributes.java deleted file mode 100644 index 34b32f7..0000000 --- a/src/net/java/textilej/parser/LinkAttributes.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.java.textilej.parser; - -import net.java.textilej.parser.builder.HtmlDocumentBuilder; - -/** - * Attributes for links (hyperlinks) - * - * @author dgreen - * @author draft - */ -public class LinkAttributes extends Attributes { - private String target; - private String rel; - - /** - * The target of a link, as defined by the HTML spec. - * - * @param target - * the target or null if there should be none - */ - public void setTarget(String target) { - this.target = target; - } - - /** - * The target of a link, as defined by the HTML spec. - * - * @return the target or null if there should be none - */ - public String getTarget() { - return target; - } - - /** - * The 'rel' of a link, as defined by the HTML spec. - * - * @return the rel or null if there should be none - * - * @see HtmlDocumentBuilder#getLinkRef() - */ - public String getRel() { - return rel; - } - - /** - * The 'rel' of a link, as defined by the HTML spec. - * - * @param rel - * the rel or null if there should be none - * - * @see HtmlDocumentBuilder#setLinkRel(String) - */ - public void setRel(String rel) { - this.rel = rel; - } - -} diff --git a/src/net/java/textilej/parser/ListAttributes.java b/src/net/java/textilej/parser/ListAttributes.java deleted file mode 100644 index 455c43a..0000000 --- a/src/net/java/textilej/parser/ListAttributes.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.java.textilej.parser; - -public class ListAttributes extends Attributes { - - private String start; - - public String getStart() { - return start; - } - - public void setStart(String start) { - this.start = start; - } - - -} diff --git a/src/net/java/textilej/parser/Locator.java b/src/net/java/textilej/parser/Locator.java deleted file mode 100644 index 66fbb4d..0000000 --- a/src/net/java/textilej/parser/Locator.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.java.textilej.parser; - -/** - * An interface that provides information about the location of the current parser activity. - * Note that parsers may make a best-effort attempt at determining the location. - * - * @author dgreen - */ -public interface Locator { - /** - * get the 1-based number of the current line. - * - * @return the line number or -1 if unknown - */ - public int getLineNumber(); - - /** - * get the 0-based character offset of the current line from the start of the document - * - * @return the offset or -1 if unknown - */ - public int getLineDocumentOffset(); - - /** - * get the 0-based character offset of the current character from the start of the document. - * Equivalent to getLineDocumentOffset()+getLineCharacterOffset() - */ - public int getDocumentOffset(); - - /** - * get the length of the current line in characters, not including the line terminator - */ - public int getLineLength(); - - /** - * get the 0-based offset of the current character in the current line - */ - public int getLineCharacterOffset(); - - /** - * Get the 0-based offset of the end of the current line segment being processed, exclusive. - * - * Generally a phrase modifier starts at {@link #getLineCharacterOffset()} and ends on - * the character preceding this offset, [s,e) where s is the start and e is the end. - */ - public int getLineSegmentEndOffset(); -} diff --git a/src/net/java/textilej/parser/MarkupParser.java b/src/net/java/textilej/parser/MarkupParser.java deleted file mode 100644 index e7274ce..0000000 --- a/src/net/java/textilej/parser/MarkupParser.java +++ /dev/null @@ -1,114 +0,0 @@ -package net.java.textilej.parser; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringWriter; - -import net.java.textilej.parser.builder.HtmlDocumentBuilder; -import net.java.textilej.parser.markup.Dialect; - -/** - * A markup processor that can process text markup formats such as Textile. - * - * @author dgreen - * - */ -public class MarkupParser { - - private Dialect dialect; - private DocumentBuilder builder; - - public MarkupParser() {} - - public MarkupParser(Dialect dialect, DocumentBuilder builder) { - this.dialect = dialect; - this.builder = builder; - } - - public MarkupParser(Dialect dialect) { - this.dialect = dialect; - } - - /** - * the dialect of the markup to process - */ - public Dialect getDialect() { - return dialect; - } - - /** - * set the dialect of the markup to process - */ - public void setDialect(Dialect dialect) { - this.dialect = dialect; - } - - /** - * the builder to which parse results are propagated - */ - public DocumentBuilder getBuilder() { - return builder; - } - - /** - * set the builder to which parse results are propagated - */ - public void setBuilder(DocumentBuilder builder) { - this.builder = builder; - } - - public void parse(Reader markupContent) throws IOException { - parse(markupContent,true); - } - - public void parse(Reader markupContent,boolean asDocument) throws IOException { - parse(readFully(markupContent),asDocument); - } - - public void parse(String markupContent) { - parse(markupContent,true); - } - - public void parse(String markupContent,boolean asDocument) { - if (dialect == null) { - throw new IllegalStateException("markup dialect is not set"); - } - if (builder == null) { - throw new IllegalStateException("builder is not set"); - } - dialect.processContent(this,markupContent,asDocument); - } - - private String readFully(Reader reader) throws IOException { - StringWriter writer = new StringWriter(); - int c; - while ((c = reader.read()) != -1) { - writer.write(c); - } - return writer.toString(); - } - - - /** - * parse the given markup content and produce the result as an HTML document. - * - * @param markupContent the textile to parse - * - * @return the HTML document text. - */ - public String parseToHtml(String markupContent) { - if (builder != null) { - throw new IllegalStateException("Builder must not be set"); - } - - StringWriter out = new StringWriter(); - - setBuilder(new HtmlDocumentBuilder(out)); - - parse(markupContent); - - setBuilder(null); - - return out.toString(); - } -} diff --git a/src/net/java/textilej/parser/QuoteAttributes.java b/src/net/java/textilej/parser/QuoteAttributes.java deleted file mode 100644 index 60d7662..0000000 --- a/src/net/java/textilej/parser/QuoteAttributes.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.java.textilej.parser; - -/** - * Attributes for block quotes. - * - * @author dgreen - * - */ -public class QuoteAttributes extends Attributes { - private String citation; - - public String getCitation() { - return citation; - } - - public void setCitation(String citation) { - this.citation = citation; - } - -} diff --git a/src/net/java/textilej/parser/TableAttributes.java b/src/net/java/textilej/parser/TableAttributes.java deleted file mode 100644 index 8675ee0..0000000 --- a/src/net/java/textilej/parser/TableAttributes.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.java.textilej.parser; - - -public class TableAttributes extends Attributes { - - private String border; - private String summary; - private String width; - private String frame; - private String rules; - private String cellspacing; - private String cellpadding; - private String bgcolor; - - public String getBorder() { - return border; - } - public void setBorder(String border) { - this.border = border; - } - public String getSummary() { - return summary; - } - public void setSummary(String summary) { - this.summary = summary; - } - public String getWidth() { - return width; - } - public void setWidth(String width) { - this.width = width; - } - public String getFrame() { - return frame; - } - public void setFrame(String frame) { - this.frame = frame; - } - public String getRules() { - return rules; - } - public void setRules(String rules) { - this.rules = rules; - } - public String getCellspacing() { - return cellspacing; - } - public void setCellspacing(String cellspacing) { - this.cellspacing = cellspacing; - } - public String getCellpadding() { - return cellpadding; - } - public void setCellpadding(String cellpadding) { - this.cellpadding = cellpadding; - } - public String getBgcolor() { - return bgcolor; - } - public void setBgcolor(String bgcolor) { - this.bgcolor = bgcolor; - } - - -} diff --git a/src/net/java/textilej/parser/TableCellAttributes.java b/src/net/java/textilej/parser/TableCellAttributes.java deleted file mode 100644 index 20f00ce..0000000 --- a/src/net/java/textilej/parser/TableCellAttributes.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.java.textilej.parser; - -public class TableCellAttributes extends Attributes { - private String bgcolor; - private String align; - private String valign; - private String rowspan; - private String colspan; - - public String getBgcolor() { - return bgcolor; - } - public void setBgcolor(String bgcolor) { - this.bgcolor = bgcolor; - } - public String getAlign() { - return align; - } - public void setAlign(String align) { - this.align = align; - } - public String getValign() { - return valign; - } - public void setValign(String valign) { - this.valign = valign; - } - public String getRowspan() { - return rowspan; - } - public void setRowspan(String rowspan) { - this.rowspan = rowspan; - } - public String getColspan() { - return colspan; - } - public void setColspan(String colspan) { - this.colspan = colspan; - } - -} diff --git a/src/net/java/textilej/parser/TableRowAttributes.java b/src/net/java/textilej/parser/TableRowAttributes.java deleted file mode 100644 index 9e94c8d..0000000 --- a/src/net/java/textilej/parser/TableRowAttributes.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.java.textilej.parser; - -public class TableRowAttributes extends Attributes { - private String bgcolor; - private String align; - private String valign; - - public String getBgcolor() { - return bgcolor; - } - public void setBgcolor(String bgcolor) { - this.bgcolor = bgcolor; - } - public String getAlign() { - return align; - } - public void setAlign(String align) { - this.align = align; - } - public String getValign() { - return valign; - } - public void setValign(String valign) { - this.valign = valign; - } - -} diff --git a/src/net/java/textilej/parser/TextileParser.java b/src/net/java/textilej/parser/TextileParser.java deleted file mode 100644 index 3d717fe..0000000 --- a/src/net/java/textilej/parser/TextileParser.java +++ /dev/null @@ -1,93 +0,0 @@ -package net.java.textilej.parser; - -import java.io.StringWriter; - -import net.java.textilej.parser.builder.HtmlDocumentBuilder; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.markup.textile.TextileDialect; - -/** - * A parser that parses basic
Textile markup and converts it to HTML. - * - * Based on the spec available at http://textile.thresholdstate.com/, - * supports basic phrase modifiers, block modifiers, attributes, footnotes, and some punctuation. - * - * Additionally supported are {toc} and {glossary}. - * - * The supported syntax of the parser may be augmented by {@link #setDialect(Dialect) setting a dialect}. - * Without adding a dialect the base syntax of the parser supports true Textile markup, with the addition of the following: - *
    - *
  1. Support for {toc} and {glossary}
  2. - *
  3. lists that start with '-'
  4. - *
  5. Confluence-style table headers
  6. - *
- * - * @author dgreen - * - * @deprecated use {@link MarkupParser} - */ -@Deprecated -public class TextileParser { - - private DocumentBuilder builder; - - /** - * parse the given textile string and produce the result as an HTML document. - * - * @param textile the textile to parse - * - * @return the HTML document text. - */ - public String parseToHtml(String textile) { - if (builder != null) { - throw new IllegalStateException("parseToHtml cannot be called if builder is set"); - } - StringWriter out = new StringWriter(); - setBuilder(new HtmlDocumentBuilder(out)); - parse(textile); - setBuilder(null); - return out.toString(); - } - - - /** - * parse the given Textile markup string and emit the results as an HTML document to - * the given writer. The given writer is closed upon return of this function. - * - * @param textile the Textile markup - */ - public void parse(String textile) { - parse(textile,true); - } - - /** - * parse the given Textile markup string and emit the results as an HTML document to - * the given writer. The given writer is closed upon return of this function. - * - * if asDocument is specified, the {@link #getBuilder() builder} is treated as a document - * ({@link DocumentBuilder#beginDocument()} and {@link DocumentBuilder#endDocument()} are called). - * - * @param textile the Textile markup - * @param asDocument if true, the {@link #getBuilder() builder} is treated as a document - */ - public void parse(String textile,boolean asDocument) { - if (builder == null) { - throw new IllegalStateException("Must set builder"); - } - - MarkupParser parser = new MarkupParser(); - parser.setDialect(new TextileDialect()); - parser.setBuilder(builder); - parser.parse(textile, asDocument); - } - - - public void setBuilder(DocumentBuilder builder) { - this.builder = builder; - } - - public DocumentBuilder getBuilder() { - return builder; - } - -} diff --git a/src/net/java/textilej/parser/builder/AbstractXmlDocumentBuilder.java b/src/net/java/textilej/parser/builder/AbstractXmlDocumentBuilder.java deleted file mode 100644 index 1fbc334..0000000 --- a/src/net/java/textilej/parser/builder/AbstractXmlDocumentBuilder.java +++ /dev/null @@ -1,108 +0,0 @@ -package net.java.textilej.parser.builder; - -import java.io.Writer; -import java.net.URI; -import java.util.regex.Pattern; - -import net.java.textilej.parser.DocumentBuilder; -import net.java.textilej.util.DefaultXmlStreamWriter; -import net.java.textilej.util.XmlStreamWriter; - -public abstract class AbstractXmlDocumentBuilder extends DocumentBuilder { - private static final Pattern ABSOLUTE_URL_PATTERN = Pattern.compile("[a-zA-Z]{3,8}://?.*"); - - protected final XmlStreamWriter writer; - protected URI base; - protected boolean baseInHead = false; - - public AbstractXmlDocumentBuilder(Writer out) { - writer = createXmlStreamWriter(out); - } - - public AbstractXmlDocumentBuilder(XmlStreamWriter writer) { - this.writer = writer; - - } - - protected XmlStreamWriter createXmlStreamWriter(Writer out) { - XmlStreamWriter writer = new DefaultXmlStreamWriter(out); - return writer; - } - - @Override - public void characters(String text) { - writer.writeCharacters(text); - } - protected String makeUrlAbsolute(String url) { - if (base == null || baseInHead || url == null) { - return url; - } - if (ABSOLUTE_URL_PATTERN.matcher(url).matches()) { - return url; - } - if (url.startsWith("#")) { - return url; - } - String absoluteUrl = base.toString(); - if (!absoluteUrl.endsWith("/") && !url.startsWith("/")) { - absoluteUrl = absoluteUrl+'/'; - } - absoluteUrl = absoluteUrl+url; - return absoluteUrl; - } - - /** - * indicate if the given URL is a link to an external source - * - * @param url the URL - * - * @return true if the given URL links to an external source - */ - protected boolean isExternalLink(String url) { - if (url == null) { - return false; - } - if (ABSOLUTE_URL_PATTERN.matcher(url).matches()) { - if (base == null || !url.startsWith(base.toString())) { - return true; - } - } - return false; - } - - /** - * Set the base URI of the HTML document. Causes all relative URLs to be prefixed with the base URI. - * The base URI is assumed to refer to a foler-like resource. - * - * @param uri the URI, or null - */ - public void setBase(URI uri) { - base = uri; - } - - /** - * Get the base URI of the HTML document. A not-null value causes all relative URLs to be prefixed with the base URI. - * The base URI is assumed to refer to a foler-like resource. - */ - public URI getBase() { - return base; - } - - /** - * Indicate if the {@link #getBase() base URI} should be emitted into the <head> of the document. - * The default value is false. - * Ignored unless {@link #isEmitAsDocument()} - */ - public boolean isBaseInHead() { - return baseInHead; - } - - /** - * Indicate if the {@link #getBase() base URI} should be emitted into the <head> of the document. - * The default value is false. - * Ignored unless {@link #isEmitAsDocument()} - */ - public void setBaseInHead(boolean baseInHead) { - this.baseInHead = baseInHead; - } -} diff --git a/src/net/java/textilej/parser/builder/DocBookDocumentBuilder.java b/src/net/java/textilej/parser/builder/DocBookDocumentBuilder.java deleted file mode 100644 index 1de715c..0000000 --- a/src/net/java/textilej/parser/builder/DocBookDocumentBuilder.java +++ /dev/null @@ -1,554 +0,0 @@ -package net.java.textilej.parser.builder; - -import java.io.Writer; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.TreeMap; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.util.FormattingXMLStreamWriter; -import net.java.textilej.util.XmlStreamWriter; - -public class DocBookDocumentBuilder extends AbstractXmlDocumentBuilder { - - private static final Pattern CSS_CLASS_INLINE = Pattern.compile("(^|\\s+)inline(\\s+|$)"); - private static Set entityReferenceToUnicode = new HashSet(); - static { - entityReferenceToUnicode.add(215); - entityReferenceToUnicode.add(8211); - entityReferenceToUnicode.add(8212); - entityReferenceToUnicode.add(8220); - entityReferenceToUnicode.add(8221); - entityReferenceToUnicode.add(8216); - entityReferenceToUnicode.add(8217); - - } - - private String bookTitle; - private String doctype = ""; - - - private Map acronyms = new HashMap(); - - private int headingLevel = 0; - - private Stack blockDescriptions = new Stack(); - - private boolean automaticGlossary = true; - - public DocBookDocumentBuilder(Writer out) { - super(out); - } - - public DocBookDocumentBuilder(XmlStreamWriter writer) { - super(writer); - } - - - protected XmlStreamWriter createFormattingXmlStreamWriter(Writer out) { - XmlStreamWriter writer = super.createXmlStreamWriter(out); - return new FormattingXMLStreamWriter(writer) { - @Override - protected boolean preserveWhitespace(String elementName) { - return elementName.equals("code") || elementName.startsWith("literal"); - } - }; - } - - public String getDoctype() { - return doctype; - } - - public void setDoctype(String doctype) { - this.doctype = doctype; - } - - public String getBookTitle() { - return bookTitle; - } - - public void setBookTitle(String bookTitle) { - this.bookTitle = bookTitle; - } - - - @Override - public void acronym(String text, String definition) { - String previousDef = acronyms.put(text, definition); - if (previousDef != null && previousDef.length() > definition.length()) { - acronyms.put(text,previousDef); - } - writer.writeStartElement("glossterm"); - characters(text); - writer.writeEndElement(); - } - - @Override - public void link(Attributes attributes,String href,final String text) { - link(attributes,href,new ContentEmitter() { - public void emit() { - writer.writeCharacters(text); - } - }); - } - - private void link(Attributes attributes,String href, ContentEmitter emitter) { - ensureBlockElementsOpen(); - if (href.startsWith("#")) { - if (href.length() > 1) { - writer.writeStartElement("link"); - writer.writeAttribute("linkend", href.substring(1)); - emitter.emit(); - writer.writeEndElement(); // link - } else { - emitter.emit(); - } - } else { - writer.writeStartElement("ulink"); - writer.writeAttribute("url", href); - emitter.emit(); - writer.writeEndElement(); // ulink - } - } - - private interface ContentEmitter { - public void emit(); - } - - @Override - public void beginBlock(BlockType type, Attributes attributes) { - if (headingLevel == 0) { - beginHeading(1,new Attributes()); - endHeading(); - } - - String elementName; - String[] elementNames = null; - boolean allowTitle = false; - boolean closeElementsOnBlockStart = false; - BlockDescription previousBlock = null; - if (!blockDescriptions.isEmpty()) { - previousBlock = blockDescriptions.peek(); - } - - switch (type) { - case BULLETED_LIST: - elementName = "itemizedlist"; - break; - case NUMERIC_LIST: - elementName = "orderedlist"; - break; - case DEFINITION_LIST: - elementName = "variablelist"; - -// variablelist -// varlistentry+ -// term+ -// listitem -// - break; - case DEFINITION_TERM: - - BlockDescription blockDescription = findBlockDescription(BlockType.DEFINITION_LIST); - if (blockDescription.entrySize > 0) { - endBlockEntry(blockDescription); - } - openBlockEntry(blockDescription, new String[] { "varlistentry" }); - - elementName = "term"; - break; - case DEFINITION_ITEM: - elementName = "listitem"; - elementNames = new String[] { "para" }; - closeElementsOnBlockStart = true; - break; - case FOOTNOTE: - case PARAGRAPH: - elementName = "para"; - break; - case CODE: - elementName = "code"; - break; - case PREFORMATTED: - elementName = "literallayout"; - break; - case QUOTE: - elementName = "blockquote"; - break; - case LIST_ITEM: - elementName = "listitem"; - elementNames = new String[] { "para" }; - closeElementsOnBlockStart = true; - break; - case TABLE: - elementName = "informaltable"; - break; - case TABLE_CELL_HEADER: - elementName = "th"; - break; - case TABLE_CELL_NORMAL: - elementName = "td"; - break; - case TABLE_ROW: - elementName = "tr"; - break; - case INFORMATION: - elementName = "important"; - allowTitle = true; - break; - case NOTE: - elementName = "note"; - allowTitle = true; - break; - case WARNING: - elementName = "warning"; - allowTitle = true; - break; - case TIP: - elementName = "tip"; - allowTitle = true; - break; - case PANEL: - elementName = "note"; // docbook has nothing better for 'note' - allowTitle = true; - break; - default: - throw new IllegalStateException(type.name()); - } - if (previousBlock != null && previousBlock.closeElementsOnBlockStart) { - endBlockEntry(previousBlock); - } - - - int blockSize = 1; - writer.writeStartElement(elementName); - applyAttributes(attributes); - - if (elementNames != null) { - for (String name: elementNames) { - writer.writeStartElement(name); - } - } - - if (allowTitle && attributes.getTitle() != null) { - writer.writeStartElement("title"); - writer.writeCharacters(attributes.getTitle()); - writer.writeEndElement(); - } - - blockDescriptions.push(new BlockDescription(type,blockSize,elementNames,closeElementsOnBlockStart)); - } - - @Override - public void endBlock() { - final BlockDescription blockDescription = blockDescriptions.pop(); - int size = blockDescription.size+blockDescription.entrySize; - for (int x = 0;x toLevel) { - writer.writeEndElement(); - --headingLevel; - } - } - - private void writeGlossaryAppendix() { - if (!acronyms.isEmpty() && automaticGlossary) { - writer.writeStartElement("appendix"); - writer.writeAttribute("id", "glossary"); - writer.writeStartElement("title"); - writer.writeAttribute("id", "glossary-end"); - writer.writeCharacters("Glossary"); - writer.writeEndElement(); // title - writer.writeStartElement("glosslist"); - - for (Map.Entry glossEntry : new TreeMap(acronyms).entrySet()) { - - writer.writeStartElement("glossentry"); - - writer.writeStartElement("glossterm"); - writer.writeCharacters(glossEntry.getKey()); - writer.writeEndElement(); // glossterm - - writer.writeStartElement("glossdef"); - writer.writeStartElement("para"); - writer.writeCharacters(glossEntry.getValue()); - writer.writeEndElement(); // para - writer.writeEndElement(); // glossdef - - writer.writeEndElement(); // glossentry - } - writer.writeEndElement(); // glosslist - writer.writeEndElement(); // appendix - } - } - - @Override - public void endSpan() { - writer.writeEndElement(); - } - @Override - public void characters(String text) { - ensureBlockElementsOpen(); - super.characters(text); - } - - @Override - public void charactersUnescaped(String literal) { - ensureBlockElementsOpen(); - // note: this *may* have HTML tags in it - writer.writeLiteral(literal); -// Logger.getLogger(DocBookDocumentBuilder.class.getName()).warning("HTML literal not supported in DocBook"); - } - - private void ensureBlockElementsOpen() { - if (!blockDescriptions.isEmpty()) { - BlockDescription blockDescription = blockDescriptions.peek(); - if (blockDescription.entrySize == 0 && blockDescription.nestedElementNames != null) { - openBlockEntry(blockDescription, blockDescription.nestedElementNames); - } - } - } - - @Override - public void entityReference(String entity) { - ensureBlockElementsOpen(); - if (entity.startsWith("#")) { - String numeric = entity.substring(1); - int base = 10; - if (numeric.startsWith("x")) { - numeric = entity.substring(1); - base = 16; - } - int unicodeValue = Integer.parseInt(numeric,base); - if (entityReferenceToUnicode.contains(unicodeValue)) { - writer.writeCharacters(""+((char)unicodeValue)); - return; - } - } - writer.writeEntityRef(entity); - } - - @Override - public void image(Attributes attributes, String url) { - ensureBlockElementsOpen(); - String cssClass = attributes.getCssClass(); - boolean inlined = false; - if (cssClass != null && CSS_CLASS_INLINE.matcher(cssClass).find()) { - inlined = true; - } - emitImage(attributes, url,inlined); - } - - private void emitImage(Attributes attributes, String url,boolean inline) { - ensureBlockElementsOpen(); - writer.writeStartElement(inline?"inlinemediaobject":"mediaobject"); - applyAttributes(attributes); - writer.writeStartElement("imageobject"); - writer.writeEmptyElement("imagedata"); - writer.writeAttribute("fileref", makeUrlAbsolute(url)); - writer.writeEndElement(); // imageobject - writer.writeEndElement(); // inlinemediaobject or mediaobject - } - - @Override - public void imageLink(Attributes linkAttributes, final Attributes imageAttributes,String href, final String imageUrl) { - link(linkAttributes,href,new ContentEmitter() { - public void emit() { - emitImage(imageAttributes,imageUrl,true); - } - }); - } - - @Override - public void lineBreak() { - ensureBlockElementsOpen(); - // no equivalent in DocBook. - characters("\n"); - } - - private BlockDescription findBlockDescription(BlockType type) { - for (int x = blockDescriptions.size()-1;x>=0;--x) { - BlockDescription blockDescription = blockDescriptions.get(x); - if (blockDescription.type == type) { - return blockDescription; - } - } - return null; - } - - private static class BlockDescription { - BlockType type; - int size; - int entrySize; // the size of an entry, if it is open, otherwise 0 - final String[] nestedElementNames; - final boolean closeElementsOnBlockStart; - - public BlockDescription(BlockType type,int size, String[] nestedElementNames, boolean closeElementsOnBlockStart) { - this.size = size; - this.entrySize = nestedElementNames==null?0:nestedElementNames.length; - this.type = type; - this.nestedElementNames = nestedElementNames; - this.closeElementsOnBlockStart = closeElementsOnBlockStart; - } - } - - /** - * Indicate if this builder should generate an automatic glossary if acronyms are used. - * When the automatic glossary is enabled and acronyms are used in the document, then an - * appendix with title 'Glossary' is added to the document, with a glosslist - * generated for all of the acronyms that appear in the document. - * - * The default is true. - */ - public boolean isAutomaticGlossary() { - return automaticGlossary; - } - - /** - * Indicate if this builder should generate an automatic glossary if acronyms are used. - * When the automatic glossary is enabled and acronyms are used in the document, then an - * appendix with title 'Glossary' is added to the document, with a glosslist - * generated for all of the acronyms that appear in the document. - * - * The default is true. - */ - public void setAutomaticGlossary(boolean automaticGlossary) { - this.automaticGlossary = automaticGlossary; - } - -} diff --git a/src/net/java/textilej/parser/builder/EventLoggingDocumentBuilder.java b/src/net/java/textilej/parser/builder/EventLoggingDocumentBuilder.java deleted file mode 100644 index ed55f38..0000000 --- a/src/net/java/textilej/parser/builder/EventLoggingDocumentBuilder.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.java.textilej.parser.builder; - -import java.util.logging.Logger; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder; - -public class EventLoggingDocumentBuilder extends DocumentBuilder { - - private Logger logger = Logger.getLogger(EventLoggingDocumentBuilder.class.getName()); - - private int blockDepth = 0; - - @Override - public void acronym(String text, String definition) { - logger.info("ACRONYM:"+text+","+definition); - } - - @Override - public void beginBlock(BlockType type, Attributes attributes) { - ++blockDepth; - logger.info("BLOCK START["+blockDepth+"]:"+type); - } - - @Override - public void beginDocument() { - logger.info("DOCUMENT START"); - } - - @Override - public void beginHeading(int level, Attributes attributes) { - logger.info("HEADING START:"+level); - } - - @Override - public void beginSpan(SpanType type, Attributes attributes) { - logger.info("SPAN START:"+type); - } - - @Override - public void characters(String text) { - logger.info("CHARACTERS:"+text); - } - - @Override - public void charactersUnescaped(String text) { - logger.info("HTML LITERAL:"+text); - } - - @Override - public void endBlock() { - logger.info("END BLOCK["+blockDepth+"]"); - --blockDepth; - } - - @Override - public void endDocument() { - logger.info("END DOCUMENT"); - } - - @Override - public void endHeading() { - logger.info("END HEADING"); - } - - @Override - public void endSpan() { - logger.info("END SPAN"); - } - - @Override - public void entityReference(String entity) { - logger.info("ENTITY: "+entity); - } - - @Override - public void image(Attributes attributes, String url) { - logger.info("IMAGE: "+url); - } - - @Override - public void imageLink(Attributes linkAttributes, Attributes imageAttributes,String href, String imageUrl) { - logger.info("IMAGE LINK: "+href+", "+imageUrl); - - } - - @Override - public void lineBreak() { - logger.info("LINE BREAK"); - } - - @Override - public void link(Attributes attributes,String hrefOrHashName, String text) { - logger.info("LINK: "+hrefOrHashName+", "+text); - } - - -} diff --git a/src/net/java/textilej/parser/builder/HtmlDocumentBuilder.java b/src/net/java/textilej/parser/builder/HtmlDocumentBuilder.java deleted file mode 100644 index 2c6a179..0000000 --- a/src/net/java/textilej/parser/builder/HtmlDocumentBuilder.java +++ /dev/null @@ -1,895 +0,0 @@ -package net.java.textilej.parser.builder; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.Map.Entry; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.ImageAttributes; -import net.java.textilej.parser.LinkAttributes; -import net.java.textilej.parser.ListAttributes; -import net.java.textilej.parser.QuoteAttributes; -import net.java.textilej.parser.TableAttributes; -import net.java.textilej.parser.TableCellAttributes; -import net.java.textilej.parser.TableRowAttributes; -import net.java.textilej.parser.ImageAttributes.Align; -import net.java.textilej.util.FormattingXMLStreamWriter; -import net.java.textilej.util.XmlStreamWriter; - -/** - * A builder that produces XHTML output. - * - * @author dgreen - */ -public class HtmlDocumentBuilder extends AbstractXmlDocumentBuilder { - - - private static final Map spanTypeToElementName = new HashMap(); - static { - spanTypeToElementName.put(SpanType.BOLD,"b"); - spanTypeToElementName.put(SpanType.CITATION,"cite"); - spanTypeToElementName.put(SpanType.ITALIC,"i"); - spanTypeToElementName.put(SpanType.EMPHASIS,"em"); - spanTypeToElementName.put(SpanType.STRONG,"strong"); - spanTypeToElementName.put(SpanType.DELETED,"del"); - spanTypeToElementName.put(SpanType.INSERTED,"ins"); - spanTypeToElementName.put(SpanType.UNDERLINED,"u"); - spanTypeToElementName.put(SpanType.SUPERSCRIPT,"sup"); - spanTypeToElementName.put(SpanType.SUBSCRIPT,"sub"); - spanTypeToElementName.put(SpanType.SPAN,"span"); - spanTypeToElementName.put(SpanType.CODE,"code"); - spanTypeToElementName.put(SpanType.MONOSPACE,"tt"); - } - - private static final Map blockTypeToElementInfo = new HashMap(); - static { - blockTypeToElementInfo.put(BlockType.BULLETED_LIST,new ElementInfo("ul")); - blockTypeToElementInfo.put(BlockType.CODE,new ElementInfo("code" )); - blockTypeToElementInfo.put(BlockType.FOOTNOTE,new ElementInfo("footnote" )); - blockTypeToElementInfo.put(BlockType.LIST_ITEM,new ElementInfo("li")); - blockTypeToElementInfo.put(BlockType.NUMERIC_LIST,new ElementInfo("ol")); - blockTypeToElementInfo.put(BlockType.DEFINITION_LIST,new ElementInfo("dl")); - blockTypeToElementInfo.put(BlockType.DEFINITION_TERM,new ElementInfo("dt")); - blockTypeToElementInfo.put(BlockType.DEFINITION_ITEM,new ElementInfo("dd")); - blockTypeToElementInfo.put(BlockType.PARAGRAPH,new ElementInfo("p" )); - blockTypeToElementInfo.put(BlockType.PREFORMATTED,new ElementInfo("pre" )); - blockTypeToElementInfo.put(BlockType.QUOTE,new ElementInfo("blockquote" )); - blockTypeToElementInfo.put(BlockType.TABLE,new ElementInfo("table" )); - blockTypeToElementInfo.put(BlockType.TABLE_CELL_HEADER,new ElementInfo("th" )); - blockTypeToElementInfo.put(BlockType.TABLE_CELL_NORMAL,new ElementInfo("td" )); - blockTypeToElementInfo.put(BlockType.TABLE_ROW,new ElementInfo("tr")); - blockTypeToElementInfo.put(BlockType.TIP,new ElementInfo("div","tip","border: 1px solid #090;background-color: #dfd;margin: 20px;padding: 0px 6px 0px 6px;")); - blockTypeToElementInfo.put(BlockType.WARNING,new ElementInfo("div","warning","border: 1px solid #c00;background-color: #fcc;margin: 20px;padding: 0px 6px 0px 6px;")); - blockTypeToElementInfo.put(BlockType.INFORMATION,new ElementInfo("div","info","border: 1px solid #3c78b5;background-color: #D8E4F1;margin: 20px;padding: 0px 6px 0px 6px;")); - blockTypeToElementInfo.put(BlockType.NOTE,new ElementInfo("div","note","border: 1px solid #F0C000;background-color: #FFFFCE;margin: 20px;padding: 0px 6px 0px 6px;")); - blockTypeToElementInfo.put(BlockType.PANEL,new ElementInfo("div","panel","border: 1px solid #ccc;background-color: #FFFFCE;margin: 10px;padding: 0px 6px 0px 6px;")); - - } - - - private String htmlNsUri = "http://www.w3.org/1999/xhtml"; - private String htmlDtd = ""; - - private boolean xhtmlStrict = false; - private boolean emitAsDocument = true; - private boolean emitDtd = false; - private String title; - - private String defaultAbsoluteLinkTarget; - - private List stylesheets = null; - private boolean useInlineStyles = true; - private boolean suppressBuiltInStyles = false; - - private String linkRel; - - public HtmlDocumentBuilder(Writer out) { - super(out); - } - - public HtmlDocumentBuilder(XmlStreamWriter writer) { - super(writer); - - } - - protected XmlStreamWriter createFormattingXmlStreamWriter(Writer out) { - XmlStreamWriter writer = super.createXmlStreamWriter(out); - return new FormattingXMLStreamWriter(writer) { - @Override - protected boolean preserveWhitespace(String elementName) { - return elementName.equals("pre") || elementName.equals("code"); - } - }; - } - - /** - * The XML Namespace URI of the HTML elements, only used if {@link #isEmitAsDocument()}. - * The default value is "http://www.w3.org/1999/xhtml". - */ - public String getHtmlNsUri() { - return htmlNsUri; - } - - /** - * The XML Namespace URI of the HTML elements, only used if {@link #isEmitAsDocument()}. - * The default value is "http://www.w3.org/1999/xhtml". - */ - public void setHtmlNsUri(String htmlNsUri) { - this.htmlNsUri = htmlNsUri; - } - - /** - * The DTD to emit, if {@link #isEmitDtd()} and {@link #isEmitAsDocument()}. - * The default value is <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - */ - public String getHtmlDtd() { - return htmlDtd; - } - - /** - * The DTD to emit, if {@link #isEmitDtd()} and {@link #isEmitAsDocument()}. - * @see #getHtmlDtd() - */ - public void setHtmlDtd(String htmlDtd) { - this.htmlDtd = htmlDtd; - } - - /** - * Indicate if the resulting HTML should be emitted as a document. If false, the html and body tags are not included - * in the output. - * Default value is true. - */ - public boolean isEmitAsDocument() { - return emitAsDocument; - } - - /** - * Indicate if the resulting HTML should be emitted as a document. If false, the html and body tags are not included - * in the output. - * Default value is true. - */ - public void setEmitAsDocument(boolean emitAsDocument) { - this.emitAsDocument = emitAsDocument; - } - - /** - * Indicate if the resulting HTML should include a DTD. Ignored unless {@link #isEmitAsDocument()}. - * Default value is false. - */ - public boolean isEmitDtd() { - return emitDtd; - } - - /** - * Indicate if the resulting HTML should include a DTD. Ignored unless {@link #isEmitAsDocument()}. - * Default value is false. - */ - public void setEmitDtd(boolean emitDtd) { - this.emitDtd = emitDtd; - } - - /** - * indicate if the builder should attempt to conform to strict XHTML rules. The default is false. - */ - public boolean isXhtmlStrict() { - return xhtmlStrict; - } - - /** - * indicate if the builder should attempt to conform to strict XHTML rules. The default is false. - */ - public void setXhtmlStrict(boolean xhtmlStrict) { - this.xhtmlStrict = xhtmlStrict; - } - - /** - * Set the document title, which will be emitted into the <title> element. - * Ignored unless {@link #isEmitAsDocument()} - * - * @return the title or null if there is none - */ - public String getTitle() { - return title; - } - - /** - * Set the document title, which will be emitted into the <title> element. - * Ignored unless {@link #isEmitAsDocument()} - * - * @param title the title or null if there is none - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * A default target attribute for links that have absolute (not relative) urls. - * By default this value is null. Setting this value will cause all HTML anchors - * to have their target attribute set if it's not explicitly specified in a {@link LinkAttributes}. - */ - public String getDefaultAbsoluteLinkTarget() { - return defaultAbsoluteLinkTarget; - } - - /** - * A default target attribute for links that have absolute (not relative) urls. - * By default this value is null. Setting this value will cause all HTML anchors - * to have their target attribute set if it's not explicitly specified in a {@link LinkAttributes}. - */ - public void setDefaultAbsoluteLinkTarget(String defaultAbsoluteLinkTarget) { - this.defaultAbsoluteLinkTarget = defaultAbsoluteLinkTarget; - } - - /** - * Add a CSS stylesheet to the output document as an URL, where the CSS stylesheet - * is referenced as an HTML link. - * Calling this method after {@link #beginDocument() starting the document} - * has no effect. - * - * Generates code similar to the following: - * - * <link type="text/css" rel="stylesheet" href="url"/> - * - * - * @param url the CSS url to use, which may be relative or absolute - * - * @see #addCssStylesheet(File) - */ - public void addCssStylesheet(String url) { - addStylesheet(new Stylesheet(url,false)); - } - - /** - * Add CSS stylesheet content to the output document. - * Calling this method after {@link #beginDocument() starting the document} - * has no effect. - * - * Generates code similar to the following: - *

-	 *   <style type="text/css">
-	 *   ... contents of the file ...
-	 *   </style>
-	 * 
- * - * @param url the CSS url to use, which may be relative or absolute - * @param append if true, the content is appended, otherwise it is prepended in the stylesheet order - * - * @see #addCssStylesheet(File) - */ - public void addCssStylesheetContent(String content) { - addStylesheet(new Stylesheet(content,true)); - } - - private void addStylesheet(Stylesheet stylesheet) { - if (stylesheets == null) { - stylesheets = new ArrayList(); - } - stylesheets.add(stylesheet); - } - - /** - * Add a CSS stylesheet to the output document, where the contents of the CSS stylesheet - * are embedded in the HTML. - * Calling this method after {@link #beginDocument() starting the document} - * has no effect. - * - * Generates code similar to the following: - *

-	 *   <style type="text/css">
-	 *   ... contents of the file ...
-	 *   </style>
-	 * 
- * - * - * @param file - * - * @see #addCssStylesheet(String) - */ - public void addCssStylesheet(File file) { - if (file == null) { - throw new IllegalArgumentException(); - } - if (!file.exists()) { - throw new IllegalArgumentException(String.format("File does not exist: %s",file)); - } - if (!file.isFile()) { - throw new IllegalArgumentException(String.format("Not a file: %s",file)); - } - if (!file.canRead()) { - throw new IllegalArgumentException(String.format("File cannot be read: %s",file)); - } - addStylesheet(new Stylesheet(file)); - } - - - /** - * Indicate if inline styles should be used when creating output such as text boxes. - * When disabled inline styles are suppressed and CSS classes are used instead, with the default styles emitted as a - * stylesheet in the document head. If disabled and {@link #isEmitAsDocument()} is false, this option has the same effect as {@link #isSuppressBuiltInStyles()}. - * - * The default is true. - * - * @see #isSuppressBuiltInStyles() - */ - public boolean isUseInlineStyles() { - return useInlineStyles; - } - - /** - * Indicate if inline styles should be used when creating output such as text boxes. - * When disabled inline styles are suppressed and CSS classes are used instead, with the default styles emitted as a - * stylesheet in the document head. If disabled and {@link #isEmitAsDocument()} is false, this option has the same effect as {@link #isSuppressBuiltInStyles()}. - * - * The default is true. - */ - public void setUseInlineStyles(boolean useInlineStyles) { - this.useInlineStyles = useInlineStyles; - } - - /** - * indicate if default built-in CSS styles should be suppressed. Built-in styles are styles that are emitted by this builder - * to create the desired visual effect when rendering certain types of elements, such as warnings or infos. - * the default is false. - * - * @see #isUseInlineStyles() - */ - public boolean isSuppressBuiltInStyles() { - return suppressBuiltInStyles; - } - - /** - * indicate if default built-in CSS styles should be suppressed. Built-in styles are styles that are emitted by this builder - * to create the desired visual effect when rendering certain types of elements, such as warnings or infos. - * the default is false. - */ - public void setSuppressBuiltInStyles(boolean suppressBuiltInStyles) { - this.suppressBuiltInStyles = suppressBuiltInStyles; - } - - /** - * The 'rel' value for HTML links. If specified the value is applied to all links generated by the builder. - * The default value is null. - * - * Setting this value to "nofollow" is recommended for rendering HTML in areas where users may - * add links, for example in a blog comment. See - * http://en.wikipedia.org/wiki/Nofollow for more information. - * - * @return the rel or null if there is none. - * @see LinkAttributes#getRef() - */ - public String getLinkRel() { - return linkRel; - } - - /** - * The 'rel' value for HTML links. If specified the value is applied to all links generated by the builder. - * The default value is null. - * - * Setting this value to "nofollow" is recommended for rendering HTML in areas where users may - * add links, for example in a blog comment. See - * http://en.wikipedia.org/wiki/Nofollow for more information. - * - * @param linkRel the rel or null if there is none. - * - * @see LinkAttributes#getRef() - */ - public void setLinkRel(String linkRel) { - this.linkRel = linkRel; - } - - @Override - public void beginDocument() { - writer.setDefaultNamespace(htmlNsUri); - - if (emitAsDocument) { - writer.writeStartDocument(); - - if (emitDtd && htmlDtd != null) { - writer.writeDTD(htmlDtd); - } - - writer.writeStartElement(htmlNsUri,"html"); - writer.writeDefaultNamespace(htmlNsUri); - - writer.writeStartElement(htmlNsUri,"head"); - if (base != null && baseInHead) { - writer.writeEmptyElement(htmlNsUri,"base"); - writer.writeAttribute("href", base.toString()); - } - if (title != null) { - writer.writeStartElement(htmlNsUri,"title"); - writer.writeCharacters(title); - writer.writeEndElement(); // title - } - if (!useInlineStyles && !suppressBuiltInStyles) { - writer.writeStartElement(htmlNsUri,"style"); - writer.writeAttribute("type", "text/css"); - writer.writeCharacters("\n"); - for (Entry ent: new TreeMap(blockTypeToElementInfo).entrySet()) { - ElementInfo elementInfo = ent.getValue(); - if (elementInfo.cssStyles != null && elementInfo.cssClass != null) { - String[] classes = elementInfo.cssClass.split("\\s+"); - for (String cssClass: classes) { - writer.writeCharacters("."); - writer.writeCharacters(cssClass); - writer.writeCharacters(" "); - } - writer.writeCharacters("{"); - writer.writeCharacters(elementInfo.cssStyles); - writer.writeCharacters("}\n"); - } - } - writer.writeEndElement(); - } - if (stylesheets != null) { - for (Stylesheet stylesheet: stylesheets) { - if (stylesheet.url != null) { - // - writer.writeEmptyElement(htmlNsUri,"link"); - writer.writeAttribute("type", "text/css"); - writer.writeAttribute("rel", "stylesheet"); - writer.writeAttribute("href", makeUrlAbsolute(stylesheet.url)); - } else { -// - writer.writeStartElement(htmlNsUri,"style"); - writer.writeAttribute("type", "text/css"); - String css; - if (stylesheet.content != null) { - css = stylesheet.content; - } else { - try { - css = readFully(stylesheet.file); - } catch (IOException e) { - throw new IllegalStateException(String.format("Cannot read file: %s",stylesheet.file),e); - } - } - writer.writeCharacters(css); - writer.writeEndElement(); - } - } - } - writer.writeEndElement(); // head - - writer.writeStartElement(htmlNsUri,"body"); - } else { - // sanity check - if (stylesheets != null && !stylesheets.isEmpty()) { - throw new IllegalStateException("CSS stylesheets are specified but the HTML output is not a document"); - } - } - } - - - @Override - public void endDocument() { - if (emitAsDocument) { - writer.writeEndElement(); // body - writer.writeEndElement(); // html - writer.writeEndDocument(); - } - - writer.close(); - } - - @Override - public void entityReference(String entity) { - writer.writeEntityRef(entity); - } - - @Override - public void acronym(String text, String definition) { - writer.writeStartElement(htmlNsUri,"acronym"); - writer.writeAttribute("title", definition); - writer.writeCharacters(text); - writer.writeEndElement(); - } - - @Override - public void link(Attributes attributes,String hrefOrHashName, String text) { - writer.writeStartElement(htmlNsUri,"a"); - writer.writeAttribute("href", makeUrlAbsolute(hrefOrHashName)); - applyLinkAttributes(attributes,hrefOrHashName); - characters(text); - writer.writeEndElement(); // a - } - - @Override - public void beginBlock(BlockType type, Attributes attributes) { - ElementInfo elementInfo = blockTypeToElementInfo.get(type); - if (elementInfo == null) { - throw new IllegalStateException(type.name()); - } - writer.writeStartElement(htmlNsUri,elementInfo.name); - if (elementInfo.cssClass != null) { - if (attributes.getCssClass() == null) { - attributes.setCssClass(elementInfo.cssClass); - } else { - attributes.setCssClass(elementInfo.cssClass+' '+attributes.getCssClass()); - } - } - if (useInlineStyles && !suppressBuiltInStyles && elementInfo.cssStyles != null) { - if (attributes.getCssStyle() == null) { - attributes.setCssStyle(elementInfo.cssStyles); - } else { - attributes.setCssStyle(elementInfo.cssStyles+attributes.getCssStyle()); - } - } - if (type == BlockType.TABLE) { - applyTableAttributes(attributes); - } else if (type == BlockType.TABLE_ROW) { - applyTableRowAttributes(attributes); - } else if (type == BlockType.TABLE_CELL_HEADER || type == BlockType.TABLE_CELL_NORMAL) { - applyCellAttributes(attributes); - } else if (type == BlockType.BULLETED_LIST || type == BlockType.NUMERIC_LIST) { - applyListAttributes(attributes); - } else if (type == BlockType.QUOTE) { - applyQuoteAttributes(attributes); - } else { - applyAttributes(attributes); - - // create the titled panel effect if a title is specified - if (attributes.getTitle() != null) { - beginBlock(BlockType.PARAGRAPH, new Attributes()); - beginSpan(SpanType.BOLD, new Attributes()); - characters(attributes.getTitle()); - endSpan(); - endBlock(); - } - } - } - - - @Override - public void beginHeading(int level, Attributes attributes) { - if (level > 6) { - level = 6; - } - writer.writeStartElement(htmlNsUri,"h"+level); - applyAttributes(attributes); - } - - @Override - public void beginSpan(SpanType type, Attributes attributes) { - String elementName = spanTypeToElementName.get(type); - if (elementName == null) { - throw new IllegalStateException(type.name()); - } - writer.writeStartElement(htmlNsUri,elementName); - applyAttributes(attributes); - } - - - @Override - public void endBlock() { - writer.writeEndElement(); - } - - @Override - public void endHeading() { - writer.writeEndElement(); - } - - @Override - public void endSpan() { - writer.writeEndElement(); - } - - @Override - public void image(Attributes attributes, String url) { - writer.writeEmptyElement(htmlNsUri,"img"); - applyImageAttributes(attributes); - writer.writeAttribute("src", makeUrlAbsolute(url)); - } - - - private void applyListAttributes(Attributes attributes) { - applyAttributes(attributes); - if (attributes instanceof ListAttributes) { - ListAttributes listAttributes = (ListAttributes) attributes; - if (listAttributes.getStart() != null) { - writer.writeAttribute("start", listAttributes.getStart()); - } - } - } - - - private void applyQuoteAttributes(Attributes attributes) { - applyAttributes(attributes); - if (attributes instanceof QuoteAttributes) { - QuoteAttributes quoteAttributes = (QuoteAttributes) attributes; - if (quoteAttributes.getCitation() != null) { - writer.writeAttribute("cite", quoteAttributes.getCitation()); - } - } - } - - private void applyTableAttributes(Attributes attributes) { - applyAttributes(attributes); - if (attributes.getTitle() != null) { - writer.writeAttribute("title", attributes.getTitle()); - } - if (attributes instanceof TableAttributes) { - TableAttributes tableAttributes = (TableAttributes) attributes; - if (tableAttributes.getBgcolor() != null) { - writer.writeAttribute("bgcolor", tableAttributes.getBgcolor()); - } - if (tableAttributes.getBorder() != null) { - writer.writeAttribute("border", tableAttributes.getBorder()); - } - if (tableAttributes.getCellpadding() != null) { - writer.writeAttribute("cellpadding", tableAttributes.getCellpadding()); - } - if (tableAttributes.getCellspacing() != null) { - writer.writeAttribute("cellspacing", tableAttributes.getCellspacing()); - } - if (tableAttributes.getFrame() != null) { - writer.writeAttribute("frame", tableAttributes.getFrame()); - } - if (tableAttributes.getRules() != null) { - writer.writeAttribute("rules", tableAttributes.getRules()); - } - if (tableAttributes.getSummary() != null) { - writer.writeAttribute("summary", tableAttributes.getSummary()); - } - if (tableAttributes.getWidth() != null) { - writer.writeAttribute("width", tableAttributes.getWidth()); - } - } - } - private void applyTableRowAttributes(Attributes attributes) { - applyAttributes(attributes); - if (attributes.getTitle() != null) { - writer.writeAttribute("title", attributes.getTitle()); - } - if (attributes instanceof TableRowAttributes) { - TableRowAttributes tableRowAttributes = (TableRowAttributes) attributes; - if (tableRowAttributes.getBgcolor() != null) { - writer.writeAttribute("bgcolor", tableRowAttributes.getBgcolor()); - } - if (tableRowAttributes.getAlign() != null) { - writer.writeAttribute("align", tableRowAttributes.getAlign()); - } - if (tableRowAttributes.getValign() != null) { - writer.writeAttribute("valign", tableRowAttributes.getValign()); - } - } - } - - - private void applyCellAttributes(Attributes attributes) { - applyAttributes(attributes); - if (attributes.getTitle() != null) { - writer.writeAttribute("title", attributes.getTitle()); - } - - if (attributes instanceof TableCellAttributes) { - TableCellAttributes tableCellAttributes = (TableCellAttributes) attributes; - if (tableCellAttributes.getBgcolor() != null) { - writer.writeAttribute("bgcolor", tableCellAttributes.getBgcolor()); - } - if (tableCellAttributes.getAlign() != null) { - writer.writeAttribute("align", tableCellAttributes.getAlign()); - } - if (tableCellAttributes.getValign() != null) { - writer.writeAttribute("valign", tableCellAttributes.getValign()); - } - if (tableCellAttributes.getRowspan() != null) { - writer.writeAttribute("rowspan", tableCellAttributes.getRowspan()); - } - if (tableCellAttributes.getColspan() != null) { - writer.writeAttribute("colspan", tableCellAttributes.getColspan()); - } - } - } - - private void applyImageAttributes(Attributes attributes) { - int border = 0; - Align align = null; - if (attributes instanceof ImageAttributes) { - ImageAttributes imageAttributes = (ImageAttributes) attributes; - border = imageAttributes.getBorder(); - align = imageAttributes.getAlign(); - } - if (xhtmlStrict) { - String borderStyle = String.format("border-width: %spx;",border); - String alignStyle = null; - if (align != null) { - switch (align) { - case Center: - case Right: - case Left: - alignStyle = "text-align: "+align.name().toLowerCase()+";"; - break; - case Bottom: - case Baseline: - case Top: - case Middle: - alignStyle = "vertical-align: "+align.name().toLowerCase()+";"; - break; - case Texttop: - alignStyle = "vertical-align: text-top;"; - break; - case Absmiddle: - alignStyle = "vertical-align: middle;"; - break; - case Absbottom: - alignStyle = "vertical-align: bottom;"; - break; - } - } - String additionalStyles = borderStyle; - if (alignStyle != null) { - additionalStyles += alignStyle; - } - if (attributes.getCssStyle() == null || attributes.getCssStyle().length() == 0) { - attributes.setCssStyle(additionalStyles); - } else { - attributes.setCssStyle(additionalStyles+attributes.getCssStyle()); - } - } - applyAttributes(attributes); - boolean haveAlt = false; - - if (attributes instanceof ImageAttributes) { - ImageAttributes imageAttributes = (ImageAttributes) attributes; - if (imageAttributes.getHeight() != -1) { - writer.writeAttribute("height", Integer.toString(imageAttributes.getHeight())); - } - if (imageAttributes.getWidth() != -1) { - writer.writeAttribute("width", Integer.toString(imageAttributes.getWidth())); - } - if (!xhtmlStrict && align != null) { - writer.writeAttribute("align", align.name().toLowerCase()); - } - if (imageAttributes.getAlt() != null) { - haveAlt = true; - writer.writeAttribute("alt", imageAttributes.getAlt()); - } - } - if (attributes.getTitle() != null) { - writer.writeAttribute("title", attributes.getTitle()); - if (!haveAlt) { - haveAlt = true; - writer.writeAttribute("alt", attributes.getTitle()); - } - } - if (xhtmlStrict) { - if (!haveAlt) { - // XHTML requires img/@alt - writer.writeAttribute("alt", ""); - } - } else { - // only specify border attribute if it's not already specified in CSS - writer.writeAttribute("border",Integer.toString(border)); - } - } - - private void applyLinkAttributes(Attributes attributes, String href) { - applyAttributes(attributes); - boolean hasTarget = false; - String rel = linkRel; - if (attributes instanceof LinkAttributes) { - LinkAttributes linkAttributes = (LinkAttributes) attributes; - if (linkAttributes.getTarget() != null) { - hasTarget = true; - writer.writeAttribute("target", linkAttributes.getTarget()); - } - if (linkAttributes.getRel() != null) { - rel = rel==null?linkAttributes.getRel():linkAttributes.getRel()+' '+rel; - } - } - if (attributes.getTitle() != null && attributes.getTitle().length() > 0) { - writer.writeAttribute("title", attributes.getTitle()); - } - if (!hasTarget && defaultAbsoluteLinkTarget != null && href != null) { - if (isExternalLink(href)) { - writer.writeAttribute("target", defaultAbsoluteLinkTarget); - } - } - if (rel != null) { - writer.writeAttribute("rel", rel); - } - } - - /** - * Note: this method does not apply the {@link Attributes#getTitle() title}. - */ - private void applyAttributes(Attributes attributes) { - if (attributes.getId() != null) { - writer.writeAttribute("id", attributes.getId()); - } - if (attributes.getCssClass() != null) { - writer.writeAttribute("class", attributes.getCssClass()); - } - if (attributes.getCssStyle() != null) { - writer.writeAttribute("style", attributes.getCssStyle()); - } - if (attributes.getLanguage() != null) { - writer.writeAttribute("lang", attributes.getLanguage()); - } - } - - @Override - public void imageLink(Attributes linkAttributes, Attributes imageAttributes, String href, String imageUrl) { - writer.writeStartElement(htmlNsUri,"a"); - writer.writeAttribute("href", makeUrlAbsolute(href)); - applyLinkAttributes(linkAttributes,href); - writer.writeEmptyElement(htmlNsUri,"img"); - applyImageAttributes(imageAttributes); - writer.writeAttribute("src", makeUrlAbsolute(imageUrl)); - writer.writeEndElement(); // a - } - - @Override - public void lineBreak() { - writer.writeEmptyElement(htmlNsUri,"br"); - } - - @Override - public void charactersUnescaped(String literal) { - writer.writeLiteral(literal); - } - - private static final class ElementInfo { - final String name; - final String cssClass; - final String cssStyles; - - public ElementInfo(String name, String cssClass, String cssStyles) { - this.name = name; - this.cssClass = cssClass; - this.cssStyles = cssStyles != null && !cssStyles.endsWith(";")?cssStyles+';':cssStyles; - } - - public ElementInfo(String name) { - this(name,null,null); - } - } - - private static class Stylesheet { - String content; - String url; - File file; - public Stylesheet(File file) { - this.file = file; - } - public Stylesheet(String urlOrContent,boolean content) { - if (content) { - this.content = urlOrContent; - } else { - this.url = urlOrContent; - } - } - } - - - private static String readFully(File inputFile) throws IOException { - int length = (int) inputFile.length(); - if (length <= 0) { - length = 2048; - } - StringBuilder buf = new StringBuilder(length); - Reader reader = new BufferedReader(new FileReader(inputFile)); - try { - int c; - while ((c = reader.read()) != -1) { - buf.append((char)c); - } - } finally { - reader.close(); - } - return buf.toString(); - } - -} diff --git a/src/net/java/textilej/parser/builder/MultiplexingDocumentBuilder.java b/src/net/java/textilej/parser/builder/MultiplexingDocumentBuilder.java deleted file mode 100644 index 09a0c50..0000000 --- a/src/net/java/textilej/parser/builder/MultiplexingDocumentBuilder.java +++ /dev/null @@ -1,143 +0,0 @@ -package net.java.textilej.parser.builder; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder; -import net.java.textilej.parser.Locator; - -public class MultiplexingDocumentBuilder extends DocumentBuilder { - - private List builders = new ArrayList(); - - public MultiplexingDocumentBuilder(DocumentBuilder... delegates) { - builders.addAll(Arrays.asList(delegates)); - } - - public void addDocumentBuilder(DocumentBuilder delegate) { - builders.add(delegate); - } - - @Override - public void acronym(String text, String definition) { - for (DocumentBuilder builder: builders) { - builder.acronym(text, definition); - } - } - - @Override - public void beginBlock(BlockType type, Attributes attributes) { - for (DocumentBuilder builder: builders) { - builder.beginBlock(type, attributes); - } - } - - @Override - public void beginDocument() { - for (DocumentBuilder builder: builders) { - builder.beginDocument(); - } - } - - @Override - public void beginHeading(int level, Attributes attributes) { - for (DocumentBuilder builder: builders) { - builder.beginHeading(level, attributes); - } - } - - @Override - public void beginSpan(SpanType type, Attributes attributes) { - for (DocumentBuilder builder: builders) { - builder.beginSpan(type, attributes); - } - } - - @Override - public void characters(String text) { - for (DocumentBuilder builder: builders) { - builder.characters(text); - } - } - - @Override - public void charactersUnescaped(String literal) { - for (DocumentBuilder builder: builders) { - builder.charactersUnescaped(literal); - } - } - - @Override - public void endBlock() { - for (DocumentBuilder builder: builders) { - builder.endBlock(); - } - } - - @Override - public void endDocument() { - for (DocumentBuilder builder: builders) { - builder.endDocument(); - } - } - - @Override - public void endHeading() { - for (DocumentBuilder builder: builders) { - builder.endHeading(); - } - } - - @Override - public void endSpan() { - for (DocumentBuilder builder: builders) { - builder.endSpan(); - } - } - - @Override - public void entityReference(String entity) { - for (DocumentBuilder builder: builders) { - builder.entityReference(entity); - } - } - - @Override - public void image(Attributes attributes, String url) { - for (DocumentBuilder builder: builders) { - builder.image(attributes, url); - } - } - - @Override - public void imageLink(Attributes linkAttributes, Attributes imageAttributes,String href, String imageUrl) { - for (DocumentBuilder builder: builders) { - builder.imageLink(linkAttributes, imageAttributes,href, imageUrl); - } - } - - @Override - public void lineBreak() { - for (DocumentBuilder builder: builders) { - builder.lineBreak(); - } - } - - @Override - public void link(Attributes attributes,String hrefOrHashName, String text) { - for (DocumentBuilder builder: builders) { - builder.link(attributes,hrefOrHashName, text); - } - } - - @Override - public void setLocator(Locator locator) { - super.setLocator(locator); - for (DocumentBuilder builder : builders) { - builder.setLocator(locator); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/Block.java b/src/net/java/textilej/parser/markup/Block.java deleted file mode 100644 index 080ed9e..0000000 --- a/src/net/java/textilej/parser/markup/Block.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.java.textilej.parser.markup; - -import net.java.textilej.parser.DocumentBuilder; - -/** - * A markup block that may span multiple lines. - * - * Implements {@link Cloneable} for the template design pattern. - * - * @author dgreen - */ -public abstract class Block extends Processor implements Cloneable { - private boolean closed; - - public Block() { - } - - /** - * Process the given line of markup starting at the provided offset. - * - * @param line the markup line to process - * @param offset the offset at which to start processing - * - * @return a non-negative integer to indicate that processing of the block completed before the end of the line, or -1 if the entire line was processed. - */ - public int processLine(String line,int offset) { - getState().setLineCharacterOffset(offset); - return processLineContent(line, offset); - } - - /** - * Process the given line of markup starting at the provided offset. - * - * @param line the markup line to process - * @param offset the offset at which to start processing - * - * @return a non-negative integer to indicate that processing of the block completed before the end of the line, or -1 if the entire line was processed. - */ - protected abstract int processLineContent(String line,int offset); - - /** - * Indicate if the block can start with the given markup line at the provided offset. - * Calling this method may cause the block to have state which is propagated - * when {@link #clone() cloning} and consumed in {@link #processLine(String, int, int)}. - * Calling this method must cause any previous state to be reset. - * Note that it is valid for block implementations to refuse to start at non-zero - * offsets. - * - * Implementations must be able to handle this method without having the - * {@link Processor processor state} initialized. - * - * @param line the line of markup to test - * @param lineOffset the offset at which the block should start processing - * - * @return true if the provided markup consists of a valid starting point for the block - */ - public abstract boolean canStart(String line,int lineOffset); - - /** - * Indicate if the current block is closed - */ - public boolean isClosed() { - return closed; - } - - /** - * Cause the block to be closed. - * If the block is going from the open to the closed state, then the block - * must cause the closed state to be propagated to the {@link DocumentBuilder builder} - * if necessary. - * - * @param closed - */ - public void setClosed(boolean closed) { - this.closed = closed; - } - - /** - * Clone the block including its state. Cloning is generally used - * after the {@link #canStart(String, int)} method is called in order - * to implement the Template design pattern. - */ - @Override - public Block clone() { - try { - return (Block) super.clone(); - } catch (CloneNotSupportedException e) { - throw new IllegalStateException(); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/ContentState.java b/src/net/java/textilej/parser/markup/ContentState.java deleted file mode 100644 index fb1f807..0000000 --- a/src/net/java/textilej/parser/markup/ContentState.java +++ /dev/null @@ -1,136 +0,0 @@ -package net.java.textilej.parser.markup; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import net.java.textilej.parser.IdGenerator; -import net.java.textilej.parser.Locator; - -/** - * State related to parsing content, propagated to {@link Block blocks} - * and other {@link Processor processors} during the parse phase. - * - * @author dgreen - */ -public class ContentState implements Locator { - private Map footnoteIdToHtmlId = new HashMap(); - private Map glossaryItems = new HashMap(); - - private String markupContent; - private IdGenerator idGenerator = new IdGenerator(); - - private int lineNumber = -1; - private int lineOffset = -1; - private int lineCharacterOffset = 0; - private int lineLength = 0; - private int lineSegmentEndOffset; - - public ContentState() {} - - public String getMarkupContent() { - return markupContent; - } - - protected void setMarkupContent(String markupContent) { - this.markupContent = markupContent; - } - - public String getFootnoteId(String footnote) { - String id = footnoteIdToHtmlId.get(footnote); - if (id == null) { - id = "fn"+UUID.randomUUID().toString().replace("-", ""); - footnoteIdToHtmlId.put(footnote,id); - } - return id; - } - - /** - * Add a glossary term (typically an acronym) with its definition. - * Has no effect if the term is already present in the glossary and the given definition is shorter or equal in length - * to the existing definition. - * - * @param term the term to add - * @param definition the definition of the term. - */ - public void addGlossaryTerm(String term, String definition) { - String previousDef = glossaryItems.put(term, definition); - if (previousDef != null && previousDef.length() > definition.length()) { - glossaryItems.put(term, previousDef); - } - } - - /** - * Get the glossary as a map of definition by acronym or term. - */ - public Map getGlossaryTerms() { - return glossaryItems; - } - - public IdGenerator getIdGenerator() { - return idGenerator; - } - - /** - * Get the 1-based line number of the current line. - * @return the line number or -1 if it is unknown. - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * the 1-based line number of the current line. - */ - protected void setLineNumber(int lineNumber) { - this.lineNumber = lineNumber; - } - - /** - * the 0-based character offset of the current line. - * @return the offset or -1 if it is unknown. - */ - public int getLineOffset() { - return lineOffset; - } - - /** - * the 0-based character offset of the current line. - */ - protected void setLineOffset(int lineOffset) { - this.lineOffset = lineOffset; - } - - public int getLineDocumentOffset() { - return lineOffset; - } - - public int getLineCharacterOffset() { - return lineCharacterOffset; - } - - public void setLineCharacterOffset(int lineCharacterOffset) { - this.lineCharacterOffset = lineCharacterOffset; - } - - public int getDocumentOffset() { - return lineOffset + lineCharacterOffset; - } - - public int getLineLength() { - return lineLength; - } - - public void setLineLength(int lineLength) { - this.lineLength = lineLength; - } - - public void setLineSegmentEndOffset(int lineSegmentEndOffset) { - this.lineSegmentEndOffset = lineSegmentEndOffset; - } - - public int getLineSegmentEndOffset() { - return lineSegmentEndOffset; - } - -} diff --git a/src/net/java/textilej/parser/markup/Dialect.java b/src/net/java/textilej/parser/markup/Dialect.java deleted file mode 100644 index ce7dc30..0000000 --- a/src/net/java/textilej/parser/markup/Dialect.java +++ /dev/null @@ -1,408 +0,0 @@ -package net.java.textilej.parser.markup; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.DocumentBuilder; -import net.java.textilej.parser.MarkupParser; -import net.java.textilej.parser.outline.OutlineParser; -import net.java.textilej.util.LocationTrackingReader; - -/** - * A markup dialect, which knows its formatting rules and is able to - * process content based on {@link Block}, {@link PatternBasedElementProcessor} and {@link PatternBasedElement} - * concepts. All markup languages supported by Textile-J extend this class. - * - * The Dialect class provides basic functionality for determining which blocks process - * which markup content in a particular document. In general multi-line documents are split into - * consecutive regions called blocks, and each line in a block is processed with spanning sections - * called phrase modifiers, and tokens within a span are replaced with their respective replacement - * tokens. These rules apply to most markup languages, however subclasses may override this default - * functionality if required. For example, by default phrase modifiers are non-overlapping and non-nested, - * however if required a subclass could permit such nesting. - * - * Generally dialect classes are not accessed directly by client code, instead client code should - * configure and call {@link MarkupParser}. - * - * @author dgreen - */ -public abstract class Dialect { - - private String name; - - private boolean filterGenerativeBlocks; - private boolean blocksOnly; - - - /** - * Create new state for tracking a document and its contents during a parse session. - * Subclasses may override this method to provide additional state tracking capability. - * - * @return the new state. - */ - protected ContentState createState() { - return new ContentState(); - } - - public void processContent(MarkupParser parser, String markupContent, boolean asDocument) { - ContentState state = createState(); - state.setMarkupContent(markupContent); - LocationTrackingReader reader = new LocationTrackingReader(new StringReader(markupContent)); - String line; - Block currentBlock = null; - - DocumentBuilder builder = parser.getBuilder(); - - builder.setLocator(state); - try { - if (asDocument) { - builder.beginDocument(); - } - - try { - while ((line = reader.readLine()) != null) { - - state.setLineNumber(reader.getLineNumber()+1); - state.setLineOffset(reader.getLineOffset()); - state.setLineCharacterOffset(0); - state.setLineSegmentEndOffset(0); - state.setLineLength(line.length()); - - int lineOffset = 0; - for (;;) { - if (currentBlock == null) { - currentBlock = startBlock(line,lineOffset); - if (currentBlock == null) { - break; - } - currentBlock.setState(state); - currentBlock.setParser(parser); - } - lineOffset = currentBlock.processLineContent(line,lineOffset); - if (currentBlock.isClosed()) { - currentBlock = null; - } - if (lineOffset < line.length() && lineOffset >= 0) { - if (currentBlock != null) { - throw new IllegalStateException("if a block does not fully process a line then it must be closed"); - } - } else { - break; - } - } - } - state.setLineNumber(reader.getLineNumber()+1); - state.setLineOffset(reader.getLineOffset()); - state.setLineCharacterOffset(0); - state.setLineLength(0); - - } catch (IOException e) { - throw new IllegalStateException(e); - } - - if (currentBlock != null && !currentBlock.isClosed()) { - currentBlock.setClosed(true); - } - - if (asDocument) { - builder.endDocument(); - } - } finally { - builder.setLocator(null); - } - } - - public Block startBlock(String line,int lineOffset) { - if (isEmptyLine(line)) { - // nothing starts on an empty line - return null; - } - for (Block block: getBlocks()) { - if (block.canStart(line, lineOffset)) { - return block.clone(); - } - } - return null; - } - - public abstract List getBlocks(); - - - /** - * Emit a markup line that may contain phrase modifiers and replacement tokens, but no - * block modifiers. - * - * @param parser - * @param state - * @param textLineOffset the offset of the provided text in the current line - * @param line the text to process - * @param offset the offset in the text at which processing should begin - */ - public void emitMarkupLine(MarkupParser parser, ContentState state,int textLineOffset, String line, int offset) { - if (blocksOnly) { - emitMarkupText(parser,state,line.substring(offset)); - return; - } - for (;;) { - PatternBasedElementProcessor phraseModifier = getPhraseModifierSyntax().findPatternBasedElement(line, offset); - if (phraseModifier != null) { - int newOffset = phraseModifier.getLineStartOffset(); - if (offset < newOffset) { - state.setLineCharacterOffset(textLineOffset+offset); - state.setLineSegmentEndOffset(textLineOffset+newOffset); - String text = line.substring(offset,newOffset); - emitMarkupText(parser,state,text); - } - phraseModifier.setParser(parser); - phraseModifier.setState(state); - state.setLineCharacterOffset(textLineOffset+phraseModifier.getLineStartOffset()); - state.setLineSegmentEndOffset(textLineOffset+phraseModifier.getLineEndOffset()); - phraseModifier.emit(); - offset = phraseModifier.getLineEndOffset(); - if (offset >= line.length()) { - break; - } - } else { - state.setLineCharacterOffset(textLineOffset+offset); - state.setLineSegmentEndOffset(textLineOffset+line.length()); - emitMarkupText(parser,state,line.substring(offset)); - break; - } - } - } - - /** - * Emit a markup line that may contain phrase modifiers and replacement tokens, but no - * block modifiers. - * - * @param parser - * @param state - * @param line - * @param offset - */ - public void emitMarkupLine(MarkupParser parser,ContentState state,String line,int offset) { - emitMarkupLine(parser, state,0, line, offset); - } - - /** - * Emit markup that may contain replacement tokens but no phrase or block modifiers. - * - * @param parser - * @param state - * @param text - */ - public void emitMarkupText(MarkupParser parser,ContentState state,String text) { - if (blocksOnly) { - parser.getBuilder().characters(text); - return; - } - int offset = 0; - for (;;) { - PatternBasedElementProcessor patternBasedElement = getReplacementTokenSyntax().findPatternBasedElement(text, offset); - if (patternBasedElement != null) { - int newOffset = patternBasedElement.getLineStartOffset(); - if (offset < newOffset) { - String text2 = text.substring(offset,newOffset); - emitMarkupText(parser,state,text2); - } - patternBasedElement.setParser(parser); - patternBasedElement.setState(state); - patternBasedElement.emit(); - offset = patternBasedElement.getLineEndOffset(); - if (offset >= text.length()) { - break; - } - } else { - parser.getBuilder().characters(offset>0?text.substring(offset):text); - break; - } - } - } - - private static class Group { - int count; - } - - public static class PatternBasedSyntax { - protected List elements = new ArrayList(); - protected Pattern elementPattern; - protected List elementGroup = new ArrayList(); - - private StringBuilder patternBuffer = new StringBuilder(); - private int patternGroup = 0; - private Stack groups = new Stack(); - { - groups.push(new Group()); - } - - public PatternBasedSyntax() {} - - public void add(PatternBasedElement element) { - elementPattern = null; - elements.add(element); - if (groups.peek().count++ > 0) { - patternBuffer.append('|'); - } - ++patternGroup; - patternBuffer.append('('); - patternBuffer.append(element.getPattern(patternGroup)); - patternBuffer.append(')'); - elementGroup.add(patternGroup); - patternGroup += element.getPatternGroupCount(); - } - public void beginGroup(String regexFragment, int size) { - add(regexFragment,size,true); - } - public void endGroup(String regexFragment, int size) { - add(regexFragment,size,false); - } - private void add(String regexFragment, int size,boolean beginGroup) { - elementPattern = null; - if (beginGroup) { - if (groups.peek().count++ > 0) { - patternBuffer.append('|'); - } - groups.push(new Group()); - patternBuffer.append("(?:"); - } else { - groups.pop(); - } - patternBuffer.append(regexFragment); - if (!beginGroup) { - patternBuffer.append(")"); - } - patternGroup += size; - } - - public PatternBasedElementProcessor findPatternBasedElement(String lineText,int offset) { - Matcher matcher = getPattern().matcher(lineText); - if (offset > 0) { - matcher.region(offset, lineText.length()); - } - if (matcher.find()) { - int size = elementGroup.size(); - for (int x = 0;x 0) { - elementPattern = Pattern.compile(patternBuffer.toString()); - } else { - return null; - } - } - return elementPattern; - } - - } - - - protected abstract PatternBasedSyntax getPhraseModifierSyntax(); - protected abstract PatternBasedSyntax getReplacementTokenSyntax(); - - /** - * The name of the dialect, typically the same as the name of the - * markup language supported by this dialect. This value may be displayed to the - * user. - * - * @return the name, or null if unknown - */ - public String getName() { - return name; - } - - /** - * The name of the dialect, typically the same as the name of the - * markup language supported by this dialect. This value may be displayed to the - * user. - * - * @param name the name - */ - public void setName(String name) { - this.name = name; - } - - @Override - public Dialect clone() { - Dialect dialect; - try { - dialect = getClass().newInstance(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - dialect.setName(name); - return dialect; - } - - /** - * Indicate if generative contents should be filtered. This option is used with the {@link OutlineParser}. - */ - public boolean isFilterGenerativeContents() { - return filterGenerativeBlocks; - } - - /** - * Indicate if table of contents should be filtered. This option is used with the {@link OutlineParser}. - */ - public void setFilterGenerativeContents(boolean filterGenerativeBlocks) { - this.filterGenerativeBlocks = filterGenerativeBlocks; - } - - /** - * indicate if the parser should detect blocks only. This is useful for use in a document partitioner where the partition boundaries are defined by blocks. - */ - public boolean isBlocksOnly() { - return blocksOnly; - } - - /** - * indicate if the parser should detect blocks only. This is useful for use in a document partitioner where the partition boundaries are defined by blocks. - */ - public void setBlocksOnly(boolean blocksOnly) { - this.blocksOnly = blocksOnly; - } - - /** - * indicate if the given line is considered 'empty'. The default implementation - * returns true for lines of length 0, and for lines whose only content is whitespace. - * - * @param line the line content - * - * @return true if the given line is considered empty by this dialect - */ - public boolean isEmptyLine(String line) { - if (line.length() == 0) { - return true; - } - for (int x = 0;x - */ -public abstract class PatternBasedElement { - - /** - * Get the regular expression pattern that matches this element. - * Generally the pattern may be assembled into a single larger regular expression. - * - * @param groupOffset the offset of the groups in the pattern, 0 indicating no offset - * - * @return the regular expression pattern - */ - protected abstract String getPattern(int groupOffset); - - /** - * The number of capturing groups in the {@link #getPattern(int) pattern}. Note that implementations must - * take care to return the correct value otherwise the dialect will not work correctly. - */ - protected abstract int getPatternGroupCount(); - - /** - * create a new processor for processing the type of element detected by this class. - */ - protected abstract PatternBasedElementProcessor newProcessor(); -} diff --git a/src/net/java/textilej/parser/markup/PatternBasedElementProcessor.java b/src/net/java/textilej/parser/markup/PatternBasedElementProcessor.java deleted file mode 100644 index a739d79..0000000 --- a/src/net/java/textilej/parser/markup/PatternBasedElementProcessor.java +++ /dev/null @@ -1,127 +0,0 @@ -package net.java.textilej.parser.markup; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; - -/** - * A processor that is capable of processing a specific type of markup element - * - * @author dgreen - * - */ -public abstract class PatternBasedElementProcessor extends Processor implements net.java.textilej.parser.util.Matcher { - - protected int lineStartOffset; - protected int lineEndOffset; - protected Map groupByIndex; - - private static class Group { - private final String text; - private final int start; - private final int end; - - public Group(String text,int start,int end) { - this.text = text; - this.start = start; - this.end = end; - } - } - - /** - * Set the captured text for the given group. - * - * @param group the 1-based group - * @param capturedText the text that was captured - * - * @see #group(int) - */ - public void setGroup(int group, String capturedText,int start,int end) { - if (groupByIndex == null) { - groupByIndex = new HashMap(); - } - groupByIndex.put(group,new Group(capturedText,start,end)); - } - - /** - * Get the offset within the line at which this element was started - * - * @see Matcher#start() - */ - public int getLineStartOffset() { - return lineStartOffset; - } - - public void setLineStartOffset(int lineStartOffset) { - this.lineStartOffset = lineStartOffset; - } - - /** - * Get the offset within the line at which this element ended - * - * @see Matcher#end() - */ - public int getLineEndOffset() { - return lineEndOffset; - } - - public void setLineEndOffset(int lineEndOffset) { - this.lineEndOffset = lineEndOffset; - } - - /** - * Get the capturing group text, or null if the group did not match any text. - * - * @param groupNumber the 1-based group - * - * @return the text, or null if the group did not match any text - * - * @see Matcher#group(int) - */ - public String group(int groupNumber) { - if (groupByIndex==null) { - return null; - } - Group group = groupByIndex.get(groupNumber); - return group == null?null:group.text; - } - - /** - * Get the start offset of a capturing group, or -1 if the group did not match any text. - * - * @param groupNumber the 1-based group - * - * @return the start offset, or -1 if the group did not match any text - * - * @see Matcher#start(int) - */ - public int start(int groupNumber) { - if (groupByIndex==null) { - return -1; - } - Group group = groupByIndex.get(groupNumber); - return group == null?-1:group.start; - } - - /** - * Get the end offset of a capturing group, or -1 if the group did not match any text. - * - * @param groupNumber the 1-based group - * - * @return the end offset, or -1 if the group did not match any text - * - * @see Matcher#start(int) - */ - public int end(int groupNumber) { - if (groupByIndex==null) { - return -1; - } - Group group = groupByIndex.get(groupNumber); - return group == null?-1:group.end; - } - - /** - * Emit the content of the element - */ - public abstract void emit(); -} diff --git a/src/net/java/textilej/parser/markup/Processor.java b/src/net/java/textilej/parser/markup/Processor.java deleted file mode 100644 index 7391579..0000000 --- a/src/net/java/textilej/parser/markup/Processor.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.java.textilej.parser.markup; - -import net.java.textilej.parser.DocumentBuilder; -import net.java.textilej.parser.MarkupParser; - -public class Processor { - protected Dialect dialect; - protected DocumentBuilder builder; - protected MarkupParser parser; - protected ContentState state; - - public Processor() { - super(); - } - - /** - * The builder that is the target for output - */ - public DocumentBuilder getBuilder() { - return builder; - } - - /** - * The parser that is actively using this processor - */ - public MarkupParser getParser() { - return parser; - } - - public void setParser(MarkupParser parser) { - this.parser = parser; - this.builder = (parser==null)?null:parser.getBuilder(); - dialect = (parser == null)?null:parser.getDialect(); - } - - public Dialect getDialect() { - return dialect; - } - - public ContentState getState() { - return state; - } - - public void setState(ContentState state) { - this.state = state; - } - -} \ No newline at end of file diff --git a/src/net/java/textilej/parser/markup/block/GlossaryBlock.java b/src/net/java/textilej/parser/markup/block/GlossaryBlock.java deleted file mode 100644 index cd7ac58..0000000 --- a/src/net/java/textilej/parser/markup/block/GlossaryBlock.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.java.textilej.parser.markup.block; - -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -public abstract class GlossaryBlock extends Block { - - protected int blockLineNumber = 0; - - private String style; - - @Override - public int processLineContent(String line,int offset) { - if (blockLineNumber++ > 0) { - setClosed(true); - return 0; - } - if (!getDialect().isFilterGenerativeContents()) { - SortedMap glossary = new TreeMap(state.getGlossaryTerms()); - - builder.beginBlock(BlockType.DEFINITION_LIST, new Attributes(null, - null, style == null ? null : "list-style: " + style, null)); - Attributes nullAttributes = new Attributes(); - for (Map.Entry ent: glossary.entrySet()) { - builder.beginBlock(BlockType.DEFINITION_TERM, nullAttributes); - builder.characters(ent.getKey()); - builder.endBlock(); - - builder.beginBlock(BlockType.DEFINITION_ITEM, nullAttributes); - builder.characters(ent.getValue()); - builder.endBlock(); - } - - builder.endBlock(); - } - return -1; - } - - public String getStyle() { - return style; - } - - public void setStyle(String style) { - this.style = style; - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/ConfluenceDialect.java b/src/net/java/textilej/parser/markup/confluence/ConfluenceDialect.java deleted file mode 100644 index bec875a..0000000 --- a/src/net/java/textilej/parser/markup/confluence/ConfluenceDialect.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.java.textilej.parser.markup.confluence; - -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.markup.confluence.block.CodeBlock; -import net.java.textilej.parser.markup.confluence.block.ExtendedPreformattedBlock; -import net.java.textilej.parser.markup.confluence.block.ExtendedQuoteBlock; -import net.java.textilej.parser.markup.confluence.block.HeadingBlock; -import net.java.textilej.parser.markup.confluence.block.ListBlock; -import net.java.textilej.parser.markup.confluence.block.ParagraphBlock; -import net.java.textilej.parser.markup.confluence.block.QuoteBlock; -import net.java.textilej.parser.markup.confluence.block.TableBlock; -import net.java.textilej.parser.markup.confluence.block.TableOfContentsBlock; -import net.java.textilej.parser.markup.confluence.block.TextBoxBlock; -import net.java.textilej.parser.markup.confluence.phrase.ImagePhraseModifier; -import net.java.textilej.parser.markup.confluence.phrase.SimplePhraseModifier; -import net.java.textilej.parser.markup.confluence.phrase.SimpleWrappedPhraseModifier; -import net.java.textilej.parser.markup.confluence.token.AnchorReplacementToken; -import net.java.textilej.parser.markup.confluence.token.HyperlinkReplacementToken; -import net.java.textilej.parser.markup.token.EntityReferenceReplacementToken; -import net.java.textilej.parser.markup.token.ImpliedHyperlinkReplacementToken; -import net.java.textilej.parser.markup.token.PatternEntityReferenceReplacementToken; -import net.java.textilej.parser.markup.token.PatternLineBreakReplacementToken; -import net.java.textilej.parser.markup.token.PatternLiteralReplacementToken; - -public class ConfluenceDialect extends Dialect { - - private List blocks = new ArrayList(); - private List paragraphBreakingBlocks = new ArrayList(); - - - private static PatternBasedSyntax tokenSyntax = new PatternBasedSyntax(); - private static PatternBasedSyntax phraseModifierSyntax = new PatternBasedSyntax(); - - - @Override - protected PatternBasedSyntax getPhraseModifierSyntax() { - return phraseModifierSyntax; - } - - @Override - protected PatternBasedSyntax getReplacementTokenSyntax() { - return tokenSyntax; - } - - { - - // IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!! - - HeadingBlock headingBlock = new HeadingBlock(); - blocks.add(headingBlock); - paragraphBreakingBlocks.add(headingBlock); - ListBlock listBlock = new ListBlock(); - blocks.add(listBlock); - paragraphBreakingBlocks.add(listBlock); - blocks.add(new QuoteBlock()); - TableBlock tableBlock = new TableBlock(); - blocks.add(tableBlock); - paragraphBreakingBlocks.add(tableBlock); - ExtendedQuoteBlock quoteBlock = new ExtendedQuoteBlock(); - blocks.add(quoteBlock); - paragraphBreakingBlocks.add(quoteBlock); - ExtendedPreformattedBlock noformatBlock = new ExtendedPreformattedBlock(); - blocks.add(noformatBlock); - paragraphBreakingBlocks.add(noformatBlock); - // TODO: {color:red}{color} - blocks.add(new TextBoxBlock(BlockType.PANEL,"panel")); - blocks.add(new TextBoxBlock(BlockType.NOTE,"note")); - blocks.add(new TextBoxBlock(BlockType.INFORMATION,"info")); - blocks.add(new TextBoxBlock(BlockType.WARNING,"warning")); - blocks.add(new TextBoxBlock(BlockType.TIP,"tip")); - CodeBlock codeBlock = new CodeBlock(); - blocks.add(codeBlock); - paragraphBreakingBlocks.add(codeBlock); - blocks.add(new TableOfContentsBlock()); - - blocks.add(new ParagraphBlock()); // ORDER DEPENDENCY: this must come last - } - static { - phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.,\\\"'?!;:\\)\\(\\[\\]])|^)(?:",0); - phraseModifierSyntax.add(new SimplePhraseModifier("*",SpanType.STRONG, true)); - phraseModifierSyntax.add(new SimplePhraseModifier("_",SpanType.EMPHASIS, true)); - phraseModifierSyntax.add(new SimplePhraseModifier("??",SpanType.CITATION, true)); - phraseModifierSyntax.add(new SimplePhraseModifier("-",SpanType.DELETED, true)); - phraseModifierSyntax.add(new SimplePhraseModifier("+",SpanType.UNDERLINED, true)); - phraseModifierSyntax.add(new SimplePhraseModifier("^",SpanType.SUPERSCRIPT, false)); - phraseModifierSyntax.add(new SimplePhraseModifier("~",SpanType.SUBSCRIPT, false)); - phraseModifierSyntax.add(new SimpleWrappedPhraseModifier("{{","}}",SpanType.MONOSPACE, false)); - phraseModifierSyntax.add(new ImagePhraseModifier()); - phraseModifierSyntax.endGroup(")(?=\\W|$)",0); - - tokenSyntax.add(new EntityReferenceReplacementToken("(tm)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(TM)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(c)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(C)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(r)","#174")); - tokenSyntax.add(new EntityReferenceReplacementToken("(R)","#174")); - tokenSyntax.add(new HyperlinkReplacementToken()); - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\w\\s)(---)(?=\\s\\w))","#8212")); // emdash - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\w\\s)(--)(?=\\s\\w))","#8211")); // endash - tokenSyntax.add(new PatternLiteralReplacementToken("(?:(?<=\\w\\s)(----)(?=\\s\\w))","
")); // horizontal rule - tokenSyntax.add(new PatternLineBreakReplacementToken("(\\\\\\\\)")); // line break - tokenSyntax.add(new ImpliedHyperlinkReplacementToken()); - tokenSyntax.add(new AnchorReplacementToken()); - } - - - public ConfluenceDialect() {} - - @Override - public List getBlocks() { - return blocks; - } - - public List getParagraphBreakingBlocks() { - return paragraphBreakingBlocks; - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/AbstractConfluenceDelimitedBlock.java b/src/net/java/textilej/parser/markup/confluence/block/AbstractConfluenceDelimitedBlock.java deleted file mode 100644 index 59c644a..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/AbstractConfluenceDelimitedBlock.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public abstract class AbstractConfluenceDelimitedBlock extends ParameterizedBlock { - - private final Pattern startPattern; - private final Pattern endPattern; - - - protected int blockLineCount = 0; - private Matcher matcher; - - public AbstractConfluenceDelimitedBlock(String blockName) { - startPattern = Pattern.compile("\\s*\\{"+blockName+"(?::([^\\}]*))?\\}(.*)"); - endPattern = Pattern.compile("\\s*(\\{"+blockName+"\\})(.*)"); - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - setOptions(matcher.group(1)); - - offset = matcher.start(2); - - beginBlock(); - } - - int end = line.length(); - int segmentEnd = end; - boolean terminating = false; - - Matcher endMatcher = endPattern.matcher(line); - if (offset < end) { - if (blockLineCount == 0) { - endMatcher.region(offset, end); - } - if (endMatcher.find()) { - terminating = true; - end = endMatcher.start(2); - segmentEnd = endMatcher.start(1); - } - } - - if (end < line.length()) { - state.setLineSegmentEndOffset(end); - } - - ++blockLineCount; - - final String content = line.substring(offset,segmentEnd); - handleBlockContent(content); - - if (terminating) { - setClosed(true); - } - return end==line.length()?-1:end; - } - - protected abstract void handleBlockContent(String content); - protected abstract void beginBlock(); - protected abstract void endBlock(); - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - endBlock(); - } - super.setClosed(closed); - } - - @Override - public boolean canStart(String line, int lineOffset) { - resetState(); - matcher = startPattern.matcher(line); - if (lineOffset > 0) { - matcher.region(lineOffset, line.length()); - } - return matcher.matches(); - } - - protected void resetState() { - blockLineCount = 0; - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/CodeBlock.java b/src/net/java/textilej/parser/markup/confluence/block/CodeBlock.java deleted file mode 100644 index 4cba10d..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/CodeBlock.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; - -public class CodeBlock extends AbstractConfluenceDelimitedBlock { - - - private String title; - - public CodeBlock() { - super("code"); - } - - @Override - protected void beginBlock() { - if (title != null) { - Attributes attributes = new Attributes(); - attributes.setTitle(title); - builder.beginBlock(BlockType.PANEL, attributes); - } - Attributes attributes = new Attributes(); - - builder.beginBlock(BlockType.PREFORMATTED, new Attributes()); - builder.beginBlock(BlockType.CODE, attributes); - } - - @Override - protected void handleBlockContent(String content) { - builder.characters(content); - builder.characters("\n"); - } - - @Override - protected void endBlock() { - if (title != null) { - builder.endBlock(); // panel - } - builder.endBlock(); // code - builder.endBlock(); // pre - } - - @Override - protected void resetState() { - super.resetState(); - title = null; - } - - - @Override - protected void setOption(String key, String value) { - if (key.equals("title")) { - title = value; - } - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/ExtendedPreformattedBlock.java b/src/net/java/textilej/parser/markup/confluence/block/ExtendedPreformattedBlock.java deleted file mode 100644 index 554d4f1..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/ExtendedPreformattedBlock.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; - -/** - * quoted text block, matches blocks that start with bc. . - * Creates an extended block type of {@link ParagraphBlock paragraph}. - * - * @author dgreen - */ -public class ExtendedPreformattedBlock extends AbstractConfluenceDelimitedBlock { - - - public ExtendedPreformattedBlock() { - super("noformat"); - } - - @Override - protected void beginBlock() { - Attributes attributes = new Attributes(); - builder.beginBlock(BlockType.PREFORMATTED, attributes); - } - - @Override - protected void endBlock() { - builder.endBlock(); // pre - } - - @Override - protected void handleBlockContent(String content) { - if (content.length() > 0) { - builder.characters(content); - } else if (blockLineCount == 1) { - return; - } - builder.characters("\n"); - } - - @Override - protected void setOption(String key, String value) { - // no options - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/ExtendedQuoteBlock.java b/src/net/java/textilej/parser/markup/confluence/block/ExtendedQuoteBlock.java deleted file mode 100644 index 9f22820..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/ExtendedQuoteBlock.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; - -/** - * quoted text block, matches blocks that start with bc. . - * Creates an extended block type of {@link ParagraphBlock paragraph}. - * - * @author dgreen - */ -public class ExtendedQuoteBlock extends AbstractConfluenceDelimitedBlock { - - private int paraLine = 0; - private boolean paraOpen = false; - - public ExtendedQuoteBlock() { - super("quote"); - } - - @Override - protected void resetState() { - super.resetState(); - paraOpen = false; - paraLine = 0; - } - - @Override - protected void beginBlock() { - Attributes attributes = new Attributes(); - builder.beginBlock(BlockType.QUOTE, attributes); - } - - @Override - protected void endBlock() { - if (paraOpen) { - builder.endBlock(); // para - paraLine = 0; - paraOpen = false; - } - builder.endBlock(); // quote - } - - @Override - protected void handleBlockContent(String content) { - if (blockLineCount == 1 && content.length() == 0) { - return; - } - if (dialect.isEmptyLine(content) && blockLineCount > 1 && paraOpen) { - builder.endBlock(); // para - paraOpen = false; - paraLine = 0; - return; - } - if (!paraOpen) { - builder.beginBlock(BlockType.PARAGRAPH, new Attributes()); - paraOpen = true; - } - if (paraLine != 0) { - builder.lineBreak(); - } - ++paraLine; - getDialect().emitMarkupLine(getParser(),state,content,0); - - } - - @Override - protected void setOption(String key, String value) { - // no options - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/HeadingBlock.java b/src/net/java/textilej/parser/markup/confluence/block/HeadingBlock.java deleted file mode 100644 index 4ab5dac..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/HeadingBlock.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.markup.Block; - -/** - * Matches any textile text, including lines starting with p. . - * - * @author dgreen - */ -public class HeadingBlock extends Block { - - static final Pattern startPattern = Pattern.compile("\\s*h([1-6])\\.\\s+(.*)"); - - private int blockLineCount = 0; - private int level = -1; - private Matcher matcher; - - public HeadingBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - // 0-offset matches may start with the "hn. " prefix. - level = Integer.parseInt(matcher.group(1)); - offset = matcher.start(2); - - if (attributes.getId() == null) { - attributes.setId(state.getIdGenerator().newId("h"+level,line.substring(offset))); - } - builder.beginHeading(level, attributes); - } - if (blockLineCount != 0 || dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endHeading(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/ListBlock.java b/src/net/java/textilej/parser/markup/confluence/block/ListBlock.java deleted file mode 100644 index 3072cb7..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/ListBlock.java +++ /dev/null @@ -1,162 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * List block, matches blocks that start with *, # or - - * - * @author dgreen - */ -public class ListBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = 2; - - static final Pattern startPattern = Pattern.compile("((?:(?:\\*)|(?:#)|(?:-))+)\\s(.*+)"); - - private int blockLineCount = 0; - private Matcher matcher; - - private Stack listState; - - public ListBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - listState = new Stack(); - Attributes attributes = new Attributes(); - String listSpec = matcher.group(1); - int level = calculateLevel(listSpec); - BlockType type = calculateType(listSpec); - - if (type == BlockType.BULLETED_LIST && "-".equals(listSpec)) { - attributes.setCssStyle("list-style: square"); - } - - // 0-offset matches may start with the "*** " prefix. - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - listState.push(new ListState(1,type)); - builder.beginBlock(type, attributes); - - adjustLevel(listSpec, level, type); - } else { - Matcher matcher = startPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - String listSpec = matcher.group(1); - int level = calculateLevel(listSpec); - BlockType type = calculateType(listSpec); - - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - adjustLevel(listSpec, level, type); - } - ++blockLineCount; - - ListState listState = this.listState.peek(); - if (listState.openItem) { - builder.endBlock(); - } - listState.openItem = true; - builder.beginBlock(BlockType.LIST_ITEM, new Attributes()); - - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - private void adjustLevel(String listSpec, int level, BlockType type) { - for (ListState previousState = listState.peek(); - level != previousState.level || previousState.type != type; - previousState = listState.peek()) { - - if (level > previousState.level) { - if (!previousState.openItem) { - builder.beginBlock(BlockType.LIST_ITEM, new Attributes()); - previousState.openItem = true; - } - - Attributes blockAttributes = new Attributes(); - if (type == BlockType.BULLETED_LIST && "-".equals(listSpec)) { - blockAttributes.setCssStyle("list-style: square"); - } - listState.push(new ListState(previousState.level+1,type)); - builder.beginBlock(type,blockAttributes); - } else { - closeOne(); - if (listState.isEmpty()) { - Attributes blockAttributes = new Attributes(); - if (type == BlockType.BULLETED_LIST && "-".equals(listSpec)) { - blockAttributes.setCssStyle("list-style: square"); - } - - listState.push(new ListState(1,type)); - builder.beginBlock(type, blockAttributes); - } - } - } - } - - private int calculateLevel(String listSpec) { - return listSpec.length(); - } - - private BlockType calculateType(String listSpec) { - return listSpec.charAt(listSpec.length()-1) == '#'?BlockType.NUMERIC_LIST:BlockType.BULLETED_LIST; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - listState = null; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - while (listState != null && !listState.isEmpty()) { - closeOne(); - } - listState = null; - } - super.setClosed(closed); - } - - private void closeOne() { - ListState e = listState.pop(); - if (e.openItem) { - builder.endBlock(); - } - builder.endBlock(); - } - - private static class ListState { - int level; - BlockType type; - boolean openItem; - - private ListState(int level, BlockType type) { - super(); - this.level = level; - this.type = type; - } - - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/ParagraphBlock.java b/src/net/java/textilej/parser/markup/confluence/block/ParagraphBlock.java deleted file mode 100644 index 4b9d2d0..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/ParagraphBlock.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.confluence.ConfluenceDialect; - -/** - * Matches any textile text, including lines starting with p. . - * - * @author dgreen - */ -public class ParagraphBlock extends Block { - - private static final Pattern confluenceBlockStart = Pattern.compile("\\{(code|info|tip|warning|panel|note|toc)(?:(:[^\\}]*))?\\}"); - - private int blockLineCount = 0; - - public ParagraphBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - - builder.beginBlock(BlockType.PARAGRAPH, attributes); - } - - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - - ++blockLineCount; - - ConfluenceDialect dialect = (ConfluenceDialect) getDialect(); - - // NOTE: in Textile paragraphs can have nested lists and other things, however - // the resulting XHTML is invalid -- so here we allow for similar constructs - // however we cause them to end the paragraph rather than being nested. - for (Block block: dialect.getParagraphBreakingBlocks()) { - if (block.canStart(line, offset)) { - setClosed(true); - return 0; - } - } - - Matcher blockStartMatcher = confluenceBlockStart.matcher(line); - if (offset > 0) { - blockStartMatcher.region(offset, line.length()); - } - if (blockStartMatcher.find()) { - int end = blockStartMatcher.start(); - if (end > offset) { - dialect.emitMarkupLine(getParser(),state,offset,line.substring(offset,end), 0); - } - setClosed(true); - return end; - } - if (blockLineCount > 1) { - builder.lineBreak(); - } - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - return true; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/ParameterizedBlock.java b/src/net/java/textilej/parser/markup/confluence/block/ParameterizedBlock.java deleted file mode 100644 index f0b8d74..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/ParameterizedBlock.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import net.java.textilej.parser.markup.Block; - -public abstract class ParameterizedBlock extends Block { - - public void setOptions(String options) { - if (options == null) { - return; - } - String[] opts = options.split("\\s*\\|\\s*"); - for (String optionPair: opts) { - String[] keyValue = optionPair.split("\\s*=\\s*"); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - setOption(key,value); - } - } - } - - protected abstract void setOption(String key, String value); -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/QuoteBlock.java b/src/net/java/textilej/parser/markup/confluence/block/QuoteBlock.java deleted file mode 100644 index 9d6e46a..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/QuoteBlock.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * quoted text block, matches blocks that start with bc. . - * Creates an extended block type of {@link ParagraphBlock paragraph}. - * - * @author dgreen - */ -public class QuoteBlock extends Block { - - - static final Pattern startPattern = Pattern.compile("bq\\.\\s+(.*)"); - - private int blockLineCount = 0; - private Matcher matcher; - - public QuoteBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - - offset = matcher.start(1); - - builder.beginBlock(BlockType.QUOTE, attributes); - builder.beginBlock(BlockType.PARAGRAPH, new Attributes()); - } - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - if (blockLineCount != 0) { - builder.lineBreak(); - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - matcher = startPattern.matcher(line); - if (lineOffset > 0) { - matcher.region(lineOffset, line.length()); - } - return matcher.matches(); - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); // para - builder.endBlock(); // quote - } - super.setClosed(closed); - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/TableBlock.java b/src/net/java/textilej/parser/markup/confluence/block/TableBlock.java deleted file mode 100644 index adb4203..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/TableBlock.java +++ /dev/null @@ -1,99 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * Table block, matches blocks that start with table. or those that - * start with a table row. - * - * @author dgreen - */ -public class TableBlock extends Block { - - static final Pattern startPattern = Pattern.compile("(\\|(.*)?(\\|\\s*$))"); - - static final Pattern TABLE_ROW_PATTERN = Pattern.compile("\\|(\\|)?" + "((?:(?:[^\\|\\[]*)(?:\\[[^\\]]*\\])?)*)" - + "(\\|\\|?\\s*$)?"); - - private int blockLineCount = 0; - - private Matcher matcher; - - public TableBlock() { - } - - @Override - public int processLineContent(String line, int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - builder.beginBlock(BlockType.TABLE, attributes); - } else if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - ++blockLineCount; - - if (offset == line.length()) { - return -1; - } - - String textileLine = offset == 0 ? line : line.substring(offset); - Matcher rowMatcher = TABLE_ROW_PATTERN.matcher(textileLine); - if (!rowMatcher.find()) { - setClosed(true); - return 0; - } - - builder.beginBlock(BlockType.TABLE_ROW, new Attributes()); - - do { - int start = rowMatcher.start(); - if (start == textileLine.length() - 1) { - break; - } - - String headerIndicator = rowMatcher.group(1); - String text = rowMatcher.group(2); - int lineOffset = offset + rowMatcher.start(2); - - boolean header = headerIndicator != null && "|".equals(headerIndicator); - - Attributes attributes = new Attributes(); - builder.beginBlock(header ? BlockType.TABLE_CELL_HEADER : BlockType.TABLE_CELL_NORMAL, attributes); - - dialect.emitMarkupLine(getParser(), state, lineOffset, text, 0); - - builder.endBlock(); // table cell - } while (rowMatcher.find()); - - builder.endBlock(); // table row - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/TableOfContentsBlock.java b/src/net/java/textilej/parser/markup/confluence/block/TableOfContentsBlock.java deleted file mode 100644 index ab33acc..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/TableOfContentsBlock.java +++ /dev/null @@ -1,104 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.confluence.ConfluenceDialect; -import net.java.textilej.parser.outline.OutlineItem; -import net.java.textilej.parser.outline.OutlineParser; - -public class TableOfContentsBlock extends ParameterizedBlock { - - static final Pattern startPattern = Pattern.compile("\\s*\\{toc(?::([^\\}]+))?\\}\\s*"); - - private int blockLineNumber = 0; - - private String style = "none"; - private int maxLevel = Integer.MAX_VALUE; - - private Matcher matcher; - - @Override - public int processLineContent(String line,int offset) { - if (blockLineNumber++ > 0) { - setClosed(true); - return 0; - } - - - if (!getDialect().isFilterGenerativeContents()) { - String options = matcher.group(1); - setOptions(options); - - OutlineParser outlineParser = new OutlineParser(new ConfluenceDialect()); - OutlineItem rootItem = outlineParser.parse(state.getMarkupContent()); - emitToc(rootItem); - } - return -1; - } - - - private void emitToc(OutlineItem item) { - if (item.getChildren().isEmpty()) { - return; - } - if ((item.getLevel()+1) > maxLevel) { - return; - } - Attributes nullAttributes = new Attributes(); - - builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes(null,null,"list-style: "+style+";",null)); - for (OutlineItem child: item.getChildren()) { - builder.beginBlock(BlockType.LIST_ITEM, nullAttributes); - builder.link('#'+child.getId(), child.getLabel()); - emitToc(child); - builder.endBlock(); - } - builder.endBlock(); - } - - @Override - public boolean canStart(String line,int lineOffset) { - style = "none"; - maxLevel = Integer.MAX_VALUE; - - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - public String getStyle() { - return style; - } - - public void setStyle(String style) { - this.style = style; - } - - public int getMaxLevel() { - return maxLevel; - } - - public void setMaxLevel(int maxLevel) { - this.maxLevel = maxLevel; - } - - - @Override - protected void setOption(String key, String value) { - if (key.equals("style")) { - setStyle(value); - } else if (key.equals("maxLevel")) { - try { - maxLevel = Integer.parseInt(value); - } catch (NumberFormatException e) {} - } - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/block/TextBoxBlock.java b/src/net/java/textilej/parser/markup/confluence/block/TextBoxBlock.java deleted file mode 100644 index 9bd7f72..0000000 --- a/src/net/java/textilej/parser/markup/confluence/block/TextBoxBlock.java +++ /dev/null @@ -1,104 +0,0 @@ -package net.java.textilej.parser.markup.confluence.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; - -public class TextBoxBlock extends ParameterizedBlock { - - - private final Pattern startPattern; - private final Pattern endPattern; - - private final BlockType blockType; - - private int blockLineCount = 0; - private Matcher matcher; - - private String title; - private StringBuilder markupContent; - - public TextBoxBlock(BlockType blockType,String name) { - this.blockType = blockType; - startPattern = Pattern.compile("\\{"+name+"(?::([^\\}]*))?\\}(.*)"); - endPattern = Pattern.compile("(\\{"+name+"\\})(.*)"); - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - setOptions(matcher.group(1)); - - Attributes attributes = new Attributes(); - attributes.setTitle(title); - - offset = matcher.start(2); - - builder.beginBlock(blockType, attributes); - markupContent = new StringBuilder(); - } - - int end = line.length(); - int segmentEnd = end; - boolean terminating = false; - - Matcher endMatcher = endPattern.matcher(line); - if (offset < end) { - if (blockLineCount == 0) { - endMatcher.region(offset, end); - } - if (endMatcher.find()) { - terminating = true; - end = endMatcher.start(2); - segmentEnd = endMatcher.start(1); - } - } - ++blockLineCount; - - - if (end < line.length()) { - state.setLineSegmentEndOffset(end); - } - markupContent.append(line.substring(offset,segmentEnd)); - markupContent.append("\n"); - - if (terminating) { - setClosed(true); - } - return end==line.length()?-1:end; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - title = null; - markupContent = null; - matcher = startPattern.matcher(line); - if (lineOffset > 0) { - matcher.region(lineOffset, line.length()); - } - return matcher.matches(); - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - if (markupContent != null) { - - getParser().parse(markupContent.toString(),false); - markupContent = null; - builder.endBlock(); // the block - } - } - super.setClosed(closed); - } - - @Override - protected void setOption(String key, String value) { - if (key.equals("title")) { - title = value; - } - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/phrase/ImagePhraseModifier.java b/src/net/java/textilej/parser/markup/confluence/phrase/ImagePhraseModifier.java deleted file mode 100644 index ba402c9..0000000 --- a/src/net/java/textilej/parser/markup/confluence/phrase/ImagePhraseModifier.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.java.textilej.parser.markup.confluence.phrase; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - -public class ImagePhraseModifier extends PatternBasedElement { - - protected static final int CONTENT_GROUP = 1; - - @Override - protected String getPattern(int groupOffset) { - - return "!([^\\|!\\s]+)(?:\\|([^!]*))?!"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new ImagePhraseModifierProcessor(); - } - - private static class ImagePhraseModifierProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String imageUrl = group(CONTENT_GROUP); - - Attributes attributes = new Attributes(); - builder.image(attributes, imageUrl); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/phrase/SimplePhraseModifier.java b/src/net/java/textilej/parser/markup/confluence/phrase/SimplePhraseModifier.java deleted file mode 100644 index 021e5a1..0000000 --- a/src/net/java/textilej/parser/markup/confluence/phrase/SimplePhraseModifier.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.java.textilej.parser.markup.confluence.phrase; - -import net.java.textilej.parser.DocumentBuilder.SpanType; - -public class SimplePhraseModifier extends SimpleWrappedPhraseModifier { - - public SimplePhraseModifier(String delimiter, SpanType spanType, boolean nesting) { - super(delimiter,delimiter,spanType, nesting); - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/phrase/SimpleWrappedPhraseModifier.java b/src/net/java/textilej/parser/markup/confluence/phrase/SimpleWrappedPhraseModifier.java deleted file mode 100644 index aa50718..0000000 --- a/src/net/java/textilej/parser/markup/confluence/phrase/SimpleWrappedPhraseModifier.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.java.textilej.parser.markup.confluence.phrase; - -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.PatternBasedElement; - - -public class SimpleWrappedPhraseModifier extends PatternBasedElement { - - protected static final int CONTENT_GROUP = 1; - - private static class SimplePhraseModifierProcessor extends PatternBasedElementProcessor { - private final SpanType spanType; - private final boolean nesting; - - public SimplePhraseModifierProcessor(SpanType spanType, boolean nesting) { - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - public void emit() { - Attributes attributes = new Attributes(); - getBuilder().beginSpan(spanType, attributes); - if (nesting) { - getDialect().emitMarkupLine(parser, state, state.getLineCharacterOffset() + getStart(this), - getContent(this), 0); - } else { - getDialect().emitMarkupText(parser, state, getContent(this)); - } - getBuilder().endSpan(); - } - } - - private String startDelimiter; - private String endDelimiter; - private SpanType spanType; - private final boolean nesting; - - public SimpleWrappedPhraseModifier(String startDelimiter,String endDelimiter, SpanType spanType, boolean nesting) { - this.startDelimiter = startDelimiter; - this.endDelimiter = endDelimiter; - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - protected String getPattern(int groupOffset) { - return - Pattern.quote(startDelimiter) + - "([^\\s-](?:.*?[^\\s-])?)" + // content: note that we dont allow preceding '-' or trailing '-' to avoid conflict with strikethrough and emdash - Pattern.quote(endDelimiter); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - protected static String getContent(PatternBasedElementProcessor processor) { - return processor.group(CONTENT_GROUP); - } - protected static int getStart(PatternBasedElementProcessor processor) { - return processor.start(CONTENT_GROUP); - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new SimplePhraseModifierProcessor(spanType, nesting); - } -} diff --git a/src/net/java/textilej/parser/markup/confluence/token/AnchorReplacementToken.java b/src/net/java/textilej/parser/markup/confluence/token/AnchorReplacementToken.java deleted file mode 100644 index 3e8f818..0000000 --- a/src/net/java/textilej/parser/markup/confluence/token/AnchorReplacementToken.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.java.textilej.parser.markup.confluence.token; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class AnchorReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "\\{anchor:([^\\}]+)\\}"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new AnchorReplacementTokenProcessor(); - } - - private static class AnchorReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String name = group(1); - Attributes attributes = new Attributes(); - attributes.setId(name); - getBuilder().beginSpan(SpanType.SPAN, attributes); - getBuilder().endSpan(); - } - - } - -} diff --git a/src/net/java/textilej/parser/markup/confluence/token/HyperlinkReplacementToken.java b/src/net/java/textilej/parser/markup/confluence/token/HyperlinkReplacementToken.java deleted file mode 100644 index 6746486..0000000 --- a/src/net/java/textilej/parser/markup/confluence/token/HyperlinkReplacementToken.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.java.textilej.parser.markup.confluence.token; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.LinkAttributes; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class HyperlinkReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "\\[([^\\]]+)\\]"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String linkComposite = group(1); - String[] parts = linkComposite.split("\\s*\\|\\s*"); - String text = parts.length > 1?parts[0]:null; - String href = parts.length > 1?parts[1]:parts[0]; - String tip = parts.length > 2?parts[2]:null; - if (text == null || text.length() == 0) { - text = href; - } - Attributes attributes = new LinkAttributes(); - attributes.setTitle(tip); - getBuilder().link(attributes,href, text); - } - } -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/MediaWikiDialect.java b/src/net/java/textilej/parser/markup/mediawiki/MediaWikiDialect.java deleted file mode 100644 index f7fd32d..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/MediaWikiDialect.java +++ /dev/null @@ -1,153 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki; - -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.markup.mediawiki.block.HeadingBlock; -import net.java.textilej.parser.markup.mediawiki.block.ListBlock; -import net.java.textilej.parser.markup.mediawiki.block.ParagraphBlock; -import net.java.textilej.parser.markup.mediawiki.block.PreformattedBlock; -import net.java.textilej.parser.markup.mediawiki.block.TableBlock; -import net.java.textilej.parser.markup.mediawiki.phrase.EscapePhraseModifier; -import net.java.textilej.parser.markup.mediawiki.phrase.SimplePhraseModifier; -import net.java.textilej.parser.markup.mediawiki.token.HyperlinkExternalReplacementToken; -import net.java.textilej.parser.markup.mediawiki.token.HyperlinkInternalReplacementToken; -import net.java.textilej.parser.markup.mediawiki.token.ImageReplacementToken; -import net.java.textilej.parser.markup.mediawiki.token.LineBreakToken; -import net.java.textilej.parser.markup.mediawiki.token.TemplateReplacementToken; -import net.java.textilej.parser.markup.phrase.HtmlCommentPhraseModifier; -import net.java.textilej.parser.markup.phrase.LimitedHtmlEndTagPhraseModifier; -import net.java.textilej.parser.markup.phrase.LimitedHtmlStartTagPhraseModifier; -import net.java.textilej.parser.markup.token.EntityReferenceReplacementToken; -import net.java.textilej.parser.markup.token.ImpliedHyperlinkReplacementToken; -import net.java.textilej.parser.markup.token.PatternLiteralReplacementToken; - -/** - * A dialect for MediaWiki - * Wikitext markup, which is the wiki format - * used by several other major sites. - * - * @author dgreen - * - */ -public class MediaWikiDialect extends Dialect { - private List blocks = new ArrayList(); - private List paragraphBreakingBlocks = new ArrayList(); - - private static PatternBasedSyntax tokenSyntax = new PatternBasedSyntax(); - private static PatternBasedSyntax phraseModifierSyntax = new PatternBasedSyntax(); - - private String internalPageHrefPrefix = "/wiki/"; - - { - - // IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!! - - blocks.add(new HeadingBlock()); - blocks.add(new ListBlock()); - blocks.add(new PreformattedBlock()); - blocks.add(new TableBlock()); - final ParagraphBlock paragraphBlock = new ParagraphBlock(); - blocks.add(paragraphBlock); // ORDER DEPENDENCY: this one must be last!! - - for (Block block: blocks) { - if (block == paragraphBlock) { - continue; - } - paragraphBreakingBlocks.add(block); - } - } - static { - phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.,\\\"'?!;:\\)\\(\\{\\}\\[\\]])|^)(?:",0); - phraseModifierSyntax.add(new EscapePhraseModifier()); - phraseModifierSyntax.add(new SimplePhraseModifier("'''''",new SpanType[] { SpanType.BOLD, SpanType.ITALIC },true)); - phraseModifierSyntax.add(new SimplePhraseModifier("'''",SpanType.BOLD,true)); - phraseModifierSyntax.add(new SimplePhraseModifier("''",SpanType.ITALIC,true)); - phraseModifierSyntax.endGroup(")(?=\\W|$)",0); - - String[] allowedHtmlTags = new String[] { - // HANDLED BY LineBreakToken "
", - // HANDLED BY LineBreakToken "
", - "b", "big", "blockquote", "caption", "center", "cite", "code", "dd", "del", "div", "dl", "dt", "em", "font", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "ins", "li", "ol", "p", "pre", "rb", "rp", "rt", "ruby", "s", "small", "span", "strike", "strong", "sub", "sup", "table", "td", "th", "tr", "tt", "u", "ul", "var" }; - phraseModifierSyntax.add(new LimitedHtmlEndTagPhraseModifier(allowedHtmlTags)); - phraseModifierSyntax.add(new LimitedHtmlStartTagPhraseModifier(allowedHtmlTags)); - phraseModifierSyntax.add(new HtmlCommentPhraseModifier()); - - tokenSyntax.add(new LineBreakToken()); - tokenSyntax.add(new EntityReferenceReplacementToken("(tm)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(TM)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(c)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(C)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(r)","#174")); - tokenSyntax.add(new EntityReferenceReplacementToken("(R)","#174")); - tokenSyntax.add(new ImageReplacementToken()); - tokenSyntax.add(new HyperlinkInternalReplacementToken()); - tokenSyntax.add(new HyperlinkExternalReplacementToken()); - tokenSyntax.add(new ImpliedHyperlinkReplacementToken()); - tokenSyntax.add(new PatternLiteralReplacementToken("(?:(?<=\\w\\s)(----)(?=\\s\\w))","
")); // horizontal rule - tokenSyntax.add(new TemplateReplacementToken()); - tokenSyntax.add(new net.java.textilej.parser.markup.mediawiki.token.EntityReferenceReplacementToken()); - } - - - @Override - protected PatternBasedSyntax getPhraseModifierSyntax() { - return phraseModifierSyntax; - } - - @Override - protected PatternBasedSyntax getReplacementTokenSyntax() { - return tokenSyntax; - } - - - - @Override - public List getBlocks() { - return blocks; - } - - public List getParagraphBreakingBlocks() { - return paragraphBreakingBlocks; - } - - /** - * Convert a page name to an href to the page. - * - * @param pageName the name of the page to target - * - * @return the href to access the page - * - * @see #getInternalPageHrefPrefix() - */ - public String toInternalHref(String pageName) { - String pageId = pageName.replace(' ', '_'); - if (pageId.startsWith(":")) { // category - pageId = pageId.substring(1); - } else if (pageId.startsWith("#")) { - // internal anchor - return pageId; - } - return internalPageHrefPrefix + pageId; - } - - /** - * Get the href prefix for references to internal pages. The default value is /wiki/. - */ - public String getInternalPageHrefPrefix() { - return internalPageHrefPrefix; - } - - /** - * Set the href prefix for references to internal pages. The default value is /wiki/. - */ - public void setInternalPageHrefPrefix(String internalPageHrefPrefix) { - this.internalPageHrefPrefix = internalPageHrefPrefix; - } - - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/block/HeadingBlock.java b/src/net/java/textilej/parser/markup/mediawiki/block/HeadingBlock.java deleted file mode 100644 index a50b6b4..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/block/HeadingBlock.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.markup.Block; - -public class HeadingBlock extends Block { - - private static final Pattern pattern = Pattern.compile("\\s*(\\={1,6})\\s*(.+?)\\s*\\1"); - - private int blockLineCount = 0; - private Matcher matcher; - - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = pattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount > 0) { - throw new IllegalStateException(); - } - ++blockLineCount; - - int level = matcher.group(1).length(); - - String text = matcher.group(2); - - final Attributes attributes = new Attributes(); - if (attributes.getId() == null) { - attributes.setId(state.getIdGenerator().newId("h"+level,line.substring(offset))); - } - builder.beginHeading(level,attributes); - builder.characters(text); - builder.endHeading(); - - setClosed(true); - return -1; - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/block/ListBlock.java b/src/net/java/textilej/parser/markup/mediawiki/block/ListBlock.java deleted file mode 100644 index 0e6b57a..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/block/ListBlock.java +++ /dev/null @@ -1,250 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.block; - -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * List block, matches blocks that start with *, # or - - * - * @author dgreen - */ -public class ListBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = 2; - - static final Pattern startPattern = Pattern.compile("((?:(?:\\*)|(?:#)|(?:-)|(?:\\;)|(?:\\:))+)\\s?(.+)"); - static final Pattern definitionPattern = Pattern.compile("(\\s+\\:\\s+)(.*)"); - - private int blockLineCount = 0; - private Matcher matcher; - - private Stack listState; - - public ListBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - boolean continuation = false; - if (blockLineCount == 0) { - listState = new Stack(); - Attributes attributes = new Attributes(); - String listSpec = matcher.group(1); - char lastChar = listSpec.charAt(listSpec.length()-1); - int level = calculateLevel(listSpec); - BlockType type = calculateType(lastChar); - BlockType itemType = calculateItemType(lastChar); - - if (type == BlockType.BULLETED_LIST && '-' == lastChar) { - attributes.setCssStyle("list-style: square"); - } - - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - listState.push(new ListState(1,type,itemType)); - builder.beginBlock(type, attributes); - - adjustLevel(lastChar, level, type, itemType); - } else { - Matcher matcher = startPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - String listSpec = matcher.group(1); - char lastChar = listSpec.charAt(listSpec.length()-1); - int lineLevel = calculateLevel(listSpec); - BlockType type = calculateType(lastChar); - BlockType itemType = calculateItemType(lastChar); - - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - continuation = adjustLevel(lastChar, lineLevel, type, itemType); - } - ++blockLineCount; - - ListState listState = this.listState.peek(); - if (!continuation && listState.openItem) { - listState.openItem = false; - builder.endBlock(); - } - if (!listState.openItem) { - listState.openItem = true; - builder.beginBlock(listState.itemType, new Attributes()); - } - - String definition = null; - int definitionOffset = -1; - if (listState.itemType == BlockType.DEFINITION_TERM) { - // detect definition on same line as term - Matcher definitionMatcher = definitionPattern.matcher(line); - if (offset > 0) { - definitionMatcher.region(offset, line.length()); - } - if (definitionMatcher.find()) { - line = line.substring(offset,definitionMatcher.start(1)); - offset = 0; - definition = definitionMatcher.group(2); - definitionOffset = definitionMatcher.start(2); - } - } - if (definition == null) { - dialect.emitMarkupLine(getParser(),state,line, offset); - } else { - dialect.emitMarkupLine(getParser(),state,offset,line,0); - } - - if (definition != null) { - listState.openItem = false; - builder.endBlock(); - - adjustLevel(' ',listState.level,BlockType.DEFINITION_LIST,BlockType.DEFINITION_ITEM); - - listState = this.listState.peek(); - if (listState.openItem) { - builder.endBlock(); - } - listState.openItem = true; - builder.beginBlock(listState.itemType, new Attributes()); - - dialect.emitMarkupLine(parser, state,definitionOffset, definition,0); - } - - return -1; - } - - /** - * - * @param lastChar the last character of the list specification, or ' ' if unknown - * - * @return true if the item is a continuation - */ - private boolean adjustLevel(char lastChar, int lineLevel, BlockType type, BlockType itemType) { - boolean continuation = false; - - for (ListState previousState = listState.peek(); - lineLevel != previousState.level || previousState.type != type || previousState.itemType != itemType; - previousState = listState.peek()) { - - if (lineLevel > previousState.level) { - if (!previousState.openItem) { - builder.beginBlock(previousState.itemType, new Attributes()); - previousState.openItem = true; - } - - Attributes blockAttributes = new Attributes(); - if (type == BlockType.BULLETED_LIST && '-' == lastChar) { - blockAttributes.setCssStyle("list-style: square"); - } - listState.push(new ListState(previousState.level+1,type,itemType)); - builder.beginBlock(type,blockAttributes); - } else if (lineLevel == previousState.level && previousState.type == type && previousState.itemType != itemType) { - if (previousState.openItem) { - builder.endBlock(); - previousState.openItem = false; - } - previousState.itemType = itemType; - } else { - if (lineLevel == previousState.level && lastChar == ':') { - // this is possibly a continuation of the previous item. - if (previousState.itemType != BlockType.DEFINITION_ITEM && previousState.itemType != BlockType.DEFINITION_TERM) { - // we found a continuation - continuation = true; - break; - } - } - closeOne(); - if (listState.isEmpty()) { - Attributes blockAttributes = new Attributes(); - if (type == BlockType.BULLETED_LIST && '-' == lastChar) { - blockAttributes.setCssStyle("list-style: square"); - } - listState.push(new ListState(1,type,itemType)); - builder.beginBlock(type,blockAttributes); - } - } - } - - return continuation; - } - - private int calculateLevel(String listSpec) { - return listSpec.length(); - } - - private BlockType calculateType(char lastChar) { - switch (lastChar) { - case '#': - return BlockType.NUMERIC_LIST; - case ':': - case ';': - return BlockType.DEFINITION_LIST; - default: - return BlockType.BULLETED_LIST; - } - } - - private BlockType calculateItemType(char lastChar) { - switch (lastChar) { - case ';': - return BlockType.DEFINITION_TERM; - case ':': - return BlockType.DEFINITION_ITEM; - default: - return BlockType.LIST_ITEM; - } - } - - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - listState = null; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - while (listState != null && !listState.isEmpty()) { - closeOne(); - } - listState = null; - } - super.setClosed(closed); - } - - private void closeOne() { - ListState e = listState.pop(); - if (e.openItem) { - builder.endBlock(); - } - builder.endBlock(); - } - - private static class ListState { - int level; - BlockType type; - BlockType itemType; - boolean openItem; - - private ListState(int level, BlockType type,BlockType itemType) { - super(); - this.level = level; - this.type = type; - this.itemType = itemType; - } - - } -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/block/ParagraphBlock.java b/src/net/java/textilej/parser/markup/mediawiki/block/ParagraphBlock.java deleted file mode 100644 index 354ab33..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/block/ParagraphBlock.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.mediawiki.MediaWikiDialect; - -/** - * Matches any markup text. - * - * @author dgreen - */ -public class ParagraphBlock extends Block { - - private int blockLineCount = 0; - private Block nestedBlock = null; - - public ParagraphBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - - builder.beginBlock(BlockType.PARAGRAPH, attributes); - } else if (nestedBlock != null) { - int returnOffset = nestedBlock.processLine(line, offset); - if (nestedBlock.isClosed()) { - nestedBlock = null; - } - if (returnOffset >= 0) { - offset = returnOffset; - if (nestedBlock != null) { - throw new IllegalStateException(); - } - } else { - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - return returnOffset; - } - } - - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - - - MediaWikiDialect dialect = (MediaWikiDialect) getDialect(); - - // paragraphs can have nested lists and other things - for (Block block: dialect.getParagraphBreakingBlocks()) { - if (block.canStart(line, offset)) { - setClosed(true); - return 0; - } - } - - ++blockLineCount; - - - if (nestedBlock != null) { - if (blockLineCount > 1) { - builder.lineBreak(); - } - nestedBlock.processLine(line, offset); - } else { - if (offset == 0 && line.length() > 0 && line.charAt(0) == ' ') { - // a preformatted block. - setClosed(true); - return 0; - } - if (blockLineCount != 1) { - // note: newlines don't automatically convert to line breaks - builder.characters("\n"); - } - dialect.emitMarkupLine(getParser(),state,line, offset); - } - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - return true; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - if (nestedBlock != null) { - nestedBlock.setClosed(closed); - nestedBlock = null; - } - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/block/PreformattedBlock.java b/src/net/java/textilej/parser/markup/mediawiki/block/PreformattedBlock.java deleted file mode 100644 index 01a9c99..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/block/PreformattedBlock.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -public class PreformattedBlock extends Block { - - private int blockLineCount = 0; - - @Override - public boolean canStart(String line, int lineOffset) { - if (lineOffset == 0 && line.length() > 0 && line.charAt(0) == ' ') { - return true; - } - return false; - } - - @Override - public int processLineContent(String line,int offset) { - if (dialect.isEmptyLine(line) || (offset == 0 && line.charAt(0) != ' ')) { - setClosed(true); - return 0; - } - if (blockLineCount++ == 0) { - builder.beginBlock(BlockType.PREFORMATTED, new Attributes()); - } - builder.characters(line.substring(1)); - builder.characters("\n"); - return -1; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); // pre - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/block/TableBlock.java b/src/net/java/textilej/parser/markup/mediawiki/block/TableBlock.java deleted file mode 100644 index f7f34cd..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/block/TableBlock.java +++ /dev/null @@ -1,245 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.TableAttributes; -import net.java.textilej.parser.TableCellAttributes; -import net.java.textilej.parser.TableRowAttributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * an implementation of MediaWiki tables, - * see MediaWiki:Help:Tables for details - * - * @author dgreen - * - */ -public class TableBlock extends Block { - - private static final Pattern rowCellSplitter = Pattern.compile("\\s*(\\|\\||!!)\\s*"); - private static final Pattern startPattern = Pattern.compile("\\{\\|\\s*(.+)?"); - private static final Pattern optionsPattern = Pattern.compile("([a-zA-Z]+)=\"([^\"]*)\""); - private static final Pattern newRowPattern = Pattern.compile("\\|-\\s*(.+)?"); - private static final Pattern cellPattern = Pattern.compile("(\\||!)\\s*(.+)?"); - private static final Pattern cellSplitterPattern = Pattern.compile("\\s*(?:([^\\|]+)?\\|)?\\s*(.+)?"); - private static final Pattern endPattern = Pattern.compile("\\|\\}\\s*(.+)?"); - - - private int blockLineCount; - private Matcher matcher; - private boolean openRow; - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount++ == 0) { - TableAttributes attributes = new TableAttributes(); - - // first line opens table - String options = matcher.group(1); - if (options != null) { - Matcher optionsMatcher = optionsPattern.matcher(options); - while (optionsMatcher.find()) { - String optionName = optionsMatcher.group(1); - String optionValue = optionsMatcher.group(2); - if (optionName.equalsIgnoreCase("id")) { - attributes.setId(optionValue); - } else if (optionName.equalsIgnoreCase("style")) { - attributes.setCssStyle(optionValue); - } else if (optionName.equalsIgnoreCase("class")) { - attributes.setCssClass(optionValue); - } else if (optionName.equalsIgnoreCase("title")) { - attributes.setTitle(optionValue); - } else if (optionName.equalsIgnoreCase("border")) { - attributes.setBorder(optionValue); - } else if (optionName.equalsIgnoreCase("summary")) { - attributes.setSummary(optionValue); - } else if (optionName.equalsIgnoreCase("width")) { - attributes.setWidth(optionValue); - } else if (optionName.equalsIgnoreCase("frame")) { - attributes.setFrame(optionValue); - } else if (optionName.equalsIgnoreCase("rules")) { - attributes.setRules(optionValue); - } else if (optionName.equalsIgnoreCase("cellspacing")) { - attributes.setCellspacing(optionValue); - } else if (optionName.equalsIgnoreCase("cellpadding")) { - attributes.setCellpadding(optionValue); - } else if (optionName.equalsIgnoreCase("bgcolor")) { - attributes.setBgcolor(optionValue); - } - } - } - builder.beginBlock(BlockType.TABLE, attributes); - // table open line never has cells - return -1; - } else { - Matcher newRowMatcher = newRowPattern.matcher(line); - if (newRowMatcher.matches()) { - TableRowAttributes attributes = new TableRowAttributes(); - String newRowOptions = newRowMatcher.group(1); - if (newRowOptions != null) { - Matcher optionsMatcher = optionsPattern.matcher(newRowOptions); - while (optionsMatcher.find()) { - String optionName = optionsMatcher.group(1); - String optionValue = optionsMatcher.group(2); - if (optionName.equalsIgnoreCase("id")) { - attributes.setId(optionValue); - } else if (optionName.equalsIgnoreCase("style")) { - attributes.setCssStyle(optionValue); - } else if (optionName.equalsIgnoreCase("class")) { - attributes.setCssClass(optionValue); - } else if (optionName.equalsIgnoreCase("title")) { - attributes.setTitle(optionValue); - } else if (optionName.equalsIgnoreCase("align")) { - attributes.setAlign(optionValue); - } else if (optionName.equalsIgnoreCase("valign")) { - attributes.setValign(optionValue); - } else if (optionName.equalsIgnoreCase("bgcolor")) { - attributes.setBgcolor(optionValue); - } - } - } - openRow(newRowMatcher.start(),attributes); - return -1; - } else { - Matcher endMatcher = endPattern.matcher(line); - if (endMatcher.matches()) { - setClosed(true); - return endMatcher.start(1); - } else { - - Matcher cellMatcher = cellPattern.matcher(line); - if (cellMatcher.matches()) { - String kind = cellMatcher.group(1); - String contents = cellMatcher.group(2); - if (contents == null) { - // likely an incomplete line - return -1; - } - int contentsStart = cellMatcher.start(2); - BlockType type = ("!".equals(kind))?BlockType.TABLE_CELL_HEADER:BlockType.TABLE_CELL_NORMAL; - - if (!openRow) { - openRow(cellMatcher.start(),new Attributes()); - } - emitCells(contentsStart,type,contents); - - return -1; - } else { - // ignore, bad formatting or unsupported syntax (caption) - return -1; - } - } - } - } - } - - private void emitCells(int contentsStart, BlockType type, String contents) { - int lastEnd = 0; - Matcher matcher = rowCellSplitter.matcher(contents); - while (matcher.find()) { - int found = matcher.start(); - String cell; - if (found > lastEnd) { - cell = contents.substring(lastEnd,found); - } else { - cell = ""; - } - emitCell(lastEnd+contentsStart,type,cell); - lastEnd = matcher.end(); - } - if (lastEnd < contents.length()) { - emitCell(lastEnd+contentsStart,type,contents.substring(lastEnd)); - } - } - - private void emitCell(int lineCharacterOffset, BlockType type, String cell) { - Matcher cellSplitterMatcher = cellSplitterPattern.matcher(cell); - if (!cellSplitterMatcher.matches()) { - throw new IllegalStateException(); - } - String cellOptions = cellSplitterMatcher.group(1); - String cellContents = cellSplitterMatcher.group(2); - if (cellContents == null) { - // probably invalid syntax - return; - } - - int contentsStart = cellSplitterMatcher.start(2); - - TableCellAttributes attributes = new TableCellAttributes(); - - if (cellOptions != null) { - Matcher optionsMatcher = optionsPattern.matcher(cellOptions); - while (optionsMatcher.find()) { - String optionName = optionsMatcher.group(1); - String optionValue = optionsMatcher.group(2); - if (optionName.equalsIgnoreCase("id")) { - attributes.setId(optionValue); - } else if (optionName.equalsIgnoreCase("style")) { - attributes.setCssStyle(optionValue); - } else if (optionName.equalsIgnoreCase("class")) { - attributes.setCssClass(optionValue); - } else if (optionName.equalsIgnoreCase("title")) { - attributes.setTitle(optionValue); - } else if (optionName.equalsIgnoreCase("align")) { - attributes.setAlign(optionValue); - } else if (optionName.equalsIgnoreCase("valign")) { - attributes.setValign(optionValue); - } else if (optionName.equalsIgnoreCase("bgcolor")) { - attributes.setBgcolor(optionValue); - } else if (optionName.equalsIgnoreCase("colspan")) { - attributes.setColspan(optionValue); - } else if (optionName.equalsIgnoreCase("rowspan")) { - attributes.setRowspan(optionValue); - } - } - } - state.setLineCharacterOffset(lineCharacterOffset); - - builder.beginBlock(type, attributes); - - dialect.emitMarkupLine(parser, state,lineCharacterOffset+contentsStart,cellContents, 0); - builder.endBlock(); - } - - private void openRow(int lineOffset,Attributes attributes) { - closeRow(); - state.setLineCharacterOffset(lineOffset); - builder.beginBlock(BlockType.TABLE_ROW, attributes); - openRow = true; - } - - private void closeRow() { - if (openRow) { - builder.endBlock(); - openRow = false; - } - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - openRow = false; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - closeRow(); - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/phrase/EscapePhraseModifier.java b/src/net/java/textilej/parser/markup/mediawiki/phrase/EscapePhraseModifier.java deleted file mode 100644 index a542a24..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/phrase/EscapePhraseModifier.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.phrase; - - - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.phrase.LiteralPhraseModifierProcessor; - -public class EscapePhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return - "" + - "(\\S(?:.*?\\S)?)" + // content - ""; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(true); - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/phrase/SimplePhraseModifier.java b/src/net/java/textilej/parser/markup/mediawiki/phrase/SimplePhraseModifier.java deleted file mode 100644 index f8c7907..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/phrase/SimplePhraseModifier.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.phrase; - -import net.java.textilej.parser.DocumentBuilder.SpanType; - -public class SimplePhraseModifier extends SimpleWrappedPhraseModifier { - - public SimplePhraseModifier(String delimiter, SpanType spanType) { - super(delimiter,delimiter,new SpanType[] { spanType }); - } - - public SimplePhraseModifier(String delimiter, SpanType spanType,boolean nesting) { - super(delimiter,delimiter,new SpanType[] { spanType },nesting); - } - - public SimplePhraseModifier(String delimiter, SpanType[] spanType) { - super(delimiter,delimiter,spanType); - } - - public SimplePhraseModifier(String delimiter, SpanType[] spanType,boolean nesting) { - super(delimiter,delimiter,spanType,nesting); - } -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/phrase/SimpleWrappedPhraseModifier.java b/src/net/java/textilej/parser/markup/mediawiki/phrase/SimpleWrappedPhraseModifier.java deleted file mode 100644 index a6a20c8..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/phrase/SimpleWrappedPhraseModifier.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.phrase; - -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - -public class SimpleWrappedPhraseModifier extends PatternBasedElement { - - protected static final int CONTENT_GROUP = 1; - - private static class SimplePhraseModifierProcessor extends PatternBasedElementProcessor { - private final SpanType[] spanType; - private final boolean nesting; - - public SimplePhraseModifierProcessor(SpanType[] spanType, boolean nesting) { - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - public void emit() { - for (SpanType type: spanType) { - getBuilder().beginSpan(type, new Attributes()); - } - if (nesting) { - getDialect().emitMarkupLine(parser, state,state.getLineCharacterOffset()+ getStart(this), getContent(this), 0); - } else { - getDialect().emitMarkupText(parser, state, getContent(this)); - } - for (int x = 0;x allowedEntities = new HashSet(); - static { - allowedEntities.add(""); - } - - @Override - protected String getPattern(int groupOffset) { - return "&(#?[a-zA-Z0-9]{2,7});"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new EntityReferenceProcessor(); - } - - private static class EntityReferenceProcessor extends PatternBasedElementProcessor { - - @Override - public void emit() { - String entity = group(1); - getBuilder().entityReference(entity); - } - - } -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkExternalReplacementToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkExternalReplacementToken.java deleted file mode 100644 index 8d1b0d6..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkExternalReplacementToken.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -/** - * match [[internal links]] - * - * @author dgreen - * - */ -public class HyperlinkExternalReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(?:\\[([^\\[\\]\\|\\s]+)(?:(?:\\||\\s)([^\\]]*))?\\s*\\])"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String href = group(1); - String altText = group(2); - - if (altText == null || altText.trim().length() == 0) { - altText = href; - } - builder.link(href, altText); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkInternalReplacementToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkInternalReplacementToken.java deleted file mode 100644 index 6f97d5b..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkInternalReplacementToken.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.LinkAttributes; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.mediawiki.MediaWikiDialect; - -/** - * match [[internal links]] - * - * @author dgreen - * - */ -public class HyperlinkInternalReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(?:\\[\\[([^\\]\\|]+?)\\s*(?:\\|\\s*([^\\]]*))?\\]\\])"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String pageName = group(1); - String altText = group(2); - String href = ((MediaWikiDialect)getDialect()).toInternalHref(pageName); - - // category references start with ':' but are not referenced that way in the text - if (pageName.startsWith(":")) { - pageName = pageName.substring(1); - } - if (altText == null || altText.trim().length() == 0) { - altText = pageName; - if (altText.startsWith("#")) { - altText = altText.substring(1); - } - } - if (pageName.startsWith("#")) { - builder.link(href, altText); - } else { - Attributes attributes = new LinkAttributes(); - attributes.setTitle(pageName); - builder.link(attributes,href, altText); - } - } - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkReplacementToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkReplacementToken.java deleted file mode 100644 index d53f1ea..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/HyperlinkReplacementToken.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class HyperlinkReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(?:(\"|\\!)([^\"]+)\\"+(1+groupOffset)+":([^\\s]+))"; - } - - @Override - protected int getPatternGroupCount() { - return 3; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String hyperlinkBoundaryText = group(1); - String hyperlinkSrc = group(2); - String href = group(3); - - if (hyperlinkBoundaryText.equals("\"")) { - builder.link(href, hyperlinkSrc); - } else { - builder.imageLink(href, hyperlinkSrc); - } - } - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/ImageReplacementToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/ImageReplacementToken.java deleted file mode 100644 index f587db7..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/ImageReplacementToken.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import net.java.textilej.parser.ImageAttributes; -import net.java.textilej.parser.ImageAttributes.Align; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -/** - * match [[Image:someImage.png]] - * - * @author dgreen - * - */ -public class ImageReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(?:\\[\\[Image:([^\\]\\|]+)(?:\\|([^\\]]*))?\\]\\])"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new ImageReplacementTokenProcessor(); - } - - private static class ImageReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String imageUrl = group(1); - String optionsString = group(2); - - ImageAttributes attributes = new ImageAttributes(); - if (optionsString != null) { - String[] options = optionsString.split("\\s*\\|\\s*"); - for (String option: options) { - if ("center".equals(option)) { - attributes.setAlign(Align.Middle); - } else if ("left".equals(option)) { - attributes.setAlign(Align.Left); - } else if ("right".equals(option)) { - attributes.setAlign(Align.Right); - } else if ("none".equals(option)) { - attributes.setAlign(null); - } else if ("thumb".equals(option)||"thumbnail".equals(option)) { - // ignore - } else if (option.matches("\\d+px")) { - try { - int size = Integer.parseInt(option.substring(0,option.length()-2)); - attributes.setWidth(size); - attributes.setHeight(size); - } catch (NumberFormatException e) { - // ignore - } - } else if ("frameless".equals(option)) { - attributes.setBorder(0); - } else if ("frame".equals(option)) { - attributes.setBorder(1); - } else { - attributes.setTitle(option); - } - } - } - builder.image(attributes, imageUrl); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/LineBreakToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/LineBreakToken.java deleted file mode 100644 index fad0611..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/LineBreakToken.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class LineBreakToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(
|
)"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LineBreakProcessor(); - } - - private static class LineBreakProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - builder.lineBreak(); - } - } -} diff --git a/src/net/java/textilej/parser/markup/mediawiki/token/TemplateReplacementToken.java b/src/net/java/textilej/parser/markup/mediawiki/token/TemplateReplacementToken.java deleted file mode 100644 index 2706b43..0000000 --- a/src/net/java/textilej/parser/markup/mediawiki/token/TemplateReplacementToken.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.java.textilej.parser.markup.mediawiki.token; - -import java.util.HashMap; -import java.util.Map; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class TemplateReplacementToken extends PatternBasedElement { - - private static Map> processorByTemplate = new HashMap>(); - static { - processorByTemplate.put("endash",EndashElementProcessor.class); - processorByTemplate.put("ndash",EndashElementProcessor.class); - processorByTemplate.put("mdash",EmdashElementProcessor.class); - processorByTemplate.put("emdash",EmdashElementProcessor.class); - } - - @Override - protected String getPattern(int groupOffset) { - return "(\\{\\{([^\\s]+)\\}\\})"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new DispatchingProcessor(); - } - - private static class DispatchingProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - Class processor = processorByTemplate.get(group(2)); - if (processor == null) { - getBuilder().characters(group(1)); - } else { - PatternBasedElementProcessor delegate; - try { - delegate = processor.newInstance(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - delegate.setLineStartOffset(getLineStartOffset()); - delegate.setLineEndOffset(getLineEndOffset()); - delegate.setParser(getParser()); - delegate.setState(getState()); - delegate.setGroup(1,group(1),start(1),end(1)); - delegate.setGroup(2,group(2),start(2),end(2)); - delegate.emit(); - } - } - } - - public static class EndashElementProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - getBuilder().entityReference("nbsp"); - getBuilder().entityReference("ndash"); - getBuilder().characters(" "); - } - } - public static class EmdashElementProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - getBuilder().entityReference("nbsp"); - getBuilder().entityReference("mdash"); - getBuilder().characters(" "); - } - } -} diff --git a/src/net/java/textilej/parser/markup/phrase/HtmlCommentPhraseModifier.java b/src/net/java/textilej/parser/markup/phrase/HtmlCommentPhraseModifier.java deleted file mode 100644 index 4b31332..0000000 --- a/src/net/java/textilej/parser/markup/phrase/HtmlCommentPhraseModifier.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - - -public class HtmlCommentPhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "()"; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - -} diff --git a/src/net/java/textilej/parser/markup/phrase/HtmlEndTagPhraseModifier.java b/src/net/java/textilej/parser/markup/phrase/HtmlEndTagPhraseModifier.java deleted file mode 100644 index 8a79aea..0000000 --- a/src/net/java/textilej/parser/markup/phrase/HtmlEndTagPhraseModifier.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - - -public class HtmlEndTagPhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "()"; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - -} diff --git a/src/net/java/textilej/parser/markup/phrase/HtmlStartTagPhraseModifier.java b/src/net/java/textilej/parser/markup/phrase/HtmlStartTagPhraseModifier.java deleted file mode 100644 index 9d9c74f..0000000 --- a/src/net/java/textilej/parser/markup/phrase/HtmlStartTagPhraseModifier.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - - -public class HtmlStartTagPhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(<[a-zA-Z][a-zA-Z0-9_:-]*(?:\\s*[a-zA-Z][a-zA-Z0-9_:-]*=\"[^\"]*\")*\\s*/?>)"; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - -} diff --git a/src/net/java/textilej/parser/markup/phrase/LimitedHtmlEndTagPhraseModifier.java b/src/net/java/textilej/parser/markup/phrase/LimitedHtmlEndTagPhraseModifier.java deleted file mode 100644 index 1688b84..0000000 --- a/src/net/java/textilej/parser/markup/phrase/LimitedHtmlEndTagPhraseModifier.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - -public class LimitedHtmlEndTagPhraseModifier extends PatternBasedElement { - - private String pattern; - - public LimitedHtmlEndTagPhraseModifier(String... elementNames) { - StringBuilder buf = new StringBuilder(); - buf.append("( 0) { - buf.append("|"); - } - buf.append(elementName); - } - buf.append(")\\s*>)"); - pattern = buf.toString(); - } - - @Override - protected String getPattern(int groupOffset) { - return pattern; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - -} diff --git a/src/net/java/textilej/parser/markup/phrase/LimitedHtmlStartTagPhraseModifier.java b/src/net/java/textilej/parser/markup/phrase/LimitedHtmlStartTagPhraseModifier.java deleted file mode 100644 index b17be66..0000000 --- a/src/net/java/textilej/parser/markup/phrase/LimitedHtmlStartTagPhraseModifier.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - -public class LimitedHtmlStartTagPhraseModifier extends PatternBasedElement { - - private String pattern; - - public LimitedHtmlStartTagPhraseModifier(String... elementNames) { - StringBuilder buf = new StringBuilder(); - buf.append("(<"); - buf.append("(?:"); - int index = 0; - for (String elementName: elementNames) { - if (index++ > 0) { - buf.append("|"); - } - buf.append(elementName); - } - buf.append(")(?:\\s*[a-zA-Z][a-zA-Z0-9_:-]*=\"[^\"]*\")*\\s*/?>)"); - pattern = buf.toString(); - } - - @Override - protected String getPattern(int groupOffset) { - return pattern; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - -} diff --git a/src/net/java/textilej/parser/markup/phrase/LiteralPhraseModifierProcessor.java b/src/net/java/textilej/parser/markup/phrase/LiteralPhraseModifierProcessor.java deleted file mode 100644 index 3dfc81c..0000000 --- a/src/net/java/textilej/parser/markup/phrase/LiteralPhraseModifierProcessor.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.java.textilej.parser.markup.phrase; - -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - -public class LiteralPhraseModifierProcessor extends PatternBasedElementProcessor { - - private final boolean escaping; - - public LiteralPhraseModifierProcessor(boolean escaping) { - this.escaping = escaping; - } - - @Override - public void emit() { - if (escaping) { - getBuilder().characters(group(1)); - } else { - getBuilder().charactersUnescaped(group(1)); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/textile/Textile.java b/src/net/java/textilej/parser/markup/textile/Textile.java deleted file mode 100644 index ca57049..0000000 --- a/src/net/java/textilej/parser/markup/textile/Textile.java +++ /dev/null @@ -1,115 +0,0 @@ -package net.java.textilej.parser.markup.textile; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.util.MatcherAdaper; - - -public class Textile { - - private static final String REGEX_TEXTILE_CLASS_ID = "(?:\\(([^#\\)]+)?(?:#([^\\)]+))?\\))"; - private static final String REGEX_TEXTILE_STYLE = "(?:\\{([^\\}]+)\\})"; - private static final String REGEX_LANGUAGE = "(?:\\[([^\\]]+)\\])"; - - public static final String REGEX_ATTRIBUTES = "(?:"+REGEX_TEXTILE_CLASS_ID+"|"+REGEX_TEXTILE_STYLE+"|"+REGEX_LANGUAGE+"){0,3}"; - public static final String REGEX_BLOCK_ATTRIBUTES = "(\\(+)?(\\)+)?(\\<|\\>|\\=|\\<\\>)?"+REGEX_ATTRIBUTES; - - public static final int ATTRIBUTES_GROUP_COUNT = 4; - public static final int ATTRIBUTES_BLOCK_GROUP_COUNT = 7; - - private static final Pattern explicitBlockBeginPattern = Pattern.compile("(((h[1-6])|p|pre|bc|bq|table)|(fn([0-9]{1,2})))" + REGEX_ATTRIBUTES +"\\.\\.?\\s+.*"); - - private static final Map alignmentToStyle = new HashMap(); - static { - alignmentToStyle.put("<","text-align: left;"); - alignmentToStyle.put(">","text-align: right;"); - alignmentToStyle.put("=","text-align: center;"); - alignmentToStyle.put("<>","text-align: justify;"); - } - - public static Attributes configureAttributes(Attributes attributes, Matcher matcher, int offset,boolean block) { - return configureAttributes(new MatcherAdaper(matcher),attributes, offset,block); - } - - private static void appendStyles(Attributes attributes, String cssStyles) { - if (cssStyles == null || cssStyles.length() == 0) { - return; - } - String styles = attributes.getCssStyle(); - if (styles == null) { - attributes.setCssStyle(cssStyles); - } else { - if (styles.endsWith(";")) { - styles += " "; - } else { - styles += "; "; - } - styles += cssStyles; - attributes.setCssStyle(styles); - } - } - - public static Attributes configureAttributes(net.java.textilej.parser.util.Matcher matcher,Attributes attributes,int offset,boolean block) { - if (offset < 1) { - throw new IllegalArgumentException(); - } - if (block) { - // padding (left) - { - String padding = matcher.group(offset); - if (padding != null) { - appendStyles(attributes, "padding-left: "+padding.length()+"em;"); - } - ++offset; - } - - // padding (right) - { - String padding = matcher.group(offset); - if (padding != null) { - appendStyles(attributes, "padding-right: "+padding.length()+"em;"); - } - ++offset; - } - - // alignment - { - String alignment = matcher.group(offset); - if (alignment != null) { - appendStyles(attributes, alignmentToStyle.get(alignment)); - } - ++offset; - } - } - - - String cssClass2 = matcher.group(offset); - String id = matcher.group(offset+1); - String cssStyles2 = matcher.group(offset+2); - String language = matcher.group(offset+3); - - if (id != null && attributes.getId() == null) { - attributes.setId(id); - } - - if (attributes.getCssClass() != null || cssClass2 != null) { - attributes.setCssClass(attributes.getCssClass()==null?cssClass2:cssClass2==null?attributes.getCssClass():attributes.getCssClass()+' '+cssClass2); - } - appendStyles(attributes, cssStyles2); - - attributes.setLanguage(language); - - return attributes; - } - - public static boolean explicitBlockBegins(String line, int offset) { - if (offset != 0) { - return false; - } - return explicitBlockBeginPattern.matcher(line).matches(); - } -} diff --git a/src/net/java/textilej/parser/markup/textile/TextileContentState.java b/src/net/java/textilej/parser/markup/textile/TextileContentState.java deleted file mode 100644 index 24fa051..0000000 --- a/src/net/java/textilej/parser/markup/textile/TextileContentState.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.java.textilej.parser.markup.textile; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.markup.ContentState; - -public class TextileContentState extends ContentState { - private static final Pattern NAMED_LINK_PATTERN = Pattern.compile("\\[(\\S+)\\]([a-zA-Z]{3,5}:\\S+)",Pattern.MULTILINE); - - private Map nameToUrl = new HashMap(); - - @Override - protected void setMarkupContent(String markupContent) { - super.setMarkupContent(markupContent); - preprocessContent(markupContent); - } - - private void preprocessContent(String markupContent) { - // look for named links - Matcher matcher = NAMED_LINK_PATTERN.matcher(markupContent); - while (matcher.find()) { - String name = matcher.group(1); - String href = matcher.group(2); - nameToUrl.put(name, href); - } - } - - public String getNamedLinkUrl(String name) { - return nameToUrl.get(name); - } -} diff --git a/src/net/java/textilej/parser/markup/textile/TextileDialect.java b/src/net/java/textilej/parser/markup/textile/TextileDialect.java deleted file mode 100644 index df79600..0000000 --- a/src/net/java/textilej/parser/markup/textile/TextileDialect.java +++ /dev/null @@ -1,135 +0,0 @@ -package net.java.textilej.parser.markup.textile; - -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.ContentState; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.markup.phrase.HtmlEndTagPhraseModifier; -import net.java.textilej.parser.markup.phrase.HtmlStartTagPhraseModifier; -import net.java.textilej.parser.markup.textile.block.CodeBlock; -import net.java.textilej.parser.markup.textile.block.FootnoteBlock; -import net.java.textilej.parser.markup.textile.block.HeadingBlock; -import net.java.textilej.parser.markup.textile.block.ListBlock; -import net.java.textilej.parser.markup.textile.block.ParagraphBlock; -import net.java.textilej.parser.markup.textile.block.PreformattedBlock; -import net.java.textilej.parser.markup.textile.block.QuoteBlock; -import net.java.textilej.parser.markup.textile.block.TableBlock; -import net.java.textilej.parser.markup.textile.block.TableOfContentsBlock; -import net.java.textilej.parser.markup.textile.block.TextileGlossaryBlock; -import net.java.textilej.parser.markup.textile.phrase.EscapeTextilePhraseModifier; -import net.java.textilej.parser.markup.textile.phrase.ImageTextilePhraseModifier; -import net.java.textilej.parser.markup.textile.phrase.SimpleTextilePhraseModifier; -import net.java.textilej.parser.markup.textile.token.FootnoteReferenceReplacementToken; -import net.java.textilej.parser.markup.textile.token.HyperlinkReplacementToken; -import net.java.textilej.parser.markup.token.AcronymReplacementToken; -import net.java.textilej.parser.markup.token.EntityReferenceReplacementToken; -import net.java.textilej.parser.markup.token.EntityWrappingReplacementToken; -import net.java.textilej.parser.markup.token.PatternEntityReferenceReplacementToken; - -/** - * A textile dialect that parses Textile markup. - * - * Based on the spec available at http://textile.thresholdstate.com/, - * supports all current Textile markup constructs. - * - * Additionally supported are {toc} and {glossary}. - * - * @author dgreen - */ -public class TextileDialect extends Dialect { - - // we use the template pattern for creating new blocks - private List blocks = new ArrayList(); - private List paragraphBreakingBlocks = new ArrayList(); - - - private static PatternBasedSyntax tokenSyntax = new PatternBasedSyntax(); - private static PatternBasedSyntax phraseModifierSyntax = new PatternBasedSyntax(); - - - @Override - protected PatternBasedSyntax getPhraseModifierSyntax() { - return phraseModifierSyntax; - } - - @Override - protected PatternBasedSyntax getReplacementTokenSyntax() { - return tokenSyntax; - } - - { - - // IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!! - - blocks.add(new HeadingBlock()); - ListBlock listBlock = new ListBlock(); - blocks.add(listBlock); - paragraphBreakingBlocks.add(listBlock); - blocks.add(new PreformattedBlock()); - blocks.add(new QuoteBlock()); - blocks.add(new CodeBlock()); - blocks.add(new FootnoteBlock()); - TableBlock tableBlock = new TableBlock(); - blocks.add(tableBlock); - paragraphBreakingBlocks.add(tableBlock); - - // extensions - blocks.add(new TextileGlossaryBlock()); - blocks.add(new TableOfContentsBlock()); - // ~extensions - - blocks.add(new ParagraphBlock()); // ORDER DEPENDENCY: this must come last - } - static { - phraseModifierSyntax.add(new HtmlEndTagPhraseModifier()); - phraseModifierSyntax.add(new HtmlStartTagPhraseModifier()); - phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.,\\\"'?!;:\\)\\(\\{\\}\\[\\]])|^)(?:",0); - phraseModifierSyntax.add(new EscapeTextilePhraseModifier()); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("**",SpanType.BOLD, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("??",SpanType.CITATION, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("__",SpanType.ITALIC, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("_",SpanType.EMPHASIS, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("*",SpanType.STRONG, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("+",SpanType.INSERTED, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("~",SpanType.SUBSCRIPT, false)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("^",SpanType.SUPERSCRIPT, false)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("@",SpanType.CODE, false)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("%",SpanType.SPAN, true)); - phraseModifierSyntax.add(new SimpleTextilePhraseModifier("-",SpanType.DELETED, true)); - phraseModifierSyntax.add(new ImageTextilePhraseModifier()); - phraseModifierSyntax.endGroup(")(?=\\W|$)",0); - - tokenSyntax.add(new EntityReferenceReplacementToken("(tm)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(TM)","#8482")); - tokenSyntax.add(new EntityReferenceReplacementToken("(c)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(C)","#169")); - tokenSyntax.add(new EntityReferenceReplacementToken("(r)","#174")); - tokenSyntax.add(new EntityReferenceReplacementToken("(R)","#174")); - tokenSyntax.add(new HyperlinkReplacementToken()); - tokenSyntax.add(new FootnoteReferenceReplacementToken()); - tokenSyntax.add(new EntityWrappingReplacementToken("\"","#8220","#8221")); - tokenSyntax.add(new EntityWrappingReplacementToken("'","#8216","#8217")); - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\w)(')(?=\\w))","#8217")); // apostrophe - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\w\\s)(--)(?=\\s\\w))","#8212")); // emdash - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\w\\s)(-)(?=\\s\\w))","#8211")); // endash - tokenSyntax.add(new PatternEntityReferenceReplacementToken("(?:(?<=\\d\\s)(x)(?=\\s\\d))","#215")); // mul - tokenSyntax.add(new AcronymReplacementToken()); - } - - public List getParagraphBreakingBlocks() { - return paragraphBreakingBlocks; - } - - @Override - public List getBlocks() { - return blocks; - } - - @Override - protected ContentState createState() { - return new TextileContentState(); - } -} diff --git a/src/net/java/textilej/parser/markup/textile/block/CodeBlock.java b/src/net/java/textilej/parser/markup/textile/block/CodeBlock.java deleted file mode 100644 index 57fec5a..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/CodeBlock.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * Code text block, matches blocks that start with bc. - * - * @author dgreen - */ -public class CodeBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - private static final int EXTENDED_GROUP = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+1; - - static final Pattern startPattern = Pattern.compile("bc"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.(\\.)?\\s+(.*)"); - - private boolean extended; - private int blockLineCount = 0; - private Matcher matcher; - - public CodeBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - - Textile.configureAttributes(attributes,matcher, 1, true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - extended = matcher.group(EXTENDED_GROUP) != null; - - builder.beginBlock(BlockType.PREFORMATTED, attributes); - builder.beginBlock(BlockType.CODE, new Attributes()); - } - if (dialect.isEmptyLine(line) && !extended) { - setClosed(true); - return 0; - } else if (extended && Textile.explicitBlockBegins(line,offset)) { - setClosed(true); - return offset; - } - ++blockLineCount; - - builder.characters(offset>0?line.substring(offset):line); - builder.characters("\n"); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock();// code - builder.endBlock();// pre - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/FootnoteBlock.java b/src/net/java/textilej/parser/markup/textile/block/FootnoteBlock.java deleted file mode 100644 index 2c4c452..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/FootnoteBlock.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * Footnote block, matching lines starting with fn\d\d?. . - * - * @author dgreen - */ -public class FootnoteBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - - static final Pattern startPattern = Pattern.compile("fn([0-9]{1,2})"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.\\s+(.*)"); - - private int blockLineCount = 0; - - private Matcher matcher; - - private String footnote; - - public FootnoteBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - attributes.setCssClass("footnote"); - - // 0-offset matches may start with the "fnnn. " prefix. - footnote = matcher.group(1); - attributes.setId(state.getFootnoteId(footnote)); - - Textile.configureAttributes(attributes,matcher, 2,true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - builder.beginBlock(BlockType.PARAGRAPH, attributes); - builder.beginSpan(SpanType.SUPERSCRIPT, new Attributes()); - builder.characters(footnote); - builder.endSpan(); - builder.characters(" "); - } - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - if (blockLineCount != 0) { - builder.lineBreak(); - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/HeadingBlock.java b/src/net/java/textilej/parser/markup/textile/block/HeadingBlock.java deleted file mode 100644 index 6cdb223..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/HeadingBlock.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * Matches any textile text, including lines starting with p. . - * - * @author dgreen - */ -public class HeadingBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - - static final Pattern startPattern = Pattern.compile("h([1-6])"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.\\s+(.*)"); - - private int blockLineCount = 0; - private int level = -1; - private Matcher matcher; - - public HeadingBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - if (offset == 0) { - // 0-offset matches may start with the "hn. " prefix. - level = Integer.parseInt(matcher.group(1)); - Textile.configureAttributes(attributes,matcher, 2,true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - } - if (attributes.getId() == null) { - attributes.setId(state.getIdGenerator().newId("h"+level,line.substring(offset))); - } - builder.beginHeading(level, attributes); - } - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - if (blockLineCount != 0) { - getDialect().emitMarkupText(getParser(), state, "\n"); - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endHeading(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/ListBlock.java b/src/net/java/textilej/parser/markup/textile/block/ListBlock.java deleted file mode 100644 index dffd6d7..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/ListBlock.java +++ /dev/null @@ -1,159 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * List block, matches blocks that start with *, # or - - * - * @author dgreen - */ -public class ListBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - - static final Pattern startPattern = Pattern.compile("((?:(?:\\*)|(?:#)|(?:-))+)"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\s(.*+)"); - - private int blockLineCount = 0; - private Matcher matcher; - - private Stack listState; - - public ListBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - listState = new Stack(); - Attributes attributes = new Attributes(); - String listSpec = matcher.group(1); - int level = calculateLevel(listSpec); - BlockType type = calculateType(listSpec); - - // 0-offset matches may start with the "*** " prefix. - Textile.configureAttributes(attributes,matcher, 2,true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - listState.push(new ListState(1,type)); - builder.beginBlock(type, attributes); - - adjustLevel(matcher, level, type); - } else { - Matcher matcher = startPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - String listSpec = matcher.group(1); - int level = calculateLevel(listSpec); - BlockType type = calculateType(listSpec); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - adjustLevel(matcher, level, type); - } - ++blockLineCount; - - ListState listState = this.listState.peek(); - if (listState.openItem) { - builder.endBlock(); - } - listState.openItem = true; - builder.beginBlock(BlockType.LIST_ITEM, new Attributes()); - - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - private void adjustLevel(Matcher matcher, int level, BlockType type) { - for (ListState previousState = listState.peek(); - level != previousState.level || previousState.type != type; - previousState = listState.peek()) { - - if (level > previousState.level) { - if (!previousState.openItem) { - builder.beginBlock(BlockType.LIST_ITEM, new Attributes()); - previousState.openItem = true; - } - - Attributes blockAttributes = new Attributes(); - if (previousState.level+1 == level) { - Textile.configureAttributes(blockAttributes,matcher, 2,true); - } - - listState.push(new ListState(previousState.level+1,type)); - builder.beginBlock(type,blockAttributes); - } else { - closeOne(); - if (listState.isEmpty()) { - Attributes blockAttributes = new Attributes(); - Textile.configureAttributes(blockAttributes,matcher, 2,true); - - listState.push(new ListState(1,type)); - builder.beginBlock(type, blockAttributes); - } - } - - } - } - - private int calculateLevel(String listSpec) { - return listSpec.length(); - } - - private BlockType calculateType(String listSpec) { - return listSpec.charAt(listSpec.length()-1) == '#'?BlockType.NUMERIC_LIST:BlockType.BULLETED_LIST; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - listState = null; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - while (listState != null && !listState.isEmpty()) { - closeOne(); - } - listState = null; - } - super.setClosed(closed); - } - - private void closeOne() { - ListState e = listState.pop(); - if (e.openItem) { - builder.endBlock(); - } - builder.endBlock(); - } - - private static class ListState { - int level; - BlockType type; - boolean openItem; - - private ListState(int level, BlockType type) { - super(); - this.level = level; - this.type = type; - } - - } -} diff --git a/src/net/java/textilej/parser/markup/textile/block/ParagraphBlock.java b/src/net/java/textilej/parser/markup/textile/block/ParagraphBlock.java deleted file mode 100644 index 38956f3..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/ParagraphBlock.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; -import net.java.textilej.parser.markup.textile.TextileDialect; - -/** - * Matches any textile text, including lines starting with p. . - * - * @author dgreen - */ -public class ParagraphBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+1; - - static final Pattern startPattern = Pattern.compile("p"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.\\s+(.*)"); - - private int blockLineCount = 0; - private boolean unwrapped = false; - - public ParagraphBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - if (offset == 0) { - // 0-offset matches may start with the "p. " prefix. - Matcher matcher = startPattern.matcher(line); - if (matcher.matches()) { - Textile.configureAttributes(attributes,matcher, 1,true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - } else { - if (line.charAt(0) == ' ') { - offset = 1; - unwrapped = true; - } - } - } - if (!unwrapped) { - builder.beginBlock(BlockType.PARAGRAPH, attributes); - } - } - - if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - - TextileDialect dialect = (TextileDialect) getDialect(); - - // NOTE: in Textile paragraphs can have nested lists and other things, however - // the resulting XHTML is invalid -- so here we allow for similar constructs - // however we cause them to end the paragraph rather than being nested. - for (Block block: dialect.getParagraphBreakingBlocks()) { - if (block.canStart(line, offset)) { - setClosed(true); - return 0; - } - } - - - if (blockLineCount != 0) { - if (unwrapped) { - builder.characters("\n"); - } else { - builder.lineBreak(); - } - } - ++blockLineCount; - - - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - unwrapped = false; - blockLineCount = 0; - return true; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - if (!unwrapped) { - builder.endBlock(); - } - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/PreformattedBlock.java b/src/net/java/textilej/parser/markup/textile/block/PreformattedBlock.java deleted file mode 100644 index b178d4d..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/PreformattedBlock.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * Preformatted text block, matches blocks that start with pre. - * - * @author dgreen - */ -public class PreformattedBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - private static final int EXTENDED_GROUP = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+1; - - static final Pattern startPattern = Pattern.compile("pre"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.(\\.)?\\s+(.*)"); - - - private boolean extended; - private int blockLineCount = 0; - private Matcher matcher; - - public PreformattedBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - - Textile.configureAttributes(attributes,matcher, 1,true); - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - extended = matcher.group(EXTENDED_GROUP) != null; - - builder.beginBlock(BlockType.PREFORMATTED, attributes); - } - if (dialect.isEmptyLine(line) && !extended) { - setClosed(true); - return 0; - } else if (extended && Textile.explicitBlockBegins(line,offset)) { - setClosed(true); - return offset; - } - ++blockLineCount; - - - builder.characters(offset>0?line.substring(offset):line); - builder.characters("\n"); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/QuoteBlock.java b/src/net/java/textilej/parser/markup/textile/block/QuoteBlock.java deleted file mode 100644 index 8a069c8..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/QuoteBlock.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.QuoteAttributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * quoted text block, matches blocks that start with bc. . - * Creates an extended block type of {@link ParagraphBlock paragraph}. - * - * @author dgreen - */ -public class QuoteBlock extends Block { - - private static final int LINE_REMAINDER_GROUP = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+3; - private static final int CITATION_GROUP = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+2; - private static final int EXTENDED_GROUP = Textile.ATTRIBUTES_BLOCK_GROUP_COUNT+1; - - static final Pattern startPattern = Pattern.compile("bq"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.(\\.)?(?::(https?://[^\\s]*))?\\s+(.*)"); - - private boolean extended; - private boolean paraOpen; - private int blockLineCount = 0; - private Matcher matcher; - - public QuoteBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - QuoteAttributes attributes = new QuoteAttributes(); - - Textile.configureAttributes(attributes,matcher, 1,true); - - attributes.setCitation(matcher.group(CITATION_GROUP)); - - offset = matcher.start(LINE_REMAINDER_GROUP); - extended = matcher.group(EXTENDED_GROUP) != null; - - builder.beginBlock(BlockType.QUOTE, attributes); - builder.beginBlock(BlockType.PARAGRAPH, new Attributes()); - paraOpen = true; - } - if (dialect.isEmptyLine(line)) { - if (!extended) { - setClosed(true); - return 0; - } else { - if (paraOpen) { - builder.endBlock(); // para - paraOpen = false; - } - return 0; - } - } else if (extended && Textile.explicitBlockBegins(line,offset)) { - setClosed(true); - return offset; - } - if (blockLineCount != 0) { - if (paraOpen) { - builder.lineBreak(); - } else { - builder.beginBlock(BlockType.PARAGRAPH, new Attributes()); - paraOpen = true; - } - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - if (paraOpen) { - builder.endBlock(); // para - paraOpen = false; - } - builder.endBlock(); // quote - } - super.setClosed(closed); - } -} diff --git a/src/net/java/textilej/parser/markup/textile/block/TableBlock.java b/src/net/java/textilej/parser/markup/textile/block/TableBlock.java deleted file mode 100644 index 9f84eae..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/TableBlock.java +++ /dev/null @@ -1,141 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.TableCellAttributes; -import net.java.textilej.parser.TableRowAttributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.Textile; - -/** - * Table block, matches blocks that start with table. or those that - * start with a table row. - * - * @author dgreen - */ -public class TableBlock extends Block { - - // NOTE: no need for whitespace after the dot on 'table.' - static final Pattern startPattern = Pattern.compile("(table"+Textile.REGEX_BLOCK_ATTRIBUTES+"\\.)|(\\|(.*)?(\\|\\s*$))"); - - static final Pattern rowAttributesPattern = Pattern.compile(Textile.REGEX_BLOCK_ATTRIBUTES+"\\.\\s*.*"); - - static final Pattern TABLE_ROW_PATTERN = Pattern.compile("\\|(?:\\\\(\\d+))?(?:/(\\d+))?((?:\\<\\>)|\\<|\\>|\\^)?"+Textile.REGEX_ATTRIBUTES+"(_|\\|)?\\.?\\s?([^\\|]*)(\\|\\|?\\s*$)?"); - - private int blockLineCount = 0; - private Matcher matcher; - - public TableBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - if (matcher.group(1) != null) { - // 0-offset matches may start with the "table. " prefix. - Textile.configureAttributes(attributes,matcher, 2,true); - offset = line.length(); - } - builder.beginBlock(BlockType.TABLE, attributes); - } else if (dialect.isEmptyLine(line)) { - setClosed(true); - return 0; - } - ++blockLineCount; - - if (offset == line.length()) { - return -1; - } - - String textileLine = offset==0?line:line.substring(offset); - Matcher rowMatcher = TABLE_ROW_PATTERN.matcher(textileLine); - if (!rowMatcher.find()) { - setClosed(true); - return 0; - } - { - TableRowAttributes rowAttributes = new TableRowAttributes(); - int rowStart = rowMatcher.start(); - if (rowStart > 0) { - // if the row content starts somewhere in the line then it's likely - // that we have some row-level attributes - Matcher rowAttributesMatcher = rowAttributesPattern.matcher(textileLine); - if (rowAttributesMatcher.matches()) { - Textile.configureAttributes(rowAttributes, rowAttributesMatcher, 1, true); - } - } - builder.beginBlock(BlockType.TABLE_ROW, rowAttributes); - } - - do { - int start = rowMatcher.start(); - if (start == textileLine.length()-1) { - break; - } - - String colSpan = rowMatcher.group(1); - String rowSpan = rowMatcher.group(2); - String alignment = rowMatcher.group(3); - String headerIndicator = rowMatcher.group(8); - String text = rowMatcher.group(9); - int textLineOffset = rowMatcher.start(9); - - boolean header = headerIndicator != null && ("_".equals(headerIndicator) || "|".equals(headerIndicator)); - - String textAlign = null; - if (alignment != null) { - if (alignment.equals("<>")) { - textAlign = "text-align: center;"; - } else if (alignment.equals(">")) { - textAlign = "text-align: right;"; - } else if (alignment.equals("<")) { - textAlign = "text-align: left;"; - } else if (alignment.equals("^")) { - textAlign = "text-align: top;"; - } - } - TableCellAttributes attributes = new TableCellAttributes(); - attributes.setCssStyle(textAlign); - attributes.setRowspan(rowSpan); - attributes.setColspan(colSpan); - Textile.configureAttributes(attributes, rowMatcher,4,false); - - state.setLineCharacterOffset(start); - builder.beginBlock(header?BlockType.TABLE_CELL_HEADER:BlockType.TABLE_CELL_NORMAL, attributes); - - dialect.emitMarkupLine(getParser(), state,textLineOffset, text, 0); - - builder.endBlock(); // table cell - } while (rowMatcher.find()); - - builder.endBlock(); // table row - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/TableOfContentsBlock.java b/src/net/java/textilej/parser/markup/textile/block/TableOfContentsBlock.java deleted file mode 100644 index a1f9c30..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/TableOfContentsBlock.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.textile.TextileDialect; -import net.java.textilej.parser.outline.OutlineItem; -import net.java.textilej.parser.outline.OutlineParser; - -public class TableOfContentsBlock extends Block { - - static final Pattern startPattern = Pattern.compile("\\s*\\{toc(?::([^\\}]+))?\\}\\s*"); - - private int blockLineNumber = 0; - - private String style = "none"; - private int maxLevel = Integer.MAX_VALUE; - - - private Matcher matcher; - - @Override - public int processLineContent(String line,int offset) { - if (blockLineNumber++ > 0) { - setClosed(true); - return 0; - } - - if (!getDialect().isFilterGenerativeContents()) { - String options = matcher.group(1); - if (options != null) { - String[] optionPairs = options.split("\\s*\\|\\s*"); - for (String optionPair: optionPairs) { - String[] keyValue = optionPair.split("\\s*=\\s*"); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - - if (key.equals("style")) { - setStyle(value); - } else if (key.equals("maxLevel")) { - try { - maxLevel = Integer.parseInt(value); - } catch (NumberFormatException e) {} - } - } - } - } - - OutlineParser outlineParser = new OutlineParser(new TextileDialect()); - OutlineItem rootItem = outlineParser.parse(state.getMarkupContent()); - - emitToc(rootItem); - } - return -1; - } - - - private void emitToc(OutlineItem item) { - if (item.getChildren().isEmpty()) { - return; - } - if ((item.getLevel()+1) > maxLevel) { - return; - } - Attributes nullAttributes = new Attributes(); - - builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes(null,null,"list-style: "+style+";",null)); - for (OutlineItem child: item.getChildren()) { - builder.beginBlock(BlockType.LIST_ITEM, nullAttributes); - builder.link('#'+child.getId(), child.getLabel()); - emitToc(child); - builder.endBlock(); - } - builder.endBlock(); - } - - @Override - public boolean canStart(String line,int lineOffset) { - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - public String getStyle() { - return style; - } - - public void setStyle(String style) { - this.style = style; - } - - public int getMaxLevel() { - return maxLevel; - } - - public void setMaxLevel(int maxLevel) { - this.maxLevel = maxLevel; - } - - - -} diff --git a/src/net/java/textilej/parser/markup/textile/block/TextileGlossaryBlock.java b/src/net/java/textilej/parser/markup/textile/block/TextileGlossaryBlock.java deleted file mode 100644 index 88e4e18..0000000 --- a/src/net/java/textilej/parser/markup/textile/block/TextileGlossaryBlock.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.java.textilej.parser.markup.textile.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.markup.block.GlossaryBlock; - -public class TextileGlossaryBlock extends GlossaryBlock { - - static final Pattern startPattern = Pattern.compile("\\s*\\{glossary(?::([^\\}]+))?\\}\\s*"); - - private Matcher matcher; - - @Override - public int processLineContent(String line,int offset) { - if (blockLineNumber == 0) { - String options = matcher.group(1); - if (options != null) { - String[] optionPairs = options.split("\\s*\\|\\s*"); - for (String optionPair: optionPairs) { - String[] keyValue = optionPair.split("\\s*=\\s*"); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - - if (key.equals("style")) { - setStyle(value); - } - } - } - } - } - return super.processLineContent(line, offset); - } - - @Override - public boolean canStart(String line,int lineOffset) { - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } -} diff --git a/src/net/java/textilej/parser/markup/textile/phrase/EscapeTextilePhraseModifier.java b/src/net/java/textilej/parser/markup/textile/phrase/EscapeTextilePhraseModifier.java deleted file mode 100644 index aa0c1cf..0000000 --- a/src/net/java/textilej/parser/markup/textile/phrase/EscapeTextilePhraseModifier.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.java.textilej.parser.markup.textile.phrase; - -import java.util.regex.Pattern; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.phrase.LiteralPhraseModifierProcessor; - -public class EscapeTextilePhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - String quotedDelimiter = Pattern.quote("=="); - - return - quotedDelimiter + - "(\\S(?:.*?\\S)?)" + // content - quotedDelimiter; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralPhraseModifierProcessor(false); - } - -} diff --git a/src/net/java/textilej/parser/markup/textile/phrase/ImageTextilePhraseModifier.java b/src/net/java/textilej/parser/markup/textile/phrase/ImageTextilePhraseModifier.java deleted file mode 100644 index 04b2783..0000000 --- a/src/net/java/textilej/parser/markup/textile/phrase/ImageTextilePhraseModifier.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.java.textilej.parser.markup.textile.phrase; - -import java.util.regex.Pattern; - -import net.java.textilej.parser.ImageAttributes; -import net.java.textilej.parser.ImageAttributes.Align; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.textile.Textile; -import net.java.textilej.parser.markup.textile.TextileContentState; - -public class ImageTextilePhraseModifier extends PatternBasedElement { - - protected static final int ALIGNMENT_GROUP = Textile.ATTRIBUTES_GROUP_COUNT+1; - protected static final int CONTENT_GROUP = Textile.ATTRIBUTES_GROUP_COUNT+2; - protected static final int ATTRIBUTES_OFFSET = 1; - - @Override - protected String getPattern(int groupOffset) { - String quotedDelimiter = Pattern.quote("!"); - - return - quotedDelimiter + - Textile.REGEX_ATTRIBUTES + - "(<|>|=)?(\\S(?:.*?\\S)?)(\\([^\\)]+\\))?" + // content - quotedDelimiter + - "(:([^\\s]*[^\\s!.)(,]))?"; // optional hyperlink suffix - } - - @Override - protected int getPatternGroupCount() { - return Textile.ATTRIBUTES_GROUP_COUNT+5; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new ImagePhraseModifierProcessor(); - } - - private static class ImagePhraseModifierProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String alignment = group(ALIGNMENT_GROUP); - String imageUrl = group(CONTENT_GROUP); - String altAndTitle = group(CONTENT_GROUP+1); - String href = group(CONTENT_GROUP+3); - String namedLinkUrl = href==null?null:((TextileContentState)getState()).getNamedLinkUrl(href); - if (namedLinkUrl != null) { - href = namedLinkUrl; - } - - ImageAttributes attributes = new ImageAttributes(); - attributes.setTitle(altAndTitle); - attributes.setAlt(altAndTitle); - if (alignment != null) { - if ("<".equals(alignment)) { - attributes.setAlign(Align.Left); - } else if (">".equals(alignment)) { - attributes.setAlign(Align.Right); - } else if ("=".equals(alignment)) { - attributes.setAlign(Align.Center); - } - } - Textile.configureAttributes(this, attributes, ATTRIBUTES_OFFSET,false); - if (href != null) { - builder.imageLink(attributes, href, imageUrl); - } else { - builder.image(attributes, imageUrl); - } - } - } - -} diff --git a/src/net/java/textilej/parser/markup/textile/phrase/SimpleTextilePhraseModifier.java b/src/net/java/textilej/parser/markup/textile/phrase/SimpleTextilePhraseModifier.java deleted file mode 100644 index 2602a7a..0000000 --- a/src/net/java/textilej/parser/markup/textile/phrase/SimpleTextilePhraseModifier.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.java.textilej.parser.markup.textile.phrase; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; -import net.java.textilej.parser.markup.textile.Textile; - -public class SimpleTextilePhraseModifier extends PatternBasedElement { - - - protected static final int CONTENT_GROUP = Textile.ATTRIBUTES_GROUP_COUNT+1; - protected static final int ATTRIBUTES_OFFSET = 1; - - private static class SimplePhraseModifierProcessor extends PatternBasedElementProcessor { - private final SpanType spanType; - private final boolean nesting; - - public SimplePhraseModifierProcessor(SpanType spanType, boolean nesting) { - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - public void emit() { - Attributes attributes = new Attributes(); - configureAttributes(this, attributes); - getBuilder().beginSpan(spanType, attributes); - if (nesting) { - getDialect().emitMarkupLine(parser, state, state.getLineCharacterOffset() + getStart(this), - getContent(this), 0); - } else { - getDialect().emitMarkupText(parser, state, getContent(this)); - } - getBuilder().endSpan(); - } - } - - private String delimiter; - private SpanType spanType; - private final boolean nesting; - - public SimpleTextilePhraseModifier(String delimiter, SpanType spanType, boolean nesting) { - this.delimiter = delimiter; - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - protected String getPattern(int groupOffset) { - String quotedDelimiter = quoteLite(getDelimiter()); - - // special casing to avoid breaking freenet keys: - if ((this.delimiter != null) && (this.delimiter.equals("-"))) { - return - "(?" | "#" | "%" | <"> -// -// -// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" -// hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | -// "a" | "b" | "c" | "d" | "e" | "f" -// escape = "%" hex hex -// -// unreserved = alpha | digit | safe | extra -// uchar = unreserved | escape -// xchar = unreserved | reserved | escape -// digits = 1*digit - - // *[ uchar | ";" | ":" | "@" | "&" | "=" ] - - @Override - protected String getPattern(int groupOffset) { - return "(?:(\"|\\!)([^\"\\!]+)\\"+(1+groupOffset)+":([^\\s]*[^\\s!.)(,]))"; - } - - @Override - protected int getPatternGroupCount() { - return 3; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String hyperlinkBoundaryText = group(1); - String hyperlinkSrc = group(2); - String href = group(3); - String namedLinkUrl = ((TextileContentState)getState()).getNamedLinkUrl(href); - if (namedLinkUrl != null) { - href = namedLinkUrl; - } - - if (hyperlinkBoundaryText.equals("\"")) { - builder.link(href, hyperlinkSrc); - } else { - builder.imageLink(new ImageAttributes(),href, hyperlinkSrc); - } - } - } - -} diff --git a/src/net/java/textilej/parser/markup/textile/validation/BlockWhitespaceRule.java b/src/net/java/textilej/parser/markup/textile/validation/BlockWhitespaceRule.java deleted file mode 100644 index 4d792c0..0000000 --- a/src/net/java/textilej/parser/markup/textile/validation/BlockWhitespaceRule.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.java.textilej.parser.markup.textile.validation; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.validation.ValidationProblem; -import net.java.textilej.validation.ValidationRule; - -public class BlockWhitespaceRule extends ValidationRule { - - private static final Pattern pattern = Pattern.compile("((?:bc|bq|pre|table|p)(?:\\.){1,2})(.)?",Pattern.MULTILINE); - - @Override - public ValidationProblem findProblem(String markup, int offset, int length) { - Matcher matcher = pattern.matcher(markup); - if (offset > 0) { - matcher.region(offset,offset+length); - } - while (matcher.find()) { - int start = matcher.start(); - boolean startOfLine = false; - if (start == 0) { - startOfLine = true; - } else { - char c = markup.charAt(start-1); - if (c == '\r' || c == '\n') { - startOfLine = true; - } - } - if (startOfLine) { - String followingCharacter = matcher.group(2); - if (followingCharacter == null || !followingCharacter.equals(" ")) { - int problemLength = matcher.end(1)-start; - String matched = matcher.group(1); - return new ValidationProblem(ValidationProblem.Severity.WARNING,String.format("'%s' will not start a new block unless it is followed by a space character (' ')",matched),start,problemLength); - } - } - } - return null; - } - -} diff --git a/src/net/java/textilej/parser/markup/token/AcronymReplacementToken.java b/src/net/java/textilej/parser/markup/token/AcronymReplacementToken.java deleted file mode 100644 index 459b618..0000000 --- a/src/net/java/textilej/parser/markup/token/AcronymReplacementToken.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class AcronymReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(?:(?:(?<=\\W)|^)([A-Z]{3,})\\(([^\\)]+)\\))"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new AcronymReplacementTokenProcessor(); - } - - private static class AcronymReplacementTokenProcessor extends PatternBasedElementProcessor { - - @Override - public void emit() { - String acronym = group(1); - String acronymDef = group(2); - state.addGlossaryTerm(acronym, acronymDef); - builder.acronym(acronym, acronymDef); - } - - } -} diff --git a/src/net/java/textilej/parser/markup/token/EntityReferenceReplacementToken.java b/src/net/java/textilej/parser/markup/token/EntityReferenceReplacementToken.java deleted file mode 100644 index 1eaa04f..0000000 --- a/src/net/java/textilej/parser/markup/token/EntityReferenceReplacementToken.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import java.util.regex.Pattern; - -public class EntityReferenceReplacementToken extends PatternEntityReferenceReplacementToken { - - public EntityReferenceReplacementToken(String token,String replacement) { - super("("+Pattern.quote(token)+")",replacement); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/EntityReplacementTokenProcessor.java b/src/net/java/textilej/parser/markup/token/EntityReplacementTokenProcessor.java deleted file mode 100644 index 8067073..0000000 --- a/src/net/java/textilej/parser/markup/token/EntityReplacementTokenProcessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class EntityReplacementTokenProcessor extends PatternBasedElementProcessor { - - private final String entity; - - public EntityReplacementTokenProcessor(String entity) { - this.entity = entity; - } - - @Override - public void emit() { - getBuilder().entityReference(entity); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/EntityWrappingReplacementToken.java b/src/net/java/textilej/parser/markup/token/EntityWrappingReplacementToken.java deleted file mode 100644 index 7ce52c7..0000000 --- a/src/net/java/textilej/parser/markup/token/EntityWrappingReplacementToken.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class EntityWrappingReplacementToken extends PatternBasedElement { - - private String delimiter; - private String leftEntity; - private String rightEntity; - - public EntityWrappingReplacementToken(String delimiter, String leftEntity, String rightEntity) { - this.delimiter = delimiter; - this.leftEntity = leftEntity; - this.rightEntity = rightEntity; - if (delimiter.length() != 1) { - throw new IllegalArgumentException(delimiter); - } - } - - @Override - protected String getPattern(int groupOffset) { - String quoted = Character.isLetterOrDigit(delimiter.charAt(0))?delimiter:"\\"+delimiter; - return "(?:(?:(?<=\\W)|^)"+quoted+"([^"+quoted+"]+)"+quoted+"(?=\\W))"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new EntityWrappingReplacementTokenProcessor(leftEntity,rightEntity); - } - - private static class EntityWrappingReplacementTokenProcessor extends PatternBasedElementProcessor { - private final String leftEntity; - private final String rightEntity; - - public EntityWrappingReplacementTokenProcessor(String leftEntity, String rightEntity) { - this.leftEntity = leftEntity; - this.rightEntity = rightEntity; - } - - @Override - public void emit() { - String content = group(1); - builder.entityReference(leftEntity); - builder.characters(content); - builder.entityReference(rightEntity); - } - } - -} diff --git a/src/net/java/textilej/parser/markup/token/ImpliedHyperlinkReplacementToken.java b/src/net/java/textilej/parser/markup/token/ImpliedHyperlinkReplacementToken.java deleted file mode 100644 index d8cba67..0000000 --- a/src/net/java/textilej/parser/markup/token/ImpliedHyperlinkReplacementToken.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class ImpliedHyperlinkReplacementToken extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - return "(https?://\\S+[^\\s\\.,;\\):])"; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new HyperlinkReplacementTokenProcessor(); - } - - private static class HyperlinkReplacementTokenProcessor extends PatternBasedElementProcessor { - @Override - public void emit() { - String target = group(1); - getBuilder().link(target,target); - } - } -} diff --git a/src/net/java/textilej/parser/markup/token/LineBreakReplacementTokenProcessor.java b/src/net/java/textilej/parser/markup/token/LineBreakReplacementTokenProcessor.java deleted file mode 100644 index 26b3376..0000000 --- a/src/net/java/textilej/parser/markup/token/LineBreakReplacementTokenProcessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class LineBreakReplacementTokenProcessor extends PatternBasedElementProcessor { - - @Override - public void emit() { - getBuilder().lineBreak(); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/LiteralReplacementTokenProcessor.java b/src/net/java/textilej/parser/markup/token/LiteralReplacementTokenProcessor.java deleted file mode 100644 index 1bd0072..0000000 --- a/src/net/java/textilej/parser/markup/token/LiteralReplacementTokenProcessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class LiteralReplacementTokenProcessor extends PatternBasedElementProcessor { - - private final String literal; - - public LiteralReplacementTokenProcessor(String literal) { - this.literal = literal; - } - - @Override - public void emit() { - getBuilder().charactersUnescaped(literal); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/PatternEntityReferenceReplacementToken.java b/src/net/java/textilej/parser/markup/token/PatternEntityReferenceReplacementToken.java deleted file mode 100644 index 19db954..0000000 --- a/src/net/java/textilej/parser/markup/token/PatternEntityReferenceReplacementToken.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class PatternEntityReferenceReplacementToken extends PatternBasedElement { - - private String pattern; - private String replacement; - - public PatternEntityReferenceReplacementToken(String pattern,String replacement) { - this.pattern = pattern; - this.replacement = replacement; - } - - @Override - protected String getPattern(int groupOffset) { - return pattern; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new EntityReplacementTokenProcessor(replacement); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/PatternLineBreakReplacementToken.java b/src/net/java/textilej/parser/markup/token/PatternLineBreakReplacementToken.java deleted file mode 100644 index 91720d5..0000000 --- a/src/net/java/textilej/parser/markup/token/PatternLineBreakReplacementToken.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class PatternLineBreakReplacementToken extends PatternBasedElement { - - private String pattern; - - public PatternLineBreakReplacementToken(String pattern) { - this.pattern = pattern; - } - - @Override - protected String getPattern(int groupOffset) { - return pattern; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LineBreakReplacementTokenProcessor(); - } - -} diff --git a/src/net/java/textilej/parser/markup/token/PatternLiteralReplacementToken.java b/src/net/java/textilej/parser/markup/token/PatternLiteralReplacementToken.java deleted file mode 100644 index c4bb041..0000000 --- a/src/net/java/textilej/parser/markup/token/PatternLiteralReplacementToken.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.java.textilej.parser.markup.token; - -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class PatternLiteralReplacementToken extends PatternBasedElement { - - private String pattern; - private String replacement; - - public PatternLiteralReplacementToken(String pattern,String replacement) { - this.pattern = pattern; - this.replacement = replacement; - } - - @Override - protected String getPattern(int groupOffset) { - return pattern; - } - - @Override - protected int getPatternGroupCount() { - return 1; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new LiteralReplacementTokenProcessor(replacement); - } - -} diff --git a/src/net/java/textilej/parser/markup/trac/TracWikiDialect.java b/src/net/java/textilej/parser/markup/trac/TracWikiDialect.java deleted file mode 100644 index 98b1d0f..0000000 --- a/src/net/java/textilej/parser/markup/trac/TracWikiDialect.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.java.textilej.parser.markup.trac; - -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.markup.token.ImpliedHyperlinkReplacementToken; -import net.java.textilej.parser.markup.trac.block.HeadingBlock; -import net.java.textilej.parser.markup.trac.block.ListBlock; -import net.java.textilej.parser.markup.trac.block.ParagraphBlock; -import net.java.textilej.parser.markup.trac.block.PreformattedBlock; -import net.java.textilej.parser.markup.trac.block.QuoteBlock; -import net.java.textilej.parser.markup.trac.block.TableBlock; -import net.java.textilej.parser.markup.trac.phrase.EscapePhraseModifier; -import net.java.textilej.parser.markup.trac.phrase.SimplePhraseModifier; -import net.java.textilej.parser.markup.trac.token.BangEscapeToken; -import net.java.textilej.parser.markup.trac.token.HyperlinkReplacementToken; -import net.java.textilej.parser.markup.trac.token.LineBreakToken; - -public class TracWikiDialect extends Dialect { - private List blocks = new ArrayList(); - private List paragraphNestableBlocks = new ArrayList(); - - private static PatternBasedSyntax tokenSyntax = new PatternBasedSyntax(); - private static PatternBasedSyntax phraseModifierSyntax = new PatternBasedSyntax(); - - { - - // IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!! - - // TODO: traclinks, images, macros, processors - - ListBlock listBlock = new ListBlock(); - blocks.add(listBlock); - paragraphNestableBlocks.add(listBlock); - HeadingBlock headingBlock = new HeadingBlock(); - blocks.add(headingBlock); - paragraphNestableBlocks.add(listBlock); - PreformattedBlock preformattedBlock = new PreformattedBlock(); - blocks.add(preformattedBlock); - paragraphNestableBlocks.add(preformattedBlock); - QuoteBlock quoteBlock = new QuoteBlock(); - blocks.add(quoteBlock); - paragraphNestableBlocks.add(quoteBlock); - TableBlock tableBlock = new TableBlock(); - blocks.add(tableBlock); - paragraphNestableBlocks.add(tableBlock); - blocks.add(new ParagraphBlock()); // ORDER DEPENDENCY: this one must be last!! - } - static { - phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.\\\"'?!;:\\)\\(\\{\\}\\[\\]])|^)(?:",0); // always starts at the start of a line or after a non-word character excluding '!' - phraseModifierSyntax.add(new EscapePhraseModifier()); - phraseModifierSyntax.add(new SimplePhraseModifier("'''''",new SpanType[] { SpanType.BOLD, SpanType.ITALIC },true)); - phraseModifierSyntax.add(new SimplePhraseModifier("'''",SpanType.BOLD,true)); - phraseModifierSyntax.add(new SimplePhraseModifier("''",SpanType.ITALIC,true)); - phraseModifierSyntax.add(new SimplePhraseModifier("__",SpanType.UNDERLINED,true)); - phraseModifierSyntax.add(new SimplePhraseModifier("--",SpanType.DELETED,true)); - phraseModifierSyntax.add(new SimplePhraseModifier("^",SpanType.SUPERSCRIPT,true)); - phraseModifierSyntax.add(new SimplePhraseModifier(",,",SpanType.SUBSCRIPT,true)); - phraseModifierSyntax.endGroup(")(?=\\W|$)",0); - - tokenSyntax.add(new BangEscapeToken()); - tokenSyntax.add(new LineBreakToken()); - tokenSyntax.add(new HyperlinkReplacementToken()); - tokenSyntax.add(new ImpliedHyperlinkReplacementToken()); - } - - @Override - public List getBlocks() { - return blocks; - } - - public List getParagraphNestableBlocks() { - return paragraphNestableBlocks; - } - - @Override - protected PatternBasedSyntax getPhraseModifierSyntax() { - return phraseModifierSyntax; - } - - @Override - protected PatternBasedSyntax getReplacementTokenSyntax() { - return tokenSyntax; - } - -} diff --git a/src/net/java/textilej/parser/markup/trac/block/HeadingBlock.java b/src/net/java/textilej/parser/markup/trac/block/HeadingBlock.java deleted file mode 100644 index da4ef74..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/HeadingBlock.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.markup.Block; - -public class HeadingBlock extends Block { - - private static final Pattern pattern = Pattern.compile("\\s*(\\={1,6})([^=]+)\\1(?:\\s+\\#(\\S+)?)?"); - - private int blockLineCount = 0; - private Matcher matcher; - - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = pattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount > 0) { - throw new IllegalStateException(); - } - ++blockLineCount; - - int level = matcher.group(1).length(); - - String text = matcher.group(2); - - String id = matcher.group(3); - - Attributes attributes = new Attributes(); - attributes.setId(id); - - builder.beginHeading(level,attributes); - builder.characters(text); - builder.endHeading(); - - setClosed(true); - return -1; - } - -} diff --git a/src/net/java/textilej/parser/markup/trac/block/ListBlock.java b/src/net/java/textilej/parser/markup/trac/block/ListBlock.java deleted file mode 100644 index 2c20da5..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/ListBlock.java +++ /dev/null @@ -1,173 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.ListAttributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * List block, matches blocks that follow trac list rules (whitespace, then '*' or 1.) - * - * @author dgreen - */ -public class ListBlock extends Block { - - private static final int LINE_REMAINDER_GROUP_OFFSET = 4; - - static final Pattern startPattern = Pattern.compile("(?:(\\s+)(?:(\\*)|(?:(\\d+)\\.)))\\s+(.*+)"); - - private int blockLineCount = 0; - private Matcher matcher; - - private Stack listState = new Stack(); - - public ListBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - ListAttributes attributes = new ListAttributes(); - String spaces = matcher.group(1); - String listSpec = matcher.group(2); - String numericListSpec = matcher.group(3); - - if (numericListSpec != null && !"1".equals(numericListSpec)) { - attributes.setStart(numericListSpec); - } - - int level = calculateLevel(spaces); - - BlockType type = listSpec == null?BlockType.NUMERIC_LIST:BlockType.BULLETED_LIST; - - if (type == BlockType.BULLETED_LIST && "-".equals(listSpec)) { - attributes.setCssStyle("list-style: square"); - } - - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - listState.push(new ListState(level,spaces.length(),type)); - builder.beginBlock(type, attributes); - } else { - ListAttributes attributes = new ListAttributes(); - Matcher matcher = startPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - String spaces = matcher.group(1); - String listSpec = matcher.group(2); - String numericListSpec = matcher.group(3); - - if (numericListSpec != null && !"1".equals(numericListSpec)) { - attributes.setStart(numericListSpec); - } - - int level = calculateLevel(spaces); - - BlockType type = listSpec == null?BlockType.NUMERIC_LIST:BlockType.BULLETED_LIST; - - - offset = matcher.start(LINE_REMAINDER_GROUP_OFFSET); - - for (ListState listState = this.listState.peek();listState.level != level || listState.type != type;listState = this.listState.peek()) { - if (listState.level > level || (listState.type != type && listState.level > 1)) { - closeOne(); - if (this.listState.isEmpty()) { - this.listState.push(new ListState(1,spaces.length(),type)); - builder.beginBlock(type, attributes); - } - } else { - this.listState.push(new ListState(level,spaces.length(),type)); - builder.beginBlock(type, attributes); - } - } - } - ++blockLineCount; - - ListState listState = this.listState.peek(); - if (listState.openItem) { - builder.endBlock(); - } - listState.openItem = true; - builder.beginBlock(BlockType.LIST_ITEM, new Attributes()); - - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - - private int calculateLevel(String spaces) { - int length = spaces.length(); - if (length == 0) { - throw new IllegalStateException(); - } - int level = 1; - for (int x = 1;x outerState.numSpaces) { - level = outerState.level+1; - } - } - return level; - } - - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - while (!listState.isEmpty()) { - closeOne(); - } - } - super.setClosed(closed); - } - - private void closeOne() { - ListState e = listState.pop(); - if (e.openItem) { - builder.endBlock(); - } - builder.endBlock(); - } - - private static class ListState { - int level; - int numSpaces; - BlockType type; - boolean openItem; - - private ListState(int level,int numSpaces, BlockType type) { - super(); - this.level = level; - this.numSpaces = numSpaces; - this.type = type; - } - - } -} diff --git a/src/net/java/textilej/parser/markup/trac/block/ParagraphBlock.java b/src/net/java/textilej/parser/markup/trac/block/ParagraphBlock.java deleted file mode 100644 index 7dcc391..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/ParagraphBlock.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; -import net.java.textilej.parser.markup.trac.TracWikiDialect; - -/** - * Matches any textile text, including lines starting with p. . - * - * @author dgreen - */ -public class ParagraphBlock extends Block { - - private int blockLineCount = 0; - - public ParagraphBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - builder.beginBlock(BlockType.PARAGRAPH, attributes); - } - - if (dialect.isEmptyLine(line)) { - setClosed(true); - return -1; - } - ++blockLineCount; - - TracWikiDialect dialect = (TracWikiDialect) getDialect(); - - // paragraphs can have nested lists and other things - for (Block block: dialect.getParagraphNestableBlocks()) { - if (block.canStart(line, offset)) { - setClosed(true); - return 0; - } - } - - if (blockLineCount != 1) { - // note: newlines don't automatically convert to line breaks - builder.characters("\n"); - } - dialect.emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - return true; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/trac/block/PreformattedBlock.java b/src/net/java/textilej/parser/markup/trac/block/PreformattedBlock.java deleted file mode 100644 index df13d4a..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/PreformattedBlock.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -public class PreformattedBlock extends Block { - - private static final Pattern startPattern = Pattern.compile("\\{\\{\\{(.*)"); - private static final Pattern endPattern = Pattern.compile("\\}\\}\\}(.*)"); - - private int blockLineCount = 0; - private Matcher matcher; - - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount++ == 0) { - offset = matcher.start(1); - builder.beginBlock(BlockType.PREFORMATTED, new Attributes()); - } else { - Matcher endMatcher = endPattern.matcher(line); - if (endMatcher.matches()) { - setClosed(true); - return endMatcher.start(1); - } - } - builder.characters(offset==0?line:line.substring(offset)); - builder.characters("\n"); - return -1; - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); // pre - } - super.setClosed(closed); - } - - @Override - public boolean canStart(String line, int lineOffset) { - if (lineOffset == 0 ) { - matcher = startPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - -} diff --git a/src/net/java/textilej/parser/markup/trac/block/QuoteBlock.java b/src/net/java/textilej/parser/markup/trac/block/QuoteBlock.java deleted file mode 100644 index 534c572..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/QuoteBlock.java +++ /dev/null @@ -1,112 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * quoted text block, matches blocks that start with > or two spaces. - * These are what they call discussion citations and block quotes, respectively. - * Creates an extended block type of {@link ParagraphBlock paragraph}. - * - * @author dgreen - */ -public class QuoteBlock extends Block { - - - static final Pattern startPattern = Pattern.compile("(?:(?:(>+)\\s+)|( ))(.*)"); - - private int blockLineCount = 0; - private Matcher matcher; - - private Stack quoteBlockState; - - public QuoteBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - quoteBlockState = new Stack(); - } else { - matcher = startPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - } - String quoteStartGroup = matcher.group(1); - int level = quoteStartGroup == null?1:quoteStartGroup.length(); - offset = matcher.start(3); - - while (quoteBlockState.size() > level) { - closeOne(); - } - while (quoteBlockState.size() < level) { - openOne(new Attributes()); - } - - BlockState blockState = quoteBlockState.peek(); - if (!blockState.paraOpen) { - builder.beginBlock(BlockType.PARAGRAPH, new Attributes()); - blockState.paraOpen = true; - } else if (blockLineCount != 0) { - builder.lineBreak(); - } - ++blockLineCount; - - getDialect().emitMarkupLine(getParser(),state,line, offset); - - return -1; - } - - private void openOne(Attributes attributes) { - if (!quoteBlockState.isEmpty()) { - BlockState blockState = quoteBlockState.peek(); - if (blockState.paraOpen) { - blockState.paraOpen = false; - builder.endBlock(); - } - } - builder.beginBlock(BlockType.QUOTE, attributes); - quoteBlockState.push(new BlockState()); - } - - @Override - public boolean canStart(String line, int lineOffset) { - quoteBlockState = null; - blockLineCount = 0; - matcher = startPattern.matcher(line); - if (lineOffset > 0) { - matcher.region(lineOffset, line.length()); - } - return matcher.matches(); - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - while (quoteBlockState != null && !quoteBlockState.isEmpty()) { - closeOne(); - } - quoteBlockState = null; - } - super.setClosed(closed); - } - - private void closeOne() { - BlockState blockState = quoteBlockState.pop(); - if (blockState.paraOpen) { - builder.endBlock(); // para - } - builder.endBlock(); // quote - } - - private static class BlockState { - boolean paraOpen; - } -} diff --git a/src/net/java/textilej/parser/markup/trac/block/TableBlock.java b/src/net/java/textilej/parser/markup/trac/block/TableBlock.java deleted file mode 100644 index acb011b..0000000 --- a/src/net/java/textilej/parser/markup/trac/block/TableBlock.java +++ /dev/null @@ -1,94 +0,0 @@ -package net.java.textilej.parser.markup.trac.block; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.BlockType; -import net.java.textilej.parser.markup.Block; - -/** - * Table block, matches any line that looks like a table row. - * - * @author dgreen - */ -public class TableBlock extends Block { - - static final Pattern tableRowPattern = Pattern.compile("(\\|\\|(.*)?(\\|\\|\\s*$))"); - - static final Pattern TABLE_ROW_PATTERN = Pattern.compile("\\|\\|\\s*([^\\|]*)\\s*(\\|\\|\\s*$)?"); - - private int blockLineCount = 0; - private Matcher matcher; - - public TableBlock() { - } - - @Override - public int processLineContent(String line,int offset) { - if (blockLineCount == 0) { - Attributes attributes = new Attributes(); - builder.beginBlock(BlockType.TABLE, attributes); - } else { - matcher = tableRowPattern.matcher(line); - if (!matcher.matches()) { - setClosed(true); - return 0; - } - } - ++blockLineCount; - - String textileLine = offset==0?line:line.substring(offset); - Matcher rowMatcher = TABLE_ROW_PATTERN.matcher(textileLine); - if (!rowMatcher.find()) { - setClosed(true); - return 0; - } - - builder.beginBlock(BlockType.TABLE_ROW, new Attributes()); - - do { - int start = rowMatcher.start(); - if (start == textileLine.length()-1) { - break; - } - - String text = rowMatcher.group(1); - int textOffset = rowMatcher.start(1); - - Attributes attributes = new Attributes(); - state.setLineCharacterOffset(start); - builder.beginBlock(BlockType.TABLE_CELL_NORMAL, attributes); - - dialect.emitMarkupLine(getParser(), state,textOffset, text, 0); - - builder.endBlock(); // table cell - } while (rowMatcher.find()); - - builder.endBlock(); // table row - - return -1; - } - - @Override - public boolean canStart(String line, int lineOffset) { - blockLineCount = 0; - if (lineOffset == 0) { - matcher = tableRowPattern.matcher(line); - return matcher.matches(); - } else { - matcher = null; - return false; - } - } - - @Override - public void setClosed(boolean closed) { - if (closed && !isClosed()) { - builder.endBlock(); - } - super.setClosed(closed); - } - - -} diff --git a/src/net/java/textilej/parser/markup/trac/phrase/EscapePhraseModifier.java b/src/net/java/textilej/parser/markup/trac/phrase/EscapePhraseModifier.java deleted file mode 100644 index de36d28..0000000 --- a/src/net/java/textilej/parser/markup/trac/phrase/EscapePhraseModifier.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.java.textilej.parser.markup.trac.phrase; - - - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - -public class EscapePhraseModifier extends PatternBasedElement { - - @Override - protected String getPattern(int groupOffset) { - String escapedContent = "(\\S(?:.*?\\S)?)"; - return - "(?:(?:`" + - escapedContent + // content - "`)|(?:\\{\\{" + - escapedContent + // content - "\\}\\}))"; - } - - @Override - protected int getPatternGroupCount() { - return 2; - } - - @Override - protected PatternBasedElementProcessor newProcessor() { - return new EscapeProcessor(); - } - - private static class EscapeProcessor extends PatternBasedElementProcessor { - - private EscapeProcessor() { - } - - @Override - public void emit() { - getBuilder().beginSpan(SpanType.MONOSPACE, new Attributes()); - String group = group(1); - if (group == null) { - group = group(2); - } - getBuilder().characters(group); - getBuilder().endSpan(); - - } - - } - - -} diff --git a/src/net/java/textilej/parser/markup/trac/phrase/SimplePhraseModifier.java b/src/net/java/textilej/parser/markup/trac/phrase/SimplePhraseModifier.java deleted file mode 100644 index 8799cf3..0000000 --- a/src/net/java/textilej/parser/markup/trac/phrase/SimplePhraseModifier.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.java.textilej.parser.markup.trac.phrase; - -import net.java.textilej.parser.DocumentBuilder.SpanType; - -public class SimplePhraseModifier extends SimpleWrappedPhraseModifier { - - public SimplePhraseModifier(String delimiter, SpanType spanType) { - super(delimiter,delimiter,new SpanType[] { spanType }); - } - - public SimplePhraseModifier(String delimiter, SpanType spanType,boolean nesting) { - super(delimiter,delimiter,new SpanType[] { spanType },nesting); - } - - public SimplePhraseModifier(String delimiter, SpanType[] spanType) { - super(delimiter,delimiter,spanType); - } - - public SimplePhraseModifier(String delimiter, SpanType[] spanType,boolean nesting) { - super(delimiter,delimiter,spanType,nesting); - } -} diff --git a/src/net/java/textilej/parser/markup/trac/phrase/SimpleWrappedPhraseModifier.java b/src/net/java/textilej/parser/markup/trac/phrase/SimpleWrappedPhraseModifier.java deleted file mode 100644 index 9469311..0000000 --- a/src/net/java/textilej/parser/markup/trac/phrase/SimpleWrappedPhraseModifier.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.java.textilej.parser.markup.trac.phrase; - -import java.util.regex.Pattern; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder.SpanType; -import net.java.textilej.parser.markup.PatternBasedElement; -import net.java.textilej.parser.markup.PatternBasedElementProcessor; - - - -public class SimpleWrappedPhraseModifier extends PatternBasedElement { - - protected static final int CONTENT_GROUP = 1; - - private static class SimplePhraseModifierProcessor extends PatternBasedElementProcessor { - private final SpanType[] spanType; - private final boolean nesting; - - public SimplePhraseModifierProcessor(SpanType[] spanType, boolean nesting) { - this.spanType = spanType; - this.nesting = nesting; - } - - @Override - public void emit() { - for (SpanType type: spanType) { - getBuilder().beginSpan(type, new Attributes()); - } - if (nesting) { - getDialect().emitMarkupLine(parser, state,state.getLineCharacterOffset()+getStart(this), getContent(this), 0); - } else { - getDialect().emitMarkupText(parser, state, getContent(this)); - } - for (int x = 0;x children = new ArrayList(); - private final int offset; - private final int length; - private final String id; - private String label; - private String kind; - private int childOffset; - private String tooltip; - - public OutlineItem(OutlineItem parent,int level,String id, int offset, int length, String label) { - super(); - this.parent = parent; - this.level = (parent == null)?0:level; - if (parent != null && level < parent.getLevel()) { - throw new IllegalArgumentException(); - } - this.id = id; - this.offset = offset; - this.length = length; - this.label = label; - if (parent != null) { - parent.addChild(this); - } - } - - public int getLength() { - return length; - } - - public String getKind() { - return kind; - } - - public void setKind(String kind) { - this.kind = kind; - } - - public String getLabel() { - return label; - } - - public String getId() { - return id; - } - - public int getLevel() { - if (parent == null) { - return 0; - } - return level; - } - - public void setLabel(String label) { - this.label = label; - } - - public OutlineItem getParent() { - return parent; - } - - public List getChildren() { - return children; - } - - public int getOffset() { - return offset; - } - - @Override - public int hashCode() { - return calculatePositionKey().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final OutlineItem other = (OutlineItem) obj; - return other.calculatePositionKey().equals(calculatePositionKey()); - } - - public void clear() { - children.clear(); - } - - private String calculatePositionKey() { - if (parent == null) { - return ""; - } - return getParent().calculatePositionKey()+"/"+kind+childOffset; - } - - private void addChild(OutlineItem outlineItem) { - outlineItem.childOffset = children.size(); - children.add(outlineItem); - } - - public OutlineItem findNearestMatchingOffset(int offset) { - NearestItemVisitor visitor = new NearestItemVisitor(offset); - accept(visitor); - - return visitor.nearest; - } - - private static class NearestItemVisitor implements Visitor { - - private OutlineItem nearest = null; - private int offset; - - public NearestItemVisitor(int offset) { - this.offset = offset; - } - - public boolean visit(OutlineItem item) { - if (item.getOffset() == -1) { - return true; - } - if (nearest == null) { - nearest = item; - return true; - } - int itemDistance = item.distance(offset); - if (itemDistance > 0) { - return true; - } - int nearestDistance = nearest.distance(offset); - nearestDistance = Math.abs(nearestDistance); - itemDistance = Math.abs(itemDistance); - if (itemDistance < nearestDistance) { - nearest = item; - } else if (itemDistance > nearestDistance) { - return false; - } - return true; - } - - } - - public int distance(int offset) { - int startDistance = this.offset-offset; - - return startDistance; - } - - public interface Visitor { - public boolean visit(OutlineItem item); - } - - public void accept(Visitor visitor) { - if (visitor.visit(this)) { - for (OutlineItem item: getChildren()) { - item.accept(visitor); - } - } - } - - public void setTooltip(String tooltip) { - this.tooltip = tooltip; - } - - public String getTooltip() { - return tooltip; - } - - -} diff --git a/src/net/java/textilej/parser/outline/OutlineParser.java b/src/net/java/textilej/parser/outline/OutlineParser.java deleted file mode 100644 index b64035e..0000000 --- a/src/net/java/textilej/parser/outline/OutlineParser.java +++ /dev/null @@ -1,204 +0,0 @@ -package net.java.textilej.parser.outline; - -import net.java.textilej.parser.Attributes; -import net.java.textilej.parser.DocumentBuilder; -import net.java.textilej.parser.IdGenerator; -import net.java.textilej.parser.MarkupParser; -import net.java.textilej.parser.markup.Dialect; - -/** - * A parser for creating an outline of a textile document based on the headings in the document. - * - * @author dgreen - * - */ -public class OutlineParser { - - private int labelMaxLength = 0; - - private Dialect dialect; - - public OutlineParser(Dialect dialect) { - this.dialect = dialect; - } - - public OutlineParser() {} - - public int getLabelMaxLength() { - return labelMaxLength; - } - - public void setLabelMaxLength(int labelMaxLength) { - this.labelMaxLength = labelMaxLength; - } - - public OutlineItem parse(String markup) { - OutlineItem root = createRootItem(); - - return parse(root, markup); - } - - public Dialect getDialect() { - return dialect; - } - - public void setDialect(Dialect dialect) { - this.dialect = dialect; - } - - public OutlineItem createRootItem() { - return createOutlineItem(null,0,"",-1,0,""); - } - - public OutlineItem parse(OutlineItem root, String markup) { - if (markup == null || markup.length() == 0 || dialect == null) { - return root; - } - - dialect.setFilterGenerativeContents(true); - dialect.setBlocksOnly(true); - - OutlineBuilder outlineBuilder = new OutlineBuilder(root,labelMaxLength); - MarkupParser markupParser = new MarkupParser(); - markupParser.setBuilder(outlineBuilder); - markupParser.setDialect(dialect); - markupParser.parse(markup); - - return root; - } - - protected static OutlineItem createOutlineItem(OutlineItem current,int level, String id, int offset, - int length, String label) { - return new OutlineItem(current,level,id,offset,length,label); - } - - public DocumentBuilder createOutlineUpdater(OutlineItem rootItem) { - return new OutlineBuilder(rootItem,labelMaxLength); - } - - private static class OutlineBuilder extends DocumentBuilder { - - private OutlineItem currentItem; - - private int level; - private StringBuilder buf; - - private IdGenerator idGenerator = new IdGenerator(); - - private int offset; - - private int length; - - private OutlineItem rootItem; - - private final int labelMaxLength; - - public OutlineBuilder(OutlineItem root,int labelMaxLength) { - super(); - this.currentItem = root; - rootItem = root; - this.labelMaxLength = labelMaxLength; - } - - @Override - public void acronym(String text, String definition) { - } - - @Override - public void beginBlock(BlockType type, Attributes attributes) { - } - - @Override - public void beginDocument() { - rootItem.clear(); - currentItem = rootItem; - } - - @Override - public void beginHeading(int level, Attributes attributes) { - this.level = level; - buf = new StringBuilder(); - offset = getLocator().getDocumentOffset(); - length = getLocator().getLineLength(); - } - - @Override - public void beginSpan(SpanType type, Attributes attributes) { - } - - @Override - public void characters(String text) { - if (buf != null) { - buf.append(text); - } - } - - @Override - public void charactersUnescaped(String literal) { - if (buf != null) { - buf.append(literal); - } - } - - @Override - public void endBlock() { - } - - @Override - public void endDocument() { - } - - @Override - public void endHeading() { - String label = buf.toString(); - String fullLabelText = label; - if (label == null) { - label = ""; - } else { - if (labelMaxLength > 0 && label.length() > labelMaxLength) { - label = label.substring(0,labelMaxLength)+"..."; - } - } - String kind = "h"+level; - - while (level <= currentItem.getLevel()) { - currentItem = currentItem.getParent(); - } - currentItem = createOutlineItem(currentItem,level,idGenerator.newId(kind,fullLabelText), offset, length, label); - currentItem.setTooltip(fullLabelText); - currentItem.setKind(kind); - - buf = null; - offset = 0; - length = 0; - } - - @Override - public void endSpan() { - } - - @Override - public void entityReference(String entity) { - } - - @Override - public void image(Attributes attributes, String url) { - } - - @Override - public void imageLink(Attributes linkAttributes, Attributes ImageAttributes,String href, String imageUrl) { - } - - @Override - public void lineBreak() { - } - - @Override - public void link(Attributes attributes,String hrefOrHashName, String text) { - if (buf != null) { - buf.append(text); - } - } - - } -} diff --git a/src/net/java/textilej/parser/util/MarkupToDocbook.java b/src/net/java/textilej/parser/util/MarkupToDocbook.java deleted file mode 100644 index d989a28..0000000 --- a/src/net/java/textilej/parser/util/MarkupToDocbook.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.java.textilej.parser.util; - -import java.io.StringWriter; -import java.io.Writer; - -import net.java.textilej.parser.MarkupParser; -import net.java.textilej.parser.builder.DocBookDocumentBuilder; -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.util.XmlStreamWriter; - -public class MarkupToDocbook { - private Dialect dialect; - - private String bookTitle; - - public String parse(String markupContent) throws Exception { - if (dialect == null) { - throw new IllegalStateException(); - } - - StringWriter out = new StringWriter(); - - - DocBookDocumentBuilder builder = new DocBookDocumentBuilder(out) { - @Override - protected XmlStreamWriter createXmlStreamWriter(Writer out) { - return super.createFormattingXmlStreamWriter(out); - } - }; - builder.setBookTitle(bookTitle); - - MarkupParser textileParser = new MarkupParser(); - - textileParser.setBuilder(builder); - textileParser.setDialect(dialect); - - textileParser.parse(markupContent); - - return out.toString(); - } - - - public String getBookTitle() { - return bookTitle; - } - - public void setBookTitle(String bookTitle) { - this.bookTitle = bookTitle; - } - - - public Dialect getDialect() { - return dialect; - } - - - public void setDialect(Dialect dialect) { - this.dialect = dialect; - } - -} diff --git a/src/net/java/textilej/parser/util/MarkupToEclipseToc.java b/src/net/java/textilej/parser/util/MarkupToEclipseToc.java deleted file mode 100644 index 082672a..0000000 --- a/src/net/java/textilej/parser/util/MarkupToEclipseToc.java +++ /dev/null @@ -1,93 +0,0 @@ -package net.java.textilej.parser.util; - -import java.io.StringWriter; -import java.io.Writer; -import java.util.List; - -import net.java.textilej.parser.markup.Dialect; -import net.java.textilej.parser.outline.OutlineItem; -import net.java.textilej.parser.outline.OutlineParser; -import net.java.textilej.util.DefaultXmlStreamWriter; -import net.java.textilej.util.FormattingXMLStreamWriter; -import net.java.textilej.util.XmlStreamWriter; - -public class MarkupToEclipseToc { - private Dialect dialect; - private String bookTitle; - private String htmlFile; - - public String parse(String markupContent) { - if (dialect == null) { - throw new IllegalStateException(); - } - OutlineParser parser = new OutlineParser(dialect); - - OutlineItem root = parser.parse(markupContent); - - StringWriter out = new StringWriter(8096); - - XmlStreamWriter writer = createXmlStreamWriter(out); - - writer.writeStartDocument("utf-8","1.0"); - - writer.writeStartElement("toc"); - writer.writeAttribute("topic", getHtmlFile()); - writer.writeAttribute("label", getBookTitle()); - - emitToc(writer,root.getChildren()); - - writer.writeEndElement(); // toc - - writer.writeEndDocument(); - writer.close(); - - return out.toString(); - - } - - private void emitToc(XmlStreamWriter writer, List children) { - for (OutlineItem item: children) { - writer.writeStartElement("topic"); - writer.writeAttribute("href", getHtmlFile()+"#"+item.getId()); - writer.writeAttribute("label", item.getLabel()); - - if (!item.getChildren().isEmpty()) { - emitToc(writer,item.getChildren()); - } - - writer.writeEndElement(); // topic - } - } - - - public String getBookTitle() { - return bookTitle; - } - - public void setBookTitle(String bookTitle) { - this.bookTitle = bookTitle; - } - - - public String getHtmlFile() { - return htmlFile; - } - - public void setHtmlFile(String htmlFile) { - this.htmlFile = htmlFile; - } - - protected XmlStreamWriter createXmlStreamWriter(Writer out) { - XmlStreamWriter writer = new DefaultXmlStreamWriter(out); - return new FormattingXMLStreamWriter(writer); - } - - public Dialect getDialect() { - return dialect; - } - - public void setDialect(Dialect dialect) { - this.dialect = dialect; - } - -} diff --git a/src/net/java/textilej/parser/util/Matcher.java b/src/net/java/textilej/parser/util/Matcher.java deleted file mode 100644 index b954a51..0000000 --- a/src/net/java/textilej/parser/util/Matcher.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.java.textilej.parser.util; - -public interface Matcher { - public String group(int group); - public int start(int group); - public int end(int group); -} diff --git a/src/net/java/textilej/parser/util/MatcherAdaper.java b/src/net/java/textilej/parser/util/MatcherAdaper.java deleted file mode 100644 index 53fecc1..0000000 --- a/src/net/java/textilej/parser/util/MatcherAdaper.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.java.textilej.parser.util; - - -public class MatcherAdaper implements Matcher { - - private java.util.regex.Matcher delegate; - - public MatcherAdaper(java.util.regex.Matcher delegate) { - this.delegate = delegate; - } - - public int end(int group) { - return delegate.end(group); - } - - public String group(int group) { - return delegate.group(group); - } - - public int start(int group) { - return delegate.start(group); - } - -} diff --git a/src/net/java/textilej/parser/util/TextileToDocbook.java b/src/net/java/textilej/parser/util/TextileToDocbook.java deleted file mode 100644 index 5f784de..0000000 --- a/src/net/java/textilej/parser/util/TextileToDocbook.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.java.textilej.parser.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; - -import net.java.textilej.parser.markup.textile.TextileDialect; - -public class TextileToDocbook extends MarkupToDocbook { - - - public static void main(String[] args) { - try { - if (args.length < 1) { - usage(); - System.exit(-1); - } - File inputFile = new File(args[0]); - File outputFile = args.length < 2?null:new File(args[1]); - if (outputFile != null && outputFile.exists()) { - System.err.println("File "+outputFile+" already exists"); - usage(); - System.exit(-1); - } - - if (!inputFile.exists()) { - System.err.println("File "+outputFile+" does not exist"); - usage(); - System.exit(-1); - } - - String textileSource = readFully(inputFile); - - TextileToDocbook textileToDocbook = new TextileToDocbook(); - String name = inputFile.getName(); - if (name.lastIndexOf('.') != -1) { - name = name.substring(0,name.lastIndexOf('.')); - } - textileToDocbook.setBookTitle(name); - - String docbookSource = textileToDocbook.parse(textileSource); - if (outputFile == null) { - System.out.println(docbookSource); - } else { - Writer writer = new OutputStreamWriter(new FileOutputStream(outputFile),"utf-8"); - try { - writer.write(docbookSource); - } finally { - writer.close(); - } - } - - } catch (Exception e) { - e.printStackTrace(); - System.exit(-1); - } - } - - public TextileToDocbook() { - setDialect(new TextileDialect()); - } - - private static String readFully(File inputFile) throws IOException { - int length = (int) inputFile.length(); - if (length <= 0) { - length = 2048; - } - StringBuilder buf = new StringBuilder(length); - Reader reader = new BufferedReader(new FileReader(inputFile)); - try { - int c; - while ((c = reader.read()) != -1) { - buf.append((char)c); - } - } finally { - reader.close(); - } - return buf.toString(); - } - - private static void usage() { - System.err.println("Usage: java "+TextileToDocbook.class.getName()+" [output file]"); - } - -} diff --git a/src/net/java/textilej/parser/util/TextileToEclipseToc.java b/src/net/java/textilej/parser/util/TextileToEclipseToc.java deleted file mode 100644 index 4fd3230..0000000 --- a/src/net/java/textilej/parser/util/TextileToEclipseToc.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.java.textilej.parser.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.List; - -import net.java.textilej.parser.markup.textile.TextileDialect; -import net.java.textilej.parser.outline.OutlineItem; -import net.java.textilej.parser.outline.OutlineParser; -import net.java.textilej.util.DefaultXmlStreamWriter; -import net.java.textilej.util.FormattingXMLStreamWriter; -import net.java.textilej.util.XmlStreamWriter; - -/** - * A conversion utility targeting the - * Eclipse help table of contents format. - * - * @author dgreen - */ -public class TextileToEclipseToc extends MarkupToEclipseToc { - public TextileToEclipseToc() { - setDialect(new TextileDialect()); - } - - public static void main(String[] args) { - try { - if (args.length < 1) { - usage(); - System.exit(-1); - } - File inputFile = new File(args[0]); - File outputFile = args.length < 2?null:new File(args[1]); - if (outputFile != null && outputFile.exists()) { - System.err.println("File "+outputFile+" already exists"); - usage(); - System.exit(-1); - } - - if (!inputFile.exists()) { - System.err.println("File "+outputFile+" does not exist"); - usage(); - System.exit(-1); - } - - String textileSource = readFully(inputFile); - - TextileToEclipseToc textileToEclipseToc = new TextileToEclipseToc(); - String name = inputFile.getName(); - if (name.lastIndexOf('.') != -1) { - name = name.substring(0,name.lastIndexOf('.')); - } - textileToEclipseToc.setBookTitle(name); - textileToEclipseToc.setHtmlFile(name+".html"); - - String docbookSource = textileToEclipseToc.parse(textileSource); - if (outputFile == null) { - System.out.println(docbookSource); - } else { - Writer writer = new OutputStreamWriter(new FileOutputStream(outputFile),"utf-8"); - try { - writer.write(docbookSource); - } finally { - writer.close(); - } - } - - } catch (Exception e) { - e.printStackTrace(); - System.exit(-1); - } - } - - private static String readFully(File inputFile) throws IOException { - int length = (int) inputFile.length(); - if (length <= 0) { - length = 2048; - } - StringBuilder buf = new StringBuilder(length); - Reader reader = new BufferedReader(new FileReader(inputFile)); - try { - int c; - while ((c = reader.read()) != -1) { - buf.append((char)c); - } - } finally { - reader.close(); - } - return buf.toString(); - } - - private static void usage() { - System.err.println("Usage: java "+TextileToEclipseToc.class.getName()+" [output file]"); - } - - -} diff --git a/src/net/java/textilej/util/DefaultXmlStreamWriter.java b/src/net/java/textilej/util/DefaultXmlStreamWriter.java deleted file mode 100644 index 131bdec..0000000 --- a/src/net/java/textilej/util/DefaultXmlStreamWriter.java +++ /dev/null @@ -1,505 +0,0 @@ -package net.java.textilej.util; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -public class DefaultXmlStreamWriter implements XmlStreamWriter { - - private PrintWriter out; - - - private Map prefixToUri = new HashMap(); - private Map uriToPrefix = new HashMap(); - - private boolean inEmptyElement = false; - private boolean inStartElement = false; - - private Stack elements = new Stack(); - - private char xmlHederQuoteChar = '\''; - - public DefaultXmlStreamWriter(OutputStream out) throws UnsupportedEncodingException { - this.out = createUtf8PrintWriter(out); - } - - public DefaultXmlStreamWriter(Writer out) { - this.out = new PrintWriter(out); - } - - public DefaultXmlStreamWriter(Writer out,char xmlHeaderQuoteChar) { - this.out = new PrintWriter(out); - this.xmlHederQuoteChar = xmlHeaderQuoteChar; - } - - protected PrintWriter createUtf8PrintWriter(java.io.OutputStream out) throws UnsupportedEncodingException { - return new java.io.PrintWriter(new OutputStreamWriter(out, "UTF8")); - } - - public void close() { - if (out != null) { - closeElement(); - flush(); - } - out = null; - } - - public void flush() { - out.flush(); - } - - - public String getPrefix(String uri) { - return uriToPrefix.get(uri); - } - - public Object getProperty(String name) throws IllegalArgumentException { - return null; - } - - public void setDefaultNamespace(String uri) { - setPrefix("", uri); - } - - public void setPrefix(String prefix, String uri) { - prefixToUri.put(prefix,uri); - uriToPrefix.put(uri,prefix); - } - - public void writeAttribute(String localName, String value) { - out.write(' '); - out.write(localName); - out.write("=\""); - if (value != null) { - attrEncode(value); - } - out.write("\""); - } - - public void writeAttribute(String namespaceURI, String localName, String value) { - out.write(' '); - String prefix = uriToPrefix.get(namespaceURI); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - } - out.write(localName); - out.write("=\""); - if (value != null) { - attrEncode(value); - } - out.write("\""); - } - - public void writeAttribute(String prefix, String namespaceURI, String localName, String value) { - out.write(' '); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - } - out.write(localName); - out.write("=\""); - if (value != null) { - attrEncode(value); - } - out.write("\""); - } - - private void attrEncode(String value) { - if (value == null) { - return; - } - printEscaped(out, value, true); - } - private void encode(String text) { - if (text == null) { - return; - } - printEscaped(out, text, false); - } - - public void writeCData(String data) { - closeElement(); - out.write(""); - } - - public void writeCharacters(String text) { - closeElement(); - encode(text); - } - - public void writeCharactersUnescaped(String text) { - closeElement(); - out.print(text); - } - - public void writeLiteral(String literal) { - writeCharactersUnescaped(literal); - } - - public void writeCharacters(char[] text, int start, int len) { - closeElement(); - encode(new String(text,start,len)); - } - - public void writeComment(String data) { - closeElement(); - out.write(""); - } - - public void writeDTD(String dtd) { - out.write(dtd); - } - - public void writeDefaultNamespace(String namespaceURI) { - writeAttribute("xmlns",namespaceURI); - } - - private void closeElement() { - if (inEmptyElement) { - out.write("/>"); - inEmptyElement = false; - } else if (inStartElement) { - out.write(">"); - inStartElement = false; - } - } - - public void writeEmptyElement(String localName) { - closeElement(); - inEmptyElement = true; - out.write('<'); - out.write(localName); - } - - - public void writeEmptyElement(String namespaceURI, String localName) { - closeElement(); - inEmptyElement = true; - String prefix = uriToPrefix.get(namespaceURI); - out.write('<'); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - } - out.write(localName); - } - - public void writeEmptyElement(String prefix, String localName, String namespaceURI) { - closeElement(); - inEmptyElement = true; - out.write('<'); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - } - out.write(localName); - } - - public void writeEndDocument() { - if (!elements.isEmpty()) { - throw new IllegalStateException(elements.size()+" elements not closed"); - } - } - - public void writeEndElement() { - closeElement(); - if (elements.isEmpty()) { - throw new IllegalStateException(); - } - String name = elements.pop(); - out.write('<'); - out.write('/'); - out.write(name); - out.write('>'); - } - - public void writeEntityRef(String name) { - closeElement(); - out.write('&'); - out.write(name); - out.write(';'); - } - - public void writeNamespace(String prefix, String namespaceURI) { - if (prefix == null || prefix.length() == 0) { - writeAttribute("xmlns",namespaceURI); - } else { - writeAttribute("xmlns:"+prefix,namespaceURI); - } - } - - public void writeProcessingInstruction(String target) { - closeElement(); - } - - public void writeProcessingInstruction(String target, String data) { - closeElement(); - - } - - public void writeStartDocument() { - out.write(processXmlHeader("")); - } - - public void writeStartDocument(String version) { - out.write(processXmlHeader("")); - } - - public void writeStartDocument(String encoding, String version) { - out.write(processXmlHeader("")); - } - - public void writeStartElement(String localName) { - closeElement(); - inStartElement = true; - elements.push(localName); - out.write('<'); - out.write(localName); - } - - public void writeStartElement(String namespaceURI, String localName) { - closeElement(); - inStartElement = true; - String prefix = uriToPrefix.get(namespaceURI); - out.write('<'); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - elements.push(prefix+':'+localName); - } else { - elements.push(localName); - } - out.write(localName); - } - - public void writeStartElement(String prefix, String localName, String namespaceURI) { - closeElement(); - inStartElement = true; - elements.push(localName); - out.write('<'); - if (prefix != null && prefix.length() > 0) { - out.write(prefix); - out.write(':'); - } - out.write(localName); - } - - public char getXmlHederQuoteChar() { - return xmlHederQuoteChar; - } - - public void setXmlHederQuoteChar(char xmlHederQuoteChar) { - this.xmlHederQuoteChar = xmlHederQuoteChar; - } - - private String processXmlHeader(String header) { - return xmlHederQuoteChar == '\''?header:header.replace('\'', xmlHederQuoteChar); - } - - private static void printEscaped(PrintWriter writer, CharSequence s,boolean attribute) { - int length = s.length(); - - try { - for (int x = 0; x < length; ++x) { - char ch = s.charAt(x); - printEscaped(writer, ch,attribute); - } - } catch (IOException ioe) { - throw new IllegalStateException(); - } - } - - - /** - * Print an XML character in its escaped form. - * - * @param writer - * The writer to which the character should be printed. - * @param ch - * the character to print. - * - * @throws IOException - */ - private static void printEscaped(PrintWriter writer, int ch,boolean attribute) throws IOException { - - String ref = getEntityRef(ch,attribute); - if (ref != null) { - writer.write('&'); - writer.write(ref); - writer.write(';'); - } else if (ch == '\r' || ch == 0x0085 || ch == 0x2028) { - printHex(writer, ch); - } else if ((ch >= ' ' && ch != 160 && isUtf8Printable((char) ch) && isXML11ValidLiteral(ch)) || ch == '\t' || ch == '\n' || ch == '\r') { - writer.write((char) ch); - } else { - printHex(writer, ch); - } - } - - /** - * Escapes chars - */ - final static void printHex(PrintWriter writer, int ch) throws IOException { - writer.write("&#x"); - writer.write(Integer.toHexString(ch)); - writer.write(';'); - } - - - protected static String getEntityRef(int ch,boolean attribute) { - // Encode special XML characters into the equivalent character - // references. - // These five are defined by default for all XML documents. - switch (ch) { - case '<': - return "lt"; - - // no need to escape '>'!! -// case '>': -// return "gt"; - case '"': - if (attribute) { - return "quot"; - } - break; - case '&': - return "amp"; - - // WARN: there is no need to encode apostrophe, and doing so has an - // adverse - // effect on XHTML documents containing javascript with some browsers. - // case '\'': - // return "apos"; - } - return null; - } - - protected static boolean isUtf8Printable(char ch) { - // fall-back method here. - if ((ch >= ' ' && ch <= 0x10FFFF && ch != 0xF7) || ch == '\n' || ch == '\r' || ch == '\t') { - // If the character is not printable, print as character reference. - // Non printables are below ASCII space but not tab or line - // terminator, ASCII delete, or above a certain Unicode threshold. - return true; - } - - return false; - } - - - - private static final byte XML11CHARS[] = new byte[1 << 16]; - public static final int MASK_XML11_VALID = 0x01; - public static final int MASK_XML11_CONTROL = 0x10; - - static { - - // Initializing the Character Flag Array - // Code generated by: XML11CharGenerator. - - Arrays.fill(XML11CHARS, 1, 9, (byte) 17); // Fill 8 of value (byte) 17 - XML11CHARS[9] = 35; - XML11CHARS[10] = 3; - Arrays.fill(XML11CHARS, 11, 13, (byte) 17); // Fill 2 of value (byte) 17 - XML11CHARS[13] = 3; - Arrays.fill(XML11CHARS, 14, 32, (byte) 17); // Fill 18 of value (byte) - // 17 - XML11CHARS[32] = 35; - Arrays.fill(XML11CHARS, 33, 38, (byte) 33); // Fill 5 of value (byte) 33 - XML11CHARS[38] = 1; - Arrays.fill(XML11CHARS, 39, 45, (byte) 33); // Fill 6 of value (byte) 33 - Arrays.fill(XML11CHARS, 45, 47, (byte) -87); // Fill 2 of value - // (byte) -87 - XML11CHARS[47] = 33; - Arrays.fill(XML11CHARS, 48, 58, (byte) -87); // Fill 10 of value - // (byte) -87 - XML11CHARS[58] = 45; - XML11CHARS[59] = 33; - XML11CHARS[60] = 1; - Arrays.fill(XML11CHARS, 61, 65, (byte) 33); // Fill 4 of value (byte) 33 - Arrays.fill(XML11CHARS, 65, 91, (byte) -19); // Fill 26 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 91, 93, (byte) 33); // Fill 2 of value (byte) 33 - XML11CHARS[93] = 1; - XML11CHARS[94] = 33; - XML11CHARS[95] = -19; - XML11CHARS[96] = 33; - Arrays.fill(XML11CHARS, 97, 123, (byte) -19); // Fill 26 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 123, 127, (byte) 33); // Fill 4 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 127, 133, (byte) 17); // Fill 6 of value - // (byte) 17 - XML11CHARS[133] = 35; - Arrays.fill(XML11CHARS, 134, 160, (byte) 17); // Fill 26 of value - // (byte) 17 - Arrays.fill(XML11CHARS, 160, 183, (byte) 33); // Fill 23 of value - // (byte) 33 - XML11CHARS[183] = -87; - Arrays.fill(XML11CHARS, 184, 192, (byte) 33); // Fill 8 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 192, 215, (byte) -19); // Fill 23 of value - // (byte) -19 - XML11CHARS[215] = 33; - Arrays.fill(XML11CHARS, 216, 247, (byte) -19); // Fill 31 of value - // (byte) -19 - XML11CHARS[247] = 33; - Arrays.fill(XML11CHARS, 248, 768, (byte) -19); // Fill 520 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 768, 880, (byte) -87); // Fill 112 of value - // (byte) -87 - Arrays.fill(XML11CHARS, 880, 894, (byte) -19); // Fill 14 of value - // (byte) -19 - XML11CHARS[894] = 33; - Arrays.fill(XML11CHARS, 895, 8192, (byte) -19); // Fill 7297 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 8192, 8204, (byte) 33); // Fill 12 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 8204, 8206, (byte) -19); // Fill 2 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 8206, 8232, (byte) 33); // Fill 26 of value - // (byte) 33 - XML11CHARS[8232] = 35; - Arrays.fill(XML11CHARS, 8233, 8255, (byte) 33); // Fill 22 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 8255, 8257, (byte) -87); // Fill 2 of value - // (byte) -87 - Arrays.fill(XML11CHARS, 8257, 8304, (byte) 33); // Fill 47 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 8304, 8592, (byte) -19); // Fill 288 of value - // (byte) -19 - Arrays.fill(XML11CHARS, 8592, 11264, (byte) 33); // Fill 2672 of - // value (byte) 33 - Arrays.fill(XML11CHARS, 11264, 12272, (byte) -19); // Fill 1008 of - // value (byte) -19 - Arrays.fill(XML11CHARS, 12272, 12289, (byte) 33); // Fill 17 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 12289, 55296, (byte) -19); // Fill 43007 of - // value (byte) -19 - Arrays.fill(XML11CHARS, 57344, 63744, (byte) 33); // Fill 6400 of - // value (byte) 33 - Arrays.fill(XML11CHARS, 63744, 64976, (byte) -19); // Fill 1232 of - // value (byte) -19 - Arrays.fill(XML11CHARS, 64976, 65008, (byte) 33); // Fill 32 of value - // (byte) 33 - Arrays.fill(XML11CHARS, 65008, 65534, (byte) -19); // Fill 526 of value - // (byte) -19 - - } // () - public static boolean isXML11ValidLiteral(int c) { - return ((c < 0x10000 && ((XML11CHARS[c] & MASK_XML11_VALID) != 0 && (XML11CHARS[c] & MASK_XML11_CONTROL) == 0)) || (0x10000 <= c && c <= 0x10FFFF)); - } - -} \ No newline at end of file diff --git a/src/net/java/textilej/util/FormattingXMLStreamWriter.java b/src/net/java/textilej/util/FormattingXMLStreamWriter.java deleted file mode 100644 index 500ec21..0000000 --- a/src/net/java/textilej/util/FormattingXMLStreamWriter.java +++ /dev/null @@ -1,241 +0,0 @@ -package net.java.textilej.util; - -import java.util.Stack; - - -public class FormattingXMLStreamWriter implements XmlStreamWriter { - - private XmlStreamWriter delegate; - private int indentLevel; - private Stack childCounts = new Stack(); - private int childCount; - - private Stack elements = new Stack(); - - private int lineOffset = 0; - - public FormattingXMLStreamWriter(XmlStreamWriter delegate) { - this.delegate = delegate; - } - - public void close() { - delegate.close(); - } - - public void flush() { - delegate.flush(); - } - - public String getPrefix(String uri) { - return delegate.getPrefix(uri); - } - - public void setDefaultNamespace(String uri) { - delegate.setDefaultNamespace(uri); - } - - public void setPrefix(String prefix, String uri) { - delegate.setPrefix(prefix, uri); - } - - public void writeAttribute(String prefix, String namespaceURI, String localName, String value) { - if (value == null) { - value = ""; - } - delegate.writeAttribute(prefix, namespaceURI, localName, value); - } - - public void writeAttribute(String namespaceURI, String localName, String value) { - if (value == null) { - value = ""; - } - delegate.writeAttribute(namespaceURI, localName, value); - } - - public void writeAttribute(String localName, String value) { - if (value == null) { - value = ""; - } - delegate.writeAttribute(localName, value); - } - - public void writeCData(String data) { - delegate.writeCData(data); - } - - public void writeCharacters(char[] text, int start, int len) { - int lineStart = start; - int length = 0; - for (int x = 0;x 0) { - delegate.writeCharacters(text, lineStart, length); - lineOffset += length; - } - } - - public void writeCharacters(String text) { - if (text == null) { - return; - } - writeCharacters(text.toCharArray(),0,text.length()); - } - - public void writeLiteral(String literal) { - delegate.writeLiteral(literal); - } - - public void writeComment(String data) { - if (data == null) { - data = ""; - } - delegate.writeComment(data); - } - - public void writeDefaultNamespace(String namespaceURI) { - delegate.writeDefaultNamespace(namespaceURI); - } - - public void writeDTD(String dtd) { - delegate.writeDTD(dtd); - } - - public void writeEmptyElement(String prefix, String localName, String namespaceURI) { - ++childCount; - maybeIndent(); - delegate.writeEmptyElement(prefix, localName, namespaceURI); - } - - public void writeEmptyElement(String namespaceURI, String localName) { - ++childCount; - maybeIndent(); - delegate.writeEmptyElement(namespaceURI, localName); - } - - public void writeEmptyElement(String localName) { - ++childCount; - maybeIndent(); - delegate.writeEmptyElement(localName); - } - - - public void writeEndDocument() { - delegate.writeEndDocument(); - } - - public void writeEndElement() { - --indentLevel; - maybeIndent(); - elements.pop(); - delegate.writeEndElement(); - childCount = childCounts.pop(); - } - - public void writeEntityRef(String name) { - delegate.writeEntityRef(name); - } - - public void writeNamespace(String prefix, String namespaceURI) { - delegate.writeNamespace(prefix, namespaceURI); - } - - public void writeProcessingInstruction(String target, String data) { - delegate.writeProcessingInstruction(target, data); - } - - public void writeProcessingInstruction(String target) { - delegate.writeProcessingInstruction(target); - } - - public void writeStartDocument() { - delegate.writeStartDocument(); - } - - public void writeStartDocument(String encoding, String version) { - delegate.writeStartDocument(encoding, version); - } - - public void writeStartDocument(String version) { - delegate.writeStartDocument(version); - } - - public void writeStartElement(String prefix, String localName, String namespaceURI) { - ++childCount; - maybeIndent(); - elements.push(localName); - childCounts.push(childCount); - childCount = 0; - ++indentLevel; - delegate.writeStartElement(prefix, localName, namespaceURI); - } - - public void writeStartElement(String namespaceURI, String localName) { - ++childCount; - maybeIndent(); - elements.push(localName); - childCounts.push(childCount); - childCount = 0; - ++indentLevel; - delegate.writeStartElement(namespaceURI, localName); - } - - public void writeStartElement(String localName) { - ++childCount; - maybeIndent(); - elements.push(localName); - childCounts.push(childCount); - childCount = 0; - ++indentLevel; - delegate.writeStartElement(localName); - } - - private void maybeIndent() { - maybeIndent(true,false); - } - - private void maybeIndent(boolean withNewline,boolean force) { - if ((childCount == 0 && !force)||preserveWhitespace()) { - return; - } - StringBuilder buf = new StringBuilder(); - if (withNewline) { - buf.append('\n'); - } - for (int x = 0;x=0;--x) { - if (preserveWhitespace(elements.get(x))) { - return true; - } - } - return false; - } - - /** - * Override this method to indicate which elements must have whitespace preserved. - * - * @param elementName the local name of the element - */ - protected boolean preserveWhitespace(String elementName) { - return false; - } - -} \ No newline at end of file diff --git a/src/net/java/textilej/util/IgnoreDtdEntityResolver.java b/src/net/java/textilej/util/IgnoreDtdEntityResolver.java deleted file mode 100644 index e34c98b..0000000 --- a/src/net/java/textilej/util/IgnoreDtdEntityResolver.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.java.textilej.util; - -import java.io.IOException; -import java.io.StringReader; - -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -/** - * An entity resolver that resolves all requests for DTD content, thus preventing network access - * when resolving DTDs. - * - */ -public class IgnoreDtdEntityResolver implements EntityResolver { - protected static final IgnoreDtdEntityResolver instance = new IgnoreDtdEntityResolver(); - - public static IgnoreDtdEntityResolver getInstance() { - return instance; - } - - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - if ((publicId != null && publicId.indexOf("//DTD") != -1) || (systemId != null && systemId.endsWith(".dtd"))) { - return new InputSource(new StringReader("")); - } - return null; - } -} diff --git a/src/net/java/textilej/util/LocationTrackingReader.java b/src/net/java/textilej/util/LocationTrackingReader.java deleted file mode 100644 index bafb661..0000000 --- a/src/net/java/textilej/util/LocationTrackingReader.java +++ /dev/null @@ -1,180 +0,0 @@ -package net.java.textilej.util; - -import java.io.IOException; -import java.io.Reader; - - -public class LocationTrackingReader extends Reader { - private Reader delegate; - - private int offset = -1; - private int lineOffset = -1; - private int lineNumber = -1; - - private char[] buf; - private int bufOffset = 0; - private int bufLength = 0; - - public LocationTrackingReader(Reader delegate) { - this(delegate,2048); - } - - public LocationTrackingReader(Reader delegate,int bufferSize) { - this.delegate = delegate; - buf = new char[bufferSize]; - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public int read(char[] cbuf, int off, int len) throws IOException { - if (bufLength > 0) { - int length = Math.min(len, bufLength); - System.arraycopy(buf, bufOffset, cbuf, off, length); - bufLength -=length; - bufOffset += length; - if (bufLength == 0) { - bufOffset = 0; - } - offset += length; - return length; - } else { - int read = delegate.read(cbuf,off,len); - if (read != -1) { - offset += read; - } - return read; - } - } - - @Override - public int read() throws IOException { - if (bufLength > 0) { - int c = buf[bufOffset]; - bufLength -= 1; - bufOffset += 1; - if (bufLength == 0) { - bufOffset = 0; - } - offset += 1; - return c; - } else { - int read = delegate.read(); - if (read != -1) { - ++offset; - } - return read; - } - } - - /** - * Read a line of text, omitting the line delimiters. - * - * @return the text or null if the end of input has been reached - * - * @see #getLineOffset() - */ - public String readLine() throws IOException { - lineOffset = offset+1; - - int lineBufOffset = bufOffset; - int c = -1; - for (int x = lineBufOffset;;++x) { - if (x >= (bufOffset+bufLength)) { - if (bufOffset > 0 && bufLength > 0) { - System.arraycopy(buf, bufOffset, buf, 0, bufLength); - x -= bufOffset; - bufOffset = 0; - lineBufOffset = 0; - } - if (bufOffset+bufLength >= buf.length) { - // expand the buffer - char[] newBuf = new char[buf.length*2]; - if (bufLength > 0) { - System.arraycopy(buf, bufOffset, newBuf, 0,bufLength); - } - x -= bufOffset; - bufOffset = 0; - lineBufOffset = 0; - buf = newBuf; - } - int emptyOffset = bufOffset+bufLength; - int read = delegate.read(buf, emptyOffset, buf.length-emptyOffset); - if (read > 0) { - bufLength += read; - } else { - // end of input - break; - } - } - if (x >= (bufOffset+bufLength)) { - // end of input - break; - } - int nc = buf[x]; - if (nc == '\n') { - // eol - int length = x-lineBufOffset+1; - bufOffset += length; - bufLength -= length; - offset += length; - - int stringLength = c=='\r'?length-2:length-1; - ++lineNumber; - return new String(buf,lineBufOffset,stringLength); - } else if (c == '\r') { - int length = x-lineBufOffset; - bufOffset += length; - bufLength -= length; - offset += length; - int stringLength = length-1; - ++lineNumber; - return new String(buf,lineBufOffset,stringLength); - } - c = nc; - } - if (bufLength > 0) { - String line = new String(buf,bufOffset,c=='\r'?bufLength -1:bufLength); - bufOffset = 0; - offset += bufLength; - bufLength = 0; - ++lineNumber; - return line; - } else { - ++lineNumber; - return null; - } - } - - /** - * Get the character offset of the last character read. - */ - public int getOffset() { - return offset; - } - - /** - * Get the character offset of the first character of the last line read. The result of calling this method is only - * meaningful immediately after having called {@link #readLine()}. - * - * @see #readLine() - */ - public int getLineOffset() { - return lineOffset; - } - - /** - * get the 0-based line number of the last line read. The result of calling this method is only - * meaningful immediately after having called {@link #readLine()}. - * - * @see #readLine() - */ - public int getLineNumber() { - return lineNumber; - } - - -} diff --git a/src/net/java/textilej/util/LocatorImpl.java b/src/net/java/textilej/util/LocatorImpl.java deleted file mode 100644 index 9449dbf..0000000 --- a/src/net/java/textilej/util/LocatorImpl.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.java.textilej.util; - -import net.java.textilej.parser.Locator; - -public class LocatorImpl implements Locator { - - private int documentOffset; - private int lineCharacterOffset; - private int lineDocumentOffset; - private int lineLength; - private int lineNumber; - private int lineSegmentEndOffset; - - public LocatorImpl(Locator other) { - documentOffset = other.getDocumentOffset(); - lineCharacterOffset = other.getLineCharacterOffset(); - lineDocumentOffset = other.getLineDocumentOffset(); - lineLength = other.getLineLength(); - lineNumber = other.getLineNumber(); - lineSegmentEndOffset = other.getLineSegmentEndOffset(); - } - - public int getDocumentOffset() { - return documentOffset; - } - - public int getLineCharacterOffset() { - return lineCharacterOffset; - } - - public int getLineDocumentOffset() { - return lineDocumentOffset; - } - - public int getLineLength() { - return lineLength; - } - - public int getLineNumber() { - return lineNumber; - } - - public int getLineSegmentEndOffset() { - return lineSegmentEndOffset; - } - -} diff --git a/src/net/java/textilej/util/LoggingXMLStreamWriter.java b/src/net/java/textilej/util/LoggingXMLStreamWriter.java deleted file mode 100644 index dd68c34..0000000 --- a/src/net/java/textilej/util/LoggingXMLStreamWriter.java +++ /dev/null @@ -1,164 +0,0 @@ -package net.java.textilej.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -public class LoggingXMLStreamWriter implements XmlStreamWriter { - - private XmlStreamWriter delegate; - private Logger logger = Logger.getLogger(LoggingXMLStreamWriter.class.getName()); - - private List elementNames = new ArrayList(); - - public LoggingXMLStreamWriter(XmlStreamWriter delegate) { - this.delegate = delegate; - } - - public void close() { - delegate.close(); - } - - public void flush() { - delegate.flush(); - } - - public String getPrefix(String uri) { - return delegate.getPrefix(uri); - } - - public void setDefaultNamespace(String uri) { - delegate.setDefaultNamespace(uri); - } - - public void setPrefix(String prefix, String uri) { - delegate.setPrefix(prefix, uri); - } - - public void writeAttribute(String prefix, String namespaceURI, - String localName, String value) { - delegate.writeAttribute(prefix, namespaceURI, localName, value); - } - - public void writeAttribute(String namespaceURI, String localName, - String value) { - delegate.writeAttribute(namespaceURI, localName, value); - } - - public void writeAttribute(String localName, String value) { - delegate.writeAttribute(localName, value); - } - - public void writeCData(String data) { - delegate.writeCData(data); - } - - public void writeCharacters(char[] text, int start, int len) { - delegate.writeCharacters(text, start, len); - } - - public void writeCharacters(String text) { - delegate.writeCharacters(text); - } - - public void writeLiteral(String literal) { - delegate.writeLiteral(literal); - } - - public void writeComment(String data) { - delegate.writeComment(data); - } - - public void writeDefaultNamespace(String namespaceURI) { - delegate.writeDefaultNamespace(namespaceURI); - } - - public void writeDTD(String dtd) { - delegate.writeDTD(dtd); - } - - public void writeEmptyElement(String prefix, String localName, - String namespaceURI) { - logger.info("Empty element["+elementNames.size()+"] "+localName); - delegate.writeEmptyElement(prefix, localName, namespaceURI); - } - - public void writeEmptyElement(String namespaceURI, String localName) - { - logger.info("Empty element["+elementNames.size()+"] "+localName); - delegate.writeEmptyElement(namespaceURI, localName); - } - - public void writeEmptyElement(String localName) { - logger.info("Empty element["+elementNames.size()+"] "+localName); - delegate.writeEmptyElement(localName); - } - - public void writeEndDocument() { - delegate.writeEndDocument(); - } - - public void writeEndElement() { - if (elementNames.size() == 0) { - throw new IllegalStateException("Too many end elements"); - } - logger.info("End element["+elementNames.size()+"]: "+elementNames); - elementNames.remove(elementNames.size()-1); - delegate.writeEndElement(); - } - - public void writeEntityRef(String name) { - delegate.writeEntityRef(name); - } - - public void writeNamespace(String prefix, String namespaceURI) - { - delegate.writeNamespace(prefix, namespaceURI); - } - - public void writeProcessingInstruction(String target, String data) - { - delegate.writeProcessingInstruction(target, data); - } - - public void writeProcessingInstruction(String target) - { - delegate.writeProcessingInstruction(target); - } - - public void writeStartDocument() { - delegate.writeStartDocument(); - } - - public void writeStartDocument(String encoding, String version) - { - delegate.writeStartDocument(encoding, version); - } - - public void writeStartDocument(String version) { - delegate.writeStartDocument(version); - } - - public void writeStartElement(String prefix, String localName, - String namespaceURI) { - elementNames.add(localName); - logger.info("Start element["+elementNames.size()+"] "+elementNames); - delegate.writeStartElement(prefix, localName, namespaceURI); - } - - public void writeStartElement(String namespaceURI, String localName) - { - elementNames.add(localName); - logger.info("Start element["+elementNames.size()+"] "+elementNames); - delegate.writeStartElement(namespaceURI, localName); - } - - public void writeStartElement(String localName) { - elementNames.add(localName); - logger.info("Start element["+elementNames.size()+"] "+elementNames); - delegate.writeStartElement(localName); - } - - - -} diff --git a/src/net/java/textilej/util/XmlStreamWriter.java b/src/net/java/textilej/util/XmlStreamWriter.java deleted file mode 100644 index 238e820..0000000 --- a/src/net/java/textilej/util/XmlStreamWriter.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.java.textilej.util; - -public interface XmlStreamWriter { - - public void close(); - - public void flush(); - - public String getPrefix(String uri); - - public void setDefaultNamespace(String uri); - - public void setPrefix(String prefix, String uri); - - public void writeAttribute(String localName, String value); - - public void writeAttribute(String namespaceURI, String localName, - String value); - - public void writeAttribute(String prefix, String namespaceURI, - String localName, String value); - - public void writeCData(String data); - - public void writeCharacters(String text); - - public void writeCharacters(char[] text, int start, int len); - - public void writeComment(String data); - - public void writeDTD(String dtd); - - public void writeDefaultNamespace(String namespaceURI); - - public void writeEmptyElement(String localName); - - public void writeEmptyElement(String namespaceURI, String localName); - - public void writeEmptyElement(String prefix, String localName, - String namespaceURI); - - public void writeEndDocument(); - - public void writeEndElement(); - - public void writeEntityRef(String name); - - public void writeNamespace(String prefix, String namespaceURI); - - public void writeProcessingInstruction(String target); - - public void writeProcessingInstruction(String target, String data); - - public void writeStartDocument(); - - public void writeStartDocument(String version); - - public void writeStartDocument(String encoding, String version); - - public void writeStartElement(String localName); - - public void writeStartElement(String namespaceURI, String localName); - - public void writeStartElement(String prefix, String localName, - String namespaceURI); - - /** - * Write an XML fragment directly to the output. The given text is not processed or XML-encoded, - * since it is assumed to be a legal XML fragment. - */ - public void writeLiteral(String literal); - -} \ No newline at end of file diff --git a/src/net/java/textilej/util/anttask/TextileToDocbookTask.java b/src/net/java/textilej/util/anttask/TextileToDocbookTask.java deleted file mode 100644 index 048480d..0000000 --- a/src/net/java/textilej/util/anttask/TextileToDocbookTask.java +++ /dev/null @@ -1,226 +0,0 @@ -package net.java.textilej.util.anttask; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.MarkupParser; -import net.java.textilej.parser.builder.DocBookDocumentBuilder; -import net.java.textilej.parser.markup.textile.TextileDialect; -import net.java.textilej.util.XmlStreamWriter; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; - -/** - * An Ant task for converting textile to docbook format. - * - * @author dgreen - */ -public class TextileToDocbookTask extends Task { - private List filesets = new ArrayList(); - - private String docbookFilenameFormat = "$1.xml"; - - private String bookTitle; - - private boolean overwrite = true; - - protected File file; - - private String doctype; - - - - /** - * Adds a set of files to process. - */ - public void addFileset(FileSet set) { - filesets.add(set); - } - - @Override - public void execute() throws BuildException { - - if (file == null && filesets.isEmpty()) { - throw new BuildException("Please add one or more source filesets or specify @file"); - } - if (file != null && !filesets.isEmpty()) { - throw new BuildException("@file may not be specified if filesets are also specified"); - } - if (file != null) { - if (!file.exists()) { - throw new BuildException(String.format("File cannot be found: %s",file)); - } else if (!file.isFile()) { - throw new BuildException(String.format("Not a file: %s",file)); - } else if (!file.canRead()) { - throw new BuildException(String.format("Cannot read file: %s",file)); - } - } - - for (FileSet fileset: filesets) { - - File filesetBaseDir = fileset.getDir(getProject()); - DirectoryScanner ds = fileset.getDirectoryScanner(getProject()); - - String[] files = ds.getIncludedFiles(); - if (files != null) { - File baseDir = ds.getBasedir(); - for (String file: files) { - File inputFile = new File(baseDir,file); - try { - processFile(filesetBaseDir,inputFile); - } catch (BuildException e) { - throw e; - } catch (Exception e) { - throw new BuildException(String.format("Cannot process file '%s': %s",inputFile,e.getMessage()),e); - } - } - } - } - - if (file != null) { - try { - processFile(file.getParentFile(),file); - } catch (BuildException e) { - throw e; - } catch (Exception e) { - throw new BuildException(String.format("Cannot process file '%s': %s",file,e.getMessage()),e); - } - } - } - - private void processFile(final File baseDir,final File source) throws BuildException { - - log(String.format("Processing file '%s'",source),Project.MSG_VERBOSE); - - String textile = null; - - String name = source.getName(); - if (name.lastIndexOf('.') != -1) { - name = name.substring(0,name.lastIndexOf('.')); - } - - File docbookOutputFile = new File(source.getParentFile(),docbookFilenameFormat.replace("$1", name)); - if (!docbookOutputFile.exists() || overwrite || docbookOutputFile.lastModified() < source.lastModified()) { - - if (textile == null) { - textile = readFully(source); - } - - Writer writer; - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(docbookOutputFile)),"utf-8"); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",docbookOutputFile,e.getMessage()),e); - } - try { - DocBookDocumentBuilder builder = new DocBookDocumentBuilder(writer) { - @Override - protected XmlStreamWriter createXmlStreamWriter(Writer out) { - return super.createFormattingXmlStreamWriter(out); - } - }; - MarkupParser parser = new MarkupParser(); - parser.setDialect(new TextileDialect()); - parser.setBuilder(builder); - builder.setBookTitle(bookTitle==null?name:bookTitle); - if (doctype != null) { - builder.setDoctype(doctype); - } - parser.parse(textile); - } finally { - try { - writer.close(); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",docbookOutputFile,e.getMessage()),e); - } - } - } - - } - - private String readFully(File inputFile) { - StringWriter w = new StringWriter(); - try { - Reader r = new InputStreamReader(new BufferedInputStream(new FileInputStream(inputFile))); - try { - int i; - while ((i = r.read()) != -1) { - w.write((char)i); - } - } finally { - r.close(); - } - } catch (IOException e) { - throw new BuildException(String.format("Cannot read file '%s': %s",inputFile,e.getMessage()),e); - } - return w.toString(); - } - - /** - * @see #setDocbookFilenameFormat(String) - */ - public String getDocbookFilenameFormat() { - return docbookFilenameFormat; - } - - /** - * The format of the DocBook output file. Consists of a pattern where the - * '$1' is replaced with the filename of the input file. Default value is - * $1.xml - * - * @param docbookFilenameFormat - */ - public void setHtmlFilenameFormat(String docbookFilenameFormat) { - this.docbookFilenameFormat = docbookFilenameFormat; - } - - /** - * Get the book title. - * - * @return the title, or null if the textile filename is to be used as the title. - */ - public String getBookTitle() { - return bookTitle; - } - - /** - * - * Get the book title. - * - * @param bookTitle the title, or null if the textile filename is to be used as the title. - */ - public void setBookTitle(String bookTitle) { - this.bookTitle = bookTitle; - } - - /** - * Set the XML doctype of the docbook. The doctype should look something like this: - * <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> - * - */ - public void setDoctype(String doctype) { - this.doctype = doctype; - } - - /** - * The XML doctype of the docbook. - */ - public String getDoctype() { - return doctype; - } -} diff --git a/src/net/java/textilej/util/anttask/TextileToEclipseHelpTask.java b/src/net/java/textilej/util/anttask/TextileToEclipseHelpTask.java deleted file mode 100644 index 875ad17..0000000 --- a/src/net/java/textilej/util/anttask/TextileToEclipseHelpTask.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.java.textilej.util.anttask; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; - -import net.java.textilej.parser.util.TextileToEclipseToc; - -import org.apache.tools.ant.BuildException; - -/** - * An Ant task for converting textile to eclipse help format. - * - * @author dgreen - */ -public class TextileToEclipseHelpTask extends TextileToHtmlTask { - - private String xmlFilenameFormat = "$1-toc.xml"; - - - protected String processFile(final File baseDir,final File source) throws BuildException { - String textile = super.processFile(baseDir, source); - - String name = source.getName(); - if (name.lastIndexOf('.') != -1) { - name = name.substring(0,name.lastIndexOf('.')); - } - - File tocOutputFile = computeTocFile(source,name); - if (!tocOutputFile.exists() || overwrite || tocOutputFile.lastModified() < source.lastModified()) { - File htmlOutputFile = computeHtmlFile(source, name); - if (textile == null) { - textile = readFully(source); - } - - Writer writer; - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(tocOutputFile)),"utf-8"); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",tocOutputFile,e.getMessage()),e); - } - try { - - TextileToEclipseToc toEclipseToc = new TextileToEclipseToc(); - toEclipseToc.setBookTitle(title==null?name:title); - - String basePath = baseDir.getAbsolutePath().replace('\\','/'); - String outputFilePath = htmlOutputFile.getAbsolutePath().replace('\\','/'); - if (outputFilePath.startsWith(basePath)) { - String filePath = outputFilePath.substring(basePath.length()); - if (filePath.startsWith("/")) { - filePath = filePath.substring(1); - } - toEclipseToc.setHtmlFile(filePath); - } else { - toEclipseToc.setHtmlFile(htmlOutputFile.getName()); - } - - String tocXml = toEclipseToc.parse(textile); - - try { - writer.write(tocXml); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",tocXml,e.getMessage()),e); - } - } finally { - try { - writer.close(); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",tocOutputFile,e.getMessage()),e); - } - } - } - return textile; - } - - - private File computeTocFile(File source, String name) { - return new File(source.getParentFile(),xmlFilenameFormat.replace("$1", name)); - } - - - /** - * @see #setXmlFilenameFormat(String) - */ - public String getXmlFilenameFormat() { - return xmlFilenameFormat; - } - - /** - * The format of the XML table of contents output file. Consists of a pattern where the - * '$1' is replaced with the filename of the input file. Default value is - * $1-toc.xml - */ - public void setXmlFilenameFormat(String xmlFilenameFormat) { - this.xmlFilenameFormat = xmlFilenameFormat; - } -} diff --git a/src/net/java/textilej/util/anttask/TextileToHtmlTask.java b/src/net/java/textilej/util/anttask/TextileToHtmlTask.java deleted file mode 100644 index 983e100..0000000 --- a/src/net/java/textilej/util/anttask/TextileToHtmlTask.java +++ /dev/null @@ -1,317 +0,0 @@ -package net.java.textilej.util.anttask; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; - -import net.java.textilej.parser.MarkupParser; -import net.java.textilej.parser.builder.HtmlDocumentBuilder; -import net.java.textilej.parser.markup.textile.TextileDialect; -import net.java.textilej.util.XmlStreamWriter; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; - -/** - * An Ant task for converting textile to HTML format. - * - * @author dgreen - */ -public class TextileToHtmlTask extends Task { - private List filesets = new ArrayList(); - - protected String htmlFilenameFormat = "$1.html"; - - protected boolean overwrite = true; - - private List stylesheets = new ArrayList(); - - protected File file; - - protected String title; - - private boolean useInlineCssStyles = true; - private boolean suppressBuiltInCssStyles = false; - - @Override - public void execute() throws BuildException { - if (file == null && filesets.isEmpty()) { - throw new BuildException("Please add one or more source filesets or specify @file"); - } - if (file != null && !filesets.isEmpty()) { - throw new BuildException("@file may not be specified if filesets are also specified"); - } - if (file != null) { - if (!file.exists()) { - throw new BuildException(String.format("File cannot be found: %s",file)); - } else if (!file.isFile()) { - throw new BuildException(String.format("Not a file: %s",file)); - } else if (!file.canRead()) { - throw new BuildException(String.format("Cannot read file: %s",file)); - } - } - - for (Stylesheet stylesheet: stylesheets) { - if (stylesheet.url == null && stylesheet.file == null) { - throw new BuildException("Must specify one of @file or @url on "); - } - if (stylesheet.url != null && stylesheet.file != null) { - throw new BuildException("May only specify one of @file or @url on "); - } - if (stylesheet.file != null) { - if (!stylesheet.file.exists()) { - throw new BuildException("Stylesheet file does not exist: "+stylesheet.file); - } - if (!stylesheet.file.isFile()) { - throw new BuildException("Referenced stylesheet is not a file: "+stylesheet.file); - } - if (!stylesheet.file.canRead()) { - throw new BuildException("Cannot read stylesheet: "+stylesheet.file); - } - } - } - - for (FileSet fileset: filesets) { - - File filesetBaseDir = fileset.getDir(getProject()); - DirectoryScanner ds = fileset.getDirectoryScanner(getProject()); - - String[] files = ds.getIncludedFiles(); - if (files != null) { - File baseDir = ds.getBasedir(); - for (String file: files) { - File inputFile = new File(baseDir,file); - try { - processFile(filesetBaseDir,inputFile); - } catch (BuildException e) { - throw e; - } catch (Exception e) { - throw new BuildException(String.format("Cannot process file '%s': %s",inputFile,e.getMessage()),e); - } - } - } - } - if (file != null) { - try { - processFile(file.getParentFile(),file); - } catch (BuildException e) { - throw e; - } catch (Exception e) { - throw new BuildException(String.format("Cannot process file '%s': %s",file,e.getMessage()),e); - } - } - } - - /** - * process the file - * - * @param baseDir - * @param source - * - * @return the textile markup, or null if the file was not written - * - * @throws BuildException - */ - protected String processFile(final File baseDir,final File source) throws BuildException { - - log(String.format("Processing file '%s'",source),Project.MSG_VERBOSE); - - String textile = null; - - String name = source.getName(); - if (name.lastIndexOf('.') != -1) { - name = name.substring(0,name.lastIndexOf('.')); - } - - File htmlOutputFile = computeHtmlFile(source, name); - if (!htmlOutputFile.exists() || overwrite || htmlOutputFile.lastModified() < source.lastModified()) { - - if (textile == null) { - textile = readFully(source); - } - - Writer writer; - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(htmlOutputFile)),"utf-8"); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",htmlOutputFile,e.getMessage()),e); - } - try { - HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer) { - @Override - protected XmlStreamWriter createXmlStreamWriter(Writer out) { - return super.createFormattingXmlStreamWriter(out); - } - }; - builder.setUseInlineStyles(useInlineCssStyles); - builder.setSuppressBuiltInStyles(suppressBuiltInCssStyles); - for (Stylesheet stylesheet: stylesheets) { - if (stylesheet.url != null) { - builder.addCssStylesheet(stylesheet.url); - } else { - builder.addCssStylesheet(stylesheet.file); - } - } - - builder.setTitle(title==null?name:title); - MarkupParser parser = new MarkupParser(); - parser.setDialect(new TextileDialect()); - parser.setBuilder(builder); - builder.setEmitDtd(true); - - parser.parse(textile); - } finally { - try { - writer.close(); - } catch (Exception e) { - throw new BuildException(String.format("Cannot write to file '%s': %s",htmlOutputFile,e.getMessage()),e); - } - } - } - return textile; - } - - protected File computeHtmlFile(final File source, String name) { - return new File(source.getParentFile(),htmlFilenameFormat.replace("$1", name)); - } - - protected String readFully(File inputFile) { - StringWriter w = new StringWriter(); - try { - Reader r = new InputStreamReader(new BufferedInputStream(new FileInputStream(inputFile))); - try { - int i; - while ((i = r.read()) != -1) { - w.write((char)i); - } - } finally { - r.close(); - } - } catch (IOException e) { - throw new BuildException(String.format("Cannot read file '%s': %s",inputFile,e.getMessage()),e); - } - return w.toString(); - } - - /** - * @see #setHtmlFilenameFormat(String) - */ - public String getHtmlFilenameFormat() { - return htmlFilenameFormat; - } - - /** - * The format of the HTML output file. Consists of a pattern where the - * '$1' is replaced with the filename of the input file. Default value is - * $1.html - * - * @param htmlFilenameFormat - */ - public void setHtmlFilenameFormat(String htmlFilenameFormat) { - this.htmlFilenameFormat = htmlFilenameFormat; - } - - /** - * The document title, as it appears in the head - */ - public String getTitle() { - return title; - } - - /** - * The document title, as it appears in the head - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * the file to process - */ - public File getFile() { - return file; - } - - /** - * the file to process - */ - public void setFile(File file) { - this.file = file; - } - - /** - * Adds a set of files to process. - */ - public void addFileset(FileSet set) { - filesets.add(set); - } - - public void addStylesheet(Stylesheet stylesheet) { - if (stylesheet == null) { - throw new IllegalArgumentException(); - } - stylesheets.add(stylesheet); - } - - - /** - * @see HtmlDocumentBuilder#isUseInlineStyles() - */ - public boolean isUseInlineCssStyles() { - return useInlineCssStyles; - } - - /** - * @see HtmlDocumentBuilder#isUseInlineStyles() - */ - public void setUseInlineCssStyles(boolean useInlineCssStyles) { - this.useInlineCssStyles = useInlineCssStyles; - } - - /** - * @see HtmlDocumentBuilder#isSuppressBuiltInStyles() - */ - public boolean isSuppressBuiltInCssStyles() { - return suppressBuiltInCssStyles; - } - - /** - * @see HtmlDocumentBuilder#isSuppressBuiltInStyles() - */ - public void setSuppressBuiltInCssStyles(boolean suppressBuiltInCssStyles) { - this.suppressBuiltInCssStyles = suppressBuiltInCssStyles; - } - - - - public static class Stylesheet { - private File file; - private String url; - - public File getFile() { - return file; - } - public void setFile(File file) { - this.file = file; - } - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } - } -} diff --git a/src/net/java/textilej/util/anttask/tasks.properties b/src/net/java/textilej/util/anttask/tasks.properties deleted file mode 100644 index 1903ca0..0000000 --- a/src/net/java/textilej/util/anttask/tasks.properties +++ /dev/null @@ -1,4 +0,0 @@ -textile-to-eclipse-help=net.java.textilej.util.anttask.TextileToEclipseHelpTask -textile-to-html=net.java.textilej.util.anttask.TextileToHtmlTask -textile-to-docbook=net.java.textilej.util.anttask.TextileToDocbookTask - diff --git a/src/net/java/textilej/validation/MarkupValidator.java b/src/net/java/textilej/validation/MarkupValidator.java deleted file mode 100644 index c587e1c..0000000 --- a/src/net/java/textilej/validation/MarkupValidator.java +++ /dev/null @@ -1,94 +0,0 @@ -package net.java.textilej.validation; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * validate markup given a set of rules - * - * @author dgreen - */ -public class MarkupValidator { - - private static final Comparator PROBLEM_COMPARATOR = new Comparator() { - public int compare(ValidationProblem o1,ValidationProblem o2) { - if (o1 == o2) { - return 0; - } - int offset1 = o1.getOffset(); - int offset2 = o2.getOffset(); - if (offset1 < offset2) { - return -1; - } else if (offset2 < offset1) { - return 1; - } else { - int length1 = o1.getLength(); - int length2 = o2.getLength(); - if (length1 > length2) { - return -1; - } else if (length2 > length1) { - return 1; - } else { - int i = o1.getMessage().compareTo(o2.getMessage()); - if (i == 0) { - i = o1.getMarkerId().compareTo(o2.getMarkerId()); - } - return i; - } - } - } - }; - - private List rules = new ArrayList(); - - public List validate(IProgressMonitor monitor,String markup) { - return validate(monitor,markup,0,markup.length()); - } - - public List validate(IProgressMonitor monitor,String markup,int offset,int length) { - final int totalWork = length == 0?1:length*rules.size(); - monitor.beginTask("Markup Validation", totalWork); - try { - if (length == 0 || rules.isEmpty()) { - return Collections.emptyList(); - } - int end = offset+length; - if (end > markup.length()) { - end = markup.length(); - } - List problems = new ArrayList(); - - for (ValidationRule rule: rules) { - int o = offset; - while (o < end) { - ValidationProblem problem = rule.findProblem(markup, o, length - (o-offset)); - if (problem == null) { - break; - } - problems.add(problem); - int newO = problem.getOffset()+problem.getLength(); - if (newO <= o) { - break; - } - monitor.worked(newO-o); - o = newO; - } - } - if (!problems.isEmpty()) { - Collections.sort(problems,PROBLEM_COMPARATOR); - } - return problems; - } finally { - monitor.done(); - } - } - - public List getRules() { - return rules; - } - -} diff --git a/src/net/java/textilej/validation/ValidationProblem.java b/src/net/java/textilej/validation/ValidationProblem.java deleted file mode 100644 index 3f07911..0000000 --- a/src/net/java/textilej/validation/ValidationProblem.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.java.textilej.validation; - - -public class ValidationProblem { - public enum Severity { - WARNING, - ERROR - } - - private String markerId = "net.java.textilej.validation.problem"; - private Severity severity; - private String message; - private int offset; - private int length; - - /** - * create a validation problem - * - * @param severity - * a severity, which must be one of the SEVERITY_* - * constants from {@link org.eclipse.core.resources.IMarker} - * @param message - * the message describing the problem - * @param offset - * the offset into the document that the problem starts - * @param length - * the length of the problem, which may be 0 - * - * @throws IllegalArgumentException - * if the severity is invalid, the offset is < 0, the length is < - * 0, or if no message is provided - */ - public ValidationProblem(Severity severity, String message, int offset, - int length) { - setSeverity(severity); - setMessage(message); - setOffset(offset); - setLength(length); - } - - public String getMarkerId() { - return markerId; - } - - public void setMarkerId(String markerId) { - this.markerId = markerId; - } - - public Severity getSeverity() { - return severity; - } - - /** - * @param severity a severity - */ - public void setSeverity(Severity severity) { - if (severity == null) { - throw new IllegalArgumentException(); - } - this.severity = severity; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - if (message == null || message.length() == 0) { - throw new IllegalArgumentException(); - } - this.message = message; - } - - public int getOffset() { - return offset; - } - - public void setOffset(int offset) { - if (offset < 0) { - throw new IllegalArgumentException(); - } - this.offset = offset; - } - - public int getLength() { - return length; - } - - public void setLength(int length) { - if (length < 0) { - throw new IllegalArgumentException(); - } - this.length = length; - } - - @Override - public String toString() { - return severity+"["+offset+","+length+"]: "+message; - } -} diff --git a/src/net/java/textilej/validation/ValidationRule.java b/src/net/java/textilej/validation/ValidationRule.java deleted file mode 100644 index 399b10d..0000000 --- a/src/net/java/textilej/validation/ValidationRule.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.java.textilej.validation; - - -/** - * A validation rule - * - * @author dgreen - */ -public abstract class ValidationRule { - - /** - * Starting at the given offset find the next validation problem. - * - * @param markup the markup content in which a validation problem should be found - * @param offset the offset at which to start looking for problems - * @param length the length at which to stop looking for problems - * - * @return the validation problem if found, or null if no validation problem was detected - */ - public abstract ValidationProblem findProblem(String markup,int offset,int length); -} From 44ad463bcceb6f5d8a18f024a2e4ee8a653dcab5 Mon Sep 17 00:00:00 2001 From: DC* Date: Sat, 29 Aug 2020 15:26:23 -0300 Subject: [PATCH 2/7] Use extraLibs to build a 'fat-jar' --- build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6cb2881..b646a42 100644 --- a/build.gradle +++ b/build.gradle @@ -22,9 +22,14 @@ repositories { jcenter() } +configurations { + extraLibs +} + dependencies { - implementation group: 'net.java', name: 'textile-j', version: '2.2' implementation group: 'org.freenetproject', name: 'fred', version: 'build+' + extraLibs group: 'net.java', name: 'textile-j', version: '2.2' + configurations.compile.extendsFrom(configurations.extraLibs) } dependencyVerification { @@ -50,6 +55,10 @@ jar { 'Built-JDK': System.getProperty('java.version') } + from { + configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) } + } + from("src/main/java") { include "**/*.l10n" include "**/*.png" From e79075e06877b3c6e2539e014251880a3aeda47c Mon Sep 17 00:00:00 2001 From: DC* Date: Sat, 29 Aug 2020 15:26:49 -0300 Subject: [PATCH 3/7] Fix activelink creator resource path --- src/main/java/plugins/Sharesite/ActivelinkCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/plugins/Sharesite/ActivelinkCreator.java b/src/main/java/plugins/Sharesite/ActivelinkCreator.java index 490b475..f4a39e0 100644 --- a/src/main/java/plugins/Sharesite/ActivelinkCreator.java +++ b/src/main/java/plugins/Sharesite/ActivelinkCreator.java @@ -15,7 +15,7 @@ public class ActivelinkCreator { public static BufferedImage create(String name) throws IOException { String str=name.substring(0,Math.min(18,name.length())); - InputStream is = Plugin.class.getClassLoader().getResourceAsStream("/templates/activelink.png"); + InputStream is = Plugin.class.getClassLoader().getResourceAsStream("resources/templates/activelink.png"); BufferedImage bg = ImageIO.read(is); BufferedImage out = new BufferedImage(108, 36, BufferedImage.TYPE_INT_ARGB); Graphics2D ogr = out.createGraphics(); From 8ae9bd26750813a09f430be0fd8ae1df971aa5b8 Mon Sep 17 00:00:00 2001 From: DC* Date: Sat, 29 Aug 2020 16:52:53 -0300 Subject: [PATCH 4/7] Remove workaround for missing language --- src/main/java/plugins/Sharesite/Plugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/plugins/Sharesite/Plugin.java b/src/main/java/plugins/Sharesite/Plugin.java index 26c7483..32c664c 100644 --- a/src/main/java/plugins/Sharesite/Plugin.java +++ b/src/main/java/plugins/Sharesite/Plugin.java @@ -39,7 +39,6 @@ public class Plugin implements FredPlugin, FredPluginVersioned, FredPluginRealVe public Plugin() { instance = this; - setLanguage(LANGUAGE.ENGLISH); } @Override From be2afa5dd4885e81c9fc99b69648fce7711f778c Mon Sep 17 00:00:00 2001 From: DC* Date: Tue, 1 Sep 2020 00:26:20 -0300 Subject: [PATCH 5/7] Update build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b646a42..d700560 100644 --- a/build.gradle +++ b/build.gradle @@ -9,8 +9,8 @@ apply plugin: 'witness' apply plugin: 'maven-publish' compileJava { - sourceCompatibility = 1.7 - targetCompatibility = 1.7 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } version = "0.4.7" From 07b795909cb79fab2601d1284e7dfa2a859c59c3 Mon Sep 17 00:00:00 2001 From: DC* Date: Tue, 1 Sep 2020 00:30:04 -0300 Subject: [PATCH 6/7] Add hash verification --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d700560..2093185 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,9 @@ dependencies { } dependencyVerification { - verify = [] + verify = [ + 'net.java:textile-j:e984944776943f1846543d93cdf2feefb266225a567f46ab665a672c79e52418', + ] } import java.nio.file.Files; From 3ff256f7802e53961eba2d458623429828ad4017 Mon Sep 17 00:00:00 2001 From: DC* Date: Tue, 1 Sep 2020 00:40:34 -0300 Subject: [PATCH 7/7] Add integrity check --- gradle/wrapper/gradle-wrapper.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 290541c..4230076 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip +distributionSha256Sum=8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists