Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/.project17
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/build.properties4
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/epl-v10.html328
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/feature.properties138
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/feature.xml73
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/license.html108
-rw-r--r--org.eclipse.mylyn.docs.epub-feature/pom.xml14
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.classpath7
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.gitignore1
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.project28
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF13
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/build-ant-jar.xml57
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/build.properties5
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/plugin.xml19
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/pom.xml48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ContributorType.java66
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverType.java38
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverageType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CreatorType.java66
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/DateType.java47
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/EpubTask.java243
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FileSetType.java36
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FormatType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/IdentifierType.java46
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ItemType.java103
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/LanguageType.java32
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/MetaType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/PublisherType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ReferenceType.java46
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RelationType.java47
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RightsType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SourceType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SubjectType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TitleType.java45
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TocType.java41
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TypeType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ContributorType.java66
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverType.java38
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverageType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CreatorType.java66
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/DateType.java47
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/EpubTask.java250
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FileSetType.java36
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FormatType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/IdentifierType.java46
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ItemType.java103
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/LanguageType.java32
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/MetaType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/PublisherType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ReferenceType.java46
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RelationType.java47
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RightsType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SourceType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SubjectType.java48
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TitleType.java45
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TocType.java41
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TypeType.java37
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/tasks.xml4
-rw-r--r--org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/tasks.properties11
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.classpath8
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.gitignore3
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.project28
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF75
-rw-r--r--org.eclipse.mylyn.docs.epub.core/OSGI-INF/l10n/bundle.properties3
-rw-r--r--org.eclipse.mylyn.docs.epub.core/build.ant34
-rw-r--r--org.eclipse.mylyn.docs.epub.core/build.properties10
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/.gitignore1
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/dc.ecore153
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/ncx.ecore695
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/ncx.genmodel168
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/ocf.ecore45
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/ocf.genmodel21
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/opf.ecore498
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/opf.genmodel371
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/readme.txt3
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/relacode.ant28
-rw-r--r--org.eclipse.mylyn.docs.epub.core/model/relacode.src223
-rw-r--r--org.eclipse.mylyn.docs.epub.core/plugin.xml23
-rw-r--r--org.eclipse.mylyn.docs.epub.core/pom.xml30
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/EPUB.java363
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPS2Publication.java297
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPSPublication.java1166
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/ValidationMessage.java36
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/wikitext/MarkupToOPS.java101
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/AbstractXHTMLScanner.java93
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBFileUtil.java316
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBXMLHelperImp.java21
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/MetadataScanner.java70
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/OPS2Validator.java214
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/ReferenceScanner.java130
-rw-r--r--org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/TOCGenerator.java144
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.classpath7
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.gitignore4
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.project28
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub.help/META-INF/MANIFEST.MF9
-rw-r--r--org.eclipse.mylyn.docs.epub.help/build-docs.xml70
-rw-r--r--org.eclipse.mylyn.docs.epub.help/build.properties7
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/Illustrations.002.jpgbin0 -> 47952 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/epub-ant-task.textile362
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/epub-format.textile19
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/examples.textile59
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/generate-ant.textile21
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/generate-epub.pngbin0 -> 20126 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/generate-epub.textile7
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/introduction.textile30
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/nook-cover.pngbin0 -> 195718 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/preface.textile5
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/runtime-jre.pngbin0 -> 27253 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/source/Illustrations.keybin0 -> 264388 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.help/docs/style.css41
-rw-r--r--org.eclipse.mylyn.docs.epub.help/plugin.xml15
-rw-r--r--org.eclipse.mylyn.docs.epub.help/pom.xml73
-rw-r--r--org.eclipse.mylyn.docs.epub.help/src/readme.txt1
-rw-r--r--org.eclipse.mylyn.docs.epub.help/toc.xml22
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.classpath10
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.gitignore4
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.project28
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF23
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/ant-test.xml39
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/build.properties7
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/pom.xml77
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/AllTests.java41
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAPI.java301
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAntTask.java86
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestOPS2Validator.java100
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestTOCGenerator.java119
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/ant/TestAntTask.java86
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/AbstractTest.java88
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestEPUB.java384
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPS2Publication.java287
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPSPublication.java808
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestOPS2Validator.java101
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestTOCGenerator.java120
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/Dogfood/toc.ncx197
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/SocketException/toc.ncx4
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/Dogfood/META-INF/container.xml6
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/SocketException/META-INF/container.xml9
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/Dogfood/content.opf52
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/SocketException/content.opf4
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/book.css0
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/drawing-100x100.svg209
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/images/drawing-2-100x100.svg209
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page.xhtml57
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.html60
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.xhtml60
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.html55
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.xhtml55
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_warnings.xhtml58
-rw-r--r--org.eclipse.mylyn.docs.epub.tests/testdata/toc.ncx35
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.classpath7
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.gitignore3
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.project28
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF29
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/OSGI-INF/l10n/bundle.properties15
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/build.properties8
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/icons/wizard-banner.pngbin0 -> 2284 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/plugin.xml25
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/pom.xml30
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src-images/wizard-banner.psdbin0 -> 52876 bytes
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/ConvertFromMarkupWizard.java154
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUB2Bean.java299
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUBUIPlugin.java39
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/MainPage.java253
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/Messages.java38
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/ConvertMarkupToEPUB.java49
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/Messages.java32
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/messages.properties12
-rw-r--r--org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/messages.properties15
-rw-r--r--pom.xml9
192 files changed, 14387 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.docs.epub-feature/.project b/org.eclipse.mylyn.docs.epub-feature/.project
new file mode 100644
index 000000000..619ed2c6c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub-feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..854cdca77
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:01 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..52cedf707
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:01 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub-feature/build.properties b/org.eclipse.mylyn.docs.epub-feature/build.properties
new file mode 100644
index 000000000..b74af86fe
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+ feature.properties,\
+ epl-v10.html,\
+ license.html
diff --git a/org.eclipse.mylyn.docs.epub-feature/epl-v10.html b/org.eclipse.mylyn.docs.epub-feature/epl-v10.html
new file mode 100644
index 000000000..ed4b19665
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>3</o:TotalTime>
+ <o:Created>2004-03-05T23:03:00Z</o:Created>
+ <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>1626</o:Words>
+ <o:Characters>9270</o:Characters>
+ <o:Lines>77</o:Lines>
+ <o:Paragraphs>18</o:Paragraphs>
+ <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+ <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p
+ {margin-right:0in;
+ mso-margin-top-alt:auto;
+ mso-margin-bottom-alt:auto;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+ {mso-style-name:"Balloon Text";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:Tahoma;
+ mso-fareast-font-family:"Times New Roman";}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub-feature/feature.properties b/org.eclipse.mylyn.docs.epub-feature/feature.properties
new file mode 100644
index 000000000..7a25a2eae
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/feature.properties
@@ -0,0 +1,138 @@
+###############################################################################
+# Copyright (c) 2011 Torkild U. Resheim
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Torkild U. Resheim - initial API and implementation
+###############################################################################
+featureName=Mylyn EPUB Support
+description=Adds API for reading and writing of EPUB files. Includes user interface for generating EPUBs from wiki markup and Ant task for assembling and writing EPUBs using Apache Ant.
+providerName=Eclipse Mylyn
+copyright=Copyright (c) 2011 Torkild U. Resheim. All rights reserved.
+license=\
+Eclipse Foundation Software User Agreement\n\
+February 1, 2011\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the\n\
+Eclipse Foundation is provided to you under the terms and conditions of\n\
+the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\
+provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse Foundation source code\n\
+repository ("Repository") in software modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Provisioning Technology (as defined below), you must agree to a license ("Feature \n\
+Update License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties" found within a Feature.\n\
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\
+terms and conditions (or references to such terms and conditions) that\n\
+govern your use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Eclipse Distribution License Version 1.0 (available at http://www.eclipse.org/licenses/edl-v1.0.html)\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+\n\Use of Provisioning Technology\n\
+\n\
+The Eclipse Foundation makes available provisioning software, examples of which include,\n\
+but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\
+the purpose of allowing users to install software, documentation, information and/or\n\
+other materials (collectively "Installable Software"). This capability is provided with\n\
+the intent of allowing such users to install, extend and update Eclipse-based products.\n\
+Information about packaging Installable Software is available at\n\
+http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\
+\n\
+You may use Provisioning Technology to allow other parties to install Installable Software.\n\
+You shall be responsible for enabling the applicable license agreements relating to the\n\
+Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\
+in accordance with the Specification. By using Provisioning Technology in such a manner and\n\
+making it available in accordance with the Specification, you further acknowledge your\n\
+agreement to, and the acquisition of all necessary rights to permit the following:\n\
+\n\
+ 1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\
+ the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\
+ extending or updating the functionality of an Eclipse-based product.\n\
+ 2. During the Provisioning Process, the Provisioning Technology may cause third party\n\
+ Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\
+ 3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\
+ govern the use of the Installable Software ("Installable Software Agreement") and such\n\
+ Installable Software Agreement shall be accessed from the Target Machine in accordance\n\
+ with the Specification. Such Installable Software Agreement must inform the user of the\n\
+ terms and conditions that govern the Installable Software and must solicit acceptance by\n\
+ the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\
+ indication of agreement by the user, the provisioning Technology will complete installation\n\
+ of the Installable Software.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use, and\n\
+re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n
diff --git a/org.eclipse.mylyn.docs.epub-feature/feature.xml b/org.eclipse.mylyn.docs.epub-feature/feature.xml
new file mode 100644
index 000000000..9d98553bf
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/feature.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.mylyn.docs.epub"
+ label="%featureName"
+ version="0.8.0.qualifier"
+ provider-name="%providerName"
+ plugin="org.eclipse.mylyn">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="license.html">
+ %license
+ </license>
+
+ <requires>
+ <import plugin="org.eclipse.emf.ecore.xmi" version="2.5.0" match="compatible"/>
+ <import plugin="org.eclipse.emf.validation" version="1.4.0" match="compatible"/>
+ <import plugin="org.eclipse.mylyn.wikitext.core" version="1.4.0" match="compatible"/>
+ <import plugin="org.eclipse.emf.mapping.ecore2xml" version="2.7.0" match="compatible"/>
+ <import plugin="org.eclipse.core.runtime" version="3.6.0" match="compatible"/>
+ <import plugin="org.eclipse.mylyn.docs.epub.core" version="0.8.0" match="compatible"/>
+ <import plugin="org.eclipse.mylyn.wikitext.ui" version="1.5.0" match="compatible"/>
+ <import plugin="org.eclipse.mylyn.wikitext.core" version="1.5.0" match="compatible"/>
+ <import plugin="org.eclipse.core.resources" version="3.6.0" match="compatible"/>
+ <import plugin="org.eclipse.ui" version="3.6.0" match="compatible"/>
+ <import plugin="org.eclipse.core.databinding"/>
+ <import plugin="org.eclipse.core.databinding.beans"/>
+ <import plugin="org.eclipse.core.databinding.observable"/>
+ <import plugin="org.eclipse.core.databinding.property"/>
+ <import plugin="org.eclipse.jface.databinding"/>
+ <import plugin="com.ibm.icu"/>
+ <import plugin="org.eclipse.emf" version="2.6.0" match="greaterOrEqual"/>
+ <import plugin="org.eclipse.emf.ecore" version="2.7.0" match="greaterOrEqual"/>
+ <import plugin="org.eclipse.emf.databinding"/>
+ <import plugin="org.eclipse.emf.validation" version="1.4.0" match="greaterOrEqual"/>
+ <import plugin="org.eclipse.emf.validation.ui" version="1.3.0" match="greaterOrEqual"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.mylyn.docs.epub.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.mylyn.docs.epub.help"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.mylyn.docs.epub.ui"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.mylyn.docs.epub.ant.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.mylyn.docs.epub-feature/license.html b/org.eclipse.mylyn.docs.epub-feature/license.html
new file mode 100644
index 000000000..f19c483b9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/license.html
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>February 1, 2011</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY &quot;CONTENT&quot;). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ (&quot;EPL&quot;). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+ repository (&quot;Repository&quot;) in software modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;. Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Eclipse Distribution License Version 1.0 (available at <a href="http://www.eclipse.org/licenses/edl-v10.html">http://www.eclipse.org/licenses/edl-v1.0.html</a>)</li>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+ Update Manager (&quot;Provisioning Technology&quot;) for the purpose of allowing users to install software, documentation, information and/or
+ other materials (collectively &quot;Installable Software&quot;). This capability is provided with the intent of allowing such users to
+ install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+ href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+ (&quot;Specification&quot;).</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+ applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+ in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+ Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+ <li>A series of actions may occur (&quot;Provisioning Process&quot;) in which a user may execute the Provisioning Technology
+ on a machine (&quot;Target Machine&quot;) with the intent of installing, extending or updating the functionality of an Eclipse-based
+ product.</li>
+ <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+ accessed and copied to the Target Machine.</li>
+ <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+ Software (&quot;Installable Software Agreement&quot;) and such Installable Software Agreement shall be accessed from the Target
+ Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+ the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+ indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/org.eclipse.mylyn.docs.epub-feature/pom.xml b/org.eclipse.mylyn.docs.epub-feature/pom.xml
new file mode 100644
index 000000000..f7549bc69
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub-feature/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-feature</packaging>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.classpath b/org.eclipse.mylyn.docs.epub.ant.core/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.gitignore b/org.eclipse.mylyn.docs.epub.ant.core/.gitignore
new file mode 100644
index 000000000..502167fa0
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.gitignore
@@ -0,0 +1 @@
+/lib
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.project b/org.eclipse.mylyn.docs.epub.ant.core/.project
new file mode 100644
index 000000000..89aab4e11
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub.ant.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..106300295
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:13 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..d8f9d7133
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:13 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..2aaecd3b9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Thu Sep 22 12:57:56 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..244c481ac
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EPUB Ant Support
+Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.ant.core;singleton:=true
+Bundle-Version: 0.8.0.qualifier
+Bundle-Vendor: Torkild U. Resheim
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.mylyn.docs.epub.ant;x-internal:=true,
+ org.eclipse.mylyn.docs.epub.ant.core;x-internal:=true;uses:="org.eclipse.mylyn.docs.epub,org.apache.tools.ant.types,org.apache.tools.ant"
+Require-Bundle: org.apache.ant;bundle-version="[1.8.2,2.0.0)",
+ org.eclipse.mylyn.docs.epub.core;bundle-version="[0.8.0,1.0.0)",
+ org.eclipse.ant.core;bundle-version="3.2.300"
+Bundle-ClassPath: .
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/build-ant-jar.xml b/org.eclipse.mylyn.docs.epub.ant.core/build-ant-jar.xml
new file mode 100644
index 000000000..8e17512b3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/build-ant-jar.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2009 Chris Aniszczyk and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Chris Aniszczyk - initial API and implementation
+ Torkild U. Resheim - Adapted to build EPUB Ant support
+-->
+<project name="Build EPUB Ant Support Jar" default="build">
+
+ <target name="build" description="Cleans, builds and refreshes" depends="clean, lib/epub-ant.jar" />
+
+ <target name="init" depends="properties">
+ <property name="temp.folder" location="${basedir}/temp.folder" />
+ <property name="build.result.folder" location="${basedir}" />
+ <property name="src.folder" location="${basedir}/src" />
+ </target>
+
+ <target name="properties" if="eclipse.running">
+ <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />
+ </target>
+
+ <target name="lib/epub-ant.jar" description="Creates the lib/epub-ant.jar" depends="init">
+ <property name="destdir" value="${temp.folder}/lib/epub-ant.bin" />
+ <property name="target.platform.path" value="${eclipse.home}" />
+ <delete dir="${destdir}" />
+ <mkdir dir="${destdir}" />
+ <mkdir dir="${build.result.folder}/lib" />
+ <!-- compile the source code -->
+ <javac target="1.5" source="1.5" destdir="${destdir}" failonerror="true" verbose="false" debug="on">
+ <classpath>
+ <dirset dir="${basedir}/../">
+ <include name="org.eclipse.mylyn.docs.epub.core/bin" />
+ </dirset>
+ </classpath>
+ <src path="${src.folder}" />
+ </javac>
+ <!-- copy the *.class files to the jar location -->
+ <copy todir="${destdir}" failonerror="true" overwrite="false">
+ <fileset dir="${src.folder}">
+ <exclude name="**/*.java" />
+ <exclude name="**/package.htm*" />
+ </fileset>
+ </copy>
+ <jar destfile="${build.result.folder}/lib/epub-ant.jar" basedir="${destdir}" />
+ <delete dir="${temp.folder}" />
+ </target>
+
+ <target name="clean" description="Deletes previous build remnants" depends="init">
+ <delete file="${build.result.folder}/lib/epub-ant.jar" />
+ <delete dir="${temp.folder}" />
+ </target>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/build.properties b/org.eclipse.mylyn.docs.epub.ant.core/build.properties
new file mode 100644
index 000000000..cd4fb4545
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ plugin.xml,\
+ lib/
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/plugin.xml b/org.eclipse.mylyn.docs.epub.ant.core/plugin.xml
new file mode 100644
index 000000000..846fa7626
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/plugin.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ant.core.antTasks">
+ <antTask
+ class="org.eclipse.mylyn.docs.epub.ant.core.EpubTask"
+ library="lib/epub-ant.jar"
+ name="epub">
+ </antTask>
+ </extension>
+ <extension
+ point="org.eclipse.ant.core.extraClasspathEntries">
+ <extraClasspathEntry
+ library="lib/epub-ant.jar">
+ </extraClasspathEntry>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/pom.xml b/org.eclipse.mylyn.docs.epub.ant.core/pom.xml
new file mode 100644
index 000000000..91077b503
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub.ant.core</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <jar destfile="lib/epub-ant.jar" basedir="target/classes"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ContributorType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ContributorType.java
new file mode 100644
index 000000000..7ef66c4d5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ContributorType.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="contributor" category="epub"
+ */
+public class ContributorType {
+
+ String fileAs;
+
+ String id;
+
+ Locale lang;
+
+ String name;
+
+ String role;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFileAs(String fileAs) {
+ this.fileAs = fileAs;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required the language code
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ /**
+ * @ant.required name of the contributor
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverType.java
new file mode 100644
index 000000000..c11d390b7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverType.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="cover" category="epub"
+ */
+public class CoverType {
+
+ String image;
+
+ String value;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String value) {
+ this.value = value;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverageType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverageType.java
new file mode 100644
index 000000000..6f7a60d65
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CoverageType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="coverage" category="epub"
+ */
+public class CoverageType {
+
+ String id;
+
+ String text;
+
+ Locale lang;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CreatorType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CreatorType.java
new file mode 100644
index 000000000..836b1893f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/CreatorType.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="creator" category="epub"
+ */
+public class CreatorType {
+
+ String fileAs;
+
+ String id;
+
+ Locale lang;
+
+ String name;
+
+ String role;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFileAs(String fileAs) {
+ this.fileAs = fileAs;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/DateType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/DateType.java
new file mode 100644
index 000000000..82aa0340b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/DateType.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="date" category="epub"
+ */
+public class DateType {
+
+ String date;
+
+ String event;
+
+ String id;
+
+ /**
+ * @ant.required
+ */
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/EpubTask.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/EpubTask.java
new file mode 100644
index 000000000..edfecaae0
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/EpubTask.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.io.File;
+import java.util.ArrayList;
+
+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.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.opf.Role;
+import org.eclipse.mylyn.docs.epub.opf.Type;
+
+/**
+ * Assemble a new EPUB.
+ *
+ *
+ * @author Torkild U. Resheim
+ * @ant.task name="epub" category="epub"
+ */
+public class EpubTask extends Task {
+
+ private final OPSPublication ops = OPSPublication.getVersion2Instance();
+
+ private final ArrayList<FileSetType> filesets;
+
+ private TocType toc = null;
+
+ private File workingFolder;
+
+ private File epubFile;
+
+ public EpubTask() {
+ super();
+ filesets = new ArrayList<FileSetType>();
+ }
+
+ public void addConfiguredContributor(ContributorType item) {
+ if (item.role == null) {
+ ops.addContributor(item.id, item.lang, item.name, null, item.fileAs);
+ } else {
+ ops.addContributor(item.id, item.lang, item.name, Role.get(item.role), item.fileAs);
+ }
+ }
+
+ public void addConfiguredCover(CoverType item) {
+ ops.setCover(new File(item.image), item.value);
+ }
+
+ public void addConfiguredCoverage(CoverageType coverage) {
+ ops.addCoverage(coverage.id, coverage.lang, coverage.text);
+ }
+
+ public void addConfiguredCreator(CreatorType item) {
+ if (item.role == null) {
+ ops.addCreator(item.id, item.lang, item.name, null, item.fileAs);
+ } else {
+ ops.addCreator(item.id, item.lang, item.name, Role.get(item.role), item.fileAs);
+ }
+ }
+
+ public void addConfiguredDate(DateType item) {
+ ops.addDate(item.id, item.date, item.event);
+ }
+
+ /**
+ * The FileSet sub-element is used to add EPUB artifacts that are not a part
+ * of the main text. This can be graphical items and styling (CSS).
+ *
+ * @param fs
+ * the fileset to add
+ */
+ public void addConfiguredFileSet(FileSetType fs) {
+ filesets.add(fs);
+ }
+
+ public void addConfiguredFormat(FormatType format) {
+ ops.addFormat(format.id, format.text);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredIdentifier(IdentifierType identifier) {
+ ops.addIdentifier(identifier.id, identifier.scheme, identifier.value);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredItem(ItemType item) {
+ ops.addItem(item.id, item.lang, item.file, item.dest, item.type, item.spine, item.linear, item.noToc);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredLanguage(LanguageType language) {
+ ops.addLanguage(language.id, language.code);
+ }
+
+ public void addConfiguredMeta(MetaType item) {
+ ops.addMeta(item.name, item.content);
+ }
+
+ public void addConfiguredPublisher(PublisherType publisher) {
+ ops.addPublisher(publisher.id, publisher.lang, publisher.text);
+ }
+
+ public void addConfiguredReference(ReferenceType reference) {
+ Type type = Type.get(reference.type);
+ if (type == null) {
+ throw new BuildException("Unknown reference type " + reference.type);
+ }
+ ops.addReference(reference.href, reference.title, type);
+ }
+
+ public void addConfiguredRelation(RelationType relation) {
+ ops.addRelation(relation.id, relation.lang, relation.text);
+ }
+
+ public void addConfiguredRights(RightsType rights) {
+ ops.addRights(rights.id, rights.lang, rights.text);
+ }
+
+ public void addConfiguredSource(SourceType source) {
+ ops.addSource(source.id, source.lang, source.text);
+ }
+
+ public void addConfiguredSubject(SubjectType subject) {
+ ops.addSubject(subject.id, subject.lang, subject.text);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredTitle(TitleType title) {
+ ops.addTitle(title.id, title.lang, title.text);
+ }
+
+ public void addConfiguredToc(TocType toc) {
+ if (this.toc != null) {
+ throw new BuildException("Only one table of contents (toc) declaration is allowed.");
+ }
+ this.toc = toc;
+ }
+
+ public void addConfiguredType(org.eclipse.mylyn.docs.epub.ant.TypeType type) {
+ ops.addType(type.id, type.text);
+ }
+
+ private void addFilesets() {
+ for (FileSetType fs : filesets) {
+ if (fs.getProject() == null) {
+ log("Deleting fileset with no project specified;" + " assuming executing project", Project.MSG_VERBOSE);
+ fs = (FileSetType) fs.clone();
+ fs.setProject(getProject());
+ }
+ final File fsDir = fs.getDir();
+ if (fsDir == null) {
+ throw new BuildException("File or Resource without directory or file specified");
+ } else if (!fsDir.isDirectory()) {
+ throw new BuildException("Directory does not exist:" + fsDir);
+ }
+ DirectoryScanner ds = fs.getDirectoryScanner();
+ String[] includedFiles = ds.getIncludedFiles();
+ for (int i = 0; i < includedFiles.length; i++) {
+ String filename = includedFiles[i].replace('\\', '/');
+ filename = filename.substring(filename.lastIndexOf("/") + 1);
+ File base = ds.getBasedir();
+ File found = new File(base, includedFiles[i]);
+ ops.addItem(null, fs.lang, found, fs.dest, null, false, true, false);
+ }
+
+ }
+
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ validate();
+ addFilesets();
+ if (toc != null) {
+ if (toc.generate) {
+ ops.setGenerateToc(true);
+ } else if (toc.file != null) {
+ ops.setTableOfContents(toc.file);
+ }
+ }
+ try {
+ EPUB epub = new EPUB();
+ epub.add(ops);
+ if (workingFolder == null) {
+ epub.pack(epubFile);
+ } else {
+ epub.pack(epubFile, workingFolder);
+ }
+
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * @ant.not-required Automatically add referenced resources.
+ */
+ public void setIncludeReferenced(boolean automatic) {
+ ops.setIncludeReferencedResources(automatic);
+ }
+
+ /**
+ *
+ *
+ * @param file
+ * path to the generated EPUB file.
+ */
+ public void setFile(File file) {
+ this.epubFile = file;
+ }
+
+ public void setIdentifierId(String identifierId) {
+ ops.setIdentifierId(identifierId);
+ }
+
+ public void setWorkingFolder(File workingFolder) {
+ this.workingFolder = workingFolder;
+ }
+
+ private void validate() {
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FileSetType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FileSetType.java
new file mode 100644
index 000000000..08c3d74b7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FileSetType.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="epubfileset" category="epub"
+ */
+public class FileSetType extends org.apache.tools.ant.types.FileSet {
+
+ String dest;
+
+ Locale lang;
+
+ public FileSetType() {
+
+ }
+
+ public void setLocale(Locale lang) {
+ this.lang = lang;
+ }
+
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FormatType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FormatType.java
new file mode 100644
index 000000000..04b5c6bd0
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/FormatType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="format" category="epub"
+ */
+public class FormatType {
+
+ String id;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/IdentifierType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/IdentifierType.java
new file mode 100644
index 000000000..a5ab87ec5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/IdentifierType.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="identifier" category="epub"
+ */
+public class IdentifierType {
+
+ String id;
+
+ String scheme;
+
+ String value;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String value) {
+ this.value = value;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ItemType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ItemType.java
new file mode 100644
index 000000000..4b67c9c83
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ItemType.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.io.File;
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="item" category="epub"
+ */
+public class ItemType {
+
+ String dest;
+
+ File file;
+
+ String id;
+
+ Locale lang;
+
+ /** Default is that items are in reading order */
+ public boolean linear = true;
+
+ boolean noToc = false;
+
+ String page;
+
+ /** Default is to add the item to the spine */
+ boolean spine = true;
+
+ String type;
+
+ /**
+ * @ant.not-required
+ */
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * A file on the local file system.
+ *
+ * @param file
+ * @ant.required
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ public void setLinear(boolean linear) {
+ this.linear = linear;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setNoToc(boolean toc) {
+ this.noToc = toc;
+ }
+
+ /**
+ * A page on the wiki.
+ *
+ * @param page
+ */
+ public void setPage(String page) {
+ this.page = page;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setSpine(boolean spine) {
+ this.spine = spine;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/LanguageType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/LanguageType.java
new file mode 100644
index 000000000..dabd9d79e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/LanguageType.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="language" category="epub"
+ */
+public class LanguageType {
+ String code;
+
+ String id;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/MetaType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/MetaType.java
new file mode 100644
index 000000000..8d535a020
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/MetaType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="meta" category="epub"
+ */
+public class MetaType {
+
+ String name;
+
+ String content;
+
+ /**
+ * @ant.required
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/PublisherType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/PublisherType.java
new file mode 100644
index 000000000..b8cf09e1e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/PublisherType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="publisher" category="epub"
+ */
+public class PublisherType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ReferenceType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ReferenceType.java
new file mode 100644
index 000000000..bf0607757
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/ReferenceType.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="reference" category="epub"
+ */
+public class ReferenceType {
+
+ String href;
+
+ String title;
+
+ String type;
+
+ /**
+ * @ant.required
+ */
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RelationType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RelationType.java
new file mode 100644
index 000000000..5a8ea129a
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RelationType.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="relation" category="epub"
+ */
+public class RelationType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RightsType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RightsType.java
new file mode 100644
index 000000000..8ba9f7c66
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/RightsType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="rights" category="epub"
+ */
+public class RightsType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SourceType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SourceType.java
new file mode 100644
index 000000000..12df3fcff
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SourceType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="source" category="epub"
+ */
+public class SourceType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SubjectType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SubjectType.java
new file mode 100644
index 000000000..04ffc718f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/SubjectType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="subject" category="epub"
+ */
+public class SubjectType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TitleType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TitleType.java
new file mode 100644
index 000000000..158f96e44
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TitleType.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="title" category="epub"
+ */
+public class TitleType {
+
+ String text;
+
+ Locale lang;
+
+ String id;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TocType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TocType.java
new file mode 100644
index 000000000..18a84e3af
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TocType.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+import java.io.File;
+
+/**
+ * Represents a table of contents element in the {@link EpubTask}. One should
+ * specify either a path to a NCX file or whether or not to generate the NCX.
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="toc" category="epub"
+ */
+public class TocType {
+
+ File file;
+
+ boolean generate;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setGenerate(boolean generate) {
+ this.generate = generate;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TypeType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TypeType.java
new file mode 100644
index 000000000..58dd9c7bb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/TypeType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="type" category="epub"
+ */
+public class TypeType {
+
+ String id;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ContributorType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ContributorType.java
new file mode 100644
index 000000000..7f99ef21f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ContributorType.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="contributor" category="epub"
+ */
+public class ContributorType {
+
+ String fileAs;
+
+ String id;
+
+ Locale lang;
+
+ String name;
+
+ String role;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFileAs(String fileAs) {
+ this.fileAs = fileAs;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required the language code
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ /**
+ * @ant.required name of the contributor
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverType.java
new file mode 100644
index 000000000..bdd900f03
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverType.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="cover" category="epub"
+ */
+public class CoverType {
+
+ String image;
+
+ String value;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String value) {
+ this.value = value;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverageType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverageType.java
new file mode 100644
index 000000000..a254d210d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CoverageType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="coverage" category="epub"
+ */
+public class CoverageType {
+
+ String id;
+
+ String text;
+
+ Locale lang;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CreatorType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CreatorType.java
new file mode 100644
index 000000000..c75f21178
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/CreatorType.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="creator" category="epub"
+ */
+public class CreatorType {
+
+ String fileAs;
+
+ String id;
+
+ Locale lang;
+
+ String name;
+
+ String role;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFileAs(String fileAs) {
+ this.fileAs = fileAs;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/DateType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/DateType.java
new file mode 100644
index 000000000..dbb0581d1
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/DateType.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="date" category="epub"
+ */
+public class DateType {
+
+ String date;
+
+ String event;
+
+ String id;
+
+ /**
+ * @ant.required
+ */
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/EpubTask.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/EpubTask.java
new file mode 100644
index 000000000..15223f370
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/EpubTask.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.io.File;
+import java.util.ArrayList;
+
+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.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPS2Publication;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.opf.Role;
+import org.eclipse.mylyn.docs.epub.opf.Type;
+
+/**
+ * Assemble a new EPUB.
+ *
+ *
+ * @author Torkild U. Resheim
+ * @ant.task name="epub" category="epub"
+ */
+public class EpubTask extends Task {
+
+ private OPSPublication ops = null;
+
+ private ArrayList<FileSetType> filesets = null;
+
+ private TocType toc = null;
+
+ private File workingFolder;
+
+ private File epubFile;
+
+ public EpubTask() {
+ super();
+ try {
+ ops = new OPS2Publication();
+ filesets = new ArrayList<FileSetType>();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addConfiguredContributor(ContributorType item) {
+ if (item.role == null) {
+ ops.addContributor(item.id, item.lang, item.name, null, item.fileAs);
+ } else {
+ ops.addContributor(item.id, item.lang, item.name, Role.get(item.role), item.fileAs);
+ }
+ }
+
+ public void addConfiguredCover(CoverType item) {
+ ops.setCover(new File(item.image), item.value);
+ }
+
+ public void addConfiguredCoverage(CoverageType coverage) {
+ ops.addCoverage(coverage.id, coverage.lang, coverage.text);
+ }
+
+ public void addConfiguredCreator(CreatorType item) {
+ if (item.role == null) {
+ ops.addCreator(item.id, item.lang, item.name, null, item.fileAs);
+ } else {
+ ops.addCreator(item.id, item.lang, item.name, Role.get(item.role), item.fileAs);
+ }
+ }
+
+ public void addConfiguredDate(DateType item) {
+ ops.addDate(item.id, item.date, item.event);
+ }
+
+ /**
+ * The FileSet sub-element is used to add EPUB artifacts that are not a part
+ * of the main text. This can be graphical items and styling (CSS).
+ *
+ * @param fs
+ * the fileset to add
+ */
+ public void addConfiguredFileSet(FileSetType fs) {
+ filesets.add(fs);
+ }
+
+ public void addConfiguredFormat(FormatType format) {
+ ops.addFormat(format.id, format.text);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredIdentifier(IdentifierType identifier) {
+ ops.addIdentifier(identifier.id, identifier.scheme, identifier.value);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredItem(ItemType item) {
+ ops.addItem(item.id, item.lang, item.file, item.dest, item.type, item.spine, item.linear, item.noToc);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredLanguage(LanguageType language) {
+ ops.addLanguage(language.id, language.code);
+ }
+
+ public void addConfiguredMeta(MetaType item) {
+ ops.addMeta(item.name, item.content);
+ }
+
+ public void addConfiguredPublisher(PublisherType publisher) {
+ ops.addPublisher(publisher.id, publisher.lang, publisher.text);
+ }
+
+ public void addConfiguredReference(ReferenceType reference) {
+ Type type = Type.get(reference.type);
+ if (type == null) {
+ throw new BuildException("Unknown reference type " + reference.type);
+ }
+ ops.addReference(reference.href, reference.title, type);
+ }
+
+ public void addConfiguredRelation(RelationType relation) {
+ ops.addRelation(relation.id, relation.lang, relation.text);
+ }
+
+ public void addConfiguredRights(RightsType rights) {
+ ops.addRights(rights.id, rights.lang, rights.text);
+ }
+
+ public void addConfiguredSource(SourceType source) {
+ ops.addSource(source.id, source.lang, source.text);
+ }
+
+ public void addConfiguredSubject(SubjectType subject) {
+ ops.addSubject(subject.id, subject.lang, subject.text);
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addConfiguredTitle(TitleType title) {
+ ops.addTitle(title.id, title.lang, title.text);
+ }
+
+ public void addConfiguredToc(TocType toc) {
+ if (this.toc != null) {
+ throw new BuildException("Only one table of contents (toc) declaration is allowed.");
+ }
+ this.toc = toc;
+ }
+
+ public void addConfiguredType(org.eclipse.mylyn.docs.epub.ant.core.TypeType type) {
+ ops.addType(type.id, type.text);
+ }
+
+ private void addFilesets() {
+ for (FileSetType fs : filesets) {
+ final File fsDir = fs.getDir(getProject());
+ if (fsDir == null) {
+ throw new BuildException("File or Resource without directory or file specified");
+ } else if (!fsDir.isDirectory()) {
+ throw new BuildException("Directory does not exist:" + fsDir);
+ }
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[] includedFiles = ds.getIncludedFiles();
+ for (int i = 0; i < includedFiles.length; i++) {
+ String filename = includedFiles[i].replace('\\', '/');
+ filename = filename.substring(filename.lastIndexOf("/") + 1);
+ File base = ds.getBasedir();
+ File found = new File(base, includedFiles[i]);
+ ops.addItem(null, fs.lang, found, fs.dest, null, false, true, false);
+ }
+
+ }
+
+ }
+
+ @Override
+ public void execute() throws BuildException {
+
+ // When running from within Eclipse, the project may not have been set
+ if (getProject() == null) {
+ Project project = new Project();
+ setProject(project);
+ }
+
+ validate();
+ addFilesets();
+ if (toc != null) {
+ if (toc.generate) {
+ ops.setGenerateToc(true);
+ } else if (toc.file != null) {
+ ops.setTableOfContents(toc.file);
+ }
+ }
+ try {
+ EPUB epub = new EPUB();
+ epub.add(ops);
+ if (workingFolder == null) {
+ epub.pack(epubFile);
+ } else {
+ epub.pack(epubFile, workingFolder);
+ }
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * @ant.not-required Automatically add referenced resources.
+ */
+ public void setIncludeReferenced(boolean automatic) {
+ ops.setIncludeReferencedResources(automatic);
+ }
+
+ /**
+ *
+ *
+ * @param file
+ * path to the generated EPUB file.
+ */
+ public void setFile(File file) {
+ this.epubFile = file;
+ }
+
+ public void setIdentifierId(String identifierId) {
+ ops.setIdentifierId(identifierId);
+ }
+
+ public void setWorkingFolder(File workingFolder) {
+ this.workingFolder = workingFolder;
+ }
+
+ private void validate() {
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FileSetType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FileSetType.java
new file mode 100644
index 000000000..10f38a4e3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FileSetType.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="epubfileset" category="epub"
+ */
+public class FileSetType extends org.apache.tools.ant.types.FileSet {
+
+ String dest;
+
+ Locale lang;
+
+ public FileSetType() {
+
+ }
+
+ public void setLocale(Locale lang) {
+ this.lang = lang;
+ }
+
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FormatType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FormatType.java
new file mode 100644
index 000000000..9d072cdbb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/FormatType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="format" category="epub"
+ */
+public class FormatType {
+
+ String id;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/IdentifierType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/IdentifierType.java
new file mode 100644
index 000000000..9d60f2504
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/IdentifierType.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="identifier" category="epub"
+ */
+public class IdentifierType {
+
+ String id;
+
+ String scheme;
+
+ String value;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String value) {
+ this.value = value;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ItemType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ItemType.java
new file mode 100644
index 000000000..954aed1a6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ItemType.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.io.File;
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="item" category="epub"
+ */
+public class ItemType {
+
+ String dest;
+
+ File file;
+
+ String id;
+
+ Locale lang;
+
+ /** Default is that items are in reading order */
+ public boolean linear = true;
+
+ boolean noToc = false;
+
+ String page;
+
+ /** Default is to add the item to the spine */
+ boolean spine = true;
+
+ String type;
+
+ /**
+ * @ant.not-required
+ */
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * A file on the local file system.
+ *
+ * @param file
+ * @ant.required
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+ public void setLinear(boolean linear) {
+ this.linear = linear;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setNoToc(boolean toc) {
+ this.noToc = toc;
+ }
+
+ /**
+ * A page on the wiki.
+ *
+ * @param page
+ */
+ public void setPage(String page) {
+ this.page = page;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setSpine(boolean spine) {
+ this.spine = spine;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/LanguageType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/LanguageType.java
new file mode 100644
index 000000000..e852725ae
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/LanguageType.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="language" category="epub"
+ */
+public class LanguageType {
+ String code;
+
+ String id;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/MetaType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/MetaType.java
new file mode 100644
index 000000000..5e612e2ae
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/MetaType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="meta" category="epub"
+ */
+public class MetaType {
+
+ String name;
+
+ String content;
+
+ /**
+ * @ant.required
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/PublisherType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/PublisherType.java
new file mode 100644
index 000000000..689dad615
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/PublisherType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="publisher" category="epub"
+ */
+public class PublisherType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ReferenceType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ReferenceType.java
new file mode 100644
index 000000000..954eb8503
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/ReferenceType.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="reference" category="epub"
+ */
+public class ReferenceType {
+
+ String href;
+
+ String title;
+
+ String type;
+
+ /**
+ * @ant.required
+ */
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RelationType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RelationType.java
new file mode 100644
index 000000000..f3b6683ce
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RelationType.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="relation" category="epub"
+ */
+public class RelationType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RightsType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RightsType.java
new file mode 100644
index 000000000..c4a6ec02e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/RightsType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="rights" category="epub"
+ */
+public class RightsType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SourceType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SourceType.java
new file mode 100644
index 000000000..b9fca9d14
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SourceType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="source" category="epub"
+ */
+public class SourceType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SubjectType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SubjectType.java
new file mode 100644
index 000000000..e877af335
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/SubjectType.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="subject" category="epub"
+ */
+public class SubjectType {
+
+ String id;
+
+ Locale lang;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TitleType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TitleType.java
new file mode 100644
index 000000000..0e02e8bf3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TitleType.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.util.Locale;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="title" category="epub"
+ */
+public class TitleType {
+
+ String text;
+
+ Locale lang;
+
+ String id;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setLang(Locale lang) {
+ this.lang = lang;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TocType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TocType.java
new file mode 100644
index 000000000..44fa12760
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TocType.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+import java.io.File;
+
+/**
+ * Represents a table of contents element in the {@link EpubTask}. One should
+ * specify either a path to a NCX file or whether or not to generate the NCX.
+ *
+ * @author Torkild U. Resheim
+ * @ant.type name="toc" category="epub"
+ */
+public class TocType {
+
+ File file;
+
+ boolean generate;
+
+ /**
+ * @ant.not-required
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setGenerate(boolean generate) {
+ this.generate = generate;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TypeType.java b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TypeType.java
new file mode 100644
index 000000000..594c5bbff
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/TypeType.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.ant.core;
+
+/**
+ * @author Torkild U. Resheim
+ * @ant.type name="type" category="epub"
+ */
+public class TypeType {
+
+ String id;
+
+ String text;
+
+ /**
+ * @ant.required
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @ant.not-required
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/tasks.xml b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/tasks.xml
new file mode 100644
index 000000000..828bad06e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/tasks.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<antlib>
+ <taskdef name="epub" classname="org.eclipse.mylyn.docs.epub.ant.core.EpubTask" />
+</antlib>
diff --git a/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/tasks.properties b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/tasks.properties
new file mode 100644
index 000000000..93321d58c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/tasks.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2011 Torkild U. Resheim
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Torkild U. Resheim - initial API and implementation
+###############################################################################
+epub=org.eclipse.mylyn.docs.epub.ant.EpubTask
diff --git a/org.eclipse.mylyn.docs.epub.core/.classpath b/org.eclipse.mylyn.docs.epub.core/.classpath
new file mode 100644
index 000000000..ea6aae6de
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src-gen"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.docs.epub.core/.gitignore b/org.eclipse.mylyn.docs.epub.core/.gitignore
new file mode 100644
index 000000000..4998874d9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.gitignore
@@ -0,0 +1,3 @@
+/bin
+/target
+/src-gen/*
diff --git a/org.eclipse.mylyn.docs.epub.core/.project b/org.eclipse.mylyn.docs.epub.core/.project
new file mode 100644
index 000000000..8a3daae7b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..d12e78f6b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:22 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..2d2366b36
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:22 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..b367ad2d4
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Sun May 01 15:29:11 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..8891462ff
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF
@@ -0,0 +1,75 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.core;singleton:=true
+Bundle-Version: 0.8.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.emf.ecore.xmi;bundle-version="[2.5.0,3.0.0)",
+ org.eclipse.emf.validation;bundle-version="[1.4.0,2.0.0)",
+ org.eclipse.mylyn.wikitext.core;bundle-version="[1.4.0,2.0.0)",
+ org.eclipse.emf.mapping.ecore2xml;bundle-version="[2.7.0,3.0.0)"
+Export-Package: org.eclipse.mylyn.docs.epub.core;uses:="org.eclipse.mylyn.docs.epub.dc,org.eclipse.mylyn.docs.epub.opf,org.eclipse.mylyn.docs.epub.ncx",
+ org.eclipse.mylyn.docs.epub.core.wikitext,
+ org.eclipse.mylyn.docs.epub.dc;uses:="org.eclipse.emf.ecore.util,org.eclipse.emf.ecore,org.eclipse.mylyn.docs.epub.opf",
+ org.eclipse.mylyn.docs.epub.dc.impl;
+ uses:="org.eclipse.emf.ecore.util,
+ org.eclipse.emf.ecore,
+ org.eclipse.mylyn.docs.epub.opf,
+ org.eclipse.mylyn.docs.epub.dc,
+ org.eclipse.emf.ecore.impl,
+ org.eclipse.emf.common.notify",
+ org.eclipse.mylyn.docs.epub.dc.util;
+ uses:="org.eclipse.emf.ecore.xmi.impl,
+ org.eclipse.emf.ecore.resource,
+ org.eclipse.emf.common.util,
+ org.eclipse.emf.ecore.resource.impl,
+ org.eclipse.emf.common.notify,
+ org.eclipse.emf.ecore.xmi.util,
+ org.eclipse.emf.ecore.util,
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.common.notify.impl,
+ org.eclipse.mylyn.docs.epub.dc",
+ org.eclipse.mylyn.docs.epub.ncx;uses:="org.eclipse.emf.ecore.util,org.eclipse.emf.ecore,org.eclipse.emf.common.util",
+ org.eclipse.mylyn.docs.epub.ncx.impl;
+ uses:="org.eclipse.emf.ecore.util,
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.common.util,
+ org.eclipse.emf.ecore.impl,
+ org.eclipse.emf.common.notify,
+ org.eclipse.mylyn.docs.epub.ncx",
+ org.eclipse.mylyn.docs.epub.ncx.util;
+ uses:="org.eclipse.emf.ecore.resource,
+ org.eclipse.emf.ecore.xmi.impl,
+ org.eclipse.emf.common.util,
+ org.eclipse.emf.ecore.xmi.util,
+ org.eclipse.emf.ecore.resource.impl,
+ org.eclipse.emf.common.notify,
+ org.eclipse.mylyn.docs.epub.ncx,
+ org.eclipse.emf.ecore.util,
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.common.notify.impl",
+ org.eclipse.mylyn.docs.epub.ocf,
+ org.eclipse.mylyn.docs.epub.ocf.impl,
+ org.eclipse.mylyn.docs.epub.ocf.util,
+ org.eclipse.mylyn.docs.epub.opf;uses:="org.eclipse.emf.ecore,org.eclipse.emf.common.util,org.eclipse.mylyn.docs.epub.dc",
+ org.eclipse.mylyn.docs.epub.opf.impl;
+ uses:="org.eclipse.emf.ecore,
+ org.eclipse.emf.common.util,
+ org.eclipse.mylyn.docs.epub.dc,
+ org.eclipse.emf.common.notify,
+ org.eclipse.emf.ecore.impl,
+ org.eclipse.mylyn.docs.epub.opf",
+ org.eclipse.mylyn.docs.epub.opf.util;
+ uses:="org.eclipse.emf.ecore.xmi.impl,
+ org.eclipse.emf.ecore.resource,
+ org.eclipse.emf.common.util,
+ org.eclipse.emf.common.notify,
+ org.eclipse.mylyn.docs.epub.opf,
+ org.eclipse.emf.ecore.xmi.util,
+ org.eclipse.emf.ecore.resource.impl,
+ org.eclipse.emf.ecore.util,
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.common.notify.impl",
+ org.eclipse.mylyn.internal.docs.epub.core;x-internal:=true
+Bundle-ClassPath: .
diff --git a/org.eclipse.mylyn.docs.epub.core/OSGI-INF/l10n/bundle.properties b/org.eclipse.mylyn.docs.epub.core/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 000000000..5f8dd6acf
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,3 @@
+#Properties file for org.eclipse.mylyn.docs.epub.core
+Bundle-Vendor = Torkild U. Resheim
+Bundle-Name = EPUB Core \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.core/build.ant b/org.eclipse.mylyn.docs.epub.core/build.ant
new file mode 100644
index 000000000..6d974a1ad
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/build.ant
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2011 Torkild U. Resheim and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Torkild U. Resheim - initial API and implementation
+-->
+<project name="Build EPUB Model" default="build">
+
+ <target name="build">
+ <!--
+ <delete failonerror="false">
+ <fileset dir="${basedir}/src-gen/org/eclipse/mylyn/docs/epub/">
+ <include name="*/**" />
+ </fileset>
+ </delete>
+
+ <eclipse.refreshLocal resource="${basedir}/src-gen" depth="infinite" />
+
+ <emf.Ecore2Java copyright="Copyright © 2011 Torkild U. Resheim"
+ reconcileGenModel="reload"
+ generateJavaCode="true"
+ model="${basedir}/model/dc.ecore"
+ genmodel="${basedir}/model/dc.genmodel"
+ modelproject="org.eclipse.mylyn.docs.epub.core"
+ modelprojectfragmentpath="src-gen" />
+ -->
+ </target>
+
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.core/build.properties b/org.eclipse.mylyn.docs.epub.core/build.properties
new file mode 100644
index 000000000..45d53621b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/build.properties
@@ -0,0 +1,10 @@
+source.. = src/,\
+ src-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ OSGI-INF/,\
+ model/
+src.includes = model/
+
diff --git a/org.eclipse.mylyn.docs.epub.core/model/.gitignore b/org.eclipse.mylyn.docs.epub.core/model/.gitignore
new file mode 100644
index 000000000..9d96209ed
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/.gitignore
@@ -0,0 +1 @@
+/relacode.ecore
diff --git a/org.eclipse.mylyn.docs.epub.core/model/dc.ecore b/org.eclipse.mylyn.docs.epub.core/model/dc.ecore
new file mode 100644
index 000000000..711b66d66
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/dc.ecore
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="dc"
+ nsURI="http://purl.org/dc/elements/1.1/" nsPrefix="dc">
+ <eClassifiers xsi:type="ecore:EClass" name="Title" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Creator" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="role" eType="ecore:EEnum opf.ecore#//Role"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fileAs" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="file-as"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Subject" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Description" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Publisher" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Contributor" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="role" eType="ecore:EEnum opf.ecore#//Role"
+ defaultValueLiteral="" unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fileAs" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="file-as"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Date" eSuperTypes="#//DCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="event" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Type" eSuperTypes="#//DCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Format" eSuperTypes="#//DCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Identifier">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ defaultValueLiteral="BookId"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="scheme" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="mixed" lowerBound="1" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="elementWildcard"/>
+ <details key="name" value=":mixed"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Language" eSuperTypes="#//DCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.w3.org/2001/XMLSchema-instance"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Relation" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Coverage" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Rights" eSuperTypes="#//LocalizedDCType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="DCType" abstract="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="mixed" lowerBound="1" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="elementWildcard"/>
+ <details key="name" value=":mixed"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="LocalizedDCType" abstract="true" eSuperTypes="#//DCType">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/ncx.ecore b/org.eclipse.mylyn.docs.epub.core/model/ncx.ecore
new file mode 100644
index 000000000..20d61e6a0
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/ncx.ecore
@@ -0,0 +1,695 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ncx"
+ nsURI="http://www.daisy.org/z3986/2005/ncx/" nsPrefix="ncx">
+ <eClassifiers xsi:type="ecore:EClass" name="Audio">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="clipBegin" lowerBound="1"
+ eType="#//SMILtimeVal">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="clipBegin"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="clipEnd" lowerBound="1"
+ eType="#//SMILtimeVal">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="clipEnd"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="src" lowerBound="1" eType="#//URI">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="src"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="BookStruct">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="bookStruct_._type"/>
+ </eAnnotations>
+ <eLiterals name="PAGENUMBER" literal="PAGE_NUMBER"/>
+ <eLiterals name="NOTE" value="1"/>
+ <eLiterals name="NOTEREFERENCE" value="2" literal="NOTE_REFERENCE"/>
+ <eLiterals name="ANNOTATION" value="3"/>
+ <eLiterals name="LINENUMBER" value="4" literal="LINE_NUMBER"/>
+ <eLiterals name="OPTIONALSIDEBAR" value="5" literal="OPTIONAL_SIDEBAR"/>
+ <eLiterals name="OPTIONALPRODUCERNOTE" value="6" literal="OPTIONAL_PRODUCER_NOTE"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="BookStructObject" instanceClassName="org.eclipse.emf.common.util.Enumerator">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="bookStruct_._type:Object"/>
+ <details key="baseType" value="bookStruct_._type"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Content">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="src" lowerBound="1" eType="#//URI">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="src"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="DefaultState">
+ <eLiterals name="true"/>
+ <eLiterals name="false" value="1"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="DefaultStateObject" instanceClassName="org.eclipse.emf.common.util.Enumerator">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="defaultState_._type:Object"/>
+ <details key="baseType" value="defaultState_._type"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="DirType">
+ <eLiterals name="ltr"/>
+ <eLiterals name="rtl" value="1"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="DirTypeObject" instanceClassName="org.eclipse.emf.common.util.Enumerator"/>
+ <eClassifiers xsi:type="ecore:EClass" name="DocAuthor">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="text" lowerBound="1" eType="#//Text"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="text"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="audio" eType="#//Audio"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="audio"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="img" eType="#//Img" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="img"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="dir" eType="#//DirType"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="dir"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NMTOKEN">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="lang"/>
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="DocTitle">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="text" lowerBound="1" eType="#//Text"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="text"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="audio" eType="#//Audio"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="audio"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="img" eType="#//Img" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="img"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="dir" eType="#//DirType"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="dir"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NMTOKEN">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="lang"/>
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Head">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="groups" unique="false"
+ upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="group"/>
+ <details key="name" value="group:0"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="smilCustomTests" upperBound="-1"
+ eType="#//SmilCustomTest" volatile="true" transient="true" derived="true"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="smilCustomTest"/>
+ <details key="namespace" value="##targetNamespace"/>
+ <details key="group" value="#group:0"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="metas" upperBound="-1"
+ eType="#//Meta" volatile="true" transient="true" derived="true" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="meta"/>
+ <details key="namespace" value="##targetNamespace"/>
+ <details key="group" value="#group:0"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Img">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="src" lowerBound="1" eType="#//URI">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="src"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Meta">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="content" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="content"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="name"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="scheme" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="scheme"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavInfo">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="text" eType="#//Text" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="text"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="audio" eType="#//Audio"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="audio"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="img" eType="#//Img" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="img"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="dir" eType="#//DirType"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="dir"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NMTOKEN">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="lang"/>
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavLabel">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="text" eType="#//Text" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="text"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="audio" eType="#//Audio"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="audio"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="img" eType="#//Img" containment="true"
+ resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="img"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="dir" eType="#//DirType"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="dir"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NMTOKEN">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="lang"/>
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavList">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navInfos" upperBound="-1"
+ eType="#//NavInfo" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navInfo"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" lowerBound="1"
+ upperBound="-1" eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navLabel"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navTargets" lowerBound="1"
+ upperBound="-1" eType="#//NavTarget" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navTarget"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavMap">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navInfos" upperBound="-1"
+ eType="#//NavInfo" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navInfo"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" upperBound="-1"
+ eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navLabel"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navPoints" lowerBound="1"
+ upperBound="-1" eType="#//NavPoint" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navPoint"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavPoint">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" lowerBound="1"
+ upperBound="-1" eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="navLabel"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="content" lowerBound="1"
+ eType="#//Content" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="content"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navPoints" upperBound="-1"
+ eType="#//NavPoint" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navPoint"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="playOrder" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="playOrder"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="NavTarget">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" lowerBound="1"
+ upperBound="-1" eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navLabel"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="content" lowerBound="1"
+ eType="#//Content" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="content"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="playOrder" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="playOrder"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="value"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Ncx">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="ncx"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="head" lowerBound="1" eType="#//Head"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="head"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="docTitle" lowerBound="1"
+ eType="#//DocTitle" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="docTitle"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="docAuthors" upperBound="-1"
+ eType="#//DocAuthor" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="docAuthor"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navMap" lowerBound="1"
+ eType="#//NavMap" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navMap"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="pageList" eType="#//PageList"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="pageList"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLists" upperBound="-1"
+ eType="#//NavList" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navList"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="dir" eType="#//DirType"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="dir"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="lang" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NMTOKEN">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="lang"/>
+ <details key="namespace" value="http://www.w3.org/XML/1998/namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" defaultValueLiteral="2005-1"
+ unsettable="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="version"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="OverrideType">
+ <eLiterals name="visible"/>
+ <eLiterals name="hidden" value="1"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="OverrideObject" instanceClassName="org.eclipse.emf.common.util.Enumerator"/>
+ <eClassifiers xsi:type="ecore:EClass" name="PageList">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navInfos" upperBound="-1"
+ eType="#//NavInfo" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navInfo"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" upperBound="-1"
+ eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="navLabel"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="pageTargets" lowerBound="1"
+ upperBound="-1" eType="#//PageTarget" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="pageTarget"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="PageTarget">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="navLabels" lowerBound="1"
+ upperBound="-1" eType="#//NavLabel" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="content" lowerBound="1"
+ eType="#//Content" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="playOrder" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" lowerBound="1" eType="#//Type"
+ unsettable="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="SmilCustomTest">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="bookStruct" eType="#//BookStruct"
+ unsettable="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultState" eType="#//DefaultState"
+ defaultValueLiteral="false" unsettable="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="override" eType="#//OverrideType"
+ defaultValueLiteral="hidden" unsettable="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="SMILtimeVal" instanceClassName="java.lang.String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="SMILtimeVal"/>
+ <details key="baseType" value="http://www.eclipse.org/emf/2003/XMLType#string"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Text">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="mixed" unique="false" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="elementWildcard"/>
+ <details key="name" value=":mixed"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnySimpleType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="class"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//ID"
+ iD="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="Type">
+ <eLiterals name="front"/>
+ <eLiterals name="normal" value="1"/>
+ <eLiterals name="special" value="2"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="TypeObject" instanceClassName="org.eclipse.emf.common.util.Enumerator"/>
+ <eClassifiers xsi:type="ecore:EDataType" name="URI" instanceClassName="java.lang.String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="URI"/>
+ <details key="baseType" value="http://www.eclipse.org/emf/2003/XMLType#string"/>
+ </eAnnotations>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EDataType" name="VersionObject" instanceClassName="org.eclipse.emf.common.util.Enumerator">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="version_._type:Object"/>
+ <details key="baseType" value="version_._type"/>
+ </eAnnotations>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/ncx.genmodel b/org.eclipse.mylyn.docs.epub.core/model/ncx.genmodel
new file mode 100644
index 000000000..4a28a2148
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/ncx.genmodel
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.mylyn.docs.epub.core/src-gen"
+ modelPluginID="org.eclipse.mylyn.docs.epub.core" modelName="NCX-2005-1" importerID="org.eclipse.emf.importer.ecore"
+ complianceLevel="5.0" copyrightFields="false" runtimeVersion="2.6">
+ <foreignModel>ncx.ecore</foreignModel>
+ <genPackages prefix="NCX" basePackage="org.eclipse.mylyn.docs.epub" resource="XML"
+ disposableProviderFactory="true" ecorePackage="ncx.ecore#/">
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="ncx.ecore#//BookStruct">
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/PAGENUMBER"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/NOTE"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/NOTEREFERENCE"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/ANNOTATION"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/LINENUMBER"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/OPTIONALSIDEBAR"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//BookStruct/OPTIONALPRODUCERNOTE"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="ncx.ecore#//DefaultState">
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//DefaultState/true"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//DefaultState/false"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="ncx.ecore#//DirType">
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//DirType/ltr"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//DirType/rtl"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="ncx.ecore#//OverrideType">
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//OverrideType/visible"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//OverrideType/hidden"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="ncx.ecore#//Type">
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//Type/front"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//Type/normal"/>
+ <genEnumLiterals ecoreEnumLiteral="ncx.ecore#//Type/special"/>
+ </genEnums>
+ <genDataTypes ecoreDataType="ncx.ecore#//BookStructObject"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//DefaultStateObject"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//DirTypeObject"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//OverrideObject"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//SMILtimeVal"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//TypeObject"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//URI"/>
+ <genDataTypes ecoreDataType="ncx.ecore#//VersionObject"/>
+ <genClasses ecoreClass="ncx.ecore#//Audio">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Audio/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Audio/clipBegin"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Audio/clipEnd"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Audio/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Audio/src"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Content">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Content/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Content/src"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//DocAuthor">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocAuthor/text"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocAuthor/audio"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocAuthor/img"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocAuthor/dir"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocAuthor/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocAuthor/lang"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//DocTitle">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocTitle/text"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocTitle/audio"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//DocTitle/img"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocTitle/dir"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocTitle/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//DocTitle/lang"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Head">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EAttribute ncx.ecore#//Head/group"/>
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference ncx.ecore#//Head/smilCustomTest"/>
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference ncx.ecore#//Head/meta"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Img">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Img/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Img/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Img/src"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Meta">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Meta/content"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Meta/name"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Meta/scheme"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavInfo">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavInfo/text"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavInfo/audio"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavInfo/img"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavInfo/dir"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavInfo/lang"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavLabel">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavLabel/text"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavLabel/audio"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavLabel/img"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavLabel/dir"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavLabel/lang"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavList">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavList/navInfo"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavList/navLabel"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavList/navTarget"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavList/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavList/id"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavMap">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavMap/navInfo"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavMap/navLabel"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavMap/navPoint"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavMap/id"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavPoint">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavPoint/navLabels"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavPoint/content"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavPoint/navPoint"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavPoint/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavPoint/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavPoint/playOrder"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//NavTarget">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavTarget/navLabel"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//NavTarget/content"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavTarget/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavTarget/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavTarget/playOrder"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//NavTarget/value"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Ncx">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/head"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/docTitle"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/docAuthor"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/navMap"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/pageList"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//Ncx/navList"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Ncx/dir"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Ncx/lang"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Ncx/version"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//PageList">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//PageList/navInfo"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//PageList/navLabel"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//PageList/pageTarget"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageList/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageList/id"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//PageTarget">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//PageTarget/navLabel"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ncx.ecore#//PageTarget/content"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageTarget/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageTarget/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageTarget/playOrder"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageTarget/type"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//PageTarget/value"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//SmilCustomTest">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//SmilCustomTest/bookStruct"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//SmilCustomTest/defaultState"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//SmilCustomTest/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//SmilCustomTest/override"/>
+ </genClasses>
+ <genClasses ecoreClass="ncx.ecore#//Text">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EAttribute ncx.ecore#//Text/mixed"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Text/class"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ncx.ecore#//Text/id"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/ocf.ecore b/org.eclipse.mylyn.docs.epub.core/model/ocf.ecore
new file mode 100644
index 000000000..11ee500e2
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/ocf.ecore
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ocf"
+ nsURI="urn:oasis:names:tc:opendocument:xmlns:container" nsPrefix="ocf">
+ <eClassifiers xsi:type="ecore:EClass" name="Container">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="container"/>
+ <details key="namespace" value="urn:oasis:names:tc:opendocument:xmlns:container"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="rootfiles" lowerBound="1"
+ eType="#//RootFiles" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="rootfiles"/>
+ <details key="namespace" value="urn:oasis:names:tc:opendocument:xmlns:container"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="RootFiles">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="rootfiles" lowerBound="1"
+ upperBound="-1" eType="#//RootFile" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="rootfile"/>
+ <details key="namespace" value="urn:oasis:names:tc:opendocument:xmlns:container"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="RootFile">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fullPath" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="full-path"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="mediaType" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="media-type"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="publication" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"
+ transient="true"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/ocf.genmodel b/org.eclipse.mylyn.docs.epub.core/model/ocf.genmodel
new file mode 100644
index 000000000..90d7704b3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/ocf.genmodel
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.mylyn.docs.epub.core/src-gen"
+ modelPluginID="org.eclipse.mylyn.docs.epub.core" modelName="Ocf" importerID="org.eclipse.emf.importer.ecore"
+ complianceLevel="5.0" copyrightFields="false" runtimeVersion="2.6">
+ <foreignModel>ocf.ecore</foreignModel>
+ <genPackages prefix="OCF" basePackage="org.eclipse.mylyn.docs.epub" resource="XML"
+ disposableProviderFactory="true" ecorePackage="ocf.ecore#/">
+ <genClasses ecoreClass="ocf.ecore#//Container">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ocf.ecore#//Container/rootfiles"/>
+ </genClasses>
+ <genClasses ecoreClass="ocf.ecore#//RootFiles">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ocf.ecore#//RootFiles/rootfiles"/>
+ </genClasses>
+ <genClasses ecoreClass="ocf.ecore#//RootFile">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ocf.ecore#//RootFile/fullPath"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ocf.ecore#//RootFile/mediaType"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/opf.ecore b/org.eclipse.mylyn.docs.epub.core/model/opf.ecore
new file mode 100644
index 000000000..5c2317074
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/opf.ecore
@@ -0,0 +1,498 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="opf"
+ nsURI="http://www.idpf.org/2007/opf" nsPrefix="opf">
+ <eClassifiers xsi:type="ecore:EClass" name="Package">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="package"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="metadata" lowerBound="1"
+ eType="#//Metadata" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="manifest" lowerBound="1"
+ eType="#//Manifest" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="spine" lowerBound="1" eType="#//Spine"
+ containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="guide" eType="#//Guide"
+ containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="tours" eType="#//Tours">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" defaultValueLiteral="2.0"
+ unsettable="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="uniqueIdentifier" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="unique-identifier"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="generateCoverHTML" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
+ transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="generateTableOfContents"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="includeReferencedResources"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" transient="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Metadata">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="titles" lowerBound="1"
+ upperBound="-1" eType="ecore:EClass dc.ecore#//Title" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="title"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="creators" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Creator" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="creator"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="subjects" lowerBound="1"
+ upperBound="-1" eType="ecore:EClass dc.ecore#//Subject" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="subject"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="descriptions" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Description" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="description"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="publishers" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Publisher" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="publisher"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="contributors" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Contributor" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="contributor"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="dates" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Date" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="date"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="types" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Type" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="type"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="formats" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Format" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="format"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="identifiers" lowerBound="1"
+ upperBound="-1" eType="ecore:EClass dc.ecore#//Identifier" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="identifier"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="sources" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Source" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="source"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="languages" lowerBound="1"
+ upperBound="-1" eType="ecore:EClass dc.ecore#//Language" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="language"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="relations" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Relation" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="relation"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="coverages" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Coverage" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="coverage"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="rights" upperBound="-1"
+ eType="ecore:EClass dc.ecore#//Rights" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="rights"/>
+ <details key="namespace" value="http://purl.org/dc/elements/1.1/"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="metas" upperBound="-1"
+ eType="#//Meta" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="meta"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Manifest">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="items" lowerBound="1" upperBound="-1"
+ eType="#//Item" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="item"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Item">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ iD="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="href" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="media_type" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="media-type"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fallback" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fallback_style" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="fallback-style"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="required_namespace" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="required-namespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="required_modules" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="required-modules"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="file" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="noToc" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
+ transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="generated" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
+ transient="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="sourcePath" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+ transient="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Spine">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="spineItems" upperBound="-1"
+ eType="#//Itemref" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="itemref"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="toc" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Guide">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="guideItems" upperBound="-1"
+ eType="#//Reference" containment="true">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="reference"/>
+ <details key="namespace" value="http://www.idpf.org/2007/opf"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Reference">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" lowerBound="1" eType="#//Type"
+ unsettable="true"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="href" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Itemref">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="idref" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="linear" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Tours"/>
+ <eClassifiers xsi:type="ecore:EEnum" name="Role">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ <eLiterals name="Art_copyist" literal="acp"/>
+ <eLiterals name="Actor" literal="act"/>
+ <eLiterals name="Adapter" literal="adp"/>
+ <eLiterals name="Author_of_afterword_colophon_etc" literal="aft"/>
+ <eLiterals name="Analyst" literal="anl"/>
+ <eLiterals name="Animator" literal="anm"/>
+ <eLiterals name="Annotator" literal="ann"/>
+ <eLiterals name="Bibliographic_antecedent" literal="ant"/>
+ <eLiterals name="Applicant" literal="app"/>
+ <eLiterals name="Author_in_quotations_or_text_abstracts" literal="aqt"/>
+ <eLiterals name="Architect" literal="arc"/>
+ <eLiterals name="Artistic_director" literal="ard"/>
+ <eLiterals name="Arranger" literal="arr"/>
+ <eLiterals name="Artist" literal="art"/>
+ <eLiterals name="Assignee" literal="asg"/>
+ <eLiterals name="Associated_name" literal="asn"/>
+ <eLiterals name="Attributed_name" literal="att"/>
+ <eLiterals name="Auctioneer" literal="auc"/>
+ <eLiterals name="Author_of_dialog" literal="aud"/>
+ <eLiterals name="Author_of_introduction" literal="aui"/>
+ <eLiterals name="Author_of_screenplay" literal="aus"/>
+ <eLiterals name="Author" literal="aut"/>
+ <eLiterals name="Binding_designer" literal="bdd"/>
+ <eLiterals name="Bookjacket_designer" literal="bjd"/>
+ <eLiterals name="Book_designer" literal="bkd"/>
+ <eLiterals name="Book_producer" literal="bkp"/>
+ <eLiterals name="Blurb_writer" literal="blw"/>
+ <eLiterals name="Binder" literal="bnd"/>
+ <eLiterals name="Bookplate_designer" literal="bpd"/>
+ <eLiterals name="Bookseller" literal="bsl"/>
+ <eLiterals name="Conceptor" literal="ccp"/>
+ <eLiterals name="Choreographer" literal="chr"/>
+ <eLiterals name="Collaborator" literal="clb"/>
+ <eLiterals name="Client" literal="cli"/>
+ <eLiterals name="Calligrapher" literal="cll"/>
+ <eLiterals name="Colorist" literal="clr"/>
+ <eLiterals name="Collotyper" literal="clt"/>
+ <eLiterals name="Commentator" literal="cmm"/>
+ <eLiterals name="Composer" literal="cmp"/>
+ <eLiterals name="Compositor" literal="cmt"/>
+ <eLiterals name="Cinematographer" literal="cng"/>
+ <eLiterals name="Conductor" literal="cnd"/>
+ <eLiterals name="Censor" literal="cns"/>
+ <eLiterals name="Contestant_appellee" literal="coe"/>
+ <eLiterals name="Collector" literal="col"/>
+ <eLiterals name="Compiler" literal="com"/>
+ <eLiterals name="Conservator" literal="con"/>
+ <eLiterals name="Contestant" literal="cos"/>
+ <eLiterals name="Contestant_appellant" literal="cot"/>
+ <eLiterals name="Cover_designer" literal="cov"/>
+ <eLiterals name="Copyright_claimant" literal="cpc"/>
+ <eLiterals name="Complainant_appellee" literal="cpe"/>
+ <eLiterals name="Copyright_holder" literal="cph"/>
+ <eLiterals name="Complainant" literal="cpl"/>
+ <eLiterals name="Complainant_appellant" literal="cpt"/>
+ <eLiterals name="Creator" literal="cre"/>
+ <eLiterals name="Correspondent" literal="crp"/>
+ <eLiterals name="Corrector" literal="crr"/>
+ <eLiterals name="Consultant" literal="csl"/>
+ <eLiterals name="Consultant_to_a_project" literal="csp"/>
+ <eLiterals name="Costume_designer" literal="cst"/>
+ <eLiterals name="Contributor" literal="ctb"/>
+ <eLiterals name="Contestee_appellee" literal="cte"/>
+ <eLiterals name="Cartographer" literal="ctg"/>
+ <eLiterals name="Contractor" literal="ctr"/>
+ <eLiterals name="Contestee" literal="cts"/>
+ <eLiterals name="Contestee_appellant" literal="ctt"/>
+ <eLiterals name="Curator" literal="cur"/>
+ <eLiterals name="Commentator_for_written_text" literal="cwt"/>
+ <eLiterals name="Defendant" literal="dfd"/>
+ <eLiterals name="Defendant_appellee" literal="dfe"/>
+ <eLiterals name="Defendant_appellant" literal="dft"/>
+ <eLiterals name="Degree_grantor" literal="dgg"/>
+ <eLiterals name="Dissertant" literal="dis"/>
+ <eLiterals name="Delineator" literal="dln"/>
+ <eLiterals name="Dancer" literal="dnc"/>
+ <eLiterals name="Donor" literal="dnr"/>
+ <eLiterals name="Distribution_place" literal="dpb"/>
+ <eLiterals name="Depicted" literal="dpc"/>
+ <eLiterals name="Depositor" literal="dpt"/>
+ <eLiterals name="Draftsman" literal="drm"/>
+ <eLiterals name="Director" literal="drt"/>
+ <eLiterals name="Designer" literal="dsr"/>
+ <eLiterals name="Distributor" literal="dst"/>
+ <eLiterals name="Data_contributor" literal="dtc"/>
+ <eLiterals name="Dedicatee" literal="dte"/>
+ <eLiterals name="Data_manager" literal="dtm"/>
+ <eLiterals name="Dedicator" literal="dto"/>
+ <eLiterals name="Dubious_author" literal="dub"/>
+ <eLiterals name="Editor" literal="edt"/>
+ <eLiterals name="Engraver" literal="egr"/>
+ <eLiterals name="Electrician" literal="elg"/>
+ <eLiterals name="Electrotyper" literal="elt"/>
+ <eLiterals name="Engineer" literal="eng"/>
+ <eLiterals name="Etcher" literal="etr"/>
+ <eLiterals name="Event_place" literal="evp"/>
+ <eLiterals name="Expert" literal="exp"/>
+ <eLiterals name="Facsimilist" literal="fac"/>
+ <eLiterals name="Field_director" literal="fld"/>
+ <eLiterals name="Film_editor" literal="flm"/>
+ <eLiterals name="Former_owner" literal="fmo"/>
+ <eLiterals name="First_party" literal="fpy"/>
+ <eLiterals name="Funder" literal="fnd"/>
+ <eLiterals name="Forger" literal="frg"/>
+ <eLiterals name="Geographic_information_specialist" literal="gis"/>
+ <eLiterals name="Graphic_technician" literal="_grt"/>
+ <eLiterals name="Honoree" literal="hnr"/>
+ <eLiterals name="Host" literal="hst"/>
+ <eLiterals name="Illustrator" literal="ill"/>
+ <eLiterals name="Illuminator" literal="ilu"/>
+ <eLiterals name="Inscriber" literal="ins"/>
+ <eLiterals name="Inventor" literal="inv"/>
+ <eLiterals name="Instrumentalist" literal="itr"/>
+ <eLiterals name="Interviewee" literal="ive"/>
+ <eLiterals name="Interviewer" literal="ivr"/>
+ <eLiterals name="Laboratory" literal="lbr"/>
+ <eLiterals name="Librettist" literal="lbt"/>
+ <eLiterals name="Laboratory_director" literal="ldr"/>
+ <eLiterals name="Lead" literal="led"/>
+ <eLiterals name="Libelee_appellee" literal="lee"/>
+ <eLiterals name="Libelee" literal="lel"/>
+ <eLiterals name="Lender" literal="len"/>
+ <eLiterals name="Libelee_appellant" literal="let"/>
+ <eLiterals name="Lighting_designer" literal="lgd"/>
+ <eLiterals name="Libelant_appellee" literal="lie"/>
+ <eLiterals name="Libelant" literal="lil"/>
+ <eLiterals name="Libelant_appellant" literal="lit"/>
+ <eLiterals name="Landscape_architect" literal="lsa"/>
+ <eLiterals name="Licensee" literal="lse"/>
+ <eLiterals name="Licensor" literal="lso"/>
+ <eLiterals name="Lithographer" literal="ltg"/>
+ <eLiterals name="Lyricist" literal="lyr"/>
+ <eLiterals name="Music_copyist" literal="mcp"/>
+ <eLiterals name="Manufacture_place" literal="mfp"/>
+ <eLiterals name="Manufacturer" literal="mfr"/>
+ <eLiterals name="Metadata_contact" literal="mdc"/>
+ <eLiterals name="Moderator" literal="mod"/>
+ <eLiterals name="Monitor" literal="mon"/>
+ <eLiterals name="Marbler" literal="mrb"/>
+ <eLiterals name="Markup_editor" literal="mrk"/>
+ <eLiterals name="Musical_director" literal="msd"/>
+ <eLiterals name="Metal_engraver" literal="mte"/>
+ <eLiterals name="Musician" literal="mus"/>
+ <eLiterals name="Narrator" literal="nrt"/>
+ <eLiterals name="Opponent" literal="opn"/>
+ <eLiterals name="Originator" literal="org"/>
+ <eLiterals name="Organizer_of_meeting" literal="orm"/>
+ <eLiterals name="Other" literal="oth"/>
+ <eLiterals name="Owner" literal="own"/>
+ <eLiterals name="Patron" literal="pat"/>
+ <eLiterals name="Publishing_director" literal="pbd"/>
+ <eLiterals name="Publisher" literal="pbl"/>
+ <eLiterals name="Project_director" literal="pdr"/>
+ <eLiterals name="Proofreader" literal="pfr"/>
+ <eLiterals name="Photographer" literal="pht"/>
+ <eLiterals name="Platemaker" literal="plt"/>
+ <eLiterals name="Permitting_agency" literal="pma"/>
+ <eLiterals name="Production_manager" literal="pmn"/>
+ <eLiterals name="Printer_of_plates" literal="pop"/>
+ <eLiterals name="Papermaker" literal="ppm"/>
+ <eLiterals name="Puppeteer" literal="ppt"/>
+ <eLiterals name="Process_contact" literal="prc"/>
+ <eLiterals name="Production_personnel" literal="prd"/>
+ <eLiterals name="Performer" literal="prf"/>
+ <eLiterals name="Programmer" literal="prg"/>
+ <eLiterals name="Printmaker" literal="prm"/>
+ <eLiterals name="Producer" literal="pro"/>
+ <eLiterals name="Production_place" literal="prp"/>
+ <eLiterals name="Printer" literal="prt"/>
+ <eLiterals name="Patent_applicant" literal="pta"/>
+ <eLiterals name="Plaintiff_appellee" literal="pte"/>
+ <eLiterals name="Plaintiff" literal="ptf"/>
+ <eLiterals name="Patent_holder" literal="pth"/>
+ <eLiterals name="Plaintiff_appellant" literal="ptt"/>
+ <eLiterals name="Publication_place" literal="pup"/>
+ <eLiterals name="Rubricator" literal="rbr"/>
+ <eLiterals name="Recording_engineer" literal="rce"/>
+ <eLiterals name="Recipient" literal="rcp"/>
+ <eLiterals name="Redactor" literal="red"/>
+ <eLiterals name="Renderer" literal="ren"/>
+ <eLiterals name="Researcher" literal="res"/>
+ <eLiterals name="Reviewer" literal="rev"/>
+ <eLiterals name="Repository" literal="rps"/>
+ <eLiterals name="Reporter" literal="rpt"/>
+ <eLiterals name="Responsible_party" literal="rpy"/>
+ <eLiterals name="Respondent_appellee" literal="rse"/>
+ <eLiterals name="Restager" literal="rsg"/>
+ <eLiterals name="Respondent" literal="rsp"/>
+ <eLiterals name="Respondent_appellant" literal="rst"/>
+ <eLiterals name="Research_team_head" literal="rth"/>
+ <eLiterals name="Research_team_member" literal="rtm"/>
+ <eLiterals name="Scientific_advisor" literal="sad"/>
+ <eLiterals name="Scenarist" literal="sce"/>
+ <eLiterals name="Sculptor" literal="scl"/>
+ <eLiterals name="Scribe" literal="scr"/>
+ <eLiterals name="Sound_designer" literal="sds"/>
+ <eLiterals name="Secretary" literal="sec"/>
+ <eLiterals name="Signer" literal="sgn"/>
+ <eLiterals name="Supporting_host" literal="sht"/>
+ <eLiterals name="Singer" literal="sng"/>
+ <eLiterals name="Speaker" literal="spk"/>
+ <eLiterals name="Sponsor" literal="spn"/>
+ <eLiterals name="Second_party" literal="spy"/>
+ <eLiterals name="Surveyor" literal="srv"/>
+ <eLiterals name="Set_designer" literal="std"/>
+ <eLiterals name="Storyteller" literal="stl"/>
+ <eLiterals name="Stage_manager" literal="stm"/>
+ <eLiterals name="Standards_body" literal="stn"/>
+ <eLiterals name="Stereotyper" literal="str"/>
+ <eLiterals name="Technical_director" literal="tcd"/>
+ <eLiterals name="Teacher" literal="tch"/>
+ <eLiterals name="Thesis_advisor" literal="ths"/>
+ <eLiterals name="Transcriber" literal="trc"/>
+ <eLiterals name="Translator" literal="trl"/>
+ <eLiterals name="Type_designer" literal="tyd"/>
+ <eLiterals name="Typographer" literal="tyg"/>
+ <eLiterals name="University_place" literal="uvp"/>
+ <eLiterals name="Videographer" literal="vdg"/>
+ <eLiterals name="Vocalist" literal="voc"/>
+ <eLiterals name="Writer_of_accompanying_material" literal="wam"/>
+ <eLiterals name="Woodcutter" literal="wdc"/>
+ <eLiterals name="Wood_engraver" literal="wde"/>
+ <eLiterals name="Witness" literal="wit"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="Type">
+ <eLiterals name="Cover" value="1" literal="cover"/>
+ <eLiterals name="Title" value="2" literal="title-page"/>
+ <eLiterals name="TOC" value="3" literal="toc"/>
+ <eLiterals name="Index" value="4" literal="index"/>
+ <eLiterals name="Glossary" value="5" literal="glossary"/>
+ <eLiterals name="Acknowledgements" value="6" literal="acknowledgements"/>
+ <eLiterals name="Bibliography" value="7" literal="bibliography"/>
+ <eLiterals name="Colophon" value="8" literal="colophon"/>
+ <eLiterals name="Copyright" value="9" literal="copyright-page"/>
+ <eLiterals name="Dedication" value="10" literal="dedication"/>
+ <eLiterals name="Epigraph" value="11" literal="epigraph"/>
+ <eLiterals name="Foreword" value="12" literal="foreword"/>
+ <eLiterals name="Illustrations" value="13" literal="loi"/>
+ <eLiterals name="Tables" value="14" literal="lot"/>
+ <eLiterals name="Notes" value="15" literal="notes"/>
+ <eLiterals name="Preface" value="16" literal="preface"/>
+ <eLiterals name="Text" value="17" literal="text"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Meta">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="content" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/opf.genmodel b/org.eclipse.mylyn.docs.epub.core/model/opf.genmodel
new file mode 100644
index 000000000..f9d771edc
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/opf.genmodel
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.mylyn.docs.epub.core/src-gen"
+ modelPluginID="org.eclipse.mylyn.docs.epub.core" modelName="OPF-2.0.1" modelPluginClass=""
+ nonNLSMarkers="true" runtimeCompatibility="true" testsDirectory="/org.eclipse.mylyn.docs.epub.tests/src-gen"
+ importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" copyrightFields="false"
+ publicConstructors="true" runtimeVersion="2.6" language="en" interfaceNamePattern="">
+ <foreignModel>opf.ecore</foreignModel>
+ <genPackages prefix="OPF" basePackage="org.eclipse.mylyn.docs.epub" resource="XML"
+ disposableProviderFactory="true" dataTypeConverters="true" ecorePackage="opf.ecore#/">
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="opf.ecore#//Role">
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Art_copyist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Actor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Adapter"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author_of_afterword_colophon_etc"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Analyst"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Animator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Annotator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Bibliographic_antecedent"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Applicant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author_in_quotations_or_text_abstracts"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Architect"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Artistic_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Arranger"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Artist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Assignee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Associated_name"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Attributed_name"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Auctioneer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author_of_dialog"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author_of_introduction"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author_of_screenplay"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Author"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Binding_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Bookjacket_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Book_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Book_producer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Blurb_writer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Binder"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Bookplate_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Bookseller"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Conceptor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Choreographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Collaborator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Client"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Calligrapher"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Colorist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Collotyper"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Commentator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Composer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Compositor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Cinematographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Conductor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Censor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestant_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Collector"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Compiler"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Conservator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestant_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Cover_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Copyright_claimant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Complainant_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Copyright_holder"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Complainant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Complainant_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Creator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Correspondent"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Corrector"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Consultant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Consultant_to_a_project"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Costume_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contributor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestee_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Cartographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contractor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Contestee_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Curator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Commentator_for_written_text"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Defendant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Defendant_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Defendant_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Degree_grantor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Dissertant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Delineator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Dancer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Donor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Distribution_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Depicted"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Depositor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Draftsman"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Distributor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Data_contributor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Dedicatee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Data_manager"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Dedicator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Dubious_author"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Editor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Engraver"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Electrician"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Electrotyper"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Engineer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Etcher"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Event_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Expert"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Facsimilist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Field_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Film_editor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Former_owner"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/First_party"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Funder"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Forger"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Geographic_information_specialist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Graphic_technician"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Honoree"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Host"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Illustrator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Illuminator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Inscriber"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Inventor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Instrumentalist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Interviewee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Interviewer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Laboratory"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Librettist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Laboratory_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Lead"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelee_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Lender"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelee_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Lighting_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelant_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Libelant_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Landscape_architect"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Licensee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Licensor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Lithographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Lyricist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Music_copyist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Manufacture_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Manufacturer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Metadata_contact"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Moderator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Monitor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Marbler"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Markup_editor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Musical_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Metal_engraver"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Musician"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Narrator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Opponent"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Originator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Organizer_of_meeting"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Other"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Owner"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Patron"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Publishing_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Publisher"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Project_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Proofreader"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Photographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Platemaker"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Permitting_agency"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Production_manager"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Printer_of_plates"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Papermaker"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Puppeteer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Process_contact"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Production_personnel"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Performer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Programmer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Printmaker"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Producer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Production_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Printer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Patent_applicant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Plaintiff_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Plaintiff"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Patent_holder"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Plaintiff_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Publication_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Rubricator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Recording_engineer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Recipient"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Redactor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Renderer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Researcher"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Reviewer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Repository"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Reporter"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Responsible_party"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Respondent_appellee"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Restager"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Respondent"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Respondent_appellant"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Research_team_head"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Research_team_member"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Scientific_advisor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Scenarist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Sculptor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Scribe"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Sound_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Secretary"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Signer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Supporting_host"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Singer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Speaker"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Sponsor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Second_party"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Surveyor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Set_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Storyteller"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Stage_manager"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Standards_body"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Stereotyper"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Technical_director"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Teacher"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Thesis_advisor"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Transcriber"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Translator"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Type_designer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Typographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/University_place"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Videographer"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Vocalist"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Writer_of_accompanying_material"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Woodcutter"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Wood_engraver"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Role/Witness"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="opf.ecore#//Scheme">
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Scheme/ISBN"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Scheme/URI"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Scheme/URL"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Scheme/UUID"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Scheme/URN"/>
+ </genEnums>
+ <genEnums typeSafeEnumCompatible="false" ecoreEnum="opf.ecore#//Type">
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Cover"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Title"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/TOC"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Index"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Glossary"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Acknowledgements"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Bibliography"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Colophon"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Copyright"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Dedication"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Epigraph"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Foreword"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Illustrations"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Tables"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Notes"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Preface"/>
+ <genEnumLiterals ecoreEnumLiteral="opf.ecore#//Type/Text"/>
+ </genEnums>
+ <genClasses ecoreClass="opf.ecore#//Package">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Package/metadata"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Package/manifest"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Package/spine"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Package/guide"/>
+ <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference opf.ecore#//Package/tours"/>
+ <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Package/version"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Package/uniqueIdentifier"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Package/generateCoverHTML"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Package/generateTableOfContents"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Package/includeReferencedResources"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Metadata">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/titles"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/creators"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/subjects"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/descriptions"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/publishers"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/contributors"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/dates"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/types"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/formats"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/identifiers"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/sources"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/languages"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/relations"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/coverages"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/rights"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Metadata/metas"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Manifest">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Manifest/items"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Item">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/href"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/media_type"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/fallback"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/fallback_style"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/required_namespace"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/required_modules"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/file"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/noToc"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/title"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/generated"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Item/sourcePath"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Spine">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Spine/spineItems"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Spine/toc"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Guide">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference opf.ecore#//Guide/guideItems"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Reference">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Reference/type"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Reference/title"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Reference/href"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Itemref">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Itemref/idref"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Itemref/linear"/>
+ </genClasses>
+ <genClasses ecoreClass="opf.ecore#//Tours"/>
+ <genClasses ecoreClass="opf.ecore#//Meta">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Meta/name"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute opf.ecore#//Meta/content"/>
+ </genClasses>
+ </genPackages>
+ <genPackages prefix="DC" basePackage="org.eclipse.mylyn.docs.epub" resource="XML"
+ disposableProviderFactory="true" ecorePackage="dc.ecore#/">
+ <genClasses ecoreClass="dc.ecore#//Title"/>
+ <genClasses ecoreClass="dc.ecore#//Creator">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Creator/role"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Creator/fileAs"/>
+ </genClasses>
+ <genClasses ecoreClass="dc.ecore#//Subject"/>
+ <genClasses ecoreClass="dc.ecore#//Description"/>
+ <genClasses ecoreClass="dc.ecore#//Publisher"/>
+ <genClasses ecoreClass="dc.ecore#//Contributor">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Contributor/role"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Contributor/fileAs"/>
+ </genClasses>
+ <genClasses ecoreClass="dc.ecore#//Date">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Date/event"/>
+ </genClasses>
+ <genClasses ecoreClass="dc.ecore#//Type"/>
+ <genClasses ecoreClass="dc.ecore#//Format"/>
+ <genClasses ecoreClass="dc.ecore#//Identifier">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Identifier/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Identifier/scheme"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EAttribute dc.ecore#//Identifier/mixed"/>
+ </genClasses>
+ <genClasses ecoreClass="dc.ecore#//Source"/>
+ <genClasses ecoreClass="dc.ecore#//Language">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//Language/type"/>
+ </genClasses>
+ <genClasses ecoreClass="dc.ecore#//Relation"/>
+ <genClasses ecoreClass="dc.ecore#//Coverage"/>
+ <genClasses ecoreClass="dc.ecore#//Rights"/>
+ <genClasses image="false" ecoreClass="dc.ecore#//DCType">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//DCType/id"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EAttribute dc.ecore#//DCType/mixed"/>
+ </genClasses>
+ <genClasses image="false" ecoreClass="dc.ecore#//LocalizedDCType">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute dc.ecore#//LocalizedDCType/lang"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/readme.txt b/org.eclipse.mylyn.docs.epub.core/model/readme.txt
new file mode 100644
index 000000000..55f410f7f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/readme.txt
@@ -0,0 +1,3 @@
+This implementation is based on EPUB version 2.0.1 http://idpf.org/epub/201.
+There is a newer version in the works (3.0).
+
diff --git a/org.eclipse.mylyn.docs.epub.core/model/relacode.ant b/org.eclipse.mylyn.docs.epub.core/model/relacode.ant
new file mode 100644
index 000000000..5dd8e2df6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/relacode.ant
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2011 Torkild U. Resheim and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Torkild U. Resheim - initial API and implementation
+-->
+<project name="Generate MARC Code List for Relators" default="build">
+
+ <!-- This target will take the MARC relators list and convert it to ecore
+ for use in the EPUB ecore model. Whenver the list has changed it can be
+ obtained from http://www.loc.gov/marc/relators/relacode.html and the
+ model can be updated with the new version using this ANT project. The
+ generated code must be copy-pasted into epub2.ecore. -->
+ <target name="build">
+ <copyfile dest="${basedir}/relacode.ecore" src="${basedir}/relacode.src" forceoverwrite="true"/>
+ <replaceregexp
+ file="${basedir}/relacode.ecore"
+ match="([\S]+)[\s](.+)"
+ byline="true"
+ replace="&lt;eLiterals name=&quot;\2&quot; literal=&quot;\1&quot;/&gt;"/>
+ </target>
+
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.core/model/relacode.src b/org.eclipse.mylyn.docs.epub.core/model/relacode.src
new file mode 100644
index 000000000..39d14ef04
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/model/relacode.src
@@ -0,0 +1,223 @@
+acp Art copyist
+act Actor
+adp Adapter
+aft Author of afterword, colophon, etc.
+anl Analyst
+anm Animator
+ann Annotator
+ant Bibliographic antecedent
+app Applicant
+aqt Author in quotations or text abstracts
+arc Architect
+ard Artistic director
+arr Arranger
+art Artist
+asg Assignee
+asn Associated name
+att Attributed name
+auc Auctioneer
+aud Author of dialog
+aui Author of introduction
+aus Author of screenplay
+aut Author
+bdd Binding designer
+bjd Bookjacket designer
+bkd Book designer
+bkp Book producer
+blw Blurb writer
+bnd Binder
+bpd Bookplate designer
+bsl Bookseller
+ccp Conceptor
+chr Choreographer
+clb Collaborator
+cli Client
+cll Calligrapher
+clr Colorist
+clt Collotyper
+cmm Commentator
+cmp Composer
+cmt Compositor
+cng Cinematographer
+cnd Conductor
+cns Censor
+coe Contestant -appellee
+col Collector
+com Compiler
+con Conservator
+cos Contestant
+cot Contestant -appellant
+cov Cover designer
+cpc Copyright claimant
+cpe Complainant-appellee
+cph Copyright holder
+cpl Complainant
+cpt Complainant-appellant
+cre Creator
+crp Correspondent
+crr Corrector
+csl Consultant
+csp Consultant to a project
+cst Costume designer
+ctb Contributor
+cte Contestee-appellee
+ctg Cartographer
+ctr Contractor
+cts Contestee
+ctt Contestee-appellant
+cur Curator
+cwt Commentator for written text
+dfd Defendant
+dfe Defendant-appellee
+dft Defendant-appellant
+dgg Degree grantor
+dis Dissertant
+dln Delineator
+dnc Dancer
+dnr Donor
+dpb Distribution place
+dpc Depicted
+dpt Depositor
+drm Draftsman
+drt Director
+dsr Designer
+dst Distributor
+dtc Data contributor
+dte Dedicatee
+dtm Data manager
+dto Dedicator
+dub Dubious author
+edt Editor
+egr Engraver
+elg Electrician
+elt Electrotyper
+eng Engineer
+etr Etcher
+evp Event place
+exp Expert
+fac Facsimilist
+fld Field director
+flm Film editor
+fmo Former owner
+fpy First party
+fnd Funder
+frg Forger
+gis Geographic information specialist
+-grt Graphic technician
+hnr Honoree
+hst Host
+ill Illustrator
+ilu Illuminator
+ins Inscriber
+inv Inventor
+itr Instrumentalist
+ive Interviewee
+ivr Interviewer
+lbr Laboratory
+lbt Librettist
+ldr Laboratory director
+led Lead
+lee Libelee-appellee
+lel Libelee
+len Lender
+let Libelee-appellant
+lgd Lighting designer
+lie Libelant-appellee
+lil Libelant
+lit Libelant-appellant
+lsa Landscape architect
+lse Licensee
+lso Licensor
+ltg Lithographer
+lyr Lyricist
+mcp Music copyist
+mfp Manufacture place
+mfr Manufacturer
+mdc Metadata contact
+mod Moderator
+mon Monitor
+mrb Marbler
+mrk Markup editor
+msd Musical director
+mte Metal-engraver
+mus Musician
+nrt Narrator
+opn Opponent
+org Originator
+orm Organizer of meeting
+oth Other
+own Owner
+pat Patron
+pbd Publishing director
+pbl Publisher
+pdr Project director
+pfr Proofreader
+pht Photographer
+plt Platemaker
+pma Permitting agency
+pmn Production manager
+pop Printer of plates
+ppm Papermaker
+ppt Puppeteer
+prc Process contact
+prd Production personnel
+prf Performer
+prg Programmer
+prm Printmaker
+pro Producer
+prp Production place
+prt Printer
+pta Patent applicant
+pte Plaintiff -appellee
+ptf Plaintiff
+pth Patent holder
+ptt Plaintiff-appellant
+pup Publication place
+rbr Rubricator
+rce Recording engineer
+rcp Recipient
+red Redactor
+ren Renderer
+res Researcher
+rev Reviewer
+rps Repository
+rpt Reporter
+rpy Responsible party
+rse Respondent-appellee
+rsg Restager
+rsp Respondent
+rst Respondent-appellant
+rth Research team head
+rtm Research team member
+sad Scientific advisor
+sce Scenarist
+scl Sculptor
+scr Scribe
+sds Sound designer
+sec Secretary
+sgn Signer
+sht Supporting host
+sng Singer
+spk Speaker
+spn Sponsor
+spy Second party
+srv Surveyor
+std Set designer
+stl Storyteller
+stm Stage manager
+stn Standards body
+str Stereotyper
+tcd Technical director
+tch Teacher
+ths Thesis advisor
+trc Transcriber
+trl Translator
+tyd Type designer
+tyg Typographer
+uvp University place
+vdg Videographer
+voc Vocalist
+wam Writer of accompanying material
+wdc Woodcutter
+wde Wood-engraver
+wit Witness \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.core/plugin.xml b/org.eclipse.mylyn.docs.epub.core/plugin.xml
new file mode 100644
index 000000000..eb9ea4fd3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/plugin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+ &copy; 2011 Torkild U. Resheim
+-->
+
+<plugin>
+ <extension
+ point="org.eclipse.emf.ecore.generated_package">
+ <package
+ class="org.eclipse.mylyn.docs.epub.opf.OPFPackage"
+ genModel="model/opf.genmodel"
+ uri="http://eclipse.org/mylyn/docs/epub/opf">
+ </package>
+ <package
+ class="org.eclipse.mylyn.docs.epub.dc.DCPackage"
+ uri="http://eclipse.org/mylyn/docs/epub/dc">
+ </package>
+ </extension>
+
+
+</plugin>
diff --git a/org.eclipse.mylyn.docs.epub.core/pom.xml b/org.eclipse.mylyn.docs.epub.core/pom.xml
new file mode 100644
index 000000000..e1d84b3fe
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub.core</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/EPUB.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/EPUB.java
new file mode 100644
index 000000000..b5a5b5182
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/EPUB.java
@@ -0,0 +1,363 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;
+import org.eclipse.mylyn.docs.epub.ocf.Container;
+import org.eclipse.mylyn.docs.epub.ocf.OCFFactory;
+import org.eclipse.mylyn.docs.epub.ocf.OCFPackage;
+import org.eclipse.mylyn.docs.epub.ocf.RootFile;
+import org.eclipse.mylyn.docs.epub.ocf.RootFiles;
+import org.eclipse.mylyn.docs.epub.ocf.util.OCFResourceImpl;
+import org.eclipse.mylyn.internal.docs.epub.core.EPUBFileUtil;
+
+/**
+ * Represents one EPUB file. Currently <b>only</b> version 2.0.1 of the EPUB
+ * specification is supported. One or more publications can be added and will be
+ * a part of the distribution when packed. See the <a
+ * href="http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section1.2">OPS
+ * specification</a> for definitions of words and terms.
+ * <p>
+ * The simplest usage of this API may look like the following:
+ * </p>
+ *
+ * <pre>
+ * EPUB epub = new EPUB();
+ * OPSPublication oebps = new OPS2Publication();
+ * oebps.addItem(new File(&quot;chapter.xhtml&quot;));
+ * epub.add(oebps);
+ * epub.pack(new File(&quot;book.epub&quot;));
+ * </pre>
+ * <p>
+ * This will create a new EPUB instance and an OPS (which is the typical content
+ * of an EPUB) with one chapter. The OPS will have one chapter with contents
+ * from <b>chapter.xhtml</b> and the final result is an EPUB named
+ * <b>book.epub</b>.
+ * </p>
+ *
+ * @author Torkild U. Resheim
+ * @see http://www.idpf.org/doc_library/epub/OPS_2.0.1_draft.htm
+ * @see http://www.idpf.org/doc_library/epub/OPF_2.0.1_draft.htm
+ */
+public class EPUB {
+
+ /** Version of the OCF specification used */
+ private static final String OCF_VERSION = "2.0";
+
+ /** OEBPS (OPS+OPF) mimetype */
+ private static final String MIMETYPE_OEBPS = "application/oebps-package+xml";
+
+ /** Suffix for OCF files */
+ private static final String OCF_FILE_SUFFIX = "xml";
+
+ /** The encoding to use for the OCF */
+ private static final String OCF_FILE_ENCODING = "UTF-8";
+
+ /** The container holding all the publications */
+ private Container ocfContainer;
+
+ /**
+ * Creates a new <b>empty</b> instance of an EPUB. Use
+ * {@link #add(OPSPublication)} and {@link #pack(File)} to add publications
+ * and ready the EPUB for distribution.
+ */
+ public EPUB() {
+ ocfContainer = OCFFactory.eINSTANCE.createContainer();
+ RootFiles rootFiles = OCFFactory.eINSTANCE.createRootFiles();
+ ocfContainer.setRootfiles(rootFiles);
+ ocfContainer.setVersion(OCF_VERSION);
+ registerOCFResourceFactory();
+ }
+
+ /**
+ * Returns the container instance of the EPUB.
+ *
+ * @return the container instance
+ */
+ public Container getContainer() {
+ return ocfContainer;
+ }
+
+ /**
+ * Adds a new OEBPS publication to the EPUB. Use {@link #add(File, String)}
+ * to add other types of content.
+ *
+ * @param oebps
+ * the publication to add.
+ */
+ public void add(OPSPublication oebps) {
+ RootFiles rootFiles = ocfContainer.getRootfiles();
+ int count = rootFiles.getRootfiles().size();
+ String rootFileName = count > 0 ? "OEBPS_" + count : "OEBPS";
+ rootFileName += "/content.opf";
+ RootFile rootFile = OCFFactory.eINSTANCE.createRootFile();
+ rootFile.setFullPath(rootFileName);
+ rootFile.setMediaType(MIMETYPE_OEBPS);
+ rootFile.setPublication(oebps);
+ rootFiles.getRootfiles().add(rootFile);
+ }
+
+ /**
+ * Adds a new publication (or root file) to the EPUB. Use
+ * {@link #add(OPSPublication)} when adding an OEBPS publication.
+ *
+ * @param file
+ * the publication to add
+ * @param type
+ * the MIME type of the publication
+ * @see #add(OPSPublication)
+ */
+ public void add(File file, String type) {
+ String name = type.substring(type.lastIndexOf('/') + 1, type.length()).toUpperCase();
+ RootFiles rootFiles = ocfContainer.getRootfiles();
+ int count = rootFiles.getRootfiles().size();
+ String rootFileName = count > 0 ? name + "_" + count : name;
+ rootFileName += File.separator + file.getName();
+ RootFile rootFile = OCFFactory.eINSTANCE.createRootFile();
+ rootFile.setFullPath(rootFileName);
+ rootFile.setMediaType(type);
+ rootFile.setPublication(file);
+ rootFiles.getRootfiles().add(rootFile);
+ }
+
+ /**
+ * Returns a list of all <i>OPS publications</i> contained within the EPUB.
+ *
+ * @return a list of all OPS publications
+ */
+ public List<OPSPublication> getOPSPublications() {
+ ArrayList<OPSPublication> publications = new ArrayList<OPSPublication>();
+ EList<RootFile> rootFiles = ocfContainer.getRootfiles().getRootfiles();
+ for (RootFile rootFile : rootFiles) {
+ if (rootFile.getMediaType().equals(MIMETYPE_OEBPS)) {
+ publications.add((OPSPublication) rootFile.getPublication());
+ }
+ }
+ return publications;
+ }
+
+ /**
+ * Assembles the EPUB file using a temporary working folder. The folder will
+ * be deleted as soon as the assembly has completed.
+ *
+ * @param epubFile
+ * the target EPUB file
+ *
+ * @throws Exception
+ */
+ public File pack(File epubFile) throws Exception {
+ File workingFolder = File.createTempFile("epub_", null);
+ if (workingFolder.delete() && workingFolder.mkdirs()) {
+ pack(epubFile, workingFolder);
+ }
+ deleteFolder(workingFolder);
+ return workingFolder;
+ }
+
+ /**
+ * Assembles the EPUB file using the specified working folder. The contents
+ * of the working folder will <b>not</b> be removed when the operation has
+ * completed. If the temporary data is not interesting, use
+ * {@link #pack(File)} instead.
+ *
+ * @param epubFile
+ * the target EPUB file
+ * @param workingFolder
+ * the working folder
+ * @throws Exception
+ * @see {@link #pack(File)}
+ */
+ public void pack(File epubFile, File workingFolder) throws Exception {
+ if (ocfContainer.getRootfiles().getRootfiles().isEmpty()) {
+ throw new IllegalArgumentException("EPUB does not contain any publications");
+ }
+ workingFolder.mkdirs();
+ if (workingFolder.isDirectory() || workingFolder.mkdirs()) {
+ writeOCF(workingFolder);
+ EList<RootFile> publications = ocfContainer.getRootfiles().getRootfiles();
+ for (RootFile rootFile : publications) {
+ Object publication = rootFile.getPublication();
+ File root = new File(workingFolder.getAbsolutePath() + File.separator + rootFile.getFullPath());
+ if (publication instanceof OPSPublication) {
+ ((OPSPublication) publication).pack(root);
+ } else {
+ if (rootFile.getPublication() instanceof File) {
+ EPUBFileUtil.copy((File) rootFile.getPublication(), root);
+ } else {
+ throw new IllegalArgumentException("Unknown publication type");
+ }
+ }
+ }
+ EPUBFileUtil.zip(epubFile, workingFolder);
+ } else {
+ throw new IOException("Could not create working folder in " + workingFolder.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Reads the <i>Open Container Format (OCF)</i> formatted list of contents
+ * of this EPUB. The result of this operation is placed in the
+ * {@link #ocfContainer} instance.
+ *
+ * @param workingFolder
+ * the folder where the EPUB was unpacked
+ * @throws IOException
+ * @see {@link #unpack(File)}
+ * @see {@link #unpack(File, File)}
+ */
+ protected void readOCF(File workingFolder) throws IOException {
+ // These file names are listed in the OCF specification and must not be
+ // changed.
+ File metaFolder = new File(workingFolder.getAbsolutePath() + File.separator + "META-INF");
+ File containerFile = new File(metaFolder.getAbsolutePath() + File.separator + "container.xml");
+ ResourceSet resourceSet = new ResourceSetImpl();
+ URI fileURI = URI.createFileURI(containerFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ resource.load(null);
+ ocfContainer = (Container) resource.getContents().get(0);
+ }
+
+ /**
+ * Registers a new resource factory for OCF data structures. This is
+ * normally done through Eclipse extension points but we also need to be
+ * able to create this factory without the Eclipse runtime.
+ */
+ private void registerOCFResourceFactory() {
+ // Register package so that it is available even without the Eclipse
+ // runtime
+ @SuppressWarnings("unused")
+ OCFPackage packageInstance = OCFPackage.eINSTANCE;
+
+ // Register the file suffix
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(OCF_FILE_SUFFIX,
+ new XMLResourceFactoryImpl() {
+
+ @Override
+ public Resource createResource(URI uri) {
+ OCFResourceImpl xmiResource = new OCFResourceImpl(uri);
+ Map<Object, Object> loadOptions = xmiResource.getDefaultLoadOptions();
+ Map<Object, Object> saveOptions = xmiResource.getDefaultSaveOptions();
+ // We use extended metadata
+ saveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ // Required in order to correctly read in attributes
+ loadOptions.put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
+ // Treat "href" attributes as features
+ loadOptions.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+ // UTF-8 encoding is required per specification
+ saveOptions.put(XMLResource.OPTION_ENCODING, OCF_FILE_ENCODING);
+ // Do not download any external DTDs.
+ Map<String, Object> parserFeatures = new HashMap<String, Object>();
+ parserFeatures.put("http://xml.org/sax/features/validation", Boolean.FALSE);
+ parserFeatures.put("http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ Boolean.FALSE);
+ loadOptions.put(XMLResource.OPTION_PARSER_FEATURES, parserFeatures);
+ return xmiResource;
+ }
+
+ });
+ }
+
+ /**
+ * Unpacks the EPUB file to a temporary location and populates the data
+ * model with the content.
+ *
+ * @param epubFile
+ * the EPUB file to unpack
+ * @return the location when the EPUB is unpacked
+ * @throws Exception
+ * @see {@link #unpack(File, File)}
+ */
+ public File unpack(File epubFile) throws Exception {
+ File workingFolder = File.createTempFile("epub_", null);
+ workingFolder.deleteOnExit();
+ if (workingFolder.delete() && workingFolder.mkdirs()) {
+ unpack(epubFile, workingFolder);
+ }
+ return workingFolder;
+ }
+
+ /**
+ * Unpacks the given EPUB file into the specified destination and populates
+ * the data model with the content.
+ *
+ * @param epubFile
+ * the EPUB file to unpack
+ * @param destination
+ * the destination folder
+ * @throws Exception
+ * @see {@link #unpack(File)} when destination is not interesting
+ */
+ public void unpack(File epubFile, File destination) throws Exception {
+ EPUBFileUtil.unzip(epubFile, destination);
+ readOCF(destination);
+ EList<RootFile> rootFiles = ocfContainer.getRootfiles().getRootfiles();
+ for (RootFile rootFile : rootFiles) {
+ if (rootFile.getMediaType().equals(MIMETYPE_OEBPS)) {
+ // XXX: Handle this better when adding support for EPUB 3
+ OPSPublication ops = OPSPublication.getVersion2Instance();
+ File root = new File(destination.getAbsolutePath() + File.separator + rootFile.getFullPath());
+ ops.unpack(root);
+ rootFile.setPublication(ops);
+ }
+ }
+ }
+
+ /**
+ * Creates a new folder named META-INF and writes the required (as per the
+ * OPS specification) <b>container.xml</b> in that folder. This is part of
+ * the packing procedure.
+ *
+ * @param workingFolder
+ * the root folder
+ */
+ private void writeOCF(File workingFolder) throws IOException {
+ File metaFolder = new File(workingFolder.getAbsolutePath() + File.separator + "META-INF");
+ if (metaFolder.mkdir()) {
+ File containerFile = new File(metaFolder.getAbsolutePath() + File.separator + "container.xml");
+ ResourceSet resourceSet = new ResourceSetImpl();
+ // Register the packages to make it available during loading.
+ URI fileURI = URI.createFileURI(containerFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ resource.getContents().add(ocfContainer);
+ resource.save(null);
+ }
+ }
+
+ /**
+ * Utility method for deleting a folder recursively.
+ *
+ * @param folder
+ * the folder to delete
+ */
+ private void deleteFolder(File folder) {
+ if (folder.isDirectory()) {
+ String[] children = folder.list();
+ for (int i = 0; i < children.length; i++) {
+ deleteFolder(new File(folder, children[i]));
+ }
+ }
+ folder.delete();
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPS2Publication.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPS2Publication.java
new file mode 100644
index 000000000..96b63f7f6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPS2Publication.java
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.xmi.XMLHelper;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.mylyn.docs.epub.ncx.DocTitle;
+import org.eclipse.mylyn.docs.epub.ncx.Head;
+import org.eclipse.mylyn.docs.epub.ncx.Meta;
+import org.eclipse.mylyn.docs.epub.ncx.NCXFactory;
+import org.eclipse.mylyn.docs.epub.ncx.NCXPackage;
+import org.eclipse.mylyn.docs.epub.ncx.NavMap;
+import org.eclipse.mylyn.docs.epub.ncx.Ncx;
+import org.eclipse.mylyn.docs.epub.ncx.Text;
+import org.eclipse.mylyn.docs.epub.ncx.util.NCXResourceFactoryImpl;
+import org.eclipse.mylyn.docs.epub.ncx.util.NCXResourceImpl;
+import org.eclipse.mylyn.docs.epub.opf.Guide;
+import org.eclipse.mylyn.docs.epub.opf.Item;
+import org.eclipse.mylyn.docs.epub.opf.Itemref;
+import org.eclipse.mylyn.docs.epub.opf.Manifest;
+import org.eclipse.mylyn.docs.epub.opf.Metadata;
+import org.eclipse.mylyn.docs.epub.opf.OPFFactory;
+import org.eclipse.mylyn.docs.epub.opf.Spine;
+import org.eclipse.mylyn.internal.docs.epub.core.EPUBXMLHelperImp;
+import org.eclipse.mylyn.internal.docs.epub.core.OPS2Validator;
+import org.eclipse.mylyn.internal.docs.epub.core.TOCGenerator;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This type represents one EPUB revision 2.0.1 formatted publication. It
+ * maintains a data structure representing the entire publication and API for
+ * building it.
+ * <p>
+ * <b>Please note that this API is provisional and should not yet be used to
+ * build applications.</b>
+ * </p>
+ *
+ * @author Torkild U. Resheim
+ * @see http://www.niso.org/workrooms/daisy/Z39-86-2005.html
+ */
+public class OPS2Publication extends OPSPublication {
+
+ /** MIME type for NCX documents */
+ private static final String MIMETYPE_NCX = "application/x-dtbncx+xml";
+
+ private static final String NCX_FILE_SUFFIX = "ncx";
+
+ /** Identifier of the table of contents file */
+ private static final String TABLE_OF_CONTENTS_ID = "ncx";
+
+ /** Default name for the table of contents */
+ private static final String TOCFILE_NAME = "toc.ncx";
+
+ /** The table of contents */
+ private Ncx ncxTOC;
+
+ /**
+ * Creates a new EPUB.
+ */
+ public OPS2Publication() {
+ super();
+ opfPackage.setVersion("2.0");
+ ncxTOC = NCXFactory.eINSTANCE.createNcx();
+ Metadata opfMetadata = OPFFactory.eINSTANCE.createMetadata();
+ opfPackage.setMetadata(opfMetadata);
+ Guide opfGuide = OPFFactory.eINSTANCE.createGuide();
+ opfPackage.setGuide(opfGuide);
+ Manifest opfManifest = OPFFactory.eINSTANCE.createManifest();
+ opfPackage.setManifest(opfManifest);
+ // Create the spine and set a reference to the table of contents
+ // item which will be added to the manifest on a later stage.
+ Spine opfSpine = OPFFactory.eINSTANCE.createSpine();
+ opfSpine.setToc(TABLE_OF_CONTENTS_ID);
+ opfPackage.setSpine(opfSpine);
+
+ registerNCXResourceFactory();
+ opfPackage.setGenerateTableOfContents(true);
+ }
+
+ /**
+ * This mechanism will traverse the spine of the publication (which is
+ * representing the reading order) and parse each file for information that
+ * can be used to assemble a table of contents.
+ *
+ * @throws SAXException
+ * @throws IOException
+ * @throws ParserConfigurationException
+ */
+ @Override
+ protected void generateTableOfContents() throws Exception {
+ NavMap navMap = NCXFactory.eINSTANCE.createNavMap();
+ ncxTOC.setNavMap(navMap);
+ ncxTOC.setVersion("2005-1");
+ // Create the required head element
+ Head head = NCXFactory.eINSTANCE.createHead();
+ ncxTOC.setHead(head);
+ Meta meta = NCXFactory.eINSTANCE.createMeta();
+ meta.setName("dtb:uid");
+ meta.setContent(getIdentifier().getMixed().getValue(0).toString());
+ head.getMetas().add(meta);
+ DocTitle docTitle = NCXFactory.eINSTANCE.createDocTitle();
+ Text text = NCXFactory.eINSTANCE.createText();
+ FeatureMapUtil.addText(text.getMixed(), "Table of contents");
+ docTitle.setText(text);
+ ncxTOC.setDocTitle(docTitle);
+ int playOrder = 0;
+ // Iterate over the spine
+ EList<Itemref> spineItems = getSpine().getSpineItems();
+ EList<Item> manifestItems = opfPackage.getManifest().getItems();
+ for (Itemref itemref : spineItems) {
+ Item referencedItem = null;
+ String id = itemref.getIdref();
+ // Find the manifest item that is referenced
+ for (Item item : manifestItems) {
+ if (item.getId().equals(id)) {
+ referencedItem = item;
+ break;
+ }
+ }
+ if (referencedItem != null && !referencedItem.isNoToc()) {
+ File file = new File(referencedItem.getFile());
+ FileInputStream fis = new FileInputStream(file);
+ playOrder = TOCGenerator.parse(new InputSource(fis), referencedItem.getHref(), ncxTOC, playOrder);
+ }
+ }
+ }
+
+ @Override
+ public Object getTableOfContents() {
+ return ncxTOC;
+ }
+
+ @Override
+ protected void readTableOfContents(File tocFile) throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ URI fileURI = URI.createFileURI(tocFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ resource.load(null);
+ ncxTOC = (Ncx) resource.getContents().get(0);
+ }
+
+ /**
+ * Registers a new resource factory for NCX data structures. This is
+ * normally done through Eclipse extension points but we also need to be
+ * able to create this factory without the Eclipse runtime.
+ */
+ private void registerNCXResourceFactory() {
+ // Register package so that it is available even without the Eclipse
+ // runtime
+ @SuppressWarnings("unused")
+ NCXPackage packageInstance = NCXPackage.eINSTANCE;
+
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(NCX_FILE_SUFFIX,
+ new NCXResourceFactoryImpl() {
+ @Override
+ public Resource createResource(URI uri) {
+ NCXResourceImpl xmiResource = new NCXResourceImpl(uri) {
+
+ @Override
+ protected XMLHelper createXMLHelper() {
+ EPUBXMLHelperImp xmlHelper = new EPUBXMLHelperImp();
+ return xmlHelper;
+ }
+
+ };
+ Map<Object, Object> loadOptions = xmiResource.getDefaultLoadOptions();
+ Map<Object, Object> saveOptions = xmiResource.getDefaultSaveOptions();
+ // We use extended metadata
+ saveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ // Required in order to correctly read in attributes
+ loadOptions.put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
+ // Treat "href" attributes as features
+ loadOptions.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+ // UTF-8 encoding is required per specification
+ saveOptions.put(XMLResource.OPTION_ENCODING, XML_ENCODING);
+ // Do not download any external DTDs.
+ Map<String, Object> parserFeatures = new HashMap<String, Object>();
+ parserFeatures.put("http://xml.org/sax/features/validation", Boolean.FALSE);
+ parserFeatures.put("http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ Boolean.FALSE);
+ loadOptions.put(XMLResource.OPTION_PARSER_FEATURES, parserFeatures);
+ return xmiResource;
+ }
+
+ });
+ }
+
+ @Override
+ public void setTableOfContents(File ncxFile) {
+ // Add the file to the publication and make sure we use the table of
+ // contents identifier.
+ Item item = addItem(opfPackage.getSpine().getToc(), null, ncxFile, null, MIMETYPE_NCX, false, false, false);
+ // The table of contents file must be first.
+ opfPackage.getManifest().getItems().move(0, item);
+
+ }
+
+ /**
+ * This method will only validate items that are in the spine, or in reading
+ * order.
+ */
+ @Override
+ protected List<ValidationMessage> validateContents() throws Exception {
+ EList<Itemref> spineItems = getSpine().getSpineItems();
+ EList<Item> manifestItems = opfPackage.getManifest().getItems();
+ ArrayList<ValidationMessage> messages = new ArrayList<ValidationMessage>();
+ for (Itemref itemref : spineItems) {
+ Item referencedItem = null;
+ String id = itemref.getIdref();
+ // Find the manifest item that is referenced
+ for (Item item : manifestItems) {
+ if (item.getId().equals(id)) {
+ referencedItem = item;
+ break;
+ }
+ }
+ if (referencedItem != null && !referencedItem.isNoToc()) {
+ File file = new File(referencedItem.getFile());
+ FileReader fr = new FileReader(file);
+ messages.addAll(OPS2Validator.validate(new InputSource(fr), referencedItem.getHref()));
+ }
+ }
+ return messages;
+ }
+
+ /**
+ * Writes the table of contents file in the specified folder using the NCX
+ * format. If a table of contents file has not been specified an empty one
+ * will be created (since it is required to have one). If in addition it has
+ * been specified that the table of contents should be created, the content
+ * files will be parsed and a TOC will be generated.
+ *
+ * @param oepbsFolder
+ * the folder to create the NCX file in
+ * @throws IOException
+ * @throws SAXException
+ * @throws ParserConfigurationException
+ * @see {@link #setTableOfContents(File)}
+ */
+ @Override
+ protected void writeTableOfContents(File oepbsFolder) throws Exception {
+ // If a table of contents file has not been specified we must create
+ // one. If it has been specified it will be copied.
+ if (getItemById(opfPackage.getSpine().getToc()) == null) {
+ File ncxFile = new File(oepbsFolder.getAbsolutePath() + File.separator + TOCFILE_NAME);
+ ResourceSet resourceSet = new ResourceSetImpl();
+ // Register the packages to make it available during loading.
+ resourceSet.getPackageRegistry().put(NCXPackage.eNS_URI, NCXPackage.eINSTANCE);
+ URI fileURI = URI.createFileURI(ncxFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ // We've been asked to generate a table of contents using pages
+ // contained in the spine.
+ if (opfPackage.isGenerateTableOfContents()) {
+ generateTableOfContents();
+ }
+ resource.getContents().add(ncxTOC);
+ Map<String, Object> options = new HashMap<String, Object>();
+ // NCX requires that we encode using UTF-8
+ options.put(XMLResource.OPTION_ENCODING, XML_ENCODING);
+ options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ resource.save(options);
+ // Make sure the table of contents file is in the manifest and
+ // referenced in the spine. We also want it to be the first element
+ // in the manifest.
+ Item item = addItem(opfPackage.getSpine().getToc(), null, ncxFile, null, MIMETYPE_NCX, false, false, false);
+ opfPackage.getManifest().getItems().move(0, item);
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPSPublication.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPSPublication.java
new file mode 100644
index 000000000..6b66916df
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPSPublication.java
@@ -0,0 +1,1166 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.core;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.util.EcoreValidator;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.xmi.XMLHelper;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;
+import org.eclipse.mylyn.docs.epub.dc.Contributor;
+import org.eclipse.mylyn.docs.epub.dc.Coverage;
+import org.eclipse.mylyn.docs.epub.dc.Creator;
+import org.eclipse.mylyn.docs.epub.dc.DCFactory;
+import org.eclipse.mylyn.docs.epub.dc.DCType;
+import org.eclipse.mylyn.docs.epub.dc.Date;
+import org.eclipse.mylyn.docs.epub.dc.Description;
+import org.eclipse.mylyn.docs.epub.dc.Format;
+import org.eclipse.mylyn.docs.epub.dc.Identifier;
+import org.eclipse.mylyn.docs.epub.dc.Language;
+import org.eclipse.mylyn.docs.epub.dc.LocalizedDCType;
+import org.eclipse.mylyn.docs.epub.dc.Publisher;
+import org.eclipse.mylyn.docs.epub.dc.Relation;
+import org.eclipse.mylyn.docs.epub.dc.Rights;
+import org.eclipse.mylyn.docs.epub.dc.Source;
+import org.eclipse.mylyn.docs.epub.dc.Subject;
+import org.eclipse.mylyn.docs.epub.dc.Title;
+import org.eclipse.mylyn.docs.epub.opf.Item;
+import org.eclipse.mylyn.docs.epub.opf.Itemref;
+import org.eclipse.mylyn.docs.epub.opf.OPFFactory;
+import org.eclipse.mylyn.docs.epub.opf.OPFPackage;
+import org.eclipse.mylyn.docs.epub.opf.Package;
+import org.eclipse.mylyn.docs.epub.opf.Reference;
+import org.eclipse.mylyn.docs.epub.opf.Role;
+import org.eclipse.mylyn.docs.epub.opf.Spine;
+import org.eclipse.mylyn.docs.epub.opf.Type;
+import org.eclipse.mylyn.docs.epub.opf.util.OPFResourceImpl;
+import org.eclipse.mylyn.internal.docs.epub.core.EPUBFileUtil;
+import org.eclipse.mylyn.internal.docs.epub.core.EPUBXMLHelperImp;
+import org.eclipse.mylyn.internal.docs.epub.core.ReferenceScanner;
+import org.xml.sax.SAXException;
+
+/**
+ * This type represents one <i>OPS publication</i>. This includes the <i>OPF
+ * package document</i> and <i>OPS content documents</i>. It maintains a data
+ * structure representing the entire publication and API for building it.
+ * <p>
+ * Please note that this API is provisional and should not yet be used to build
+ * applications.
+ * </p>
+ *
+ * @author Torkild U. Resheim
+ */
+public abstract class OPSPublication {
+ // Rules of engagement:
+ // * Keep all data in the model, use "transient" for temporary properties
+ // * Do not actually do anything before the final assemble
+
+ /** Default identifier for the cover page */
+ private static final String COVER_ID = "cover";
+
+ /** Publication identifier for the cover image item */
+ public static final String COVER_IMAGE_ID = "cover-image";
+
+ protected static final String CREATION_DATE_ID = "creation";
+
+ public final static String MIMETYPE_CSS = "text/css";
+
+ public static final String MIMETYPE_EPUB = "application/epub+zip";
+
+ public static final String MIMETYPE_XHTML = "application/xhtml+xml";
+
+ private static final String OPF_FILE_SUFFIX = "opf";
+
+ protected static final String UUID_SCHEME = "uuid";
+
+ /** The encoding to use in XML files */
+ protected static final String XML_ENCODING = "UTF-8";
+
+ /**
+ * Returns an EPUB version 2.0.1 instance.
+ *
+ * @return an EPUB instance
+ */
+ public static OPSPublication getVersion2Instance() {
+ return new OPS2Publication();
+ }
+
+ /** List of validation messages */
+ public List<ValidationMessage> messages;
+
+ /** The root model element */
+ protected Package opfPackage;
+
+ /** The root folder TODO: Move to opfPackage */
+ private File rootFolder;
+
+ protected OPSPublication() {
+ opfPackage = OPFFactory.eINSTANCE.createPackage();
+ registerOPFResourceFactory();
+ }
+
+ /**
+ * Adds data to the publication that we always want to be present.
+ * <ul>
+ * <li>The creation date.</li>
+ * <li><i>Eclipse Mylyn Docs project</i> as contributor redactor role.</li>
+ * <li>A unique identifier if none has been specified.</li>
+ * <li>A empty description if none has been specified.</li>
+ * <li>Language "English" if none has been specified.</li>
+ * <li>A dummy title if none has been specified.</li>
+ * <li>The publication format if none has been specified.</li>
+ * </ul>
+ */
+ private void addCompulsoryData() {
+ // Creation date is always when we build
+ addDate(null, new java.util.Date(System.currentTimeMillis()), CREATION_DATE_ID);
+ // Make it clear where the tooling comes from
+ addContributor(null, null, "Eclipse Mylyn Docs project", Role.REDACTOR, null);
+ // Generate an unique identifier
+ if (getIdentifier() == null) {
+ addIdentifier(UUID_SCHEME, "uuid", "urn:uuid" + UUID.randomUUID().toString());
+ setIdentifierId(UUID_SCHEME);
+ }
+ // Add empty subject
+ if (opfPackage.getMetadata().getSubjects().isEmpty()) {
+ addSubject(null, null, "");
+ }
+ // Add English language
+ if (opfPackage.getMetadata().getLanguages().isEmpty()) {
+ addLanguage(null, Locale.ENGLISH.toString());
+ }
+ // Add dummy title
+ if (opfPackage.getMetadata().getTitles().isEmpty()) {
+ addTitle(null, null, "No title specified");
+ }
+ // Set the publication format
+ if (opfPackage.getMetadata().getFormats().isEmpty()) {
+ addFormat(null, MIMETYPE_EPUB);
+ }
+ }
+
+ /**
+ * Specifies a new contributor for the publication.
+ *
+ * @param id
+ * an identifier or <code>null</code>
+ * @param name
+ * name of the creator
+ * @param role
+ * the role or <code>null</code>
+ * @param fileAs
+ * name to file the creator under or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @return the new creator
+ */
+ public Contributor addContributor(String id, Locale lang, String name, Role role, String fileAs) {
+ Contributor dc = DCFactory.eINSTANCE.createContributor();
+ setDcLocalized(dc, id, lang, name);
+ if (role != null) {
+ dc.setRole(role);
+ }
+ if (fileAs != null) {
+ dc.setFileAs(fileAs);
+ }
+ opfPackage.getMetadata().getContributors().add(dc);
+ return dc;
+ }
+
+ /**
+ * Specifies a new &quot;coverage&quot; for the publication.
+ *
+ * @param id
+ * an identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * value of the item
+ * @return the new coverage
+ */
+ public Coverage addCoverage(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Coverage dc = DCFactory.eINSTANCE.createCoverage();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getCoverages().add(dc);
+ return dc;
+ }
+
+ /**
+ * Specifies a new creator for the publication.
+ *
+ * @param id
+ * a unique identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param name
+ * name of the creator
+ * @param role
+ * the role or <code>null</code>
+ * @param fileAs
+ * name to file the creator under or <code>null</code>
+ * @return the new creator
+ */
+ public Creator addCreator(String id, Locale lang, String name, Role role, String fileAs) {
+ Creator dc = DCFactory.eINSTANCE.createCreator();
+ setDcLocalized(dc, id, lang, name);
+ if (role != null) {
+ dc.setRole(role);
+ }
+ if (fileAs != null) {
+ dc.setFileAs(fileAs);
+ }
+ opfPackage.getMetadata().getCreators().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a new date to the publication. The given instance will be
+ * represented in a format defined by "Date and Time Formats" at
+ * http://www.w3.org/TR/NOTE-datetime and by ISO 8601 on which it is based.
+ *
+ * @param id
+ * optional identifier
+ * @param date
+ * the date
+ * @param event
+ * the event
+ * @return the new date
+ * @see #addDate(String, String, String)
+ */
+ public Date addDate(String id, java.util.Date date, String event) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ df.setTimeZone(tz);
+ Date dc = DCFactory.eINSTANCE.createDate();
+ setDcCommon(dc, id, df.format(date));
+ if (event != null) {
+ dc.setEvent(event);
+ }
+ opfPackage.getMetadata().getDates().add(dc);
+ return dc;
+ }
+
+ /**
+ * Date of publication, in the format defined by the W3C specification
+ * "<a href="http://www.w3.org/TR/NOTE-datetime">Date and Time Formats</a>"
+ * and by ISO 8601. In particular, dates without times must be represented
+ * in the form YYYY[-MM[-DD]]: a required 4-digit year, an optional 2-digit
+ * month, and if the month is given, an optional 2-digit day of month. The
+ * event attribute is optional, possible values may include: "creation",
+ * "publication", and "modification".
+ *
+ * @param value
+ * the date string
+ * @param event
+ * an optional event description
+ * @return the new date
+ */
+ public Date addDate(String id, String value, String event) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Date dc = DCFactory.eINSTANCE.createDate();
+ setDcCommon(dc, id, value);
+ if (event != null) {
+ dc.setEvent(event);
+ }
+ opfPackage.getMetadata().getDates().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a new description to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the description text
+ * @return the new description
+ */
+ public Description addDescription(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Description dc = DCFactory.eINSTANCE.createDescription();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getDescriptions().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds an optional publication format.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param value
+ * the format to add
+ * @return the new format
+ */
+ public Format addFormat(String id, String value) {
+ Format dc = DCFactory.eINSTANCE.createFormat();
+ setDcCommon(dc, id, value);
+ opfPackage.getMetadata().getFormats().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a new identifier to the publication.
+ *
+ * @param id
+ * the identifier id
+ * @param scheme
+ * the scheme used for representing the identifier
+ * @param value
+ * the identifier value
+ * @return the new identifier
+ */
+ public Identifier addIdentifier(String id, String scheme, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Identifier dc = DCFactory.eINSTANCE.createIdentifier();
+ dc.setId(id);
+ dc.setScheme(scheme);
+ FeatureMapUtil.addText(dc.getMixed(), value);
+ opfPackage.getMetadata().getIdentifiers().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a new item to the manifest using default values for properties not
+ * specified. Same as
+ * <code>addItem(null, null, file, null, null, true, false);</code>.
+ *
+ * @param file
+ * @return the new item
+ */
+ public Item addItem(File file) {
+ return addItem(null, null, file, null, null, true, true, false);
+ }
+
+ /**
+ * Adds a new item to the manifest. If an identifier is not specified it
+ * will automatically be assigned.
+ *
+ * <p>
+ * The <i>spine</i> defines the reading order, so the order items are added
+ * and whether or not <i>spine</i> is <code>true</code> does matter. Unless
+ * a table of contents file has been specified it will be generated. All
+ * files that have been added to the spine will be examined unless the
+ * <i>noToc</i> attribute has been set to <code>true</code>.
+ * </p>
+ *
+ * @param file
+ * the file to add
+ * @param dest
+ * the destination sub-folder or <code>null</code>
+ * @param id
+ * identifier or <code>null</code>
+ * @param type
+ * MIME file type
+ * @param spine
+ * whether or not to add the item to the spine
+ * @param linear
+ * whether or not the item is part of the reading order
+ * @param noToc
+ * whether or not to include in TOC when automatically generated
+ * @return the new item
+ */
+ public Item addItem(String id, Locale lang, File file, String dest, String type, boolean spine, boolean linear,
+ boolean noToc) {
+ if (file == null || !file.exists()) {
+ throw new IllegalArgumentException("\"file\" " + file.getAbsolutePath() + " must exist.");
+ }
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException("\"file\" " + file.getAbsolutePath() + " must not be a directory.");
+ }
+ Item item = OPFFactory.eINSTANCE.createItem();
+ if (type == null) {
+ type = EPUBFileUtil.getMimeType(file);
+ if (type == null) {
+ throw new IllegalArgumentException("Could not automatically determine MIME type for file " + file
+ + ". Please specify the correct value");
+ }
+ }
+ if (id == null) {
+ String prefix = "";
+ if (!type.equals(MIMETYPE_XHTML)) {
+ prefix = (type.indexOf('/')) == -1 ? type : type.substring(0, type.indexOf('/')) + "-";
+ }
+ id = prefix + file.getName().substring(0, file.getName().lastIndexOf('.'));
+ }
+ item.setId(id);
+ if (dest == null) {
+ item.setHref(file.getName());
+ } else {
+ item.setHref(dest + '/' + file.getName());
+ }
+ item.setNoToc(noToc);
+ item.setMedia_type(type);
+ item.setFile(file.getAbsolutePath());
+ opfPackage.getManifest().getItems().add(item);
+ if (spine) {
+ Itemref ref = OPFFactory.eINSTANCE.createItemref();
+ if (!linear) {
+ ref.setLinear("no");
+ }
+ ref.setIdref(id);
+ getSpine().getSpineItems().add(ref);
+ }
+ return item;
+ }
+
+ /**
+ * Adds a new language specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param lang
+ * the RFC-3066 format of the language code
+ * @return the language instance
+ */
+ public Language addLanguage(String id, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Language dc = DCFactory.eINSTANCE.createLanguage();
+ setDcCommon(dc, id, value);
+ opfPackage.getMetadata().getLanguages().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a new meta item to the publication.
+ *
+ * @param name
+ * name of the item
+ * @param value
+ * content of the item
+ * @return the new meta
+ */
+ public org.eclipse.mylyn.docs.epub.opf.Meta addMeta(String name, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException("A name must be specified");
+ }
+ org.eclipse.mylyn.docs.epub.opf.Meta opf = OPFFactory.eINSTANCE.createMeta();
+ opf.setName(name);
+ opf.setContent(value);
+ opfPackage.getMetadata().getMetas().add(opf);
+ return opf;
+ }
+
+ /**
+ * Adds a new publisher to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * name of the publisher
+ * @return the new publisher
+ */
+ public Publisher addPublisher(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Publisher dc = DCFactory.eINSTANCE.createPublisher();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getPublishers().add(dc);
+ return dc;
+ }
+
+ /**
+ * The structural components of the books are listed in reference elements
+ * contained within the guide element. These components could refer to the
+ * table of contents, list of illustrations, foreword, bibliography, and
+ * many other standard parts of the book. Reading systems are not required
+ * to use the guide element but it is a good idea to use it.
+ *
+ * @param href
+ * the item referenced
+ * @param title
+ * title of the reference
+ * @param value
+ * type of the reference
+ * @return the reference
+ */
+ public Reference addReference(String href, String title, Type value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ if (href == null) {
+ throw new IllegalArgumentException("A href must be specified");
+ }
+ if (title == null) {
+ throw new IllegalArgumentException("A title must be specified");
+ }
+ Reference reference = OPFFactory.eINSTANCE.createReference();
+ reference.setHref(href);
+ reference.setTitle(title);
+ reference.setType(value);
+ opfPackage.getGuide().getGuideItems().add(reference);
+ return reference;
+ }
+
+ /**
+ * Adds a optional <i>relation</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the value of the relation
+ * @return the new relation
+ */
+ public Relation addRelation(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Relation dc = DCFactory.eINSTANCE.createRelation();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getRelations().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a optional <i>rights</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the rights text
+ * @return the new rights element
+ */
+ public Rights addRights(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Rights dc = DCFactory.eINSTANCE.createRights();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getRights().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a optional <i>source</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the source text
+ * @return the new source element
+ */
+ public Source addSource(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Source dc = DCFactory.eINSTANCE.createSource();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getSources().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a required <i>subject</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the subject
+ */
+ public Subject addSubject(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Subject dc = DCFactory.eINSTANCE.createSubject();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getSubjects().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a required <i>title</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param lang
+ * the language code or <code>null</code>
+ * @param value
+ * the new title
+ * @return the new title
+ */
+ public Title addTitle(String id, Locale lang, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ Title dc = DCFactory.eINSTANCE.createTitle();
+ setDcLocalized(dc, id, lang, value);
+ opfPackage.getMetadata().getTitles().add(dc);
+ return dc;
+ }
+
+ /**
+ * Adds a optional <i>type</i> specification to the publication.
+ *
+ * @param id
+ * identifier or <code>null</code>
+ * @param type
+ * the type to add
+ * @return the new type
+ */
+ public org.eclipse.mylyn.docs.epub.dc.Type addType(String id, String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("A value must be specified");
+ }
+ org.eclipse.mylyn.docs.epub.dc.Type dc = DCFactory.eINSTANCE.createType();
+ setDcCommon(dc, id, value);
+ opfPackage.getMetadata().getTypes().add(dc);
+ return dc;
+ }
+
+ /**
+ * Copies all items part of the publication into the OEPBS folder unless the
+ * item in question will be generated.
+ *
+ * @param rootFolder
+ * the folder to copy into.
+ * @throws IOException
+ */
+ private void copyContent(File rootFolder) throws IOException {
+ EList<Item> items = opfPackage.getManifest().getItems();
+ for (Item item : items) {
+ if (!item.isGenerated()) {
+ File source = new File(item.getFile());
+ File destination = new File(rootFolder.getAbsolutePath() + File.separator + item.getHref());
+ EPUBFileUtil.copy(source, destination);
+ }
+ }
+ }
+
+ /**
+ * Implement to handle generation of table of contents from the items added
+ * to the <i>spine</i>.
+ *
+ * @throws Exception
+ */
+ protected abstract void generateTableOfContents() throws Exception;
+
+ /**
+ * Returns the main identifier of the publication or <code>null</code> if it
+ * could not be determined.
+ *
+ * @return the main identifier or <code>null</code>
+ */
+ public Identifier getIdentifier() {
+ EList<Identifier> identifiers = opfPackage.getMetadata().getIdentifiers();
+ for (Identifier identifier : identifiers) {
+ if (identifier.getId().equals(opfPackage.getUniqueIdentifier())) {
+ return identifier;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Locates and returns an item from the manifest corresponding to the given
+ * identifier.
+ *
+ * @param id
+ * the identifier
+ * @return the item
+ */
+ public Item getItemById(String id) {
+ EList<Item> items = opfPackage.getManifest().getItems();
+ for (Item item : items) {
+ if (item.getId().equals(id)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a list of all manifest items that have the specified MIME type.
+ *
+ * @param mimetype
+ * the MIME type to search for
+ * @return a list of all items
+ */
+ public List<Item> getItemsByMIMEType(String mimetype) {
+ ArrayList<Item> stylesheets = new ArrayList<Item>();
+ EList<Item> items = opfPackage.getManifest().getItems();
+ for (Item item : items) {
+ if (item.getMedia_type().equals(mimetype)) {
+ stylesheets.add(item);
+ }
+ }
+ return stylesheets;
+ }
+
+ public Package getOpfPackage() {
+ return opfPackage;
+ }
+
+ /**
+ * Returns the root folder of the publication. This is the folder where the
+ * OPF file resides. Note that this property will only have a value if this
+ * instance has been populated using an existing publication, such as when
+ * unpacking an EPUB file.
+ *
+ * @return the root folder or <code>null</code>
+ */
+ public File getRootFolder() {
+ return rootFolder;
+ }
+
+ /**
+ * Returns the publication spine.
+ *
+ * @return the spine
+ */
+ protected Spine getSpine() {
+ return opfPackage.getSpine();
+ }
+
+ /**
+ * Returns the table of contents for the publication. As the actual
+ * implementation may vary depending on
+ *
+ * @return the table of contents
+ */
+ public abstract Object getTableOfContents();
+
+ /**
+ * Returns a list of validation messages. This list is only populated when
+ * {@link #pack(File)} has taken place.
+ *
+ * @return a list of validation messages
+ */
+ public List<ValidationMessage> getValidationMessages() {
+ return messages;
+ }
+
+ /**
+ * Iterates over all files in the manifest attempting to determine
+ * referenced resources such as image files and adds these to the manifest.
+ *
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ private void includeReferencedResources() throws ParserConfigurationException, SAXException, IOException {
+ EList<Item> manifestItems = opfPackage.getManifest().getItems();
+ // Compose a list of file references
+ HashMap<File, List<File>> references = new HashMap<File, List<File>>();
+ for (Item item : manifestItems) {
+ // Only parse XHTML-files and files that are not generated
+ if (item.getMedia_type().equals(MIMETYPE_XHTML) && !item.isGenerated()) {
+ if (item.getSourcePath() != null) {
+ File source = new File(item.getSourcePath());
+ references.put(source, ReferenceScanner.parse(item));
+ } else {
+ File source = new File(item.getFile());
+ references.put(source, ReferenceScanner.parse(item));
+ }
+ }
+ }
+ for (File root : references.keySet()) {
+ List<File> files = references.get(root);
+ for (File file : files) {
+ File relativePath = new File(EPUBFileUtil.getRelativePath(root, file));
+ addItem(null, null, file, relativePath.getParent(), null, false, false, false);
+ }
+ }
+
+ }
+
+ /**
+ * Assembles the OPS publication in a location relative to the root file.
+ *
+ * @param rootFile
+ * the root file
+ * @throws Exception
+ */
+ void pack(File rootFile) throws Exception {
+ if (opfPackage.getSpine().getSpineItems().isEmpty()) {
+ throw new IllegalArgumentException("Spine does not contain any items");
+ }
+ // Note that order is important here. Some of the steps for assembling
+ // the EPUB may insert data into the EPUB structure. Hence the OPF must
+ // be written last.
+ this.rootFolder = rootFile.getAbsoluteFile().getParentFile();
+ addCompulsoryData();
+ if (rootFolder.isDirectory() || rootFolder.mkdirs()) {
+ if (opfPackage.isGenerateCoverHTML()) {
+ writeCoverHTML(rootFolder);
+ }
+ if (opfPackage.isIncludeReferencedResources()) {
+ includeReferencedResources();
+ }
+ copyContent(rootFolder);
+ messages = validateContents();
+ writeTableOfContents(rootFolder);
+ writeOPF(rootFile);
+ } else {
+ throw new IOException("Could not create OEBPS folder in " + rootFolder.getAbsolutePath());
+ }
+ validateMetadata();
+ }
+
+ /**
+ * Reads the root file.
+ *
+ * @param rootFile
+ * the file to read
+ * @throws IOException
+ */
+ protected void readOPF(File rootFile) throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ URI fileURI = URI.createFileURI(rootFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ resource.load(null);
+ opfPackage = (Package) resource.getContents().get(0);
+ }
+
+ /**
+ * Implement to read the table of contents for the particular OEPBS
+ * implementation.
+ *
+ * @param tocFile
+ * the table of contents file
+ * @throws IOException
+ */
+ protected abstract void readTableOfContents(File tocFile) throws IOException;
+
+ /**
+ * Registers a new resource factory for OPF data structures. This is
+ * normally done through Eclipse extension points but we also need to be
+ * able to create this factory without the Eclipse runtime.
+ */
+ private void registerOPFResourceFactory() {
+ // Register package so that it is available even without the Eclipse
+ // runtime
+ @SuppressWarnings("unused")
+ OPFPackage packageInstance = OPFPackage.eINSTANCE;
+
+ // Register the file suffix
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(OPF_FILE_SUFFIX,
+ new XMLResourceFactoryImpl() {
+
+ @Override
+ public Resource createResource(URI uri) {
+ OPFResourceImpl xmiResource = new OPFResourceImpl(uri) {
+
+ @Override
+ protected XMLHelper createXMLHelper() {
+ EPUBXMLHelperImp xmlHelper = new EPUBXMLHelperImp();
+ return xmlHelper;
+ }
+
+ };
+ Map<Object, Object> loadOptions = xmiResource.getDefaultLoadOptions();
+ Map<Object, Object> saveOptions = xmiResource.getDefaultSaveOptions();
+ // We use extended metadata
+ saveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ // Required in order to correctly read in attributes
+ loadOptions.put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
+ // Treat "href" attributes as features
+ loadOptions.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+ // UTF-8 encoding is required per specification
+ saveOptions.put(XMLResource.OPTION_ENCODING, XML_ENCODING);
+ // Do not download any external DTDs.
+ Map<String, Object> parserFeatures = new HashMap<String, Object>();
+ parserFeatures.put("http://xml.org/sax/features/validation", Boolean.FALSE);
+ parserFeatures.put("http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ Boolean.FALSE);
+ loadOptions.put(XMLResource.OPTION_PARSER_FEATURES, parserFeatures);
+ return xmiResource;
+ }
+
+ });
+ }
+
+ /**
+ * Convenience method for adding a cover to the publication. This method
+ * will make sure the required actions are taken to provide a cover page for
+ * all reading systems.
+ *
+ * @param image
+ * the cover image (jpeg, png, svg or gif)
+ * @param title
+ * title of the cover page
+ */
+ public void setCover(File image, String title) {
+ // Add the cover image to the manifest
+ Item item = addItem(COVER_IMAGE_ID, null, image, null, null, false, false, true);
+ item.setTitle(title);
+ // Point to the cover using a meta tag
+ addMeta(COVER_ID, COVER_IMAGE_ID);
+ opfPackage.setGenerateCoverHTML(true);
+
+ }
+
+ /**
+ * Sets common properties for <i>Dublin Core</i> elements.
+ *
+ * @param dc
+ * the Dublin Core element
+ * @param id
+ * optional identifier
+ * @param value
+ * value of the element
+ */
+ private void setDcCommon(DCType dc, String id, String value) {
+ FeatureMapUtil.addText(dc.getMixed(), value);
+ if (id != null) {
+ dc.setId(id);
+ }
+ }
+
+ /**
+ * Sets common properties for localized <i>Dublin Core</i> elements.
+ *
+ * @param dc
+ * the Dublin Core element
+ * @param id
+ * optional identifier
+ * @param lang
+ * language code
+ * @param value
+ * value of the element
+ */
+ private void setDcLocalized(LocalizedDCType dc, String id, Locale lang, String value) {
+ setDcCommon(dc, id, value);
+ if (lang != null) {
+ dc.setLang(lang.toString());
+ }
+ }
+
+ /**
+ * Specifies whether or not to automatically generate table of contents from
+ * the publication contents. The default is <code>true</code>
+ *
+ * @param generateToc
+ * whether or not to generate a table of contents
+ */
+ public void setGenerateToc(boolean generateToc) {
+ opfPackage.setGenerateTableOfContents(generateToc);
+ }
+
+ /**
+ * Specifies the id of the identifier used for the publication.
+ *
+ * @param identifier_id
+ * the identifier id
+ * @see #addIdentifier(String, String, String)
+ */
+ public void setIdentifierId(String identifier_id) {
+ opfPackage.setUniqueIdentifier(identifier_id);
+ }
+
+ /**
+ * Specifies whether or not to automatically include resources (files) that
+ * are referenced in the contents. The default is <code>false</code>.
+ *
+ * @param include
+ * whether or not automatically include resources
+ */
+ public void setIncludeReferencedResources(boolean include) {
+ opfPackage.setIncludeReferencedResources(include);
+ }
+
+ /**
+ * Specifies a target of contents file for the publication. This is an
+ * alternative to {@link #setGenerateToc(boolean)}.
+ *
+ * @param tocFile
+ * the table of contents file
+ */
+ public abstract void setTableOfContents(File tocFile);
+
+ /**
+ * Populates the data model with the content from an unpacked EPUB.
+ *
+ * @param epubFile
+ * the EPUB file to unpack
+ * @param destination
+ * the destination folder
+ * @throws Exception
+ */
+ void unpack(File rootFile) throws Exception {
+ readOPF(rootFile);
+ rootFolder = rootFile.getAbsoluteFile().getParentFile();
+ String tocId = opfPackage.getSpine().getToc();
+ Item tocItem = getItemById(tocId);
+ File tocFile = new File(rootFolder.getAbsolutePath() + File.separator + tocItem.getHref());
+ readTableOfContents(tocFile);
+ }
+
+ /**
+ * Implement to validate contents.
+ *
+ * @throws Exception
+ */
+ protected abstract List<ValidationMessage> validateContents() throws Exception;
+
+ /**
+ * Validates the data model contents.
+ *
+ * @return a list of EMF diagnostics
+ */
+ public List<Diagnostic> validateMetadata() {
+ EValidator.Registry.INSTANCE.put(OPFPackage.eINSTANCE, new EcoreValidator());
+ BasicDiagnostic diagnostics = new BasicDiagnostic();
+ for (EObject eo : opfPackage.eContents()) {
+ Map<Object, Object> context = new HashMap<Object, Object>();
+ Diagnostician.INSTANCE.validate(eo, diagnostics, context);
+ }
+ return diagnostics.getChildren();
+ }
+
+ /**
+ * Writes a XHTML-file for the cover image. This is added to the publication
+ * and all required references set.
+ *
+ * @param rootFolder
+ * the publication root folder
+ * @throws IOException
+ *
+ */
+ private void writeCoverHTML(File rootFolder) throws IOException {
+ Item coverImage = getItemById(COVER_IMAGE_ID);
+ File coverFile = new File(rootFolder.getAbsolutePath() + File.separator + "cover-page.xhtml");
+ if (!coverFile.exists()) {
+
+ try {
+ FileWriter fw = new FileWriter(coverFile);
+ fw.append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n");
+ fw.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
+ fw.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");
+ fw.append(" <head>\n");
+ fw.append(" <title>" + coverImage.getTitle() + "</title>\n");
+ fw.append(" <style type=\"text/css\">");
+ fw.append(" #cover-body {\n");
+ fw.append(" margin: 0px;\n");
+ fw.append(" text-align: center;\n");
+ fw.append(" background-color: #222222;\n");
+ fw.append(" }\n");
+ fw.append(" #cover-block {\n");
+ fw.append(" height: 100%;\n");
+ fw.append(" margin-top: 0;\n");
+ fw.append(" }\n");
+ fw.append(" #cover-image {\n");
+ fw.append(" height: 100%;\n");
+ fw.append(" text-align: center;\n");
+ fw.append(" max-width: 100%;\n");
+ fw.append(" }\n");
+ fw.append(" </style>\n");
+ fw.append(" </head>\n");
+ fw.append(" <body id=\"cover-body\">\n");
+ fw.append(" <div id=\"cover-block\">\n");
+ fw.append(" <img id=\"cover-image\" src=\"" + coverImage.getHref() + "\" alt=\""
+ + coverImage.getTitle() + "\"/>\n");
+ fw.append(" </div>\n");
+ fw.append(" </body>\n");
+ fw.append("</html>\n");
+ fw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ // Add the cover page item
+ Item coverPage = addItem(COVER_ID, null, coverFile, null, MIMETYPE_XHTML, true, false, false);
+ coverPage.setGenerated(true);
+ addReference(coverPage.getHref(), coverImage.getTitle(), Type.COVER);
+ // Move the cover page first in the spine.
+ EList<Itemref> spine = opfPackage.getSpine().getSpineItems();
+ Itemref cover = null;
+ for (Itemref itemref : spine) {
+ if (itemref.getIdref().equals(COVER_ID)) {
+ cover = itemref;
+ }
+ }
+ if (cover != null) {
+ spine.move(0, cover);
+ }
+ }
+
+ /**
+ * Writes the <b>content.opf</b> file.
+ *
+ * @param rootFolder
+ * the folder where to write the file.
+ * @throws IOException
+ */
+ private void writeOPF(File opfFile) throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ // Register the packages to make it available during loading.
+ URI fileURI = URI.createFileURI(opfFile.getAbsolutePath());
+ Resource resource = resourceSet.createResource(fileURI);
+ resource.getContents().add(opfPackage);
+ resource.save(null);
+ }
+
+ /**
+ * Implement to handle writing of the table of contents. Note that this
+ * method should do nothing if the table of contents has already been
+ * specified using {@link #setTableOfContents(File)}.
+ *
+ * @param rootFolder
+ * the folder to write in
+ * @throws Exception
+ */
+ protected abstract void writeTableOfContents(File rootFolder) throws Exception;
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/ValidationMessage.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/ValidationMessage.java
new file mode 100644
index 000000000..fd97d67d7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/ValidationMessage.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.core;
+
+public class ValidationMessage {
+
+ public enum Severity {
+ WARNING, ERROR
+ }
+
+ private final Severity severity;
+
+ private final String message;
+
+ public ValidationMessage(Severity severity, String message) {
+ this.severity = severity;
+ this.message = message;
+ }
+
+ public Severity getSeverity() {
+ return severity;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/wikitext/MarkupToOPS.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/wikitext/MarkupToOPS.java
new file mode 100644
index 000000000..db09a8aa7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/wikitext/MarkupToOPS.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.core.wikitext;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.opf.Item;
+import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
+import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;
+import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder.Stylesheet;
+import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
+import org.eclipse.mylyn.wikitext.core.util.XmlStreamWriter;
+
+/**
+ * This type can be used to populate an OPS publication directly from WikiText
+ * markup.
+ *
+ * @author Torkild U. Resheim
+ * @since 1.0
+ */
+public class MarkupToOPS {
+
+ private MarkupLanguage markupLanguage;
+
+ /**
+ * Parses the markup file and populates the OPS data.
+ *
+ * @param ops
+ * the OPS publication the content will be added to
+ * @param markupFile
+ * the WikiText markup file
+ *
+ * @return the temporary folder used for generating the HTML from markup
+ */
+ public File parse(OPSPublication ops, File markupFile) throws IOException, FileNotFoundException {
+ if (markupLanguage == null) {
+ throw new IllegalStateException("must set markupLanguage"); //$NON-NLS-1$
+ }
+ // Create a temporary working folder
+ File workingFolder = File.createTempFile("wikitext_", null);
+ if (workingFolder.delete() && workingFolder.mkdirs()) {
+ File htmlFile = new File(workingFolder.getAbsolutePath() + File.separator + "markup.html");
+ FileWriter out = new FileWriter(htmlFile);
+ HtmlDocumentBuilder builder = new HtmlDocumentBuilder(out) {
+ @Override
+ protected XmlStreamWriter createXmlStreamWriter(Writer out) {
+ return super.createFormattingXmlStreamWriter(out);
+ }
+ };
+
+ List<Item> stylesheets = ops.getItemsByMIMEType(OPSPublication.MIMETYPE_CSS);
+ for (Item item : stylesheets) {
+ File file = new File(item.getFile());
+ Stylesheet css = new Stylesheet(file);
+ builder.addCssStylesheet(css);
+ }
+ // Make sure we get the correct XHTML header
+ builder.setEmitDtd(true);
+ builder.setHtmlDtd("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
+ builder.setXhtmlStrict(true);
+
+ MarkupParser markupParser = new MarkupParser();
+
+ markupParser.setBuilder(builder);
+ markupParser.setMarkupLanguage(markupLanguage);
+ markupParser.parse(new FileReader(markupFile));
+ // Convert the generated HTML to EPUB
+ ops.setGenerateToc(true);
+ ops.setIncludeReferencedResources(true);
+ Item item = ops.addItem(htmlFile);
+ item.setSourcePath(markupFile.getAbsolutePath());
+ }
+ return workingFolder;
+ }
+
+ /**
+ * Sets the markup language to use when generating HTML from markup.
+ *
+ * @param markupLanguage
+ * the markup language
+ */
+ public void setMarkupLanguage(MarkupLanguage markupLanguage) {
+ this.markupLanguage = markupLanguage;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/AbstractXHTMLScanner.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/AbstractXHTMLScanner.java
new file mode 100644
index 000000000..1f5082470
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/AbstractXHTMLScanner.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+
+/**
+ * This abstract type should be used to form the basis for all types that are
+ * used to scan EPUB XHTML content files.
+ *
+ * @author Torkild U. Resheim
+ */
+public abstract class AbstractXHTMLScanner extends DefaultHandler2 {
+
+ /** Buffer holding element text */
+ protected StringBuilder buffer = null;
+
+ /** Whether or not we are capturing element text */
+ protected boolean recording = false;
+
+ protected String currentHref = null;
+
+ /**
+ * <code>true</code> indicates that the parser is within a &lt;head&gt; HTML
+ * element
+ */
+ protected boolean insideHead;
+
+ public AbstractXHTMLScanner() {
+ super();
+ buffer = new StringBuilder();
+ }
+
+ /**
+ * Determines whether or not the given element name represents a HTML
+ * header.
+ *
+ * @param qName
+ * the element name
+ * @return <code>true</code> if the element is a header
+ */
+ protected int isHeader(String qName) {
+ if (qName.startsWith("h") || qName.startsWith("H")) {
+ if (qName.length() == 2 && !qName.equalsIgnoreCase("hr")) {
+ String n = qName.substring(1);
+ try {
+ int i = Integer.parseInt(n);
+ // Levels must be between 1 and 6
+ if (i > 0 && i < 7) {
+ return i;
+ }
+ } catch (NumberFormatException e) {
+ System.err.println("Bad header in " + currentHref);
+ }
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (qName.equalsIgnoreCase("head")) {
+ insideHead = true;
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (qName.equalsIgnoreCase("head")) {
+ insideHead = false;
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ // Some titles actually contain newlines – so we need to remove them.
+ if (recording) {
+ String s = new String(ch, start, length);
+ buffer.append(s.replace("\n", ""));
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBFileUtil.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBFileUtil.java
new file mode 100644
index 000000000..4143157e6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBFileUtil.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+
+/**
+ * Various EPUB file related utilities.
+ *
+ * @author Torkild U. Resheim
+ */
+public class EPUBFileUtil {
+
+ static final int BUFFERSIZE = 2048;
+
+ /**
+ * Copies the contents of <i>source</i> to the new <i>destination</i> file.
+ *
+ * @param source
+ * the source file
+ * @param destination
+ * the destination file
+ * @throws IOException
+ */
+ public static void copy(File source, File destination) throws IOException {
+ destination.getParentFile().mkdirs();
+ FileInputStream from = null;
+ FileOutputStream to = null;
+ try {
+ from = new FileInputStream(source);
+ to = new FileOutputStream(destination);
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+
+ while ((bytesRead = from.read(buffer)) != -1) {
+ to.write(buffer, 0, bytesRead);
+ }
+ } finally {
+ if (from != null)
+ try {
+ from.close();
+ } catch (IOException e) {
+ }
+ if (to != null)
+ try {
+ to.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Attempts to figure out the MIME-type for the file.
+ *
+ * @param file
+ * the file to determine MIME-type for
+ * @return the MIME-type or <code>null</code>
+ */
+ public static String getMimeType(File file) {
+ String name = file.getName().toLowerCase();
+ // These are not (correctly) detected by mechanism below
+ if (name.endsWith("xhtml")) {
+ return "application/xhtml+xml";
+ }
+ if (name.endsWith(".otf")) {
+ return "font/opentype";
+ }
+ if (name.endsWith(".ttf")) {
+ return "font/truetype";
+ }
+ if (name.endsWith(".svg")) {
+ return "image/svg+xml";
+ }
+ if (name.endsWith(".css")) {
+ return "text/css";
+ }
+ try {
+ // Use URLConnection or content type detection
+ String mimeType_name = URLConnection.guessContentTypeFromName(file.getName());
+ InputStream is = new BufferedInputStream(new FileInputStream(file));
+ String mimeType_content = URLConnection.guessContentTypeFromStream(is);
+ is.close();
+ // Handle situations where we have file name that indicates we have
+ // plain HTML, but the contents say XML. Hence we are probably
+ // looking at XHTML (see bug 360701).
+ if (mimeType_name != null && mimeType_content != null) {
+ if (mimeType_name.equals("text/html") && mimeType_content.equals("application/xml")) {
+ return "application/xhtml+xml";
+ }
+ }
+ // We trust name over content
+ return mimeType_name == null ? mimeType_content : mimeType_name;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a path segment list.
+ *
+ * @param root
+ * the root folder
+ * @param file
+ * the destination file
+ * @param segments
+ * @see #getRelativePath(File, File)
+ */
+ private static void getPathSegments(File root, File file, ArrayList<String> segments) {
+ if (root.equals(file)) {
+ return;
+ }
+ segments.add(0, file.getName());
+ getPathSegments(root, file.getParentFile(), segments);
+ }
+
+ /**
+ * Determines the <i>root</i> relative path of <i>file</i> in a platform
+ * independent manner. The returned string is a path starting from but
+ * excluding <i>root</i> using the '/' character as a directory separator.
+ * If the <i>file</i> argument is a folder a trailing directory separator is
+ * added. if the <i>root</i> argument is a file, it's parent folder will be
+ * used.
+ *
+ * @param root
+ * the root directory or file
+ * @param file
+ * the root contained file or directory
+ * @return the platform independent, relative path
+ */
+ public static String getRelativePath(File root, File file) {
+ ArrayList<String> segments = new ArrayList<String>();
+ if (root.isFile()) {
+ root = root.getParentFile();
+ }
+ getPathSegments(root, file, segments);
+ StringBuilder path = new StringBuilder();
+ for (int p = 0; p < segments.size(); p++) {
+ if (p > 0) {
+ path.append('/');
+ }
+ path.append(segments.get(p));
+ }
+ if (file.isDirectory()) {
+ path.append('/');
+ }
+ return path.toString();
+ }
+
+ /**
+ * Unpacks the given <i>epubfile</i> to the <i>destination</i> directory.
+ * This method will also validate the first item contained in the EPUB (see
+ * {@link #writeEPUBHeader(ZipOutputStream)}).
+ *
+ * @param epubfile
+ * the EPUB file
+ * @param destination
+ * the destination folder
+ * @throws IOException
+ * if the operation was unsuccessful
+ */
+ public static void unzip(File epubfile, File destination) throws IOException {
+ if (!destination.exists()) {
+ if (!destination.mkdirs()) {
+ throw new IOException("Could not create directory for EPUB contents");
+ }
+ }
+ ZipInputStream in = new ZipInputStream(new FileInputStream(epubfile));
+ byte[] buf = new byte[BUFFERSIZE];
+ ZipEntry entry = null;
+ boolean checkFirstItem = true;
+ while ((entry = in.getNextEntry()) != null) {
+ // for each entry to be extracted
+ String entryName = entry.getName();
+ File newFile = new File(destination.getAbsolutePath() + File.separator + entryName);
+ if (entry.isDirectory()) {
+ newFile.mkdirs();
+ continue;
+ } else {
+ newFile.getParentFile().mkdirs();
+ }
+ int n;
+ FileOutputStream fileoutputstream = new FileOutputStream(newFile);
+ while ((n = in.read(buf, 0, BUFFERSIZE)) > -1) {
+ fileoutputstream.write(buf, 0, n);
+ }
+ fileoutputstream.close();
+ in.closeEntry();
+ if (checkFirstItem) {
+ if (!entryName.equals("mimetype")) {
+ throw new IOException("Invalid EPUB file. First item must be \"mimetype\"");
+ }
+ String type = new String(buf);
+ if (!type.trim().equals(OPSPublication.MIMETYPE_EPUB)) {
+ throw new IOException("Invalid EPUB file. Expected \"" + OPSPublication.MIMETYPE_EPUB + "\"");
+ }
+ checkFirstItem = false;
+ }
+ }
+ }
+
+ /**
+ * A correctly formatted EPUB file must contain an uncompressed entry named
+ * <b>mimetype</b> that is placed at the beginning. The contents of this
+ * file must be the ASCII-encoded string <b>application/epub+zip</b>. This
+ * method will create this file.
+ *
+ * @param zos
+ * the zip output stream to write to.
+ * @throws IOException
+ */
+ public static void writeEPUBHeader(ZipOutputStream zos) throws IOException {
+ byte[] bytes = OPSPublication.MIMETYPE_EPUB.getBytes("ASCII");
+ ZipEntry mimetype = new ZipEntry("mimetype");
+ mimetype.setMethod(ZipOutputStream.STORED);
+ mimetype.setSize(bytes.length);
+ mimetype.setCompressedSize(bytes.length);
+ CRC32 crc = new CRC32();
+ crc.update(bytes);
+ mimetype.setCrc(crc.getValue());
+ zos.putNextEntry(mimetype);
+ zos.write(bytes);
+ zos.closeEntry();
+ }
+
+ /**
+ * Recursively compresses contents of the given folder into a zip-file. If a
+ * file already exists in the given location an exception will be thrown.
+ *
+ * @param destination
+ * the destination file
+ * @param folder
+ * the source folder
+ * @param uncompressed
+ * a list of files to keep uncompressed
+ * @throws ZipException
+ * @throws IOException
+ */
+ public static void zip(File destination, File folder) throws ZipException, IOException {
+ if (destination.exists()) {
+ throw new IOException("A file already exists at " + destination.getAbsolutePath());
+ }
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destination));
+ writeEPUBHeader(out);
+ zip(folder, folder, out);
+ out.close();
+ }
+
+ /**
+ * Adds a folder recursively to the output stream.
+ *
+ * @param folder
+ * the root folder
+ * @param out
+ * the output stream
+ * @throws IOException
+ */
+ private static void zip(File root, File folder, ZipOutputStream out) throws IOException {
+ // Files first in order to make sure "metadata" is placed first in the
+ // zip file. We need that in order to support EPUB properly.
+ File[] files = folder.listFiles(new java.io.FileFilter() {
+ public boolean accept(File pathname) {
+ return !pathname.isDirectory();
+ }
+ });
+ byte[] tmpBuf = new byte[BUFFERSIZE];
+
+ for (int i = 0; i < files.length; i++) {
+ FileInputStream in = new FileInputStream(files[i].getAbsolutePath());
+ ZipEntry zipEntry = new ZipEntry(getRelativePath(root, files[i]));
+ out.putNextEntry(zipEntry);
+ int len;
+ while ((len = in.read(tmpBuf)) > 0) {
+ out.write(tmpBuf, 0, len);
+ }
+ out.closeEntry();
+ in.close();
+ }
+ File[] dirs = folder.listFiles(new java.io.FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ });
+ for (int i = 0; i < dirs.length; i++) {
+ out.putNextEntry(new ZipEntry(getRelativePath(root, dirs[i])));
+ zip(root, dirs[i], out);
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBXMLHelperImp.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBXMLHelperImp.java
new file mode 100644
index 000000000..b04e4ec55
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBXMLHelperImp.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ */
+public class EPUBXMLHelperImp extends XMLHelperImpl {
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/MetadataScanner.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/MetadataScanner.java
new file mode 100644
index 000000000..5ef69ff6c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/MetadataScanner.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.mylyn.docs.epub.opf.Metadata;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This type is used to scan XHTML files for information that may be used in
+ * EPUB metadata. This can be the publication title, copyright and author. Some
+ * of this information can be found inside Dublin Core elements.
+ *
+ * XXX: Not in use yet
+ *
+ * @author Torkild U. Resheim
+ * @see http://dublincore.org/documents/dc-html/
+ * @see http://dublincore.org/documents/dcq-html/ (obsolete)
+ */
+public final class MetadataScanner extends AbstractXHTMLScanner {
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ }
+
+ private final Metadata metadata;
+
+ public MetadataScanner(Metadata metadata) {
+ super();
+ this.metadata = metadata;
+ }
+
+ public static void parse(InputSource file, Metadata metadata) throws ParserConfigurationException, SAXException,
+ IOException {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setFeature("http://xml.org/sax/features/validation", false);
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ SAXParser parser = factory.newSAXParser();
+ MetadataScanner tocGenerator = new MetadataScanner(metadata);
+ try {
+ parser.parse(file, tocGenerator);
+ } catch (SAXException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Metadata getMetadata() {
+ return metadata;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/OPS2Validator.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/OPS2Validator.java
new file mode 100644
index 000000000..b2e10b370
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/OPS2Validator.java
@@ -0,0 +1,214 @@
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.mylyn.docs.epub.core.ValidationMessage;
+import org.eclipse.mylyn.docs.epub.core.ValidationMessage.Severity;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * This type is a SAX parser that will read a XHTML file and produce a new
+ * version where elements and attributes not in the EPUB 2.0.1 <b>preferred</b>
+ * vocabulary are stripped. Alternatively warnings can be issued when such
+ * elements and attributes are found.
+ *
+ * @author Torkild U. Resheim
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm
+ */
+public class OPS2Validator extends DefaultHandler {
+
+ public enum Mode {
+ /** Remove non-preferred elements and attributes */
+ REMOVE,
+ /** Issue warnings when non-preferred elements or attributes are found */
+ WARN
+ }
+
+ private StringBuilder contents = null;
+
+ private final ArrayList<ValidationMessage> messages;
+
+ public StringBuilder getContents() {
+ return contents;
+ }
+
+ public ArrayList<ValidationMessage> getMessages() {
+ return messages;
+ }
+
+ public static List<ValidationMessage> validate(InputSource file, String href)
+ throws ParserConfigurationException,
+ SAXException, IOException {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setFeature("http://xml.org/sax/features/validation", false);
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ SAXParser parser = factory.newSAXParser();
+ OPS2Validator tocGenerator = new OPS2Validator(href, Mode.WARN);
+ try {
+ parser.parse(file, tocGenerator);
+ return tocGenerator.getMessages();
+ } catch (SAXException e) {
+ System.err.println("Could not parse " + href);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String clean(InputSource file, String href) throws ParserConfigurationException, SAXException,
+ IOException {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setFeature("http://xml.org/sax/features/validation", false);
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ SAXParser parser = factory.newSAXParser();
+ OPS2Validator tocGenerator = new OPS2Validator(href, Mode.REMOVE);
+ try {
+ parser.parse(file, tocGenerator);
+ return tocGenerator.getContents().toString();
+ } catch (SAXException e) {
+ System.err.println("Could not parse " + href);
+ e.printStackTrace();
+ }
+ return null;
+ }
+ private StringBuilder buffer = null;
+
+ private final String[] legalAttributes = new String[] { "accesskey", "charset", "class", "coords", "dir", "href",
+ "hreflang", "id", "rel", "rev", "shape", "style", "tabindex", "target", "title", "type", "xml:lang",
+ /* Are these OK? */
+ "xmlns", "src", "alt" };
+
+ /**
+ * A list of legal elements according to the EPUB 2.0.1 specification
+ *
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section1.3.4
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section2.2
+ */
+ private final String[] legalElements = new String[] { "body", "head", "html", "title", "abbr", "acronym",
+ "address", "blockquote", "br", "cite", "code", "dfn", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6",
+ "kbd", "p", "pre", "q", "samp", "span", "strong", "var", "a", "dl", "dt", "dd", "ol", "ul", "li", "object",
+ "param", "b", "big", "hr", "i", "small", "sub", "sup", "tt", "del", "ins", "bdo", "caption", "col",
+ "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "img", "area", "map", "style", "link",
+ "base" };
+
+ private Mode mode = Mode.WARN;
+
+ /**
+ * A list of elements that should be let through regardless of contents.
+ */
+ private final String[] passthroughElements = new String[] { "meta" };
+
+ private boolean recording = false;
+
+ public OPS2Validator(String href, Mode mode) {
+ super();
+ buffer = new StringBuilder();
+ contents = new StringBuilder();
+ messages = new ArrayList<ValidationMessage>();
+ this.mode = mode;
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (recording) {
+ buffer.append(ch, start, length);
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (isLegalElement(qName)) {
+ contents.append(buffer);
+ contents.append("</" + qName + ">");
+ buffer.setLength(0);
+ }
+ recording = false;
+ }
+
+ /**
+ * Returns <code>true</code> if the given attribute name is legal.
+ *
+ * @param name
+ * @return
+ */
+ private boolean isLegalAttribute(String name) {
+ for (String legal : legalAttributes) {
+ if (name.equalsIgnoreCase(legal)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isLegalElement(String name) {
+ for (String legal : legalElements) {
+ if (name.equalsIgnoreCase(legal)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isPassthroughElement(String name) {
+ for (String legal : passthroughElements) {
+ if (name.equalsIgnoreCase(legal)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (isPassthroughElement(qName)) {
+ // Record any text content
+ contents.append('<');
+ contents.append(qName);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String name = attributes.getQName(i);
+ contents.append(' ');
+ contents.append(name);
+ contents.append("=\"");
+ contents.append(attributes.getValue(i));
+ contents.append("\"");
+ }
+ contents.append('>');
+ recording = true;
+
+ } else if (mode.equals(Mode.WARN) || isLegalElement(qName)) {
+ // Record any text content
+ contents.append('<');
+ contents.append(qName);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String name = attributes.getQName(i);
+ if (mode.equals(Mode.WARN) || isLegalAttribute(name)) {
+ contents.append(' ');
+ contents.append(name);
+ contents.append("=\"");
+ contents.append(attributes.getValue(i));
+ contents.append("\"");
+ if (!isLegalAttribute(name)) {
+ messages.add(new ValidationMessage(Severity.WARNING, "Attribute " + name
+ + " is not in OPS Preferred Vocabularies."));
+ }
+ }
+ }
+ contents.append('>');
+ recording = true;
+ if (!isLegalElement(qName)) {
+ messages.add(new ValidationMessage(Severity.WARNING, "Element " + qName
+ + " is not in OPS Preferred Vocabularies."));
+
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/ReferenceScanner.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/ReferenceScanner.java
new file mode 100644
index 000000000..8ef95141d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/ReferenceScanner.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.mylyn.docs.epub.opf.Item;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This type is a SAX parser that will read a XHTML file and create a list of
+ * all images that are referenced either through an <i>img<i/> tag or a link.
+ *
+ * @author Torkild U. Resheim
+ */
+public class ReferenceScanner extends AbstractXHTMLScanner {
+
+ public static List<File> parse(Item item) throws ParserConfigurationException, SAXException, IOException {
+ FileReader fr = new FileReader(item.getFile());
+ InputSource file = new InputSource(fr);
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setFeature("http://xml.org/sax/features/validation", false);
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ SAXParser parser = factory.newSAXParser();
+ String href = item.getHref();
+ ReferenceScanner scanner = new ReferenceScanner(item);
+ try {
+ parser.parse(file, scanner);
+ return scanner.files;
+ } catch (SAXException e) {
+ System.err.println("Could not parse " + href);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ Item currentItem;
+
+ ArrayList<File> files;
+
+ public ReferenceScanner(Item item) {
+ super();
+ files = new ArrayList<File>();
+ currentItem = item;
+ }
+
+ /**
+ * Case-insensitive method for obtaining an attribute.
+ *
+ * @param attributes
+ * SAX attributes
+ * @param name
+ * the attribute name
+ * @return the attribute value or <code>null</code>
+ */
+ private String getAttribute(Attributes attributes, String name) {
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String aname = attributes.getQName(i);
+ if (aname.equalsIgnoreCase(name)) {
+ return attributes.getValue(i);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+ // Handle inline image files
+ if (qName.equalsIgnoreCase("img")) {
+ String ref = getAttribute(attributes, "src");
+ if (ref != null) {
+ String t = ref.toLowerCase();
+ if (t.startsWith("http://") || t.startsWith("https://")) {
+ return;
+ }
+ // If the item was generated for instance by WikiText we need to
+ // use the original path. Otherwise we use the item path.
+ String source = currentItem.getSourcePath();
+ if (source == null) {
+ source = currentItem.getFile();
+ }
+ File sourceFile = new File(source);
+ File file = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + ref);
+ files.add(file);
+ }
+ }
+
+ // Also handle links to image files
+ if (qName.equalsIgnoreCase("a")) {
+ String ref = getAttribute(attributes, "href");
+ if (ref != null) {
+ String t = ref.toLowerCase();
+ if (t.startsWith("#") || t.startsWith("http://") || t.startsWith("https://")) {
+ return;
+ }
+ // If the item was generated for instance by WikiText we need to
+ // use the original path. Otherwise we use the item path.
+ String source = currentItem.getSourcePath();
+ if (source == null) {
+ source = currentItem.getFile();
+ }
+ File sourceFile = new File(source);
+ File file = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + ref);
+ if (!file.isDirectory()) {
+ files.add(file);
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/TOCGenerator.java b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/TOCGenerator.java
new file mode 100644
index 000000000..10dc7a2e9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/TOCGenerator.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.core;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.mylyn.docs.epub.ncx.Content;
+import org.eclipse.mylyn.docs.epub.ncx.NCXFactory;
+import org.eclipse.mylyn.docs.epub.ncx.NavLabel;
+import org.eclipse.mylyn.docs.epub.ncx.NavPoint;
+import org.eclipse.mylyn.docs.epub.ncx.Ncx;
+import org.eclipse.mylyn.docs.epub.ncx.Text;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This type is a SAX parser that will read a XHTML file, locate headers and
+ * create NCX items for the EPUB table of contents. Each header must have an
+ * "id" attribute or it will not be possible to link to the header.
+ *
+ * @author Torkild U. Resheim
+ */
+public class TOCGenerator extends AbstractXHTMLScanner {
+
+ private String currentId = null;
+
+ private NavPoint[] headers = null;
+
+ private final Ncx ncx;
+
+ private int playOrder;
+
+ public int getPlayOrder() {
+ return playOrder;
+ }
+
+ public TOCGenerator(String href, Ncx ncx, int playOrder) {
+ super();
+ buffer = new StringBuilder();
+ currentHref = href;
+ headers = new NavPoint[6];
+ this.ncx = ncx;
+ this.playOrder = playOrder;
+ }
+
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ int level = isHeader(qName);
+ if (level > 0) {
+ recording = false;
+ NavPoint np = createNavPoint(buffer.toString());
+ // Determine the parent header
+ NavPoint h = headers[level - 1];
+ while (level > 1 && h == null) {
+ level--;
+ if (level == 1) {
+ h = headers[0];
+ break;
+ }
+ h = headers[level - 1];
+ }
+ // Add to the parent header or to the root
+ if (level > 1) {
+ h.getNavPoints().add(np);
+ } else {
+ ncx.getNavMap().getNavPoints().add(np);
+ }
+ headers[level] = np;
+ buffer.setLength(0);
+ }
+ }
+
+ private NavPoint createNavPoint(String title) {
+ NavPoint np = NCXFactory.eINSTANCE.createNavPoint();
+ NavLabel nl = NCXFactory.eINSTANCE.createNavLabel();
+ Content c = NCXFactory.eINSTANCE.createContent();
+ c.setSrc(currentId == null ? currentHref : currentHref + "#" + currentId);
+ Text text = NCXFactory.eINSTANCE.createText();
+ FeatureMapUtil.addText(text.getMixed(), title);
+ nl.setText(text);
+ np.getNavLabels().add(nl);
+ np.setPlayOrder(++playOrder);
+ np.setId("navpoint" + playOrder);
+ np.setContent(c);
+ return np;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (isHeader(qName) > 0) {
+ recording = true;
+ if (attributes.getValue("id") != null) {
+ currentId = attributes.getValue("id");
+ } else {
+ currentId = null;
+ }
+ }
+ }
+
+ /**
+ *
+ * @param file
+ * @param href
+ * @param ncx
+ * the NCX
+ * @param playOrder
+ * initial play order
+ * @return
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ public static int parse(InputSource file, String href, Ncx ncx, int playOrder) throws ParserConfigurationException,
+ SAXException, IOException {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setFeature("http://xml.org/sax/features/validation", false);
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ SAXParser parser = factory.newSAXParser();
+ TOCGenerator tocGenerator = new TOCGenerator(href, ncx, playOrder);
+ try {
+ parser.parse(file, tocGenerator);
+ } catch (SAXException e) {
+ System.err.println("Could not parse " + href);
+ e.printStackTrace();
+ }
+ return tocGenerator.getPlayOrder();
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.help/.classpath b/org.eclipse.mylyn.docs.epub.help/.classpath
new file mode 100644
index 000000000..ad32c83a7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.docs.epub.help/.gitignore b/org.eclipse.mylyn.docs.epub.help/.gitignore
new file mode 100644
index 000000000..4c93aec46
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.gitignore
@@ -0,0 +1,4 @@
+/build
+/bin
+/Building_EPUBs.epub
+/help
diff --git a/org.eclipse.mylyn.docs.epub.help/.project b/org.eclipse.mylyn.docs.epub.help/.project
new file mode 100644
index 000000000..13962a4b6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub.help</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..0068c6fce
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Thu Oct 06 23:37:22 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..b8bf216f5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:44 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..6d8c9a65c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Aug 31 09:27:04 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub.help/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.help/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..4de12cc68
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EPUB Help and User Guide
+Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.help;singleton:=true
+Bundle-Version: 0.8.0.qualifier
+Bundle-Vendor: Torkild U. Resheim
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.mylyn.docs.epub.core;bundle-version="0.8.0",
+ org.eclipse.mylyn.docs.epub.ant.core;bundle-version="0.8.0"
diff --git a/org.eclipse.mylyn.docs.epub.help/build-docs.xml b/org.eclipse.mylyn.docs.epub.help/build-docs.xml
new file mode 100644
index 000000000..9f3242f8a
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/build-docs.xml
@@ -0,0 +1,70 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+ Copyright (c) 2007, 2009 David Green and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ David Green - initial API and implementation
+ Torkild U. Resheim - Adapted for building the EPUB user guide
+ -->
+
+<!-- Will currently only work when called from Maven - see pom.xml -->
+<project name="org.eclipse.mylyn.docs.epub.ui.docs" default="all">
+
+ <property name="wikitext.help" location="../org.eclipse.mylyn.wikitext.help.ui" />
+
+ <path id="wikitext.ant.classpath">
+ <pathelement path="${compile_classpath}"/>
+ </path>
+
+ <target name="clean">
+ <delete failonerror="false">
+ <fileset dir="help">
+ <include name="**/*"/>
+ </fileset>
+ </delete>
+ <delete dir="${wikitext.ui.textile.bin}" failonerror="false"/>
+ </target>
+
+ <target name="all" depends="plugin-docs">
+ </target>
+
+ <target name="plugin-docs" description="generate plugin help documentation">
+ <taskdef resource="org/eclipse/mylyn/wikitext/core/util/anttask/tasks.properties" classpathref="wikitext.ant.classpath"/>
+
+ <mkdir dir="${basedir}/help"/>
+
+ <wikitext-to-eclipse-help markupLanguage="org.eclipse.mylyn.wikitext.textile.core.TextileLanguage"
+ overwrite="true"
+ multipleOutputFiles="true"
+ navigationImages="true"
+ helpPrefix="help">
+ <fileset dir="docs">
+ <include name="*.textile"/>
+ </fileset>
+ <stylesheet url="../../PRODUCT_PLUGIN/book.css"/>
+ <stylesheet file="${wikitext.help}/help/styles/main.css"/>
+ <stylesheet file="${basedir}/docs/style.css"/>
+ </wikitext-to-eclipse-help>
+
+ <move todir="${basedir}/help">
+ <fileset dir="${basedir}/docs">
+ <include name="*.html" />
+ <include name="*-toc.xml" />
+ </fileset>
+ </move>
+
+ <copy todir="${basedir}/help">
+ <fileset dir="${basedir}/docs">
+ <include name="*.gif" />
+ <include name="*.png" />
+ <include name="*.jpg" />
+ </fileset>
+ </copy>
+
+ </target>
+
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.help/build.properties b/org.eclipse.mylyn.docs.epub.help/build.properties
new file mode 100644
index 000000000..0a74da007
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ help/,\
+ toc.xml,\
+ plugin.xml
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/Illustrations.002.jpg b/org.eclipse.mylyn.docs.epub.help/docs/Illustrations.002.jpg
new file mode 100644
index 000000000..d125677d2
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/Illustrations.002.jpg
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/epub-ant-task.textile b/org.eclipse.mylyn.docs.epub.help/docs/epub-ant-task.textile
new file mode 100644
index 000000000..7ec3a724d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/epub-ant-task.textile
@@ -0,0 +1,362 @@
+h1. The EPUB ANT task
+
+The **epub** "Ant":http://www.apache.org task is used to assemble an EPUB file from a given set of source items. It is assumes that most of the source material such as HTML-files and illustrations has been prepared beforehand. Ant version 1.7 and newer is supported.
+
+The following is an approximate DTD for the task:
+
+bc..
+
+<!ELEMENT epub (identifier | type | subject | reference
+ | creator | meta | publisher | source | language
+ | rights | contributor | format | cover |
+ toc | item | date | title | fileset)*>
+<!ATTLIST epub
+ id ID #IMPLIED
+ taskname CDATA #IMPLIED
+ identifierid CDATA #IMPLIED
+ file CDATA #IMPLIED
+ description CDATA #IMPLIED
+ workingfolder CDATA #IMPLIED
+ includeReferenced %boolean; #IMPLIED>
+
+p.
+* **id** - item identifier
+* **taskname** - name to use for task when logging
+* **identifierid** - reference to an identifier added using the **identifier** element.
+* **file** - path to the resulting EPUB file.
+* **description** - description of the task.
+* **workingfolder** - optionally used to specify the folder used for assembling the EPUB. If not specified a temporary folder will be used and deleted when the processing has completed.
+* **includeReferenced** - optionally used to automatically include referenced items in the finished publication. When setting this to **true** there should be no need to explicitly add for instance referenced image files. This value is per default **false**.
+
+h2. Adding "header" information
+
+Certain elements are required in the header of the publication. These include the title of the publication, the identifier and the language code. It is possible to add more than one element of some types.
+
+The following elements can be used:
+|_. id |_. Required |_. Description |
+|"title":#Publicationtitle|yes|The publication title|
+|"identifier":#Publicationidentifiers|yes|The publication identifier|
+|"language":#Languagespecification|yes|The publication language|
+|"publisher":#Publisher|no|Name of the publisher|
+|"subject":#Publicationsubject|no|Subject of the publication|
+|"creator":#ContributorsandCreators|no|One or more creators|
+|"contributor":#ContributorsandCreators|no|One or more contributors|
+|"date":#Dates|no|One or more dates|
+|"cover":#Cover|no|The cover page|
+
+h3. Publication title
+
+p. Typically, the title will be a name by which the resource is formally known.
+
+bc..
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Publication identifiers
+
+p. The recommended best practice is to identify the resource by means of a string or number conforming to a formal identification system. These include but are not limited to the "Uniform Resource Identifier":http://en.wikipedia.org/wiki/Uniform_Resource_Identifier, the "Digital Object Identifier":http://en.wikipedia.org/wiki/Digital_object_identifier (DOI) and the "International Standard Book Number":http://en.wikipedia.org/wiki/International_Standard_Book_Number (ISBN).
+
+bc..
+<!ELEMENT identifier (#PCDATA)>
+<!ATTLIST identifier
+ id ID #IMPLIED
+ scheme CDATA #IMPLIED>
+
+p. If an identifier is not specified, one will be generated based using a random "UUID":http://en.wikipedia.org/wiki/Universally_unique_identifier. However it is probably a good idea to specify an identifier. Reading systems may use this field as intended and replace older versions of the publication when a newer is added to the library. A new identifier will be generated for each run of the script unless specified.
+
+h3. Language specification
+
+p. The recommended best practice is to use RFC 3066 which, in conjunction with "ISO639":http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes, defines two- and three-letter primary language tags with optional subtags. Examples include "no" for Norwegian, "en" for English", and "en-GB" for English used in the United Kingdom.
+
+bc..
+<!ELEMENT language EMPTY>
+<!ATTLIST language
+ id ID #IMPLIED
+ code CDATA #IMPLIED>
+
+p.
+* **id** - optional unique identifier.
+* **code** - the language code.
+
+p. If a language is not specified it will be set to "en" for generic English.
+
+h3. Publisher
+
+bc..
+<!ELEMENT publisher (#PCDATA)>
+<!ATTLIST publisher
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+p.
+* **id** - optional unique identifier.
+* **lang** - optional language code.
+* **text** - name of the publisher.
+
+h3. Publication subject
+
+p. The subject will typically be represented using keywords, key phrases, or classification codes.
+
+bc..
+<!ELEMENT subject (#PCDATA)>
+<!ATTLIST subject
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Contributors and Creators
+
+p. Examples of a contributor and creator include a person, an organization, or a service.
+
+bc..
+<!ELEMENT contributor EMPTY>
+<!ATTLIST contributor
+ id ID #IMPLIED
+ fileAs CDATA #IMPLIED
+ name CDATA #IMPLIED
+ lang CDATA #IMPLIED
+ role CDATA #IMPLIED>
+
+<!ELEMENT creator EMPTY>
+<!ATTLIST creator
+ id ID #IMPLIED
+ fileAs CDATA #IMPLIED
+ name CDATA #IMPLIED
+ lang CDATA #IMPLIED
+ role CDATA #IMPLIED>
+
+p.
+* **id** - optional unique identifier.
+* **fileAs** - optional filing specification.
+* **name** - name of the creator or contributor.
+* **lang** - optional language code.
+* **role** - optional MARC relator code.
+
+Optionally one can specify **fileas** to indicate a formal way of filing the entry. For instance "Last name, first name".
+
+bc..
+<creator name="Nomen Nescio" file-as="Nescio, Nomen"
+ role="aut/>
+
+p. This tooling will automatically add "Eclipse Committers and Contributors" in the redactor role.
+
+p. In **role** "MARC relator codes":http://www.loc.gov/marc/relators/ are used for indicating the role of the entity. The complete list is quite long. Some of the more typical are:
+
+|_. Name |_. Code |_. Description |
+|Artist|art|Use for a person (e.g., a painter) who conceives, and perhaps also implements, an original graphic design or work of art, if specific codes (e.g., [egr], [etr]) are not desired. For book illustrators, prefer Illustrator [ill].|
+|Author|aut|Use for a person or corporate body chiefly responsible for the intellectual or artistic content of a work. This term may also be used when more than one person or body bears such responsibility.|
+|Author in quotations or text extracts|aqt|Use for a person whose work is largely quoted or extracted in a works to which he or she did not contribute directly. Such quotations are found particularly in exhibition catalogs, collections of photographs, etc.|
+|Author of afterword, colophon, etc.|aft|Use for a person or corporate body responsible for an afterword, postface, colophon, etc. but who is not the chief author of a work.|
+|Author of introduction, etc.|aui|Use for a person or corporate body responsible for an introduction, preface, foreword, or other critical matter, but who is not the chief author.|
+|Collaborator|clb|Use for a person or corporate body that takes a limited part in the elaboration of a work of another author or that brings complements (e.g., appendices, notes) to the work of another author.|
+|Compiler|com|Use for a person who produces a work or publication by selecting and putting together material from the works of various persons or bodies.|
+|Editor|edt|Use for a person who prepares for publication a work not primarily his/her own, such as by elucidating text, adding introductory or other critical matter, or technically directing an editorial staff.|
+|Illustrator|ill|Use for the person who conceives, and perhaps also implements, a design or illustration, usually to accompany a written text.|
+|Photographer|pht|Use for the person or organization responsible for taking photographs, whether they are used in their original form or as reproductions.|
+|Redactor|red|Use for a person who writes or develops the framework for an item without being intellectually responsible for its content.|
+|Reviewer|rev|Use for a person or corporate body responsible for the review of book, motion picture, performance, etc.|
+
+h3. Dates
+
+bc..
+<!ELEMENT date EMPTY>
+<!ATTLIST date
+ id ID #IMPLIED
+ date CDATA #IMPLIED
+ event CDATA #IMPLIED>
+
+p.
+* **id** - optional unique identifier.
+* **date** - a date on the format YYYY[-MM[-DD]].
+* **event** - an optional event specification.
+
+p. Date of publication, in the format defined by "Date and Time Formats":http://www.w3.org/TR/NOTE-datetime and by ISO 8601 on which it is based. In particular, dates without times are represented in the form YYYY[-MM[-DD]]: a required 4-digit year, an optional 2-digit month, and if the month is given, an optional 2-digit day of month.
+
+p. You may also set the **event** attribute. Legal values are not defined but may include "creation", "publication" and "modification".
+
+p. The epub task will always add a "creation" date using the current date when assembling the epub file.
+
+h3. Types
+
+p. Type includes terms describing general categories, functions, genres, or aggregation levels for content. The advised best practice is to select a value from a controlled vocabulary. To describe the physical or digital manifestation of the resource, use the "format":#Formats element. There should normally be no need to specify either.
+
+bc..
+<!ELEMENT type (#PCDATA)>
+<!ATTLIST type
+ id ID #IMPLIED>
+
+h3. Formats
+
+p. Use to specify the format of the publication. Typically this is the MIME type or the software, hardware, or other equipment needed. The epub task will always set the format to "application/epub+zip" unless a different format is specified.
+
+bc..
+<!ELEMENT format (#PCDATA)>
+<!ATTLIST format
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Source
+
+p. The publication may be derived from another resource in whole or part. The referenced resource should be identified by means of a string or number conforming to a formal identification system. If the publication is built from a web site it would be a good idea to use the URL of the entry page.
+
+bc..
+<!ELEMENT source (#PCDATA)>
+<!ATTLIST source
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Rights
+
+p. A statement about rights, or a reference to one. In this specification, the copyright notice and any further rights description should appear directly.
+This specification does not address the manner in which a Content Provider specifies to a secure distributor any licensing terms under which readership rights or copies of the content could be sold.
+
+p. Typically, Rights will contain a rights management statement for the resource, or reference a service providing such information. Rights information often encompasses Intellectual Property Rights (IPR), Copyright, and various Property Rights. If the Rights element is absent, no assumptions may be made about any rights held in or over the resource.
+
+bc..
+<!ELEMENT rights (#PCDATA)>
+<!ATTLIST rights
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Coverage
+
+p. The extent or scope of the publication's content. The advised best practice is to select a value from a controlled vocabulary; see the Dublin Core Metadata Element Set (http://dublincore.org/documents/2004/12/20/dces/).
+
+p. Typically, Coverage will include spatial location (a place name or geographic coordinates), temporal period (a period label, date, or date range) or jurisdiction (such as a named administrative entity).
+
+bc..
+<!ELEMENT coverage (#PCDATA)>
+<!ATTLIST coverage
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+
+h3. Relation
+
+p. Recommended best practice is to identify the referenced resource by means of a string or number conforming to a formal identification system.
+
+bc..
+<!ELEMENT relation (#PCDATA)>
+<!ATTLIST relation
+ id ID #IMPLIED
+ lang CDATA #IMPLIED>
+
+h3. Meta
+
+p. This type is used to express arbitrary metadata beyond the data described by the Dublin Core specification.
+
+bc..
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+ id ID #IMPLIED
+ name CDATA #IMPLIED
+ content CDATA #IMPLIED>
+
+h3. Cover
+
+bc..
+<!ELEMENT cover EMPTY>
+<!ATTLIST cover
+ image CDATA #IMPLIED
+ title CDATA #IMPLIED>
+
+p. Adds a cover page using the supplied image file. Use a PNG, SVG or JPEG formatted file. When supplying raster images a dimension of 760x1000 pixels is typical.
+
+h2. Adding content
+
+p. No publication is complete without content. So you will have to add at a minimum one chapter.
+
+h3. Primary content files
+
+p. Content is added using the **item** element. At a minimum you will have to specify the **file** attribute. This points to the file that will be added to the __spine__. The __spine__ is a structure within the publication that defines the reading order. So the order you add items does matter. If you're adding other types of files such as cascading style sheets you will have to specify the type and whether or not to add it to the spine.
+
+bc..
+<!ELEMENT item EMPTY>
+<!ATTLIST item
+ id ID #IMPLIED
+ file CDATA #IMPLIED
+ type CDATA #IMPLIED
+ page CDATA #IMPLIED
+ spine %boolean; #IMPLIED>
+
+p.
+* **file** - points to a file to include in the manifest
+* **type** - The MIME type of the file. If omitted it will be automatically detected if possible.
+* **spine** - Whether or not to include the file in the reading order of the publication.
+
+h3. Secondary content files
+
+p. Files that are not required to be in the __spine__ and which MIME-type can be automatically determined may be added to the publication using a nested **fileset**. This is identical to the "fileset":http://ant.apache.org/manual/Types/fileset.html element type found in ANT except that you may add a extra **dest** and **lang** attributes. The new attribute can be used to specify the destination sub-folder of the files. If you for instance have illustrations in the form of JPEG, PNG or GIF images; this is the most straightforward to add these.
+
+p. An identifier will automatically be created for each file added. It is on the form __&lt;mimetype&gt;-&lt;filename&gt;__. So a JPEG file named __my_house.jpg__ will be identified as __image-my_house__. If you have another file named __my_house.gif__ you will get a conflict so it would be wise to rename one of the files or add both using the **item** element and specify the identifier.
+
+An example of use is shown below:
+
+bc..
+<fileset dir="${srcdir}" dest="images/" lang="en">
+ <include name="*.gif" />
+ <include name="*.png" />
+ <include name="*.jpg" />
+ <include name="*.otf" />
+</fileset>
+
+h3. References
+
+The __guide__ allows you to specify the role of each file in the publication. While not required it is recommended that this feature is used. It is basically a list of references to each of the content files and the role they play. Some reading systems will for instance open a fresh book on the first page that contains __text__.
+
+bc..
+<!ELEMENT reference EMPTY>
+<!ATTLIST reference
+ id ID #IMPLIED
+ href CDATA #IMPLIED
+ type CDATA #IMPLIED
+ title CDATA #IMPLIED>
+p.
+* **id** - optional unique identifier.
+* **href** - the file that is referenced.
+* **type** - the role.
+* **title** - title of the reference.
+
+bc..
+<reference href="cover.html"
+ type="cover" title="Cover Page" />
+<reference href="title-page.html"
+ type="title-page" title="Building EPUBs" />
+<reference href="introduction.html"
+ type="preface" title="Introduction" />
+
+p. The following types are allowed:
+
+|_. Type |_. Description |
+|cover|The book cover.|
+|title-page|Page with title, author, publisher, and other metadata.|
+|toc|Table of contents.|
+|index|Back-of-book style index|
+|glossary|An alphabetical list of terms used in the publication with definitions or explanations.|
+|acknowledgements|Statement acknowledging use of works of other authors.|
+|bibliography|A list of books or other material on a subject.|
+|colophon|A publisher's emblem on a book.|
+|copyright-page|Subject to or controlled by copyright.|
+|dedication|Address or inscription to a person, cause, etc as a token of affection or respect.|
+|epigraph|A quotation at the beginning of a book, chapter, etc, suggesting its theme.|
+|foreword|A phrase or passage from a book, poem, play, etc, remembered and spoken, esp to illustrate succinctly or support a point or an argument.|
+|loi|A list of illustrations.|
+|lot|A list of tables.|
+|notes|A brief summary or record in writing.|
+|preface|A statement written as an introduction to the publication, typically explaining its scope, intention, method, etc; foreword.|
+|text|First "real" page of content (e.g. "Chapter 1").|
+
+h3. Table of contents
+
+bc..
+<!ELEMENT toc EMPTY>
+<!ATTLIST toc
+ id ID #IMPLIED
+ generate %boolean; #IMPLIED
+ file CDATA #IMPLIED>
+
+p. Exactly one **toc** element is used to declare a table of contents. There are two ways of doing this. Either by pointing to a readily prepared __ncx__ file using the **file** attribute or by setting **generate** to **true**. This will iterate through all the elements in the spine and figure out the table of contents based on the header elements.
+
+p. If the **file** attribute is used the task will automatically do the house-keeping. The file will be copied into the OEPBS folder of the publication, it will be placed first in the content declaration and properly referenced.
+
+p. If this element is not used - a table of contents will still be generated in order to satisfy EPUB requirements. However it will be empty.
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/epub-format.textile b/org.eclipse.mylyn.docs.epub.help/docs/epub-format.textile
new file mode 100644
index 000000000..4a1b56cc5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/epub-format.textile
@@ -0,0 +1,19 @@
+h1. The EPUB file format
+
+p. The __EPUB file format__ is basically a ZIP-file with a defined set of contents. The first file in the container is a file by the ASCII name of "mimetype" which holds the MIME type for the ZIP container. This file must be treated a bit special as the contents are defined and the file must not be compressed, nor encrypted and there must be no extra fields in it's ZIP header.
+
+p. The EPUB also have a META-INF folder that contains a file named __container.xml__. This declares the format of the publication(s) and points to the main entry, which in most cases is __content.opf__. If there is a table of contents (__toc.ncx__) the main entry will point to it.
+
+p. "The OCF (Open Container Format) specification":http://idpf.org/epub/20/spec/OCF_2.0.1_draft.doc states that one can add multiple publications to one EPUB. For instance an OEBPS (aka EPUB) and one PDF. Or two OEBPS publications in different languages. While the current API does handle this - the Ant task or UI action does not.
+
+p. The actual content of an EPUB version 2.0.1 formatted publication may be of the following OPS Core Media types:
+* XHTML (but only with a subset of the full HTML element types).
+* Cascading Style Sheets (CSS) for styling of the publication.
+* Graphics in the form of SVG, PNG, GIF and JPEG formatted files.
+* Fonts as TTF or OTF.
+
+Other types may be used, but then a __fallback__ item must be specified for reading systems that does not support the type. This tooling currently does not support the fallback mechanism.
+
+!Illustrations.002.jpg(Contents of a example EPUB container.)!
+
+The illustration shows the contents of an example publication. The marked files and folders marked are ones created by the EPUB tooling.
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/examples.textile b/org.eclipse.mylyn.docs.epub.help/docs/examples.textile
new file mode 100644
index 000000000..b4439149e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/examples.textile
@@ -0,0 +1,59 @@
+h1. Practical examples
+
+h2. Building the example book
+
+The example below shows the how the example book is assembled. If you want to play around with it, you will find the examples project in the "org.eclipse.mylyn.docs":http://git.eclipse.org/c/mylyn/org.eclipse.mylyn.docs.git/ Git repository.
+
+h2. Adding a cover
+
+p. Correctly adding a cover to a publication can be a bit awkward as different reading systems expect different input. So there is a shortcut:
+
+bc..
+<cover image="cover.jpg" title="My Title"/>
+
+p. Simply point to the file in question and this EPUB tooling will take care of the rest. There is of course another, more laborious way allowing more control. The procedure is as follows:
+
+# Add a cover image to the publication
+# Add a HTML file using the image
+# Reference the HTML file
+# Add a meta element pointing to the image
+
+p. Assuming the cover image is at hand we will add it using the **item** element as this:
+
+bc..
+<item file="images/cover.jpg" id="cover-image"
+ type="image/jpg" spine="false" />
+
+p. Next we add a XHTML file (named __cover.html__) to the publication. This will be used by some reading systems.
+
+bc..
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Cover Page</title>
+ <style type="text/css">
+ img { max-width: 100%; }
+ </style>
+ </head>
+ <body>
+ <div id="cover-image">
+ <img src="cover.jpg" alt="Building EPUBs"/>
+ </div>
+ </body>
+</html>
+
+p. Then some more Ant code:
+
+bc..
+<item file="cover.xhtml"/>
+<reference href="cover.xhtml"
+ type="cover" title="Cover Page" />
+<meta name="cover" content="cover-image"/>
+
+p. Both methods will produce a cover page that will work with all the tested reading systems; including Syny Reader PRS-T1, Calibre, iBooks, Nook for Mac, Adobe Digital Editions for Mac and Kindle (after converting to MOBI using Calibre).
+
+!nook-cover.png(The cover of this book as it is rendered on Nook for Mac.)!
+
+p. The end result can be something like the illustration above - showing the cover of the example book as it is rendered on Nook for Mac.
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/generate-ant.textile b/org.eclipse.mylyn.docs.epub.help/docs/generate-ant.textile
new file mode 100644
index 000000000..f28485068
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/generate-ant.textile
@@ -0,0 +1,21 @@
+h1. Generate EPUB using Ant
+
+p. Using the **epub** Ant task one can assemble an EPUB during continuous building or from within Eclipse. The example below shows a complete minimum Ant script.
+
+bc.
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Build an EPUB" default="build">
+ <target name="build">
+ <epub file="My Book.epub">
+ <title>My Book</title>
+ <subject>My Book's subject</subject>
+ <item file="my_chapter.xhtml" />
+ </epub>
+ </target>
+</project>
+
+p. In this example only some of the required properties have been specified, the rest will be automatically added. See the comprehensive description of the "epub":epub-ant-task.html Ant task for details. A more complete example is found in the "examples":examples.html chapter.
+
+p. Note that in order for the script to execute the epub task must be in the classpath. If you execute the script from within Eclipse simply make sure that the runtime environment of the workspace is used as shown in the illustration below.
+
+!runtime-jre.png(External task launch configuration.)! \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.png b/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.png
new file mode 100644
index 000000000..bdd8493b1
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.png
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.textile b/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.textile
new file mode 100644
index 000000000..a68beeb8a
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.textile
@@ -0,0 +1,7 @@
+h1. Generate EPUB directly from markup
+
+p. Lightweight wikitext markup can easily be converted into EPUBs. From within Eclipse right click on any supported markup file (ending in @*.textile@, @*.mediawiki@ etc), then select **Wikitext > Generate EPUB** from the context menu. This will bring up a wizard as illustrated below.
+
+!generate-epub.png!
+
+As the EPUB specification requires that certain properties are set for a publication - this dialog will offer the user interface for setting these. At a minimum you will have to enter a **title**, **language** and **subject**.
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/introduction.textile b/org.eclipse.mylyn.docs.epub.help/docs/introduction.textile
new file mode 100644
index 000000000..8ab0f9985
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/introduction.textile
@@ -0,0 +1,30 @@
+h1. Introduction
+
+p. Electronic books are everywhere these days and new reading devices seem to be announced monthly. With a few exceptions (e.g. Amazon's Kindle) - all of these can display books formatted as EPUB. There are also a few decent desktop applications capable of displaying EPUBs. With this abundance of reading systems it could be wise to take advantage of the situation and publish for instance user guides and manuals in this format. This way users can read them at home, at the desktop and everywhere in between. Most reading systems also supports annotating and bookmarking with synchronization between devices.
+
+p. There are several ways of assembling EPUBs: You can write a document in Apple's __Pages__ and directly export to EPUB. You can for example write it in Microsoft's __Word__ and convert it to EPUB using "EPUBGen":http://code.google.com/p/epub-tools/, in DocBook and convert it using "docbook2epub":http://code.google.com/p/epub-tools/ or even manually assembling the publication using various command line tools. The popular "Calibre":http://calibre-ebook.com/ tool can also be used to create a number of formats. All these methods have their merits but few can be easily used to assemble publications during a __continuous build__ and none can be used without adding a few extra dependencies such as Ruby or Python.
+
+p. Hence the primary goal of the EPUB support in Mylyn Docs is to create a mechanism that allows consistent building of EPUB files adhering to all relevant standards, using ANT tasks, while introducing as few dependencies as possible (only Java and parts of Eclipse). The secondary goal is to create an API that can be used for manipulating EPUBs. For instance loading an existing publication and altering it's contents or metadata.
+
+p. The EPUB support in Eclipse is built around an EMF data model describing the publication along with various mechanisms to manipulate this structure and assemble a EPUB file. The model is expressed in "Ecore":http://wiki.eclipse.org/Ecore, representing the "Open Packaging Format (OPF)":http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm, a subset of Dublin Core and the Navigation Control File (NCX). All required parts of a properly assembled EPUB file following the 2.0.1 revision of the standard.
+
+p. The mechanisms mentioned is an API for handling the EPUB and a Ant task that can be used during building. The following code shows the minimum Ant script required to generate a publication.
+
+bc..
+<epub file="My Book.epub">
+ <title>My Book</title>
+ <subject>My Book's subject</subject>
+ <item file="my_chapter.xhtml" />
+</epub>
+
+p. Some of the fields required by will be automatically created and added to the publication when not specified in the Ant script. The table of contents will for instance be automatically created, the language set to __en__ for "English" and an identifier (based on UUID) will be generated. Details can be found in the chapter describing the "epub":epub-ant-task.html Ant task.
+
+h2. Learning more
+
+If you would like to learn more about building EPUBs you may want to take a look at following resources:
+
+* Elizabeth Castro: EPUB Straight to the Point - ISBN: 9780132366984
+* International Digital Publishing Forum: "EPUB":http://idpf.org/epub
+* Liza Daly: "Build a digital book with EPUB":http://www.ibm.com/developerworks/xml/tutorials/x-epubtut/index.html
+* Harrison Ainsworth: "Epub Format Construction Guide":http://www.hxa.name/articles/content/epub-guide_hxa7241_2007.html
+
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/nook-cover.png b/org.eclipse.mylyn.docs.epub.help/docs/nook-cover.png
new file mode 100644
index 000000000..8c9852511
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/nook-cover.png
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/preface.textile b/org.eclipse.mylyn.docs.epub.help/docs/preface.textile
new file mode 100644
index 000000000..eb0141c35
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/preface.textile
@@ -0,0 +1,5 @@
+h1. Preface
+
+h2. Who should read this book
+
+p. The purpose of this publication is to describe the \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/runtime-jre.png b/org.eclipse.mylyn.docs.epub.help/docs/runtime-jre.png
new file mode 100644
index 000000000..44fef4081
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/runtime-jre.png
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/source/Illustrations.key b/org.eclipse.mylyn.docs.epub.help/docs/source/Illustrations.key
new file mode 100644
index 000000000..733d9939f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/source/Illustrations.key
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.help/docs/style.css b/org.eclipse.mylyn.docs.epub.help/docs/style.css
new file mode 100644
index 000000000..45748bcde
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/docs/style.css
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+
+table, td, th {
+ border-color: gray;
+ border-style: solid;
+}
+
+table {
+ width: 100%;
+ border-width: 0 0 1px 1px;
+ border-spacing: 0;
+ border-collapse: collapse;
+ margin: 1em;
+ padding: 1em;
+ }
+
+td, th {
+ margin: 0;
+ padding: 4px;
+ border-width: 1px 1px 0 0;
+ font-size: 0.9em;
+}
+
+th {
+ background-color: #c0c0c0;
+ color: #ffffff;
+ font-weight: bold;
+}
+
+td {
+ background-color: #f0f0f0;
+}
diff --git a/org.eclipse.mylyn.docs.epub.help/plugin.xml b/org.eclipse.mylyn.docs.epub.help/plugin.xml
new file mode 100644
index 000000000..72a86d53e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension point="org.eclipse.help.toc">
+ <toc file="help/introduction-toc.xml" primary="false"/>
+ <toc file="help/epub-format-toc.xml" primary="false"/>
+ <toc file="help/generate-ant-toc.xml" primary="false"/>
+ <toc file="help/generate-epub-toc.xml" primary="false"/>
+ <toc file="help/epub-ant-task-toc.xml" primary="false"/>
+ <toc file="help/examples-toc.xml" primary="false"/>
+ <toc file="toc.xml" primary="true"/>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.mylyn.docs.epub.help/pom.xml b/org.eclipse.mylyn.docs.epub.help/pom.xml
new file mode 100644
index 000000000..0711a7dfd
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub.help</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+
+ <properties>
+ <test.suite>${project.artifactId}.AllTests</test.suite>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <configuration>
+ <target>
+ <pathconvert refid="maven.compile.classpath" property="compile_classpath"/>
+ <ant antfile="build-docs.xml" inheritAll="true"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ <dependencies>
+ <!-- Make sure these are built first -->
+ <dependency>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <artifactId>org.eclipse.mylyn.wikitext.core</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <artifactId>org.eclipse.mylyn.wikitext.textile.core</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+
+ </build>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.help/src/readme.txt b/org.eclipse.mylyn.docs.epub.help/src/readme.txt
new file mode 100644
index 000000000..c98429c4b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/src/readme.txt
@@ -0,0 +1 @@
+Placeholder for future source code. \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.help/toc.xml b/org.eclipse.mylyn.docs.epub.help/toc.xml
new file mode 100644
index 000000000..2ed5043cb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.help/toc.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2007, 2009 David Green and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ David Green - initial API and implementation
+ -->
+<toc label="Mylyn Docs EPUB Documentation" link_to="../org.eclipse.mylyn.help.ui/primary-toc.xml#additions">
+ <topic label="EPUB User Guide">
+ <link toc="help/introduction-toc.xml"/>
+ <link toc="help/epub-format-toc.xml"/>
+ <link toc="help/generate-ant-toc.xml"/>
+ <link toc="help/generate-epub-toc.xml"/>
+ <link toc="help/epub-ant-task-toc.xml"/>
+ <link toc="help/examples-toc.xml"/>
+ </topic>
+ <anchor id="additions"/>
+</toc>
diff --git a/org.eclipse.mylyn.docs.epub.tests/.classpath b/org.eclipse.mylyn.docs.epub.tests/.classpath
new file mode 100644
index 000000000..7f56a6284
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry exported="true" kind="lib" path="epubcheck/lib/jing.jar"/>
+ <classpathentry exported="true" kind="lib" path="epubcheck/lib/saxon.jar"/>
+ <classpathentry exported="true" kind="lib" path="epubcheck/epubcheck-1.2.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.docs.epub.tests/.gitignore b/org.eclipse.mylyn.docs.epub.tests/.gitignore
new file mode 100644
index 000000000..fccf0f5f3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.gitignore
@@ -0,0 +1,4 @@
+/test
+/org.eclipse*/bin
+/org.eclipse*/target
+/epubcheck
diff --git a/org.eclipse.mylyn.docs.epub.tests/.project b/org.eclipse.mylyn.docs.epub.tests/.project
new file mode 100644
index 000000000..18f21198d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..9d8c255bb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:56 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..b32a05408
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Sat Oct 08 16:01:56 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..21a60005f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Sun May 01 22:36:28 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..8114e543b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Mylyn EPUB Tests
+Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.tests
+Bundle-Version: 0.8.0.qualifier
+Bundle-Vendor: Torkild U. Resheim
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.emf.databinding.edit;bundle-version="1.2.0",
+ org.eclipse.emf.ecore.change.edit;bundle-version="2.5.0",
+ org.eclipse.emf.ecore.editor;bundle-version="2.6.0",
+ org.eclipse.emf.exporter;bundle-version="2.6.0",
+ org.eclipse.emf.importer;bundle-version="2.6.0",
+ org.eclipse.emf.mapping.ecore2ecore.editor;bundle-version="2.4.0",
+ org.eclipse.emf.mapping.ecore2xml.ui;bundle-version="2.5.0",
+ org.junit,
+ org.apache.ant;bundle-version="1.8.2",
+ org.eclipse.mylyn.docs.epub.core,
+ org.apache.ant.source;bundle-version="1.8.2"
+Bundle-ClassPath: .,
+ epubcheck/epubcheck-1.2.jar,
+ epubcheck/lib/jing.jar,
+ epubcheck/lib/saxon.jar
+Import-Package: org.junit
diff --git a/org.eclipse.mylyn.docs.epub.tests/ant-test.xml b/org.eclipse.mylyn.docs.epub.tests/ant-test.xml
new file mode 100644
index 000000000..a79ad1370
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/ant-test.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Test markup-to-epub" basedir=".">
+ <property name="testdir" location="${basedir}/test/ant" />
+ <property name="srcdir" location="${basedir}/testdata" />
+
+ <path id="java.class.path">
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <path id="epub-classpath">
+ <pathelement location="${basedir}/../org.eclipse.mylyn.docs.epub.core/bin/" />
+ <pathelement location="${basedir}/../org.eclipse.mylyn.docs.epub.ant.core/bin/" />
+ </path>
+
+ <taskdef classpathref="epub-classpath" resource="org/eclipse/mylyn/docs/epub/ant/tasks.properties" />
+
+ <!-- Prepare source files that we need for the tests -->
+ <target name="init">
+ <delete dir="${testdir}" failonerror="false">
+ <fileset dir="${testdir}">
+ <include name="**/*" />
+ </fileset>
+ </delete>
+ <mkdir dir="${testdir}" />
+ </target>
+
+ <target name="test.publication">
+ <epub identifierId="uuid" file="${testdir}/simple.epub" workingFolder="${testdir}/work">
+ <title>Mylyn Docs Test EPUB</title>
+ <language code="en" />
+ <identifier id="uuid" scheme="UUID">urn:uuid:15bcb770-882d-11e0-9d78-0800200c9a66</identifier>
+ <subject>Testing</subject>
+ <creator fileAs="Resheim, Torkild U." role="aut" name="Torkild U. Resheim"/>
+ <publisher>Eclipse.org</publisher>
+ <item file="${srcdir}/plain-page.xhtml" />
+ </epub>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/build.properties b/org.eclipse.mylyn.docs.epub.tests/build.properties
new file mode 100644
index 000000000..49a802fe5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ epubcheck/epubcheck-1.2.jar,\
+ epubcheck/lib/jing.jar,\
+ epubcheck/lib/saxon.jar
diff --git a/org.eclipse.mylyn.docs.epub.tests/pom.xml b/org.eclipse.mylyn.docs.epub.tests/pom.xml
new file mode 100644
index 000000000..504f9194b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub.tests</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-test-plugin</packaging>
+
+ <properties>
+ <platform-version-name>indigo</platform-version-name>
+ <eclipse-site>http://download.eclipse.org/releases/${platform-version-name}</eclipse-site>
+ <test.suite>${project.artifactId}.AllTests</test.suite>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>indigo</id>
+ <name>Eclipse Indigo p2 Repository</name>
+ <layout>p2</layout>
+ <url>${eclipse-site}</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <phase>initialize</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${basedir}/epubcheck/" />
+ <get src="http://epubcheck.googlecode.com/files/epubcheck-1.2.zip" dest="${basedir}/epubcheck/epubcheck-1.2.zip"/>
+ <unzip src="${basedir}/epubcheck/epubcheck-1.2.zip" dest="${basedir}/epubcheck/" />
+ <delete file="${basedir}/epubcheck/epubcheck-1.2.zip" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-surefire-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <useUIHarness>false</useUIHarness>
+ <testSuite>${project.artifactId}</testSuite>
+ <testClass>${test.suite}</testClass>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <resolver>p2</resolver>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/AllTests.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/AllTests.java
new file mode 100644
index 000000000..89fb97b00
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/AllTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.mylyn.docs.epub.tests.api.TestEPUB;
+import org.eclipse.mylyn.docs.epub.tests.api.TestOPS2Publication;
+import org.eclipse.mylyn.docs.epub.tests.api.TestOPSPublication;
+import org.eclipse.mylyn.docs.epub.tests.core.TestOPS2Validator;
+import org.eclipse.mylyn.docs.epub.tests.core.TestTOCGenerator;
+
+public class AllTests {
+ public static Test suite() {
+ return suite(false);
+ }
+
+ public static Test suite(boolean defaultOnly) {
+ TestSuite suite = new TestSuite("Tests for org.eclipse.mylyn.docs.epub");
+ // API tests
+ suite.addTestSuite(TestEPUB.class);
+ suite.addTestSuite(TestOPS2Publication.class);
+ suite.addTestSuite(TestOPSPublication.class);
+ // Core tests
+ suite.addTestSuite(TestOPS2Validator.class);
+ suite.addTestSuite(TestTOCGenerator.class);
+ // Ant tests
+ // TODO: Also execute ANT tests.
+ // suite.addTestSuite(TestAntTask.class);
+ return suite;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAPI.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAPI.java
new file mode 100644
index 000000000..064acbfb2
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAPI.java
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Locale;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.Assert;
+
+import org.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.opf.Role;
+import org.eclipse.mylyn.docs.epub.opf.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.adobe.epubcheck.api.EpubCheck;
+
+/**
+ *
+ * @author Torkild U. Resheim
+ *
+ */
+public class TestAPI {
+
+ private File testRoot;
+
+ private File packingFolder;
+
+ private void delete(File f) throws IOException {
+ if (f.isDirectory()) {
+ for (File c : f.listFiles())
+ delete(c);
+ }
+
+ if (f.exists() && !f.delete())
+ throw new FileNotFoundException("Failed to delete file: " + f);
+ }
+
+ private boolean fileExists(String filename) {
+ String path = packingFolder.getAbsolutePath() + File.separator
+ + "OEBPS" + File.separator + filename;
+ File file = new File(path);
+ return file.exists();
+ }
+
+ private File getFile(String path) throws URISyntaxException {
+ return new File(path);
+ }
+
+ /**
+ * Reads the OPF into a DOM for further analysis.
+ *
+ * @return the DOM document element
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ private Element readOPF() throws ParserConfigurationException,
+ SAXException, IOException {
+ File fXmlFile = new File(packingFolder.getAbsolutePath()
+ + File.separator + "OEBPS" + File.separator + "content.opf");
+ Assert.assertEquals(true, fXmlFile.exists());
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ Document doc = dBuilder.parse(fXmlFile);
+ doc.getDocumentElement().normalize();
+ return doc.getDocumentElement();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ packingFolder = getFile("test/api/pack");
+ testRoot = getFile("test/api/");
+ delete(testRoot);
+ }
+
+ @After
+ public void tearDown() {
+
+ }
+
+ /**
+ * Tests node attributes.
+ *
+ * @param node
+ * the node to test
+ * @param ids
+ * expected identifiers
+ * @param values
+ * expected values
+ */
+ private void testAttributes(Node node, String[] ids, String[] values) {
+ Assert.assertEquals(ids.length, values.length);
+ Assert.assertEquals(
+ "Wrong number of attributes in '" + node.getNodeName() + "'",
+ ids.length, node.getAttributes().getLength());
+ for (int x = 0; x < ids.length; x++) {
+ Assert.assertEquals("No such node '" + ids[x] + "'", true,
+ node.getAttributes().getNamedItem(ids[x]) != null);
+ Assert.assertEquals(values[x],
+ node.getAttributes().getNamedItem(ids[x]).getNodeValue());
+ }
+ }
+
+ /**
+ * Creates a new simple EPUB and tests whether it can be validated using
+ * "epubcheck".
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testPackSimpleEPUB() throws Exception {
+ File epubfile = new File(testRoot.getAbsolutePath() + File.separator + "simple.epub");
+ createSimpleEPUB(epubfile);
+ EpubCheck checker = new EpubCheck(epubfile);
+ Assert.assertTrue(checker.validate());
+ }
+
+ /**
+ * Creates a very simple EPUB file with only required metadata added and one
+ * single page.
+ *
+ * @return the new EPUB file
+ * @throws URISyntaxException
+ * @throws Exception
+ */
+ private OPSPublication createSimpleEPUB(File epubfile) throws URISyntaxException, Exception {
+ OPSPublication ops = OPSPublication.getVersion2Instance();
+ ops.addTitle(null, null, "Mylyn Docs Test EPUB");
+ ops.addSubject(null, null, "Testing");
+ ops.addItem(getFile("testdata/plain-page.xhtml"));
+ ops.setGenerateToc(true);
+ EPUB epub = new EPUB();
+ epub.add(ops);
+ epub.pack(epubfile, packingFolder);
+ return ops;
+ }
+
+ /**
+ * See if all contributors are serialised properly.
+ * <ul>
+ * <li>Wrong number of attributes due to EMF default value handling.</li>
+ * <li>Unexpected attribute names and or values.</li>
+ * <li>Wrong element value.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSerializationContributors() throws Exception {
+ OPSPublication ops = OPSPublication.getVersion2Instance();
+ File epubfile = new File(testRoot.getAbsolutePath() + File.separator + "simple.epub");
+ Role[] roles = Role.values();
+ for (Role role : roles) {
+ ops.addContributor(role.getLiteral(), Locale.ENGLISH,
+ "Nomen Nescio", role, "Nescio, Nomen");
+ }
+ EPUB epub = new EPUB();
+ epub.add(ops);
+ ops.addItem(new File("testdata/plain-page.xhtml"));
+ epub.pack(epubfile, packingFolder);
+ Element doc = readOPF();
+ Node guide = doc.getElementsByTagName("opf:metadata").item(0);
+ Node node = guide.getFirstChild(); // Discard first TEXT node
+ node = discard(node); // title
+ node = discard(node); // subject
+ String[] ids = new String[] { "id", "xml:lang", "opf:role",
+ "opf:file-as" };
+ for (Role role : roles) {
+ node = node.getNextSibling();
+ String[] values = new String[] { role.getLiteral(),
+ Locale.ENGLISH.getLanguage(),
+ role.getLiteral(), "Nescio, Nomen" };
+ assertNode(node, "dc:contributor", "Nomen Nescio");
+ testAttributes(node, ids, values);
+ node = node.getNextSibling(); // Discard next TEXT node
+ }
+ }
+
+ private Node discard(Node node) {
+ node = node.getNextSibling(); // Discard element node
+ node = node.getNextSibling(); // Discard TEXT node
+ return node;
+ }
+
+ private void assertNode(Node node, String name, String value) {
+ Assert.assertEquals(name, node.getNodeName());
+ if (value != null) {
+ Assert.assertEquals(value, node.getFirstChild().getNodeValue());
+ }
+ }
+
+
+ /**
+ * Checks the contents of the OPF when nothing has been added to the
+ * publication.
+ * <ul>
+ * <li>There should be a table of contents</li>
+ * <li>The metadata, manifest, spine and guide elements should exist.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSerializationEmpty() throws Exception {
+ OPSPublication ops = OPSPublication.getVersion2Instance();
+ File epubfile = new File(testRoot.getAbsolutePath() + File.separator + "simple.epub");
+ EPUB epub = new EPUB();
+ epub.add(ops);
+ ops.addItem(new File("testdata/plain-page.xhtml"));
+ epub.pack(epubfile, packingFolder);
+ Element doc = readOPF();
+ Assert.assertEquals("opf:package", doc.getNodeName());
+ NodeList nl = doc.getChildNodes();
+ // Text nodes in between
+ Assert.assertEquals("opf:metadata", nl.item(1).getNodeName());
+ Assert.assertEquals("opf:manifest", nl.item(3).getNodeName());
+ Assert.assertEquals("opf:spine", nl.item(5).getNodeName());
+ Assert.assertEquals("opf:guide", nl.item(7).getNodeName());
+
+ // Table of contents
+ Node toc = nl.item(3).getFirstChild().getNextSibling();
+ Assert.assertEquals("opf:item", toc.getNodeName());
+ Assert.assertEquals("ncx", toc.getAttributes().getNamedItem("id")
+ .getNodeValue());
+ Assert.assertEquals("toc.ncx", toc.getAttributes().getNamedItem("href")
+ .getNodeValue());
+ Assert.assertEquals("application/x-dtbncx+xml", toc.getAttributes()
+ .getNamedItem("media-type")
+ .getNodeValue());
+ Assert.assertEquals(true, fileExists("toc.ncx"));
+ Node spine = nl.item(5);
+ Assert.assertEquals("ncx", spine.getAttributes().getNamedItem("toc")
+ .getNodeValue());
+ doc = null;
+ }
+
+ /**
+ * See if all references are serialised properly.
+ * <ul>
+ * <li>Wrong number of attributes due to EMF default value handling.</li>
+ * <li>Unexpected attribute names and or values</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSerializationReferences() throws Exception {
+ OPSPublication ops = OPSPublication.getVersion2Instance();
+ File epubfile = new File(testRoot.getAbsolutePath() + File.separator + "simple.epub");
+ Type[] types = Type.values();
+ for (Type type : types) {
+ ops.addReference(type.getLiteral() + ".xhtml", type.getName(),
+ type);
+ }
+ EPUB epub = new EPUB();
+ ops.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(ops);
+ epub.pack(epubfile, packingFolder);
+ Element doc = readOPF();
+ Node guide = doc.getElementsByTagName("opf:guide").item(0);
+ Node ref = guide.getFirstChild(); // Discard first TEXT node
+ String[] ids = new String[] { "title", "href", "type" };
+ for (Type type : types) {
+ ref = ref.getNextSibling();
+ // The should be exactly three attributes
+ Assert.assertEquals(
+ "Wrong number of attributes in '" + type.getLiteral() + "'",
+ 3,
+ ref.getAttributes().getLength());
+ String[] values = new String[] { type.getName(),
+ type.getLiteral() + ".xhtml", type.getLiteral() };
+ testAttributes(ref, ids, values);
+ ref = ref.getNextSibling();
+ }
+ doc = null;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAntTask.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAntTask.java
new file mode 100644
index 000000000..360dd7abf
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestAntTask.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.Assert;
+
+import org.apache.tools.ant.BuildFileTest;
+
+import com.adobe.epubcheck.api.EpubCheck;
+
+/**
+ * Tests for the <b>epub</b> ANT task.
+ *
+ * @author Torkild U. Resheim
+ */
+public class TestAntTask extends BuildFileTest {
+
+ static ClassLoader classLoader;
+
+ private static final String SIMPLE_FILE_PATH = "test/ant/simple.epub";
+
+ private static final String DOC_FILE_PATH = "../org.eclipse.mylyn.docs.epub.help/Building_EPUBs.epub";
+
+ public TestAntTask(String s) {
+ super(s);
+ classLoader = getClass().getClassLoader();
+ }
+
+ private void assertEpub(String file) {
+ File f = getFile(file);
+ assertTrue("Missing publication " + file, f.exists());
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ EpubCheck checker = new EpubCheck(f, pw);
+ checker.validate();
+ Assert.assertTrue(sw.getBuffer().toString().trim(), checker.errorCount == 0);
+ }
+
+ private File getFile(String file) {
+ return new File(getProjectDir().getAbsolutePath() + File.separator + file);
+ }
+
+ @Override
+ public void setUp() {
+ configureProject("ant-test.xml");
+ project.setCoreLoader(this.getClass().getClassLoader());
+ }
+
+ /**
+ * Creates a simple book using the Ant task and tests it using the epub
+ * validator.
+ */
+ public void testSimplePublication() {
+ executeTarget("init");
+ executeTarget("test.publication");
+ assertEpub(SIMPLE_FILE_PATH);
+ }
+
+ /**
+ * Tests the "Building EPUBs" book (generated using the Ant task) using the
+ * epub validator. This book is assembled by building the
+ * "org.eclipse.mylyn.docs.epub.ui" bundle. The book contents is converted
+ * from Textile markup to HTML using WikiText.
+ */
+ public void testDocumentationBook() {
+ File file = getFile(DOC_FILE_PATH);
+ assertTrue("Missing publication " + file, file.exists());
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ EpubCheck checker = new EpubCheck(file, pw);
+ checker.validate();
+ Assert.assertTrue(sw.getBuffer().toString().trim(), checker.errorCount == 0);
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestOPS2Validator.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestOPS2Validator.java
new file mode 100644
index 000000000..ba614c163
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestOPS2Validator.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.Assert;
+
+import org.eclipse.mylyn.internal.docs.epub.core.OPS2Validator;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests for the OPS2 validator.
+ *
+ * @author Torkild U. Resheim
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm
+ */
+@SuppressWarnings("restriction")
+public class TestOPS2Validator {
+
+ private final String[] illegalAttributes = new String[] { "anything", "goes", "in", "here" };
+
+ private final String[] illegalElements = new String[] { "anything", "goes", "in", "here" };
+
+ private final String[] legalAttributes = new String[] { "accesskey", "charset", "class", "coords", "dir", "href",
+ "hreflang", "id", "rel", "rev", "shape", "style", "tabindex", "target", "title", "type", "xml:lang" };
+
+ /**
+ * A list of legal elements according to the EPUB 2.0.1 specification
+ *
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section1.3.4
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section2.2
+ */
+ private final String[] legalElements = new String[] { "body", "head", "html", "title", "abbr", "acronym",
+ "address", "blockquote", "br", "cite", "code", "dfn", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6",
+ "kbd", "p", "pre", "q", "samp", "span", "strong", "var", "a", "dl", "dt", "dd", "ol", "ul", "li", "object",
+ "param", "b", "big", "hr", "i", "small", "sub", "sup", "tt", "del", "ins", "bdo", "caption", "col",
+ "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "img", "area", "map", "style", "link",
+ "base" };
+
+ @Test
+ public void testIllegalAttributes() throws ParserConfigurationException, SAXException, IOException {
+ for (String attr : illegalAttributes) {
+ String in = "<html><body><div " + attr + "=\"test\">content</div></body></html>";
+ String expected = "<html><body><div>content</div></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(expected, out);
+ }
+ }
+
+ @Test
+ public void testIllegalElements() throws ParserConfigurationException, SAXException, IOException {
+ for (String element : illegalElements) {
+ String in = "<html><body><" + element + "></" + element + "></body></html>";
+ String result = "<html><body></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(result, out);
+
+ }
+ }
+
+ @Test
+ public void testLegalAttributes() throws ParserConfigurationException, SAXException, IOException {
+ for (String attr : legalAttributes) {
+ String in = "<html><body><div " + attr + "=\"test\"></div></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+ }
+ }
+
+ @Test
+ public void testLegalElements() throws ParserConfigurationException, SAXException, IOException {
+ for (String element : legalElements) {
+ String in = "<html><body><" + element + ">content</" + element + "></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+
+ }
+ }
+
+ @Test
+ public void testNormal() throws ParserConfigurationException, SAXException, IOException {
+ String in = "<body><h1 id=\"h1-1\">test</h1></body>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestTOCGenerator.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestTOCGenerator.java
new file mode 100644
index 000000000..14520598e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/TestTOCGenerator.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.Assert;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.mylyn.docs.epub.ncx.NCXFactory;
+import org.eclipse.mylyn.docs.epub.ncx.NavMap;
+import org.eclipse.mylyn.docs.epub.ncx.NavPoint;
+import org.eclipse.mylyn.docs.epub.ncx.Ncx;
+import org.eclipse.mylyn.internal.docs.epub.core.TOCGenerator;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests for the table of contents generator.
+ *
+ * @author Torkild U. Resheim
+ */
+@SuppressWarnings("restriction")
+public class TestTOCGenerator {
+
+ @Test
+ public void testNormal() throws ParserConfigurationException, SAXException,
+ IOException {
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h2 id='h2-1'>test</h2>" +
+ "<h2 id='h2-2'>test</h2>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ Assert.assertEquals(2, points.get(0).getNavPoints().size());
+ Assert.assertEquals(1, points.get(0).getNavPoints().get(1).getNavPoints().size());
+ }
+
+ @Test
+ public void testMissingIdentifier() throws ParserConfigurationException, SAXException, IOException{
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h2>test</h2>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ Assert.assertEquals(0, points.get(0).getNavPoints().size());
+ }
+
+ /**
+ * All items should be placed at the root.
+ *
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ @Test
+ public void testCrazyStructure() throws ParserConfigurationException, SAXException, IOException{
+ String html = "<body>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h2 id='h2-1'>test</h2>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ for (NavPoint navPoint : points) {
+ System.out.println(navPoint);
+ }
+ Assert.assertEquals(3,points.size());
+ }
+
+ @Test
+ public void testMissingParent() throws ParserConfigurationException,
+ SAXException, IOException {
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ Assert.assertEquals(1, points.get(0).getNavPoints().size());
+ }
+
+
+ private Ncx createNcx() {
+ Ncx ncx = NCXFactory.eINSTANCE.createNcx();
+ NavMap navMap = NCXFactory.eINSTANCE.createNavMap();
+ ncx.setNavMap(navMap);
+ return ncx;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/ant/TestAntTask.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/ant/TestAntTask.java
new file mode 100644
index 000000000..6e26cf81c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/ant/TestAntTask.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests.ant;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.Assert;
+
+import org.apache.tools.ant.BuildFileTest;
+
+import com.adobe.epubcheck.api.EpubCheck;
+
+/**
+ * Tests for the <b>epub</b> ANT task.
+ *
+ * @author Torkild U. Resheim
+ */
+public class TestAntTask extends BuildFileTest {
+
+ static ClassLoader classLoader;
+
+ private static final String SIMPLE_FILE_PATH = "test/ant/simple.epub";
+
+ private static final String DOC_FILE_PATH = "../org.eclipse.mylyn.docs.epub.help/Building_EPUBs.epub";
+
+ public TestAntTask(String s) {
+ super(s);
+ classLoader = getClass().getClassLoader();
+ }
+
+ private void assertEpub(String file) {
+ File f = getFile(file);
+ assertTrue("Missing publication " + file, f.exists());
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ EpubCheck checker = new EpubCheck(f, pw);
+ checker.validate();
+ Assert.assertTrue(sw.getBuffer().toString().trim(), checker.errorCount == 0);
+ }
+
+ private File getFile(String file) {
+ return new File(getProjectDir().getAbsolutePath() + File.separator + file);
+ }
+
+ @Override
+ public void setUp() {
+ configureProject("ant-test.xml");
+ project.setCoreLoader(this.getClass().getClassLoader());
+ }
+
+ /**
+ * Creates a simple book using the Ant task and tests it using the epub
+ * validator.
+ */
+ public void testSimplePublication() {
+ executeTarget("init");
+ executeTarget("test.publication");
+ assertEpub(SIMPLE_FILE_PATH);
+ }
+
+ /**
+ * Tests the "Building EPUBs" book (generated using the Ant task) using the
+ * epub validator. This book is assembled by building the
+ * "org.eclipse.mylyn.docs.epub.ui" bundle. The book contents is converted
+ * from Textile markup to HTML using WikiText.
+ */
+ public void testDocumentationBook() {
+ File file = getFile(DOC_FILE_PATH);
+ assertTrue("Missing publication " + file, file.exists());
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ EpubCheck checker = new EpubCheck(file, pw);
+ checker.validate();
+ Assert.assertTrue(sw.getBuffer().toString().trim(), checker.errorCount == 0);
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/AbstractTest.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/AbstractTest.java
new file mode 100644
index 000000000..129a3f1d0
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/AbstractTest.java
@@ -0,0 +1,88 @@
+package org.eclipse.mylyn.docs.epub.tests.api;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil.FeatureEList;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.mylyn.docs.epub.dc.DCType;
+import org.eclipse.mylyn.docs.epub.dc.Identifier;
+import org.junit.After;
+import org.junit.Before;
+
+public abstract class AbstractTest extends TestCase {
+ protected final File epubFile = new File("test" + File.separator + "test.epub");
+
+ protected final File epubFolder = new File("test" + File.separator + "epub");
+
+ protected static final EStructuralFeature TEXT = XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Text();
+
+ @SuppressWarnings("rawtypes")
+ public String getText(DCType identifier) {
+ FeatureMap fm = identifier.getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getText(Identifier element) {
+ FeatureMap fm = element.getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ return null;
+ }
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ epubFolder.mkdirs();
+ }
+
+ private boolean deleteFolder(File folder) {
+ if (folder.isDirectory()) {
+ String[] children = folder.list();
+ for (int i = 0; i < children.length; i++) {
+ boolean ok = deleteFolder(new File(folder, children[i]));
+ if (!ok) {
+ return false;
+ }
+ }
+ }
+ return folder.delete();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestEPUB.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestEPUB.java
new file mode 100644
index 000000000..36fa58633
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestEPUB.java
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests.api;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPS2Publication;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.ocf.Container;
+import org.eclipse.mylyn.docs.epub.ocf.RootFile;
+import org.eclipse.mylyn.docs.epub.ocf.RootFiles;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Torkild U. Resheim
+ *
+ */
+public class TestEPUB extends AbstractTest {
+
+ private final File epubFile = new File("test" + File.separator + "test.epub");
+
+ private final File epubFolder = new File("test" + File.separator + "epub");
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ epubFolder.mkdirs();
+ }
+
+ private boolean deleteFolder(File folder) {
+ if (folder.isDirectory()) {
+ String[] children = folder.list();
+ for (int i = 0; i < children.length; i++) {
+ boolean ok = deleteFolder(new File(folder, children[i]));
+ if (!ok) {
+ return false;
+ }
+ }
+ }
+ return folder.delete();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.mylyn.docs.epub.core.EPUB#EPUB()}.
+ * <p>
+ * It must be possible to obtain the publication list which must be empty.
+ * </p>
+ */
+ @Test
+ public final void testEPUB() {
+ EPUB epub = new EPUB();
+ Assert.assertEquals(true, epub.getOPSPublications().isEmpty());
+
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#add(java.io.File, java.lang.String)}
+ * .
+ * <ul>
+ * <li>Publication MIME-type shall be correct</li>
+ * <li>Rootfile path shall be correct</li>
+ * <li>Rootfile object shall be correct.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testAddFileString() throws Exception {
+ EPUB epub = new EPUB();
+ File drawing = new File("testdata/drawing-100x100.svg");
+ epub.add(drawing, "image/svg+xml");
+ Container container = epub.getContainer();
+ RootFiles rootfiles = container.getRootfiles();
+ EList<RootFile> files = rootfiles.getRootfiles();
+ Assert.assertEquals(true, files.get(0).getFullPath().equals("SVG+XML/drawing-100x100.svg"));
+ Assert.assertEquals(true, files.get(0).getMediaType().equals("image/svg+xml"));
+ Assert.assertEquals(true, files.get(0).getPublication() == drawing);
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#pack(java.io.File)}.
+ * <ul>
+ * <li>Shall throw exception when unknown publication type is added.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPackFail() throws Exception {
+ EPUB epub = new EPUB();
+ File drawing = new File("testdata/drawing-100x100.svg");
+ epub.add(drawing, "image/svg+xml");
+ Container container = epub.getContainer();
+ RootFiles rootfiles = container.getRootfiles();
+ EList<RootFile> files = rootfiles.getRootfiles();
+ files.get(0).setPublication(null);
+ try {
+ epub.pack(epubFile);
+ fail();
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#add(org.eclipse.mylyn.docs.epub.core.OPSPublication)}
+ * .
+ * <ul>
+ * <li>Container shall hold more than one OPS publication</li>
+ * <li>OPS structures shall follow naming conventions.</li>
+ * <li>OPS MIME-type shall be correct</li>
+ * <li>Rootfile object shall be correct.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testAddOPSPublication() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps1 = new OPS2Publication();
+ OPSPublication oebps2 = new OPS2Publication();
+ epub.add(oebps1);
+ epub.add(oebps2);
+ Container container = epub.getContainer();
+ RootFiles rootfiles = container.getRootfiles();
+ EList<RootFile> files = rootfiles.getRootfiles();
+ Assert.assertEquals(true, files.get(0).getFullPath().equals("OEBPS/content.opf"));
+ Assert.assertEquals(true, files.get(1).getFullPath().equals("OEBPS_1/content.opf"));
+ Assert.assertEquals(true, files.get(0).getMediaType().equals("application/oebps-package+xml"));
+ Assert.assertEquals(true, files.get(1).getMediaType().equals("application/oebps-package+xml"));
+ Assert.assertEquals(true, files.get(0).getPublication() == oebps1);
+ Assert.assertEquals(true, files.get(1).getPublication() == oebps2);
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#getOPSPublications()}.
+ * <p>
+ * One OPS-publication and one SVG drawing are added. Only the
+ * OPS-publication shall be returned.
+ * </p>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testGetOPSPublications() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ epub.add(oebps);
+ File drawing = new File("testdata/drawing-100x100.svg");
+ epub.add(drawing, "image/svg+xml");
+ Assert.assertEquals(1, epub.getOPSPublications().size());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#pack(java.io.File)}.
+ * <ul>
+ * <li>Temporary folder shall not exist when job is done.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPackFile() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ oebps.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(oebps);
+ File drawing = new File("testdata/drawing-100x100.svg");
+ epub.add(drawing, "image/svg+xml");
+ File tempFolder = epub.pack(epubFile);
+ Assert.assertEquals(false, tempFolder.exists());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#pack(java.io.File, java.io.File)}
+ * .
+ * <ul>
+ * <li>Work folder shall exist when job is done.</li>
+ * <li>Work folder shall contain EPUB artifacts.</li>
+ * <li>Exception shall be thrown if working folder already exist.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPackFileFile() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ oebps.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(oebps);
+ epub.pack(epubFile, epubFolder);
+ // Make sure all required files are present
+ File metaFolder = new File(epubFolder.getAbsolutePath() + File.separator + "META-INF");
+ Assert.assertEquals(true, metaFolder.exists());
+ Assert.assertEquals(true, metaFolder.isDirectory());
+ File containerFile = new File(epubFolder.getAbsolutePath() + File.separator + "META-INF" + File.separator
+ + "container.xml");
+ Assert.assertEquals(true, containerFile.exists());
+ Assert.assertEquals(false, containerFile.isDirectory());
+ File oebpsFolder = new File(epubFolder.getAbsolutePath() + File.separator + "OEBPS");
+ Assert.assertEquals(true, oebpsFolder.exists());
+ Assert.assertEquals(true, oebpsFolder.isDirectory());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#pack(java.io.File, java.io.File)}
+ * .
+ * <ul>
+ * <li>Exception shall be thrown if working folder already exist.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPackFileFileExists() throws Exception {
+ File workingFolder = File.createTempFile("epub_", null);
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ epub.add(oebps);
+ try {
+ epub.pack(epubFile, workingFolder);
+ fail();
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#pack(java.io.File)} .
+ * <ul>
+ * <li>Exception shall be thrown if the EPUB is empty.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPackMissingPublication() throws Exception {
+ EPUB epub = new EPUB();
+ try {
+ epub.pack(epubFile);
+ fail();
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#unpack(java.io.File)}.
+ * <ul>
+ * <li>Unpacked EPUB shall have the same contents as the packed one.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testUnpackFile() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps1 = new OPS2Publication();
+ OPSPublication oebps2 = new OPS2Publication();
+ oebps1.addItem(new File("testdata/plain-page.xhtml"));
+ oebps2.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(oebps1);
+ epub.add(oebps2);
+ epub.pack(epubFile, epubFolder);
+ EPUB epub2 = new EPUB();
+ epub2.unpack(epubFile);
+ Assert.assertEquals(2, epub2.getOPSPublications().size());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.EPUB#unpack(java.io.File, java.io.File)}
+ * .
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testUnpackFileFile() throws Exception {
+ // First pack the EPUB
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ oebps.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(oebps);
+ epub.pack(epubFile, epubFolder);
+ deleteFolder(epubFolder);
+
+ // Then check for some contents when unpacked
+ EPUB epub2 = new EPUB();
+ epub2.unpack(epubFile, epubFolder);
+
+ // Make sure all required files are present
+ File metaFolder = new File(epubFolder.getAbsolutePath() + File.separator + "META-INF");
+ Assert.assertEquals(true, metaFolder.exists());
+ Assert.assertEquals(true, metaFolder.isDirectory());
+ File containerFile = new File(epubFolder.getAbsolutePath() + File.separator + "META-INF" + File.separator
+ + "container.xml");
+ Assert.assertEquals(true, containerFile.exists());
+ Assert.assertEquals(false, containerFile.isDirectory());
+ File oebpsFolder = new File(epubFolder.getAbsolutePath() + File.separator + "OEBPS");
+ Assert.assertEquals(true, oebpsFolder.exists());
+ Assert.assertEquals(true, oebpsFolder.isDirectory());
+ }
+
+ private class EPUB_OCF_Test extends EPUB {
+ public void testReadOCF(File workingFolder) throws IOException {
+ readOCF(workingFolder);
+ }
+ }
+
+ /**
+ * See if the OCF file generated by this tooling can be read.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadOCF_Dogfood() throws Exception {
+ File workingFolder = new File("testdata/OCF-Tests/Dogfood");
+ EPUB_OCF_Test epub = new EPUB_OCF_Test();
+ epub.testReadOCF(workingFolder);
+ }
+
+ /**
+ * This case was discovered when testing an EPUB file generated by DocBook
+ * Reading the OCF fails with a java.net.SocketException: Unexpected end of
+ * file from server. On closer inspection we can see that the file is
+ * declared as XHTML (which it of course is not). This is probably due to an
+ * issue in DocBook XSL 1.76.1
+ *
+ * @see http://sourceforge.net/tracker/index.php?func=detail&aid=3353537
+ * &group_id=21935&atid=373747.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadOCF_SocketException() throws Exception {
+ File workingFolder = new File("testdata/OCF-Tests/SocketException");
+ EPUB_OCF_Test epub = new EPUB_OCF_Test();
+ epub.testReadOCF(workingFolder);
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPS2Publication.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPS2Publication.java
new file mode 100644
index 000000000..0ccf279d2
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPS2Publication.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests.api;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil.FeatureEList;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPS2Publication;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.core.ValidationMessage;
+import org.eclipse.mylyn.docs.epub.core.ValidationMessage.Severity;
+import org.eclipse.mylyn.docs.epub.ncx.Meta;
+import org.eclipse.mylyn.docs.epub.ncx.NavPoint;
+import org.eclipse.mylyn.docs.epub.ncx.Ncx;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Torkild U. Resheim
+ *
+ */
+public class TestOPS2Publication extends AbstractTest {
+
+ private static final EStructuralFeature TEXT = XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Text();
+
+ private final static String TOCFILE_ID = "3063f615-672e-4083-911a-65c5ff245e75";
+
+ private final File epubFile = new File("test" + File.separator + "test.epub");
+
+ private final File epubFolder = new File("test" + File.separator + "epub");
+
+ private boolean deleteFolder(File folder) {
+ if (folder.isDirectory()) {
+ String[] children = folder.list();
+ for (int i = 0; i < children.length; i++) {
+ boolean ok = deleteFolder(new File(folder, children[i]));
+ if (!ok) {
+ return false;
+ }
+ }
+ }
+ return folder.delete();
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getText(Object element) {
+ if (element instanceof NavPoint) {
+ FeatureMap fm = ((NavPoint) element).getNavLabels().get(0).getText().getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ if (element instanceof Meta) {
+ Object o = ((Meta) element).getContent();
+ return o.toString();
+ }
+ return "null";
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ epubFolder.mkdirs();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ if (epubFolder.exists()) {
+ deleteFolder(epubFolder);
+ }
+ if (epubFile.exists()) {
+ epubFile.delete();
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPS2Publication#generateTableOfContents()}
+ * .
+ * <ul>
+ * <li>Table of contents shall be generated from content per default.</li>
+ * <li>Table of contents shall exist but be empty if not otherwise
+ * specified.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testGenerateTableOfContents() throws Exception {
+ EPUB epub1 = new EPUB();
+ OPSPublication oebps1 = new OPS2Publication();
+ epub1.add(oebps1);
+ oebps1.addItem(new File("testdata/plain-page.xhtml"));
+ epub1.pack(epubFile);
+ Assert.assertTrue(oebps1.getTableOfContents() != null);
+ Assert.assertTrue(oebps1.getTableOfContents() instanceof Ncx);
+ Ncx ncx = (Ncx) oebps1.getTableOfContents();
+ NavPoint h1_1 = ncx.getNavMap().getNavPoints().get(0);
+ NavPoint h1_2 = ncx.getNavMap().getNavPoints().get(1);
+ Assert.assertEquals("First item", getText(h1_1));
+ Assert.assertEquals("Second item", getText(h1_2));
+ epubFile.delete();
+
+
+ EPUB epub2 = new EPUB();
+ OPSPublication oebps2 = new OPS2Publication();
+ epub2.add(oebps2);
+ oebps2.addItem(new File("testdata/plain-page.xhtml"));
+ oebps2.setGenerateToc(false);
+ epub2.pack(epubFile);
+ Assert.assertTrue(oebps2.getTableOfContents() != null);
+ Assert.assertTrue(oebps2.getTableOfContents() instanceof Ncx);
+ Ncx ncx2 = (Ncx) oebps2.getTableOfContents();
+ Assert.assertEquals(null, ncx2.getNavMap());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPS2Publication#getTableOfContents()}
+ * .
+ * <ul>
+ * <li>There shall be a table of contents, even if empty.</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testGetTableOfContents() throws Exception {
+ EPUB epub = new EPUB();
+ OPSPublication oebps = new OPS2Publication();
+ epub.add(oebps);
+ Assert.assertTrue(oebps.getTableOfContents() != null);
+ Assert.assertTrue(oebps.getTableOfContents() instanceof Ncx);
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPS2Publication#readTableOfContents(java.io.File)}
+ * .
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadTableOfContents() throws Exception {
+ EPUB epub_out = new EPUB();
+ OPSPublication oebps_out = new OPS2Publication();
+ epub_out.add(oebps_out);
+ oebps_out.addItem(new File("testdata/plain-page.xhtml"));
+ epub_out.pack(epubFile);
+
+ EPUB epub_in = new EPUB();
+ epub_in.unpack(epubFile, epubFolder);
+ OPSPublication oebps_in = epub_in.getOPSPublications().get(0);
+ Assert.assertTrue(oebps_in.getTableOfContents() != null);
+ Assert.assertTrue(oebps_in.getTableOfContents() instanceof Ncx);
+ Ncx ncx = (Ncx) oebps_in.getTableOfContents();
+ NavPoint h1_1 = ncx.getNavMap().getNavPoints().get(0);
+ NavPoint h1_2 = ncx.getNavMap().getNavPoints().get(1);
+ Assert.assertEquals("First item", getText(h1_1));
+ Assert.assertEquals("Second item", getText(h1_2));
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPS2Publication#setTableOfContents(java.io.File)}
+ * .
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testSetTableOfContents() throws Exception {
+ EPUB epub_out = new EPUB();
+ OPSPublication oebps_out = new OPS2Publication();
+ oebps_out.setTableOfContents(new File("testdata/toc.ncx"));
+ epub_out.add(oebps_out);
+ oebps_out.addItem(new File("testdata/plain-page.xhtml"));
+ epub_out.pack(epubFile);
+ EPUB epub_in = new EPUB();
+ epub_in.unpack(epubFile, epubFolder);
+ OPSPublication oebps_in = epub_in.getOPSPublications().get(0);
+ Assert.assertTrue(oebps_in.getTableOfContents() != null);
+ Assert.assertTrue(oebps_in.getTableOfContents() instanceof Ncx);
+ Ncx ncx = (Ncx) oebps_in.getTableOfContents();
+ NavPoint h1_1 = ncx.getNavMap().getNavPoints().get(0);
+ NavPoint h1_2 = ncx.getNavMap().getNavPoints().get(1);
+ Assert.assertEquals("First item", getText(h1_1));
+ Assert.assertEquals("Second item", getText(h1_2));
+ Meta meta = ncx.getHead().getMetas().get(0);
+ String id = getText(meta);
+ // The UUID for the NCX file should be different if it comes from
+ // another NCX than the one specified.
+ Assert.assertTrue(TOCFILE_ID.equals(id));
+
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPS2Publication#validateContents()}
+ * .
+ * <ul>
+ * <li>There shall be a warning message</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testValidateContents() throws Exception {
+ EPUB epub_out = new EPUB();
+ OPSPublication oebps_out = new OPS2Publication();
+ epub_out.add(oebps_out);
+ oebps_out.addItem(new File("testdata/plain-page_warnings.xhtml"));
+ epub_out.pack(epubFile);
+ Assert.assertEquals(1, oebps_out.getValidationMessages().size());
+ ValidationMessage msg = oebps_out.getValidationMessages().get(0);
+ Assert.assertEquals(Severity.WARNING, msg.getSeverity());
+ Assert.assertEquals("Element bad is not in OPS Preferred Vocabularies.", msg.getMessage());
+ }
+
+ private class EPUB_NCX_Test extends OPS2Publication {
+ public void testReadOCF(File tocFile) throws IOException {
+ readTableOfContents(tocFile);
+ }
+ }
+
+ /**
+ * See if the NCX file generated by this tooling can be read.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadNCX_Dogfood() throws Exception {
+ File workingFolder = new File("testdata/NCX-Tests/Dogfood/toc.ncx");
+ EPUB_NCX_Test epub = new EPUB_NCX_Test();
+ epub.testReadOCF(workingFolder);
+ }
+
+ /**
+ * This case was discovered when testing an EPUB file generated by DocBook
+ * Reading the NCX fails with a java.net.SocketException: Unexpected end of
+ * file from server. On closer inspection we can see that the file is
+ * declared as XHTML (which it of course is not). This is probably due to an
+ * issue in DocBook XSL 1.76.1
+ *
+ * @see http://sourceforge.net/tracker/index.php?func=detail&aid=3353537&group_id=21935&atid=373747.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadNCX_SocketException() throws Exception {
+ File workingFolder = new File("testdata/NCX-Tests/SocketException/toc.ncx");
+ EPUB_NCX_Test epub = new EPUB_NCX_Test();
+ epub.testReadOCF(workingFolder);
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPSPublication.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPSPublication.java
new file mode 100644
index 000000000..0c5b12905
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPSPublication.java
@@ -0,0 +1,808 @@
+/**
+ *
+ */
+package org.eclipse.mylyn.docs.epub.tests.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPS2Publication;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.dc.Coverage;
+import org.eclipse.mylyn.docs.epub.dc.Date;
+import org.eclipse.mylyn.docs.epub.dc.Description;
+import org.eclipse.mylyn.docs.epub.dc.Identifier;
+import org.eclipse.mylyn.docs.epub.dc.Publisher;
+import org.eclipse.mylyn.docs.epub.dc.Relation;
+import org.eclipse.mylyn.docs.epub.dc.Rights;
+import org.eclipse.mylyn.docs.epub.dc.Source;
+import org.eclipse.mylyn.docs.epub.dc.Subject;
+import org.eclipse.mylyn.docs.epub.dc.Title;
+import org.eclipse.mylyn.docs.epub.opf.Item;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.adobe.epubcheck.api.EpubCheck;
+
+/**
+ * @author Torkild U. Resheim
+ *
+ */
+public class TestOPSPublication extends AbstractTest {
+
+ OPSPublication oebps;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ oebps = new OPS2Publication();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ oebps = null;
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addContributor(java.lang.String, java.util.Locale, java.lang.String, org.eclipse.mylyn.docs.epub.opf.Role, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddContributor() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addCoverage(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddCoverage() {
+ oebps.addCoverage("Coverage", Locale.CANADA_FRENCH, "My Coverage");
+ oebps.addCoverage(null, Locale.CANADA_FRENCH, "My Coverage");
+ oebps.addCoverage(null, null, "My Coverage");
+ EList<Coverage> Coverages = oebps.getOpfPackage().getMetadata().getCoverages();
+ Assert.assertEquals("Coverage", Coverages.get(0).getId());
+ Assert.assertEquals("fr_CA", Coverages.get(0).getLang());
+ Assert.assertEquals("My Coverage", getText(Coverages.get(0)));
+ Assert.assertEquals(null, Coverages.get(1).getId());
+ Assert.assertEquals("fr_CA", Coverages.get(1).getLang());
+ Assert.assertEquals("My Coverage", getText(Coverages.get(1)));
+ Assert.assertEquals(null, Coverages.get(2).getId());
+ Assert.assertEquals(null, Coverages.get(2).getLang());
+ Assert.assertEquals("My Coverage", getText(Coverages.get(2)));
+ try {
+ oebps.addCoverage(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addCreator(java.lang.String, java.util.Locale, java.lang.String, org.eclipse.mylyn.docs.epub.opf.Role, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddCreator() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addDate(java.lang.String, java.util.Date, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddDateStringDateString() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addDate(java.lang.String, java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddDateStringStringString() {
+ oebps.addDate(null, "1969", null);
+ oebps.addDate(null, "1969-03", null);
+ oebps.addDate(null, "1969-03-14", null);
+ oebps.addDate(null, "1969-03-14", "event");
+ EList<Date> dates = oebps.getOpfPackage().getMetadata().getDates();
+ assertEquals("1969", getText(dates.get(0)));
+ assertEquals("1969-03", getText(dates.get(1)));
+ assertEquals("1969-03-14", getText(dates.get(2)));
+ assertEquals("event", dates.get(3).getEvent());
+ try {
+ oebps.addDate(null, (String) null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addDescription(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddDescription() {
+ oebps.addDescription("Description", Locale.CANADA_FRENCH, "My Description");
+ oebps.addDescription(null, Locale.CANADA_FRENCH, "My Description");
+ oebps.addDescription(null, null, "My Description");
+ EList<Description> Descriptions = oebps.getOpfPackage().getMetadata().getDescriptions();
+ Assert.assertEquals("Description", Descriptions.get(0).getId());
+ Assert.assertEquals("fr_CA", Descriptions.get(0).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(0)));
+ Assert.assertEquals(null, Descriptions.get(1).getId());
+ Assert.assertEquals("fr_CA", Descriptions.get(1).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(1)));
+ Assert.assertEquals(null, Descriptions.get(2).getId());
+ Assert.assertEquals(null, Descriptions.get(2).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(2)));
+ try {
+ oebps.addDescription(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addFormat(java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddFormat() {
+ oebps.addDescription("Description", Locale.CANADA_FRENCH, "My Description");
+ oebps.addDescription(null, Locale.CANADA_FRENCH, "My Description");
+ oebps.addDescription(null, null, "My Description");
+ EList<Description> Descriptions = oebps.getOpfPackage().getMetadata().getDescriptions();
+ Assert.assertEquals("Description", Descriptions.get(0).getId());
+ Assert.assertEquals("fr_CA", Descriptions.get(0).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(0)));
+ Assert.assertEquals(null, Descriptions.get(1).getId());
+ Assert.assertEquals("fr_CA", Descriptions.get(1).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(1)));
+ Assert.assertEquals(null, Descriptions.get(2).getId());
+ Assert.assertEquals(null, Descriptions.get(2).getLang());
+ Assert.assertEquals("My Description", getText(Descriptions.get(2)));
+ try {
+ oebps.addDescription(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addIdentifier(java.lang.String, java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddIdentifier() {
+ oebps.addIdentifier("Identifier", "ID", "My Identifier");
+ oebps.addIdentifier(null, "ID", "My Identifier");
+ oebps.addIdentifier(null, null, "My Identifier");
+ EList<Identifier> Identifiers = oebps.getOpfPackage().getMetadata().getIdentifiers();
+ Assert.assertEquals("Identifier", Identifiers.get(0).getId());
+ Assert.assertEquals("ID", Identifiers.get(0).getScheme());
+ Assert.assertEquals("My Identifier", getText(Identifiers.get(0)));
+ Assert.assertEquals(null, Identifiers.get(1).getId());
+ Assert.assertEquals("ID", Identifiers.get(1).getScheme());
+ Assert.assertEquals("My Identifier", getText(Identifiers.get(1)));
+ Assert.assertEquals(null, Identifiers.get(2).getId());
+ Assert.assertEquals(null, Identifiers.get(2).getScheme());
+ Assert.assertEquals("My Identifier", getText(Identifiers.get(2)));
+ try {
+ oebps.addIdentifier(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addItem(java.io.File)}
+ * .
+ */
+ @Test
+ public final void testAddItemFile() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addItem(java.lang.String, java.util.Locale, java.io.File, java.lang.String, java.lang.String, boolean, boolean, boolean)}
+ * .
+ */
+ @Test
+ public final void testAddItemStringLocaleFileStringStringBooleanBooleanBoolean() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addLanguage(java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddLanguage() {
+ oebps.addLanguage(null, "no");
+ oebps.addLanguage("id", "no");
+ Assert.assertEquals("no", getText(oebps.getOpfPackage().getMetadata().getLanguages().get(0)));
+ Assert.assertEquals("id", oebps.getOpfPackage().getMetadata().getLanguages().get(1).getId());
+ try {
+ oebps.addLanguage(null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addMeta(java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddMeta() {
+ oebps.addMeta("name", "value");
+ assertEquals("name", oebps.getOpfPackage().getMetadata().getMetas().get(0).getName());
+ assertEquals("value", oebps.getOpfPackage().getMetadata().getMetas().get(0).getContent());
+ try {
+ oebps.addMeta(null, "value");
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ oebps.addMeta("name", null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addPublisher(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddPublisher() {
+ oebps.addPublisher("Publisher", Locale.CANADA_FRENCH, "My Publisher");
+ oebps.addPublisher(null, Locale.CANADA_FRENCH, "My Publisher");
+ oebps.addPublisher(null, null, "My Publisher");
+ EList<Publisher> Publishers = oebps.getOpfPackage().getMetadata().getPublishers();
+ Assert.assertEquals("Publisher", Publishers.get(0).getId());
+ Assert.assertEquals("fr_CA", Publishers.get(0).getLang());
+ Assert.assertEquals("My Publisher", getText(Publishers.get(0)));
+ Assert.assertEquals(null, Publishers.get(1).getId());
+ Assert.assertEquals("fr_CA", Publishers.get(1).getLang());
+ Assert.assertEquals("My Publisher", getText(Publishers.get(1)));
+ Assert.assertEquals(null, Publishers.get(2).getId());
+ Assert.assertEquals(null, Publishers.get(2).getLang());
+ Assert.assertEquals("My Publisher", getText(Publishers.get(2)));
+ try {
+ oebps.addPublisher(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addReference(java.lang.String, java.lang.String, org.eclipse.mylyn.docs.epub.opf.Type)}
+ * .
+ */
+ @Test
+ public final void testAddReference() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addRelation(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddRelation() {
+ oebps.addRelation("Relation", Locale.CANADA_FRENCH, "My Relation");
+ oebps.addRelation(null, Locale.CANADA_FRENCH, "My Relation");
+ oebps.addRelation(null, null, "My Relation");
+ EList<Relation> Relations = oebps.getOpfPackage().getMetadata().getRelations();
+ Assert.assertEquals("Relation", Relations.get(0).getId());
+ Assert.assertEquals("fr_CA", Relations.get(0).getLang());
+ Assert.assertEquals("My Relation", getText(Relations.get(0)));
+ Assert.assertEquals(null, Relations.get(1).getId());
+ Assert.assertEquals("fr_CA", Relations.get(1).getLang());
+ Assert.assertEquals("My Relation", getText(Relations.get(1)));
+ Assert.assertEquals(null, Relations.get(2).getId());
+ Assert.assertEquals(null, Relations.get(2).getLang());
+ Assert.assertEquals("My Relation", getText(Relations.get(2)));
+ try {
+ oebps.addRelation(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addRights(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddRights() {
+ oebps.addRights("Rights", Locale.CANADA_FRENCH, "My Rights");
+ oebps.addRights(null, Locale.CANADA_FRENCH, "My Rights");
+ oebps.addRights(null, null, "My Rights");
+ EList<Rights> Rightss = oebps.getOpfPackage().getMetadata().getRights();
+ Assert.assertEquals("Rights", Rightss.get(0).getId());
+ Assert.assertEquals("fr_CA", Rightss.get(0).getLang());
+ Assert.assertEquals("My Rights", getText(Rightss.get(0)));
+ Assert.assertEquals(null, Rightss.get(1).getId());
+ Assert.assertEquals("fr_CA", Rightss.get(1).getLang());
+ Assert.assertEquals("My Rights", getText(Rightss.get(1)));
+ Assert.assertEquals(null, Rightss.get(2).getId());
+ Assert.assertEquals(null, Rightss.get(2).getLang());
+ Assert.assertEquals("My Rights", getText(Rightss.get(2)));
+ try {
+ oebps.addRights(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addSource(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddSource() {
+ oebps.addSource("Source", Locale.CANADA_FRENCH, "My Source");
+ oebps.addSource(null, Locale.CANADA_FRENCH, "My Source");
+ oebps.addSource(null, null, "My Source");
+ EList<Source> Sources = oebps.getOpfPackage().getMetadata().getSources();
+ Assert.assertEquals("Source", Sources.get(0).getId());
+ Assert.assertEquals("fr_CA", Sources.get(0).getLang());
+ Assert.assertEquals("My Source", getText(Sources.get(0)));
+ Assert.assertEquals(null, Sources.get(1).getId());
+ Assert.assertEquals("fr_CA", Sources.get(1).getLang());
+ Assert.assertEquals("My Source", getText(Sources.get(1)));
+ Assert.assertEquals(null, Sources.get(2).getId());
+ Assert.assertEquals(null, Sources.get(2).getLang());
+ Assert.assertEquals("My Source", getText(Sources.get(2)));
+ try {
+ oebps.addSource(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addSubject(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddSubject() {
+ oebps.addSubject("Subject", Locale.CANADA_FRENCH, "My Subject");
+ oebps.addSubject(null, Locale.CANADA_FRENCH, "My Subject");
+ oebps.addSubject(null, null, "My Subject");
+ EList<Subject> subjects = oebps.getOpfPackage().getMetadata().getSubjects();
+ Assert.assertEquals("Subject", subjects.get(0).getId());
+ Assert.assertEquals("fr_CA", subjects.get(0).getLang());
+ Assert.assertEquals("My Subject", getText(subjects.get(0)));
+ Assert.assertEquals(null, subjects.get(1).getId());
+ Assert.assertEquals("fr_CA", subjects.get(1).getLang());
+ Assert.assertEquals("My Subject", getText(subjects.get(1)));
+ Assert.assertEquals(null, subjects.get(2).getId());
+ Assert.assertEquals(null, subjects.get(2).getLang());
+ Assert.assertEquals("My Subject", getText(subjects.get(2)));
+ try {
+ oebps.addSubject(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addTitle(java.lang.String, java.util.Locale, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddTitle() {
+ oebps.addTitle("Title", Locale.CANADA_FRENCH, "My Title");
+ oebps.addTitle(null, Locale.CANADA_FRENCH, "My Title");
+ oebps.addTitle(null, null, "My Title");
+ EList<Title> titles = oebps.getOpfPackage().getMetadata().getTitles();
+ Assert.assertEquals("Title", titles.get(0).getId());
+ Assert.assertEquals("fr_CA", titles.get(0).getLang());
+ Assert.assertEquals("My Title", getText(titles.get(0)));
+ Assert.assertEquals(null, titles.get(1).getId());
+ Assert.assertEquals("fr_CA", titles.get(1).getLang());
+ Assert.assertEquals("My Title", getText(titles.get(1)));
+ Assert.assertEquals(null, titles.get(2).getId());
+ Assert.assertEquals(null, titles.get(2).getLang());
+ Assert.assertEquals("My Title", getText(titles.get(2)));
+ try {
+ oebps.addTitle(null, null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#addType(java.lang.String, java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testAddType() {
+ oebps.addType("Type", "My Type");
+ oebps.addType(null, "My Type");
+ EList<org.eclipse.mylyn.docs.epub.dc.Type> Types = oebps.getOpfPackage().getMetadata().getTypes();
+ Assert.assertEquals("Type", Types.get(0).getId());
+ Assert.assertEquals("My Type", getText(Types.get(0)));
+ Assert.assertEquals(null, Types.get(1).getId());
+ Assert.assertEquals("My Type", getText(Types.get(1)));
+ try {
+ oebps.addType(null, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#generateTableOfContents()}
+ * .
+ */
+ @Test
+ public final void testGenerateTableOfContents() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getIdentifier()}.
+ */
+ @Test
+ public final void testGetIdentifier() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getItemById(java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testGetItemById() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getItemsByMIMEType(java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testGetItemsByMIMEType() {
+ Item i_in_1 = oebps.addItem(new File("testdata/drawing-100x100.svg"));
+ Item i_in_2 = oebps.addItem(new File("testdata/plain-page.xhtml"));
+ List<Item> i_out_1 = oebps.getItemsByMIMEType("image/svg+xml");
+ assertEquals(1, i_out_1.size());
+ assertEquals(i_in_1, i_out_1.get(0));
+ List<Item> i_out_2 = oebps.getItemsByMIMEType("application/xhtml+xml");
+ assertEquals(1, i_out_2.size());
+ assertEquals(i_in_2, i_out_2.get(0));
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getOpfPackage()}.
+ */
+ @Test
+ public final void testGetOpfPackage() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getRootFolder()}.
+ */
+ @Test
+ public final void testGetRootFolder() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getSpine()}.
+ */
+ @Test
+ public final void testGetSpine() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getTableOfContents()}
+ * .
+ */
+ @Test
+ public final void testGetTableOfContents() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#getValidationMessages()}
+ * .
+ */
+ @Test
+ public final void testGetValidationMessages() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#pack(java.io.File)}
+ * .
+ * <ul>
+ * <li>An EPUB where only a single page has been added shall be packed
+ * without issues</li>
+ * <li>An EPUB with no content shall fail when packed</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testPack() throws Exception {
+ EPUB epub = new EPUB();
+ oebps.addItem(new File("testdata/plain-page.xhtml"));
+ epub.add(oebps);
+ epub.pack(epubFile);
+ oebps.validateMetadata();
+ EpubCheck checker = new EpubCheck(epubFile);
+ Assert.assertTrue(checker.validate());
+
+ EPUB epub2 = new EPUB();
+ epub2.add(new OPS2Publication());
+ try {
+ epubFile.delete();
+ epub2.pack(epubFile);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#readTableOfContents(java.io.File)}
+ * .
+ */
+ @Test
+ public final void testReadTableOfContents() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#setCover(java.io.File, java.lang.String)}
+ * .
+ * <ul>
+ * <li>Cover page SVG shall exist in the unpacked folder</li>
+ * <li>Cover page HTML shall exist in the unpacked folder</li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testSetCover() throws Exception {
+ oebps.setCover(new File("testdata" + File.separator + "drawing-100x100.svg"), "Title");
+ oebps.addItem(new File("testdata/plain-page.xhtml"));
+ EPUB epub = new EPUB();
+ epub.add(oebps);
+ epub.pack(epubFile);
+
+ EPUB epub2 = new EPUB();
+ epub2.unpack(epubFile, epubFolder);
+ oebps = epub2.getOPSPublications().get(0);
+ File root = oebps.getRootFolder();
+ File svg = new File(root.getAbsolutePath() + File.separator + "drawing-100x100.svg");
+ Assert.assertTrue(svg.exists());
+ File html = new File(root.getAbsolutePath() + File.separator + "cover-page.xhtml");
+ Assert.assertTrue(html.exists());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#setGenerateToc(boolean)}
+ * .
+ */
+ @Test
+ public final void testSetGenerateToc() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#setIdentifierId(java.lang.String)}
+ * .
+ */
+ @Test
+ public final void testSetIdentifierId() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#setIncludeReferencedResources(boolean)}
+ * .
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testSetIncludeReferencedResources() throws Exception {
+ EPUB epub = new EPUB();
+ oebps.setIncludeReferencedResources(true);
+ oebps.addItem(new File("testdata/plain-page_link.xhtml"));
+ epub.add(oebps);
+ // Included resources will only be added when we pack
+ epub.pack(epubFile);
+
+ EPUB epub2 = new EPUB();
+ epub2.unpack(epubFile, epubFolder);
+ oebps = epub2.getOPSPublications().get(0);
+ File root = oebps.getRootFolder();
+ File svg = new File(root.getAbsolutePath() + File.separator + "drawing-100x100.svg");
+ Assert.assertTrue(svg.exists());
+ File svg2 = new File(root.getAbsolutePath() + File.separator + "images" + File.separator
+ + "drawing-2-100x100.svg");
+ Assert.assertTrue(svg2.exists());
+ File html = new File(root.getAbsolutePath() + File.separator + "plain-page_no-header.xhtml");
+ Assert.assertTrue(html.exists());
+
+ }
+
+ /**
+ * Test method for bug 360701: [epub] Automatic inclusion of referenced
+ * resources don't work for WikiText generated HTML.
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=360701
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void test_Bug360701() throws Exception {
+ EPUB epub = new EPUB();
+ oebps.setIncludeReferencedResources(true);
+ oebps.addItem(new File("testdata/plain-page_link.html"));
+ epub.add(oebps);
+ // Included resources will only be added when we pack
+ epub.pack(epubFile);
+
+ EPUB epub2 = new EPUB();
+ epub2.unpack(epubFile, epubFolder);
+ oebps = epub2.getOPSPublications().get(0);
+ File root = oebps.getRootFolder();
+ File svg = new File(root.getAbsolutePath() + File.separator + "drawing-100x100.svg");
+ Assert.assertTrue(svg.exists());
+ File svg2 = new File(root.getAbsolutePath() + File.separator + "images" + File.separator
+ + "drawing-2-100x100.svg");
+ Assert.assertTrue(svg2.exists());
+ File html = new File(root.getAbsolutePath() + File.separator + "plain-page_no-header.html");
+ Assert.assertTrue(html.exists());
+
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#setTableOfContents(java.io.File)}
+ * .
+ *
+ * @see TestOPS2Publication#testSetTableOfContents()
+ */
+ @Test
+ public final void testSetTableOfContents() {
+ // Handled by subclass test.
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#unpack(java.io.File)}
+ * .
+ */
+ @Test
+ public final void testUnpack() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#validateContents()}
+ * .
+ */
+ @Test
+ public final void testValidateContents() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#validateMetadata()}
+ * .
+ */
+ @Test
+ public final void testValidateMetadata() {
+ // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.mylyn.docs.epub.core.OPSPublication#writeTableOfContents(java.io.File)}
+ * .
+ */
+ @Test
+ public final void testWriteTableOfContents() {
+ // TODO
+ }
+
+ private class EPUB_OPF_Test extends OPS2Publication {
+ public void testReadOPF(File rootFile) throws IOException {
+ readOPF(rootFile);
+ }
+ }
+
+ /**
+ * See if the OPF file generated by this tooling can be read.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadOCF_Dogfood() throws Exception {
+ File rootFile = new File("testdata/OPF-Tests/Dogfood/content.opf");
+ EPUB_OPF_Test epub = new EPUB_OPF_Test();
+ epub.testReadOPF(rootFile);
+ }
+
+ /**
+ * This case was discovered when testing an EPUB file generated by DocBook
+ * Reading the OPF fails with a java.net.SocketException: Unexpected end of
+ * file from server. On closer inspection we can see that the file is
+ * declared as XHTML (which it of course is not). This is probably due to an
+ * issue in DocBook XSL 1.76.1
+ *
+ * @see http://sourceforge.net/tracker/index.php?func=detail&aid=3353537
+ * &group_id=21935&atid=373747.
+ *
+ * @throws Exception
+ */
+ @Test
+ public final void testReadOCF_SocketException() throws Exception {
+ File rootFile = new File("testdata/OPF-Tests/SocketException/content.opf");
+ EPUB_OPF_Test epub = new EPUB_OPF_Test();
+ epub.testReadOPF(rootFile);
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestOPS2Validator.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestOPS2Validator.java
new file mode 100644
index 000000000..dc733ace3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestOPS2Validator.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.eclipse.mylyn.internal.docs.epub.core.OPS2Validator;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests for the OPS2 validator.
+ *
+ * @author Torkild U. Resheim
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm
+ */
+@SuppressWarnings("restriction")
+public class TestOPS2Validator extends TestCase {
+
+ private final String[] illegalAttributes = new String[] { "anything", "goes", "in", "here" };
+
+ private final String[] illegalElements = new String[] { "anything", "goes", "in", "here" };
+
+ private final String[] legalAttributes = new String[] { "accesskey", "charset", "class", "coords", "dir", "href",
+ "hreflang", "id", "rel", "rev", "shape", "style", "tabindex", "target", "title", "type", "xml:lang" };
+
+ /**
+ * A list of legal elements according to the EPUB 2.0.1 specification
+ *
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section1.3.4
+ * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm#Section2.2
+ */
+ private final String[] legalElements = new String[] { "body", "head", "html", "title", "abbr", "acronym",
+ "address", "blockquote", "br", "cite", "code", "dfn", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6",
+ "kbd", "p", "pre", "q", "samp", "span", "strong", "var", "a", "dl", "dt", "dd", "ol", "ul", "li", "object",
+ "param", "b", "big", "hr", "i", "small", "sub", "sup", "tt", "del", "ins", "bdo", "caption", "col",
+ "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "img", "area", "map", "style", "link",
+ "base" };
+
+ @Test
+ public void testIllegalAttributes() throws ParserConfigurationException, SAXException, IOException {
+ for (String attr : illegalAttributes) {
+ String in = "<html><body><div " + attr + "=\"test\">content</div></body></html>";
+ String expected = "<html><body><div>content</div></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(expected, out);
+ }
+ }
+
+ @Test
+ public void testIllegalElements() throws ParserConfigurationException, SAXException, IOException {
+ for (String element : illegalElements) {
+ String in = "<html><body><" + element + "></" + element + "></body></html>";
+ String result = "<html><body></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(result, out);
+
+ }
+ }
+
+ @Test
+ public void testLegalAttributes() throws ParserConfigurationException, SAXException, IOException {
+ for (String attr : legalAttributes) {
+ String in = "<html><body><div " + attr + "=\"test\"></div></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+ }
+ }
+
+ @Test
+ public void testLegalElements() throws ParserConfigurationException, SAXException, IOException {
+ for (String element : legalElements) {
+ String in = "<html><body><" + element + ">content</" + element + "></body></html>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+
+ }
+ }
+
+ @Test
+ public void testNormal() throws ParserConfigurationException, SAXException, IOException {
+ String in = "<body><h1 id=\"h1-1\">test</h1></body>";
+ String out = OPS2Validator.clean(new InputSource(new StringReader(in)), "test.html");
+ Assert.assertEquals(in, out);
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestTOCGenerator.java b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestTOCGenerator.java
new file mode 100644
index 000000000..3d01d0a6c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/core/TestTOCGenerator.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.epub.tests.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.mylyn.docs.epub.ncx.NCXFactory;
+import org.eclipse.mylyn.docs.epub.ncx.NavMap;
+import org.eclipse.mylyn.docs.epub.ncx.NavPoint;
+import org.eclipse.mylyn.docs.epub.ncx.Ncx;
+import org.eclipse.mylyn.internal.docs.epub.core.TOCGenerator;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests for the table of contents generator.
+ *
+ * @author Torkild U. Resheim
+ */
+@SuppressWarnings("restriction")
+public class TestTOCGenerator extends TestCase {
+
+ @Test
+ public void testNormal() throws ParserConfigurationException, SAXException,
+ IOException {
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h2 id='h2-1'>test</h2>" +
+ "<h2 id='h2-2'>test</h2>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ Assert.assertEquals(2, points.get(0).getNavPoints().size());
+ Assert.assertEquals(1, points.get(0).getNavPoints().get(1).getNavPoints().size());
+ }
+
+ @Test
+ public void testMissingIdentifier() throws ParserConfigurationException, SAXException, IOException{
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h2>test</h2>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ // "h2" will be added as a sub-node to the first "h1" regardless of the
+ // missing identifier.
+ Assert.assertEquals(1, points.get(0).getNavPoints().size());
+ }
+
+ /**
+ * All items should be placed at the root.
+ *
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ @Test
+ public void testCrazyStructure() throws ParserConfigurationException, SAXException, IOException{
+ String html = "<body>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h2 id='h2-1'>test</h2>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ // "h3" will be created as a "h1" and "h2" added to it
+ Assert.assertEquals(2, points.size());
+ }
+
+ @Test
+ public void testMissingParent() throws ParserConfigurationException,
+ SAXException, IOException {
+ String html = "<body>" +
+ "<h1 id='h1-1'>test</h1>" +
+ "<h3 id='h3-1'>test</h3>" +
+ "<h1 id='h1-2'>test</h1>" +
+ "</body>";
+ Ncx ncx = createNcx();
+ TOCGenerator.parse(new InputSource(new StringReader(html)), "test.html",
+ ncx,0);
+ EList<NavPoint> points = ncx.getNavMap().getNavPoints();
+ Assert.assertEquals(2,points.size());
+ Assert.assertEquals(1, points.get(0).getNavPoints().size());
+ }
+
+
+ private Ncx createNcx() {
+ Ncx ncx = NCXFactory.eINSTANCE.createNcx();
+ NavMap navMap = NCXFactory.eINSTANCE.createNavMap();
+ ncx.setNavMap(navMap);
+ return ncx;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/Dogfood/toc.ncx b/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/Dogfood/toc.ncx
new file mode 100644
index 000000000..0f40cb3bb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/Dogfood/toc.ncx
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ncx:ncx xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
+ <ncx:head>
+ <ncx:meta content="70ce7c20-8f9e-11e0-91e4-0800200c9a66" name="dtb:uid"/>
+ </ncx:head>
+ <ncx:docTitle>
+ <ncx:text>Table of contents</ncx:text>
+ </ncx:docTitle>
+ <ncx:navMap>
+ <ncx:navPoint id="navpoint1" playOrder="1">
+ <ncx:navLabel>
+ <ncx:text>Copyrights</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="copyright.html#Copyrights"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint2" playOrder="2">
+ <ncx:navLabel>
+ <ncx:text>Introduction</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="introduction.html#Introduction"/>
+ <ncx:navPoint id="navpoint3" playOrder="3">
+ <ncx:navLabel>
+ <ncx:text>Learning more</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="introduction.html#Learningmore"/>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint4" playOrder="4">
+ <ncx:navLabel>
+ <ncx:text>The EPUB file format</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-format.html#TheEPUBfileformat"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint5" playOrder="5">
+ <ncx:navLabel>
+ <ncx:text>Generate EPUB using Ant</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="generate-ant.html#GenerateEPUBusingAnt"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint6" playOrder="6">
+ <ncx:navLabel>
+ <ncx:text>Generate EPUB directly from markup</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="generate-epub.html#GenerateEPUBdirectlyfrommarkup"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint7" playOrder="7">
+ <ncx:navLabel>
+ <ncx:text>The EPUB ANT task</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#TheEPUBANTtask"/>
+ <ncx:navPoint id="navpoint8" playOrder="8">
+ <ncx:navLabel>
+ <ncx:text>Adding “header” information</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Addingheaderinformation"/>
+ <ncx:navPoint id="navpoint9" playOrder="9">
+ <ncx:navLabel>
+ <ncx:text>Publication title</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Publicationtitle"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint10" playOrder="10">
+ <ncx:navLabel>
+ <ncx:text>Publication identifiers</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Publicationidentifiers"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint11" playOrder="11">
+ <ncx:navLabel>
+ <ncx:text>Language specification</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Languagespecification"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint12" playOrder="12">
+ <ncx:navLabel>
+ <ncx:text>Publisher</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Publisher"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint13" playOrder="13">
+ <ncx:navLabel>
+ <ncx:text>Publication subject</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Publicationsubject"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint14" playOrder="14">
+ <ncx:navLabel>
+ <ncx:text>Contributors and Creators</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#ContributorsandCreators"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint15" playOrder="15">
+ <ncx:navLabel>
+ <ncx:text>Dates</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Dates"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint16" playOrder="16">
+ <ncx:navLabel>
+ <ncx:text>Types</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Types"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint17" playOrder="17">
+ <ncx:navLabel>
+ <ncx:text>Formats</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Formats"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint18" playOrder="18">
+ <ncx:navLabel>
+ <ncx:text>Source</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Source"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint19" playOrder="19">
+ <ncx:navLabel>
+ <ncx:text>Rights</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Rights"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint20" playOrder="20">
+ <ncx:navLabel>
+ <ncx:text>Coverage</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Coverage"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint21" playOrder="21">
+ <ncx:navLabel>
+ <ncx:text>Relation</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Relation"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint22" playOrder="22">
+ <ncx:navLabel>
+ <ncx:text>Meta</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Meta"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint23" playOrder="23">
+ <ncx:navLabel>
+ <ncx:text>Cover</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Cover"/>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint24" playOrder="24">
+ <ncx:navLabel>
+ <ncx:text>Adding content</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Addingcontent"/>
+ <ncx:navPoint id="navpoint25" playOrder="25">
+ <ncx:navLabel>
+ <ncx:text>Primary content files</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Primarycontentfiles"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint26" playOrder="26">
+ <ncx:navLabel>
+ <ncx:text>Secondary content files</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Secondarycontentfiles"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint27" playOrder="27">
+ <ncx:navLabel>
+ <ncx:text>References</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#References"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint28" playOrder="28">
+ <ncx:navLabel>
+ <ncx:text>Table of contents</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="epub-ant-task.html#Tableofcontents"/>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint29" playOrder="29">
+ <ncx:navLabel>
+ <ncx:text>Practical examples</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="examples.html#Practicalexamples"/>
+ <ncx:navPoint id="navpoint30" playOrder="30">
+ <ncx:navLabel>
+ <ncx:text>Building the example book</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="examples.html#Buildingtheexamplebook"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint31" playOrder="31">
+ <ncx:navLabel>
+ <ncx:text>Adding a cover</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="examples.html#Addingacover"/>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ </ncx:navMap>
+</ncx:ncx>
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/SocketException/toc.ncx b/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/SocketException/toc.ncx
new file mode 100644
index 000000000..8bcfe224b
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/NCX-Tests/SocketException/toc.ncx
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE ncx
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1"><head><meta name="cover" content="cover"/><meta name="dtb:uid" content="_d0e1"/></head><docTitle><text>Distributed Version Control with Git</text></docTitle><navMap><navPoint id="d0e1" playOrder="1"><navLabel><text>Distributed Version Control with Git</text></navLabel><content src="index.html"/><navPoint id="d0e40" playOrder="2"><navLabel><text>Foreword</text></navLabel><content src="pr01.html"/></navPoint><navPoint id="d0e55" playOrder="3"><navLabel><text>Preface</text></navLabel><content src="pr02.html"/><navPoint id="d0e58" playOrder="4"><navLabel><text>1. Welcome</text></navLabel><content src="pr02.html#d0e58"/></navPoint><navPoint id="d0e69" playOrder="5"><navLabel><text>2. Prerequisites</text></navLabel><content src="pr02s02.html"/></navPoint><navPoint id="d0e76" playOrder="6"><navLabel><text>3. Errata</text></navLabel><content src="pr02s03.html"/></navPoint><navPoint id="d0e95" playOrder="7"><navLabel><text>4. How this book is organized</text></navLabel><content src="pr02s04.html"/></navPoint><navPoint id="d0e110" playOrder="8"><navLabel><text>5. About the Author</text></navLabel><content src="pr02s05.html"/></navPoint><navPoint id="d0e121" playOrder="9"><navLabel><text>6. Acknowledgement</text></navLabel><content src="pr02s06.html"/></navPoint></navPoint><navPoint id="d0e128" playOrder="10"><navLabel><text>1. Introduction to Git</text></navLabel><content src="ch01.html"/><navPoint id="d0e133" playOrder="11"><navLabel><text>1.1. Git</text></navLabel><content src="ch01.html#git"/><navPoint id="d0e136" playOrder="12"><navLabel><text>What is Git?</text></navLabel><content src="ch01.html#gitdefintion"/></navPoint><navPoint id="d0e155" playOrder="13"><navLabel><text>Important terminology</text></navLabel><content src="ch01.html#gitterminology"/></navPoint><navPoint id="d0e201" playOrder="14"><navLabel><text>Staging index</text></navLabel><content src="ch01.html#git_stagingindex"/></navPoint></navPoint><navPoint id="d0e214" playOrder="15"><navLabel><text>1.2. Installation</text></navLabel><content src="ch01s02.html"/></navPoint><navPoint id="d0e228" playOrder="16"><navLabel><text>1.3. Setup</text></navLabel><content src="ch01s03.html"/><navPoint id="d0e238" playOrder="17"><navLabel><text>User Configuration</text></navLabel><content src="ch01s03.html#setup_user"/></navPoint><navPoint id="d0e255" playOrder="18"><navLabel><text>Color Highlighting</text></navLabel><content src="ch01s03.html#setup_highlighting"/></navPoint><navPoint id="d0e265" playOrder="19"><navLabel><text>Ignore certain files</text></navLabel><content src="ch01s03.html#setup_ignore"/></navPoint></navPoint></navPoint><navPoint id="d0e289" playOrder="20"><navLabel><text>2. A typical Git workflow</text></navLabel><content src="ch02.html"/><navPoint id="d0e294" playOrder="21"><navLabel><text>2.1. Getting started with Git</text></navLabel><content src="ch02.html#firstgit"/><navPoint id="d0e301" playOrder="22"><navLabel><text>Create content</text></navLabel><content src="ch02.html#firstgit_content"/></navPoint><navPoint id="d0e311" playOrder="23"><navLabel><text>Create repository, add and commit</text></navLabel><content src="ch02.html#firstgit_repo"/></navPoint><navPoint id="d0e329" playOrder="24"><navLabel><text>See differences via diff and commit changes</text></navLabel><content src="ch02.html#firstgit_changes"/></navPoint><navPoint id="d0e345" playOrder="25"><navLabel><text>Status, Diff and Commit Log</text></navLabel><content src="ch02.html#gitcommands_status"/></navPoint><navPoint id="d0e355" playOrder="26"><navLabel><text>Correction of commit messages - git amend</text></navLabel><content src="ch02.html#firstgit_amend"/></navPoint><navPoint id="d0e370" playOrder="27"><navLabel><text>Delete files</text></navLabel><content src="ch02.html#firstgit_deletefile"/></navPoint></navPoint><navPoint id="d0e392" playOrder="28"><navLabel><text>2.2. Working with remote repositories</text></navLabel><content src="ch02s02.html"/><navPoint id="d0e395" playOrder="29"><navLabel><text>Setting up a remote (bare) Git repository</text></navLabel><content src="ch02s02.html#remotes_setup"/></navPoint><navPoint id="d0e414" playOrder="30"><navLabel><text>Push changes to another repository</text></navLabel><content src="ch02s02.html#remotes_push"/></navPoint><navPoint id="d0e424" playOrder="31"><navLabel><text>Add remote</text></navLabel><content src="ch02s02.html#remotes_remoteadd"/></navPoint><navPoint id="d0e440" playOrder="32"><navLabel><text>Show the existing remote repositories</text></navLabel><content src="ch02s02.html#remotes_showremote"/></navPoint><navPoint id="d0e450" playOrder="33"><navLabel><text>Clone your repository</text></navLabel><content src="ch02s02.html#remotes_clone"/></navPoint><navPoint id="d0e460" playOrder="34"><navLabel><text>Pull changes</text></navLabel><content src="ch02s02.html#remotes_pull"/></navPoint></navPoint><navPoint id="d0e470" playOrder="35"><navLabel><text>2.3. Revert Changes</text></navLabel><content src="ch02s03.html"/></navPoint><navPoint id="d0e531" playOrder="36"><navLabel><text>2.4. Tagging in Git</text></navLabel><content src="ch02s04.html"/></navPoint></navPoint><navPoint id="d0e560" playOrder="37"><navLabel><text>3. Branch, merge and rebase</text></navLabel><content src="ch03.html"/><navPoint id="d0e565" playOrder="38"><navLabel><text>3.1. Branches and Merging</text></navLabel><content src="ch03.html#gitbranchmerge"/><navPoint id="d0e568" playOrder="39"><navLabel><text>Branches</text></navLabel><content src="ch03.html#gitbranch"/></navPoint><navPoint id="d0e600" playOrder="40"><navLabel><text>Merging</text></navLabel><content src="ch03.html#gitmerge"/></navPoint><navPoint id="d0e614" playOrder="41"><navLabel><text>Delete a branch</text></navLabel><content src="ch03.html#gitdeletebrach"/></navPoint></navPoint><navPoint id="d0e624" playOrder="42"><navLabel><text>3.2. Solving merge conflicts</text></navLabel><content src="ch03s02.html"/></navPoint><navPoint id="d0e658" playOrder="43"><navLabel><text>3.3. Rebase</text></navLabel><content src="ch03s03.html"/><navPoint id="d0e661" playOrder="44"><navLabel><text>Rebasing commits in the same branch</text></navLabel><content src="ch03s03.html#rebase_commits"/></navPoint><navPoint id="d0e696" playOrder="45"><navLabel><text>Rebasing branches</text></navLabel><content src="ch03s03.html#rebase_branches"/></navPoint><navPoint id="d0e711" playOrder="46"><navLabel><text>Best practice for rebase</text></navLabel><content src="ch03s03.html#rebase_bestpractise"/></navPoint></navPoint></navPoint><navPoint id="d0e724" playOrder="47"><navLabel><text>4. Git recipes</text></navLabel><content src="ch04.html"/><navPoint id="d0e729" playOrder="48"><navLabel><text>4.1. Create and apply patches</text></navLabel><content src="ch04.html#gitpatch"/></navPoint><navPoint id="d0e741" playOrder="49"><navLabel><text>4.2. Define alias</text></navLabel><content src="ch04s02.html"/></navPoint><navPoint id="d0e776" playOrder="50"><navLabel><text>4.3. Untrack a file / directory</text></navLabel><content src="ch04s03.html"/></navPoint><navPoint id="d0e794" playOrder="51"><navLabel><text>4.4. Other useful commands</text></navLabel><content src="ch04s04.html"/></navPoint><navPoint id="d0e825" playOrder="52"><navLabel><text>4.5. Installing a Git server</text></navLabel><content src="ch04s05.html"/></navPoint></navPoint><navPoint id="d0e865" playOrder="53"><navLabel><text>5. Getting online</text></navLabel><content src="ch05.html"/><navPoint id="d0e870" playOrder="54"><navLabel><text>5.1. Online remote repositories</text></navLabel><content src="ch05.html#remote"/><navPoint id="d0e873" playOrder="55"><navLabel><text>Cloning remote repositories</text></navLabel><content src="ch05.html#remote_clone"/></navPoint><navPoint id="d0e898" playOrder="56"><navLabel><text>Add more remote repositories</text></navLabel><content src="ch05.html#remote_add"/></navPoint><navPoint id="d0e921" playOrder="57"><navLabel><text>Remote operations via http and a proxy</text></navLabel><content src="ch05.html#remote_proxy"/></navPoint></navPoint><navPoint id="d0e942" playOrder="58"><navLabel><text>5.2. Git Hosting Provider</text></navLabel><content src="ch05s02.html"/><navPoint id="d0e947" playOrder="59"><navLabel><text>GitHub</text></navLabel><content src="ch05s02.html#hosting_github"/></navPoint><navPoint id="d0e969" playOrder="60"><navLabel><text>Bitbucket</text></navLabel><content src="ch05s02.html#hosting_bickbucket"/></navPoint></navPoint></navPoint><navPoint id="d0e974" playOrder="61"><navLabel><text>6. Outlook: Graphical user interfaces</text></navLabel><content src="ch06.html"/><navPoint id="d0e979" playOrder="62"><navLabel><text>6.1. Graphical UI's for Git</text></navLabel><content src="ch06.html#uis"/></navPoint></navPoint></navPoint></navMap></ncx> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/Dogfood/META-INF/container.xml b/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/Dogfood/META-INF/container.xml
new file mode 100644
index 000000000..09798f34f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/Dogfood/META-INF/container.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ocf:container xmlns:ocf="urn:oasis:names:tc:opendocument:xmlns:container" version="2.0">
+ <ocf:rootfiles>
+ <ocf:rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
+ </ocf:rootfiles>
+</ocf:container>
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/SocketException/META-INF/container.xml b/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/SocketException/META-INF/container.xml
new file mode 100644
index 000000000..5bf2d1930
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/OCF-Tests/SocketException/META-INF/container.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE container
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
+ version="1.0">
+ <rootfiles>
+ <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml" />
+ </rootfiles>
+</container> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/Dogfood/content.opf b/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/Dogfood/content.opf
new file mode 100644
index 000000000..fa3202d49
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/Dogfood/content.opf
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<opf:package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="uuid">
+ <opf:metadata>
+ <dc:title>Building EPUBs with Eclipse</dc:title>
+ <dc:creator opf:role="aut" opf:file-as="Resheim, Torkild Ulvøy">Torkild Ulvøy Resheim</dc:creator>
+ <dc:subject>Computing, Eclipse, Mylyn, EPUB</dc:subject>
+ <dc:publisher>Eclipse.Org</dc:publisher>
+ <dc:contributor opf:role="red">Eclipse Committers and Contributors</dc:contributor>
+ <dc:date opf:event="creation">2011-12-08</dc:date>
+ <dc:type>Technical article.</dc:type>
+ <dc:format>application/epub+zip</dc:format>
+ <dc:identifier id="uuid" opf:scheme="UUID">70ce7c20-8f9e-11e0-91e4-0800200c9a66</dc:identifier>
+ <dc:language>en</dc:language>
+ <dc:rights>Copyright (c) 2011, Torkild Ulvøy Resheim. Licensed under the Eclipse Public License version 1.0</dc:rights>
+ <opf:meta name="cover" content="cover-image"/>
+ </opf:metadata>
+ <opf:manifest>
+ <opf:item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
+ <opf:item id="cover-image" href="cover.jpg" media-type="image/jpeg"/>
+ <opf:item id="title-page" href="title-page.html" media-type="application/xhtml+xml"/>
+ <opf:item id="copyright" href="copyright.html" media-type="application/xhtml+xml"/>
+ <opf:item id="introduction" href="introduction.html" media-type="application/xhtml+xml"/>
+ <opf:item id="epub-format" href="epub-format.html" media-type="application/xhtml+xml"/>
+ <opf:item id="generate-ant" href="generate-ant.html" media-type="application/xhtml+xml"/>
+ <opf:item id="generate-epub" href="generate-epub.html" media-type="application/xhtml+xml"/>
+ <opf:item id="epub-ant-task" href="epub-ant-task.html" media-type="application/xhtml+xml"/>
+ <opf:item id="examples" href="examples.html" media-type="application/xhtml+xml"/>
+ <opf:item id="text-style" href="style.css" media-type="text/css"/>
+ <opf:item id="image-Illustrations.002" href="Illustrations.002.jpg" media-type="image/jpeg"/>
+ <opf:item id="image-generate-epub" href="generate-epub.png" media-type="image/png"/>
+ <opf:item id="image-nook-cover" href="nook-cover.png" media-type="image/png"/>
+ <opf:item id="image-runtime-jre" href="runtime-jre.png" media-type="image/png"/>
+ <opf:item id="cover" href="cover-page.xhtml" media-type="application/xhtml+xml"/>
+ </opf:manifest>
+ <opf:spine toc="ncx">
+ <opf:itemref idref="cover" linear="no"/>
+ <opf:itemref idref="title-page"/>
+ <opf:itemref idref="copyright"/>
+ <opf:itemref idref="introduction"/>
+ <opf:itemref idref="epub-format"/>
+ <opf:itemref idref="generate-ant"/>
+ <opf:itemref idref="generate-epub"/>
+ <opf:itemref idref="epub-ant-task"/>
+ <opf:itemref idref="examples"/>
+ </opf:spine>
+ <opf:guide>
+ <opf:reference type="title-page" title="Building EPUBs" href="title-page.html"/>
+ <opf:reference type="preface" title="Introduction" href="introduction.html"/>
+ <opf:reference type="copyright-page" title="Copyright" href="copyright.html"/>
+ <opf:reference type="cover" title="Cover page" href="cover-page.xhtml"/>
+ </opf:guide>
+</opf:package>
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/SocketException/content.opf b/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/SocketException/content.opf
new file mode 100644
index 000000000..aa96e98f1
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/OPF-Tests/SocketException/content.opf
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE package
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid"><metadata><dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/" id="bookid">_d0e1</dc:identifier><dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">Distributed Version Control with Git</dc:title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" opf:file-as="Vogel, Lars">Lars Vogel</dc:creator><dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2011</dc:date><dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/">Copyright © 2009, 2010, 2011 Lars Vogel</dc:rights><dc:language xmlns:dc="http://purl.org/dc/elements/1.1/">en</dc:language><meta name="cover" content="cover-image"/></metadata><manifest><item id="ncxtoc" media-type="application/x-dtbncx+xml" href="toc.ncx"/><item id="htmltoc" media-type="application/xhtml+xml" href="bk01-toc.html"/><item media-type="text/css" id="css" href="stylesepub.css"/><item id="cover" href="cover.html" media-type="application/xhtml+xml"/><item id="d0e1" href="index.html" media-type="application/xhtml+xml"/><item id="cover-image" href="images/Git-cover.png" media-type="image/png"/><item id="d0e40" href="pr01.html" media-type="application/xhtml+xml"/><item id="d0e55" href="pr02.html" media-type="application/xhtml+xml"/><item id="d0e69" href="pr02s02.html" media-type="application/xhtml+xml"/><item id="d0e76" href="pr02s03.html" media-type="application/xhtml+xml"/><item id="d0e95" href="pr02s04.html" media-type="application/xhtml+xml"/><item id="d0e110" href="pr02s05.html" media-type="application/xhtml+xml"/><item id="d0e121" href="pr02s06.html" media-type="application/xhtml+xml"/><item id="d0e128" href="ch01.html" media-type="application/xhtml+xml"/><item id="d0e214" href="ch01s02.html" media-type="application/xhtml+xml"/><item id="d0e228" href="ch01s03.html" media-type="application/xhtml+xml"/><item id="d0e289" href="ch02.html" media-type="application/xhtml+xml"/><item id="d0e392" href="ch02s02.html" media-type="application/xhtml+xml"/><item id="d0e470" href="ch02s03.html" media-type="application/xhtml+xml"/><item id="d0e531" href="ch02s04.html" media-type="application/xhtml+xml"/><item id="d0e560" href="ch03.html" media-type="application/xhtml+xml"/><item id="d0e624" href="ch03s02.html" media-type="application/xhtml+xml"/><item id="d0e658" href="ch03s03.html" media-type="application/xhtml+xml"/><item id="d0e724" href="ch04.html" media-type="application/xhtml+xml"/><item id="d0e741" href="ch04s02.html" media-type="application/xhtml+xml"/><item id="d0e776" href="ch04s03.html" media-type="application/xhtml+xml"/><item id="d0e794" href="ch04s04.html" media-type="application/xhtml+xml"/><item id="d0e825" href="ch04s05.html" media-type="application/xhtml+xml"/><item id="d0e865" href="ch05.html" media-type="application/xhtml+xml"/><item id="d0e942" href="ch05s02.html" media-type="application/xhtml+xml"/><item id="d0e974" href="ch06.html" media-type="application/xhtml+xml"/></manifest><spine toc="ncxtoc"><itemref idref="cover" linear="no"/><itemref idref="htmltoc" linear="yes"/><itemref idref="d0e1"/><itemref idref="d0e40"/><itemref idref="d0e55"/><itemref idref="d0e69"/><itemref idref="d0e76"/><itemref idref="d0e95"/><itemref idref="d0e110"/><itemref idref="d0e121"/><itemref idref="d0e128"/><itemref idref="d0e214"/><itemref idref="d0e228"/><itemref idref="d0e289"/><itemref idref="d0e392"/><itemref idref="d0e470"/><itemref idref="d0e531"/><itemref idref="d0e560"/><itemref idref="d0e624"/><itemref idref="d0e658"/><itemref idref="d0e724"/><itemref idref="d0e741"/><itemref idref="d0e776"/><itemref idref="d0e794"/><itemref idref="d0e825"/><itemref idref="d0e865"/><itemref idref="d0e942"/><itemref idref="d0e974"/></spine><guide><reference href="cover.html" type="cover" title="Cover"/><reference href="bk01-toc.html" type="toc" title="Table of Contents"/></guide></package> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/book.css b/org.eclipse.mylyn.docs.epub.tests/testdata/book.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/book.css
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/drawing-100x100.svg b/org.eclipse.mylyn.docs.epub.tests/testdata/drawing-100x100.svg
new file mode 100644
index 000000000..44a7f88f9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/drawing-100x100.svg
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="EPUB Test File">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3652">
+ <stop
+ style="stop-color:#ebed3c;stop-opacity:1;"
+ offset="0"
+ id="stop3654" />
+ <stop
+ style="stop-color:#ebedff;stop-opacity:1;"
+ offset="1"
+ id="stop3656" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3632">
+ <stop
+ style="stop-color:#9eeba2;stop-opacity:1;"
+ offset="0"
+ id="stop3634" />
+ <stop
+ style="stop-color:#9eeba2;stop-opacity:0;"
+ offset="1"
+ id="stop3636" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3590">
+ <stop
+ style="stop-color:#008400;stop-opacity:0.46368715;"
+ offset="0"
+ id="stop3592" />
+ <stop
+ style="stop-color:#ffffd4;stop-opacity:0;"
+ offset="1"
+ id="stop3594" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="-26.423218 : -155.35634 : 1"
+ inkscape:vp_y="-23.686995 : 425.71923 : 0"
+ inkscape:vp_z="1021.8599 : -153.53301 : 1"
+ inkscape:persp3d-origin="501.87287 : -229.11314 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3590"
+ id="linearGradient3596"
+ x1="55.705997"
+ y1="100.19342"
+ x2="54.932304"
+ y2="0.1934236"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3632"
+ id="radialGradient3640"
+ cx="43.130703"
+ cy="972.86798"
+ fx="43.130703"
+ fy="972.86798"
+ r="39.445312"
+ gradientTransform="matrix(1,0,0,0.39616756,6.5265487,646.07757)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3652"
+ id="radialGradient3658"
+ cx="18.032286"
+ cy="43.940254"
+ fx="18.032286"
+ fy="43.940254"
+ r="19.967714"
+ gradientTransform="matrix(1,0,0,1.0101761,0,-0.4471386)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="9.04"
+ inkscape:cx="28.871681"
+ inkscape:cy="50.708853"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1152"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <rect
+ id="rect2816"
+ width="100"
+ height="100"
+ x="-0.1934236"
+ y="0.1934236"
+ transform="translate(0,952.36218)"
+ style="fill-opacity:1;fill:url(#linearGradient3596);stroke:#000000;stroke-opacity:1" />
+ <g
+ sodipodi:type="inkscape:box3d"
+ id="g3612"
+ inkscape:perspectiveID="#perspective10"
+ inkscape:corner0="5.1502873 : 3.3791652 : 0 : 1"
+ inkscape:corner7="4.4941374 : 3.1208021 : 0.25 : 1">
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3624"
+ style="fill:#e9e9ff;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="11"
+ d="m 84.560018,994.40393 12.677559,-24.36681 1.065407,19.14824 -12.786783,22.40374 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3614"
+ style="fill:#353564;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="6"
+ d="m 46.460177,985.80713 0.99505,17.88377 38.060974,7.8982 -0.956183,-17.18517 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3616"
+ style="fill:#4d4d9f;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="5"
+ d="m 46.460177,985.80713 8.704266,-26.50227 42.073134,10.73226 -12.677559,24.36681 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3622"
+ style="fill:#afafde;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="13"
+ d="m 47.455227,1003.6909 8.823102,-24.3665 42.024655,9.86096 -12.786783,22.40374 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3620"
+ style="fill:#d7d7ff;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="14"
+ d="m 55.164443,959.30486 1.113886,20.01954 42.024655,9.86096 -1.065407,-19.14824 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3618"
+ style="fill:#8686bf;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="3"
+ d="m 46.460177,985.80713 8.704266,-26.50227 1.113886,20.01954 -8.823102,24.3665 z" />
+ </g>
+ <path
+ sodipodi:type="star"
+ id="path3626"
+ sodipodi:sides="5"
+ sodipodi:cx="19.247787"
+ sodipodi:cy="43.141594"
+ sodipodi:r1="20.844067"
+ sodipodi:r2="10.422033"
+ sodipodi:arg1="0.50400573"
+ sodipodi:arg2="1.1323243"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 37.5,53.207966 23.67253,52.577718 15.314343,63.61116 11.640821,50.265697 -1.4354278,45.72611 10.121681,38.108408 10.398302,24.269347 21.21451,32.906811 34.46172,28.893388 29.589395,41.849337 37.5,53.207966 z"
+ transform="translate(7.3008848,933.66749)"
+ style="fill:url(#radialGradient3658);fill-opacity:1;stroke:#9eeba2;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#335900;fill-opacity:1;stroke:url(#radialGradient3640);stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ x="8.0752211"
+ y="1046.0568"
+ id="text3628"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3630"
+ x="8.0752211"
+ y="1046.0568"
+ style="fill:#335900;fill-opacity:1;stroke:url(#radialGradient3640)">SVG</tspan></text>
+ </g>
+</svg>
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/images/drawing-2-100x100.svg b/org.eclipse.mylyn.docs.epub.tests/testdata/images/drawing-2-100x100.svg
new file mode 100644
index 000000000..44a7f88f9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/images/drawing-2-100x100.svg
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="EPUB Test File">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3652">
+ <stop
+ style="stop-color:#ebed3c;stop-opacity:1;"
+ offset="0"
+ id="stop3654" />
+ <stop
+ style="stop-color:#ebedff;stop-opacity:1;"
+ offset="1"
+ id="stop3656" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3632">
+ <stop
+ style="stop-color:#9eeba2;stop-opacity:1;"
+ offset="0"
+ id="stop3634" />
+ <stop
+ style="stop-color:#9eeba2;stop-opacity:0;"
+ offset="1"
+ id="stop3636" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3590">
+ <stop
+ style="stop-color:#008400;stop-opacity:0.46368715;"
+ offset="0"
+ id="stop3592" />
+ <stop
+ style="stop-color:#ffffd4;stop-opacity:0;"
+ offset="1"
+ id="stop3594" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="-26.423218 : -155.35634 : 1"
+ inkscape:vp_y="-23.686995 : 425.71923 : 0"
+ inkscape:vp_z="1021.8599 : -153.53301 : 1"
+ inkscape:persp3d-origin="501.87287 : -229.11314 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3590"
+ id="linearGradient3596"
+ x1="55.705997"
+ y1="100.19342"
+ x2="54.932304"
+ y2="0.1934236"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3632"
+ id="radialGradient3640"
+ cx="43.130703"
+ cy="972.86798"
+ fx="43.130703"
+ fy="972.86798"
+ r="39.445312"
+ gradientTransform="matrix(1,0,0,0.39616756,6.5265487,646.07757)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3652"
+ id="radialGradient3658"
+ cx="18.032286"
+ cy="43.940254"
+ fx="18.032286"
+ fy="43.940254"
+ r="19.967714"
+ gradientTransform="matrix(1,0,0,1.0101761,0,-0.4471386)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="9.04"
+ inkscape:cx="28.871681"
+ inkscape:cy="50.708853"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1152"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <rect
+ id="rect2816"
+ width="100"
+ height="100"
+ x="-0.1934236"
+ y="0.1934236"
+ transform="translate(0,952.36218)"
+ style="fill-opacity:1;fill:url(#linearGradient3596);stroke:#000000;stroke-opacity:1" />
+ <g
+ sodipodi:type="inkscape:box3d"
+ id="g3612"
+ inkscape:perspectiveID="#perspective10"
+ inkscape:corner0="5.1502873 : 3.3791652 : 0 : 1"
+ inkscape:corner7="4.4941374 : 3.1208021 : 0.25 : 1">
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3624"
+ style="fill:#e9e9ff;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="11"
+ d="m 84.560018,994.40393 12.677559,-24.36681 1.065407,19.14824 -12.786783,22.40374 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3614"
+ style="fill:#353564;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="6"
+ d="m 46.460177,985.80713 0.99505,17.88377 38.060974,7.8982 -0.956183,-17.18517 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3616"
+ style="fill:#4d4d9f;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="5"
+ d="m 46.460177,985.80713 8.704266,-26.50227 42.073134,10.73226 -12.677559,24.36681 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3622"
+ style="fill:#afafde;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="13"
+ d="m 47.455227,1003.6909 8.823102,-24.3665 42.024655,9.86096 -12.786783,22.40374 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3620"
+ style="fill:#d7d7ff;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="14"
+ d="m 55.164443,959.30486 1.113886,20.01954 42.024655,9.86096 -1.065407,-19.14824 z" />
+ <path
+ sodipodi:type="inkscape:box3dside"
+ id="path3618"
+ style="fill:#8686bf;fill-rule:evenodd;stroke:none"
+ inkscape:box3dsidetype="3"
+ d="m 46.460177,985.80713 8.704266,-26.50227 1.113886,20.01954 -8.823102,24.3665 z" />
+ </g>
+ <path
+ sodipodi:type="star"
+ id="path3626"
+ sodipodi:sides="5"
+ sodipodi:cx="19.247787"
+ sodipodi:cy="43.141594"
+ sodipodi:r1="20.844067"
+ sodipodi:r2="10.422033"
+ sodipodi:arg1="0.50400573"
+ sodipodi:arg2="1.1323243"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 37.5,53.207966 23.67253,52.577718 15.314343,63.61116 11.640821,50.265697 -1.4354278,45.72611 10.121681,38.108408 10.398302,24.269347 21.21451,32.906811 34.46172,28.893388 29.589395,41.849337 37.5,53.207966 z"
+ transform="translate(7.3008848,933.66749)"
+ style="fill:url(#radialGradient3658);fill-opacity:1;stroke:#9eeba2;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#335900;fill-opacity:1;stroke:url(#radialGradient3640);stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ x="8.0752211"
+ y="1046.0568"
+ id="text3628"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3630"
+ x="8.0752211"
+ y="1046.0568"
+ style="fill:#335900;fill-opacity:1;stroke:url(#radialGradient3640)">SVG</tspan></text>
+ </g>
+</svg>
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page.xhtml b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page.xhtml
new file mode 100644
index 000000000..4d9bff095
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page.xhtml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+</head>
+<body>
+ <h1 id="h1_1">First item</h1>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <h2 id="h2_1">First sub-item</h2>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <h2 id="h2_2">Second sub-item</h2>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <h1 id="h1_2">Second item</h1>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.html b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.html
new file mode 100644
index 000000000..40de7ec05
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+</head>
+<body>
+ <h1 id="h1_1">First item</h1>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ <img src="drawing-100x100.svg" alt="drawing"/>
+ <img src="images/drawing-2-100x100.svg" alt="drawing"/>
+ <a href="plain-page_no-header.html">Link to another page</a>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <h2 id="h2_1">First sub-item</h2>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <h2 id="h2_2">Second sub-item</h2>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <h1 id="h1_2">Second item</h1>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.xhtml b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.xhtml
new file mode 100644
index 000000000..841dfba6f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.xhtml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+</head>
+<body>
+ <h1 id="h1_1">First item</h1>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ <img src="drawing-100x100.svg" alt="drawing"/>
+ <img src="images/drawing-2-100x100.svg" alt="drawing"/>
+ <a href="plain-page_no-header.xhtml">Link to another page</a>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <h2 id="h2_1">First sub-item</h2>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <h2 id="h2_2">Second sub-item</h2>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <h1 id="h1_2">Second item</h1>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.html b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.html
new file mode 100644
index 000000000..d7486c21d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+<link rel="stylesheet" href="css/book.css" type="text/css" />
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
+</head>
+<body>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.xhtml b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.xhtml
new file mode 100644
index 000000000..d7486c21d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+<link rel="stylesheet" href="css/book.css" type="text/css" />
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
+</head>
+<body>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_warnings.xhtml b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_warnings.xhtml
new file mode 100644
index 000000000..4334504f5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_warnings.xhtml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<title>XHTML Test</title>
+</head>
+<body>
+ <bad>Not a XHTML 1.1 element</bad>
+ <h1 id="h1_1">First item</h1>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec
+ odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem
+ at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
+ tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
+ nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
+ per inceptos himenaeos.</p>
+ <p>
+ Curabitur sodales ligula in libero. <i>Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit</i>. Sed dignissim lacinia nunc. Curabitur tortor.
+ Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
+ Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
+ Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac
+ turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus,
+ ullamcorper vel, tincidunt sed, euismod in, nibh.
+ </p>
+ <h2 id="h2_1">First sub-item</h2>
+ <p>
+ Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora
+ torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed
+ lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus
+ ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. <i>Aenean
+ quam</i>. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin
+ quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed
+ lectus.
+ </p>
+ <h2 id="h2_2">Second sub-item</h2>
+ <p>
+ Integer euismod lacus luctus magna. <i>Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos</i>. Quisque cursus,
+ metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue
+ eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+ posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.
+ Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit
+ amet pede facilisis laoreet. <i>Ut fringilla</i>. Donec lacus nunc, viverra
+ nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
+ Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est
+ pulvinar ullamcorper.
+ </p>
+ <h1 id="h1_2">Second item</h1>
+ <p>Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed
+ aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis,
+ venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales
+ libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo
+ ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor,
+ cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at
+ pede suscipit sodales.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.tests/testdata/toc.ncx b/org.eclipse.mylyn.docs.epub.tests/testdata/toc.ncx
new file mode 100644
index 000000000..51c5fe808
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.tests/testdata/toc.ncx
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ncx:ncx xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
+ <ncx:head>
+ <ncx:meta content="3063f615-672e-4083-911a-65c5ff245e75" name="dtb:uid"/>
+ </ncx:head>
+ <ncx:docTitle>
+ <ncx:text>Table of contents</ncx:text>
+ </ncx:docTitle>
+ <ncx:navMap>
+ <ncx:navPoint id="navpoint1" playOrder="1">
+ <ncx:navLabel>
+ <ncx:text>First item</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="plain-page.xhtml#h1_1"/>
+ <ncx:navPoint id="navpoint2" playOrder="2">
+ <ncx:navLabel>
+ <ncx:text>First sub-item</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="plain-page.xhtml#h2_1"/>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint3" playOrder="3">
+ <ncx:navLabel>
+ <ncx:text>Second sub-item</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="plain-page.xhtml#h2_2"/>
+ </ncx:navPoint>
+ </ncx:navPoint>
+ <ncx:navPoint id="navpoint4" playOrder="4">
+ <ncx:navLabel>
+ <ncx:text>Second item</ncx:text>
+ </ncx:navLabel>
+ <ncx:content src="plain-page.xhtml#h1_2"/>
+ </ncx:navPoint>
+ </ncx:navMap>
+</ncx:ncx>
diff --git a/org.eclipse.mylyn.docs.epub.ui/.classpath b/org.eclipse.mylyn.docs.epub.ui/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.docs.epub.ui/.gitignore b/org.eclipse.mylyn.docs.epub.ui/.gitignore
new file mode 100644
index 000000000..a31f1846c
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.gitignore
@@ -0,0 +1,3 @@
+/org.eclipse*/bin
+/org.eclipse*/target
+
diff --git a/org.eclipse.mylyn.docs.epub.ui/.project b/org.eclipse.mylyn.docs.epub.ui/.project
new file mode 100644
index 000000000..94414c47d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.docs.epub.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..3e4d701a4
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri May 20 15:07:41 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..8a54ffecf
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Fri May 20 15:07:41 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..b367ad2d4
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Sun May 01 15:29:11 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..3e988b07f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 31 11:01:26 PDT 2008
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..6b8fe8a4f
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.ui;singleton:=true
+Bundle-Version: 0.8.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.mylyn.docs.epub.core;bundle-version="[0.8.0,1.0.0)",
+ org.eclipse.mylyn.wikitext.ui;bundle-version="[1.5.0,2.0.0)",
+ org.eclipse.mylyn.wikitext.core;bundle-version="[1.5.0,2.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.ui;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.core.databinding,
+ org.eclipse.core.databinding.beans,
+ org.eclipse.core.databinding.observable,
+ org.eclipse.core.databinding.property,
+ org.eclipse.jface.databinding,
+ com.ibm.icu,
+ org.eclipse.emf;bundle-version="2.6.0",
+ org.eclipse.emf.ecore;bundle-version="2.7.0",
+ org.eclipse.emf.databinding,
+ org.eclipse.emf.validation;bundle-version="1.4.0",
+ org.eclipse.emf.validation.ui;bundle-version="1.3.0"
+Bundle-ClassPath: .
+Bundle-Activator: org.eclipse.mylyn.internal.docs.epub.ui.EPUBUIPlugin
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.mylyn.internal.docs.epub.ui;x-internal:=true,
+ org.eclipse.mylyn.internal.docs.epub.ui.commands;x-internal:=true
diff --git a/org.eclipse.mylyn.docs.epub.ui/OSGI-INF/l10n/bundle.properties b/org.eclipse.mylyn.docs.epub.ui/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 000000000..3ae9acdc6
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2011 Torkild U. Resheim.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Torkild U. Resheim - initial API and implementation
+###############################################################################
+#Properties file for org.eclipse.mylyn.docs.epub.ui
+Bundle-Vendor = Torkild U. Resheim
+Bundle-Name = EPUB User Interface
+command.name = Generate EPUB
+command.label = Generate EPUB... \ No newline at end of file
diff --git a/org.eclipse.mylyn.docs.epub.ui/build.properties b/org.eclipse.mylyn.docs.epub.ui/build.properties
new file mode 100644
index 000000000..2daa3d13e
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .,\
+ icons/,\
+ OSGI-INF/
+jre.compilation.profile = J2SE-1.5
diff --git a/org.eclipse.mylyn.docs.epub.ui/icons/wizard-banner.png b/org.eclipse.mylyn.docs.epub.ui/icons/wizard-banner.png
new file mode 100644
index 000000000..db07eddee
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/icons/wizard-banner.png
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.ui/plugin.xml b/org.eclipse.mylyn.docs.epub.ui/plugin.xml
new file mode 100644
index 000000000..b68b3d1b7
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/plugin.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ defaultHandler="org.eclipse.mylyn.internal.docs.epub.ui.commands.ConvertMarkupToEPUB"
+ id="org.eclipse.mylyn.docs.epub.ui.convertToEPUBCommand"
+ name="%command.name">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="true"
+ locationURI="popup:org.eclipse.mylyn.wikitext.ui.contextmenu?after=additions">
+ <command
+ commandId="org.eclipse.mylyn.docs.epub.ui.convertToEPUBCommand"
+ label="%command.label"
+ style="push">
+ </command>
+ </menuContribution>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.mylyn.docs.epub.ui/pom.xml b/org.eclipse.mylyn.docs.epub.ui/pom.xml
new file mode 100644
index 000000000..49c6e3e8d
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.docs-parent</artifactId>
+ <groupId>org.eclipse.mylyn.docs</groupId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.docs.epub.ui</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <groupId>org.eclipse.mylyn.docs.epub</groupId>
+</project>
diff --git a/org.eclipse.mylyn.docs.epub.ui/src-images/wizard-banner.psd b/org.eclipse.mylyn.docs.epub.ui/src-images/wizard-banner.psd
new file mode 100644
index 000000000..0744a6b35
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src-images/wizard-banner.psd
Binary files differ
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/ConvertFromMarkupWizard.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/ConvertFromMarkupWizard.java
new file mode 100644
index 000000000..2a55f68f5
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/ConvertFromMarkupWizard.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.ui;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.mylyn.docs.epub.core.EPUB;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.core.wikitext.MarkupToOPS;
+import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public class ConvertFromMarkupWizard extends Wizard {
+
+ private static final String PLUGIN_ID = "org.eclipse.mylyn.docs.epub.ui";
+
+ private EPUB2Bean bean;
+
+ OPSPublication epub;
+
+ private IFile epubFile;
+
+ private File epubFolder;
+
+ private IFile markupFile;
+
+ private File markupFolder = null;
+
+ private MarkupLanguage markupLanguage;
+
+ private MainPage page;
+
+ public ConvertFromMarkupWizard() {
+ setWindowTitle("Generate EPUB");
+ setNeedsProgressMonitor(true);
+ }
+
+ @Override
+ public void addPages() {
+ epub = OPSPublication.getVersion2Instance();
+ // XXX: Read back epub
+ File workingFolder = null;
+ // if (epubFile.exists()) {
+ // try {
+ // workingFolder = epub.unpack(epubFile.getLocation().toFile());
+ // } catch (Exception e) {
+ // e.printStackTrace();
+ // }
+ // }
+ bean = new EPUB2Bean(epub, markupFile.getLocation().toFile(), epubFile.getLocation().toFile(), workingFolder);
+ page = new MainPage(bean);
+ addPage(page);
+ }
+
+ /**
+ * Delete the folder recursively.
+ *
+ * @param folder
+ * the folder to delete
+ * @return <code>true</code> if the folder was deleted
+ */
+ private void deleteFolder(File folder) {
+ if (folder == null) {
+ return;
+ }
+ if (folder.isDirectory() && folder.exists()) {
+ String[] children = folder.list();
+ for (int i = 0; i < children.length; i++) {
+ deleteFolder(new File(folder, children[i]));
+ }
+ }
+ if (folder.exists()) {
+ folder.delete();
+ }
+ }
+
+ public void init(IFile markupFile, IFile epubFile, MarkupLanguage markupLanguage) {
+ this.markupFile = markupFile;
+ this.epubFile = epubFile;
+ this.markupLanguage = markupLanguage;
+ }
+
+ @Override
+ public boolean performFinish() {
+ final MarkupToOPS markupToEPUB = new MarkupToOPS();
+ markupToEPUB.setMarkupLanguage(markupLanguage);
+ final MultiStatus ms = new MultiStatus(PLUGIN_ID, 0, "Could not generate EPUB", null);
+ try {
+ getContainer().run(false, false, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask("Generate EPUB", 3);
+ try {
+ if (epubFile.exists()) {
+ // Delete the old one
+ epubFile.delete(true, monitor);
+ }
+ // Parse the wiki markup and populate the EPUB
+ markupFolder = markupToEPUB.parse(epub, markupFile.getLocation().toFile());
+ monitor.worked(1);
+ List<Diagnostic> problems = epub.validateMetadata();
+
+ if (problems.size() > 0) {
+ for (Diagnostic diagnostic : problems) {
+ ms.add(new Status(IStatus.ERROR, PLUGIN_ID, diagnostic.getMessage()));
+ }
+ monitor.setCanceled(true);
+ StatusManager.getManager().handle(ms, StatusManager.BLOCK);
+ return;
+ }
+ EPUB publication = new EPUB();
+ publication.add(epub);
+ epubFolder = publication.pack(epubFile.getLocation().toFile());
+ monitor.worked(1);
+ epubFile.refreshLocal(IResource.DEPTH_ONE, monitor);
+ monitor.worked(1);
+ } catch (Exception e) {
+ ms.add(new Status(IStatus.ERROR, EPUBUIPlugin.PLUGIN_ID, "An exception occured", e));
+ monitor.setCanceled(true);
+ StatusManager.getManager().handle(ms);
+ StatusManager.getManager().handle(ms, StatusManager.BLOCK);
+ return;
+ } finally {
+ deleteFolder(epubFolder);
+ deleteFolder(markupFolder);
+ monitor.done();
+ }
+ }
+ });
+ } catch (Throwable e) {
+ ms.add(new Status(IStatus.ERROR, EPUBUIPlugin.PLUGIN_ID, "Could not convert to EPUB", e));
+ return false;
+ }
+ return ms.isOK();
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUB2Bean.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUB2Bean.java
new file mode 100644
index 000000000..9844b0926
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUB2Bean.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.ui;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil.FeatureEList;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.mylyn.docs.epub.core.OPSPublication;
+import org.eclipse.mylyn.docs.epub.dc.Creator;
+import org.eclipse.mylyn.docs.epub.dc.Date;
+import org.eclipse.mylyn.docs.epub.dc.Identifier;
+import org.eclipse.mylyn.docs.epub.dc.Language;
+import org.eclipse.mylyn.docs.epub.dc.Rights;
+import org.eclipse.mylyn.docs.epub.dc.Subject;
+import org.eclipse.mylyn.docs.epub.dc.Title;
+import org.eclipse.mylyn.docs.epub.opf.Item;
+
+/**
+ * Simplified representation of an EPUB revision 2.0 instance.
+ *
+ * @author Torkild U. Resheim
+ *
+ */
+class EPUB2Bean {
+
+ private static final String STYLING_ID = "styling";
+
+ private static final String EMPTY_STRING = "";
+
+ private static final EStructuralFeature TEXT = XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Text();
+
+ private final OPSPublication epub;
+
+ private final File markupFile;
+
+ public File getMarkupFile() {
+ return markupFile;
+ }
+
+ public EPUB2Bean() {
+ epub = OPSPublication.getVersion2Instance();
+ markupFile = null;
+ }
+
+ class ValueComparator implements Comparator<String> {
+
+ Map<String, String> base;
+
+ public ValueComparator(Map<String, String> base) {
+ this.base = base;
+ }
+
+ public int compare(String a, String b) {
+ String key_a = a;
+ String key_b = b;
+
+ return key_a.compareTo(key_b);
+ }
+ }
+
+ TreeMap<String, String> sorted_locales;
+
+ public EPUB2Bean(OPSPublication epub, File markupFile, File epubFile, File workingFolder) {
+ this.epub = epub;
+ this.markupFile = markupFile;
+ String id = epub.getOpfPackage().getUniqueIdentifier();
+ if (id == null || id.trim().length() == 0) {
+ epub.getOpfPackage().setUniqueIdentifier(ID);
+ epub.addIdentifier(ID, "UUID", UUID.randomUUID().toString());
+ }
+ // Clear everything except the metadata
+ epub.getOpfPackage().getManifest().getItems().clear();
+ epub.getOpfPackage().getGuide().getGuideItems().clear();
+ epub.getOpfPackage().getSpine().getSpineItems().clear();
+
+ sorted_locales = new TreeMap<String, String>();
+ String[] iso639s = Locale.getISOLanguages();
+ for (String iso639 : iso639s) {
+ Locale locale = new Locale(iso639);
+ sorted_locales.put(locale.getDisplayLanguage(), locale.getLanguage());
+ }
+ }
+
+ public String getCover() {
+ Item item = epub.getItemById(OPSPublication.COVER_IMAGE_ID);
+ if (item == null) {
+ return EMPTY_STRING;
+ } else {
+ return item.getFile();
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getCreator() {
+ EList<Creator> creators = epub.getOpfPackage().getMetadata().getCreators();
+ if (creators.size() > 0) {
+ FeatureMap fm = creators.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ public OPSPublication getEPUB() {
+ return epub;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getIdentifier() {
+ EList<Identifier> identifiers = epub.getOpfPackage().getMetadata().getIdentifiers();
+ if (identifiers.size() > 0) {
+ FeatureMap fm = identifiers.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getLanguage() {
+ EList<Language> languages = epub.getOpfPackage().getMetadata().getLanguages();
+ if (languages.size() > 0) {
+ FeatureMap fm = languages.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ String iso639 = ((FeatureEList) o).get(0).toString();
+ Locale l = new Locale(iso639);
+ return l.getDisplayLanguage();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ public void setLanguage(String language) {
+ epub.getOpfPackage().getMetadata().getLanguages().clear();
+ epub.addLanguage(null, sorted_locales.get(language));
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getRights() {
+ EList<Rights> rights = epub.getOpfPackage().getMetadata().getRights();
+ if (rights.size() > 0) {
+ FeatureMap fm = rights.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ public String getStyleSheet() {
+ List<Item> stylesheets = epub.getItemsByMIMEType(OPSPublication.MIMETYPE_CSS);
+ if (stylesheets.isEmpty()) {
+ return EMPTY_STRING;
+ } else {
+ return stylesheets.get(0).getHref();
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getSubject() {
+ EList<Subject> subjects = epub.getOpfPackage().getMetadata().getSubjects();
+ if (subjects.size() > 0) {
+ FeatureMap fm = subjects.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getTitle() {
+ EList<Title> titles = epub.getOpfPackage().getMetadata().getTitles();
+ if (titles.size() > 0) {
+ FeatureMap fm = titles.get(0).getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ public void setCover(String cover) {
+ epub.setCover(new File(cover), "Cover page");
+ }
+
+ public void setCreator(String creator) {
+ epub.getOpfPackage().getMetadata().getCreators().clear();
+ epub.addCreator(null, null, creator, null, null);
+ }
+
+ private final static String ID = "epub-id";
+
+ public void setIdentifier(String identifier) {
+ String scheme = getScheme();
+ epub.getOpfPackage().getMetadata().getIdentifiers().clear();
+ epub.addIdentifier(ID, scheme, identifier);
+ epub.getOpfPackage().setUniqueIdentifier(ID);
+ }
+
+ public void setScheme(String schemeName) {
+ String identifier = getIdentifier();
+ epub.getOpfPackage().getMetadata().getIdentifiers().clear();
+ epub.getOpfPackage().setUniqueIdentifier(ID);
+ epub.addIdentifier(ID, schemeName, identifier);
+ }
+
+ public String getScheme() {
+ Identifier ident = epub.getOpfPackage().getMetadata().getIdentifiers().get(0);
+ return ident.getScheme();
+ }
+
+ public void setRights(String rights) {
+ epub.getOpfPackage().getMetadata().getRights().clear();
+ epub.addRights(null, null, rights);
+ }
+
+ public void setStyleSheet(String css) {
+ epub.getOpfPackage().getManifest().getItems().remove(epub.getItemsByMIMEType(OPSPublication.MIMETYPE_CSS));
+ epub.addItem(STYLING_ID, null, new File(css), null, null, false, false, true);
+ }
+
+ public void setSubject(String subject) {
+ epub.getOpfPackage().getMetadata().getSubjects().clear();
+ epub.addSubject(null, null, subject);
+ }
+
+ public void setTitle(String title) {
+ epub.getOpfPackage().getMetadata().getTitles().clear();
+ epub.addTitle(null, null, title);
+ }
+
+ public void setPublicationDate(String date){
+ epub.getOpfPackage().getMetadata().getDates().clear();
+ epub.addDate(null, date, "publication");
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getPublicationDate() {
+ EList<Date> dates = epub.getOpfPackage().getMetadata().getDates();
+ if (dates.size() > 0) {
+ for (Date date : dates) {
+ if (date.getEvent().equals("publication")) {
+ FeatureMap fm = date.getMixed();
+ Object o = fm.get(TEXT, false);
+ if (o instanceof FeatureEList) {
+ if (((FeatureEList) o).size() > 0) {
+ return ((FeatureEList) o).get(0).toString();
+ }
+ }
+ }
+ }
+ }
+ return EMPTY_STRING;
+
+ }
+
+ public Map<String, String> getLocales() {
+ return sorted_locales;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUBUIPlugin.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUBUIPlugin.java
new file mode 100644
index 000000000..81d6af9c3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUBUIPlugin.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse License v1.0 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+public class EPUBUIPlugin extends AbstractUIPlugin {
+
+ private static EPUBUIPlugin plugin;
+
+ public static final String PLUGIN_ID = "org.eclipse.mylyn.docs.epub.ui";
+
+ @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 EPUBUIPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/MainPage.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/MainPage.java
new file mode 100644
index 000000000..291ca85e9
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/MainPage.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.ui;
+
+import java.util.Set;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.PojoObservables;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DateTime;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class MainPage extends WizardPage {
+
+ @SuppressWarnings("unused")
+ private DataBindingContext m_bindingContext;
+
+ private Text titleText;
+
+ private Text copyrightText;
+
+ private Text coverText;
+
+ private Text styleSheetText;
+
+ private Text identifierText;
+
+ private Text subjectText;
+
+ /**
+ * @wbp.nonvisual location=681,21
+ */
+ private EPUB2Bean bean = new EPUB2Bean();
+
+ private Combo schemeText;
+
+ private Text authorText;
+
+ private Combo combo;
+
+ private DateTime dateTime;
+
+ /**
+ * Create the wizard.
+ *
+ * @wbp.parser.constructor
+ */
+ public MainPage() {
+ super("wizardPage");
+ setMessage("Define properties for the resulting EPUB file.");
+ setImageDescriptor(EPUBUIPlugin.imageDescriptorFromPlugin("org.eclipse.mylyn.docs.epub.ui",
+ "icons/wizard-banner.png"));
+ setTitle("EPUB Properties");
+ }
+
+ public MainPage(EPUB2Bean bean) {
+ this();
+ this.bean = bean;
+ }
+
+ /**
+ * Create contents of the wizard.
+ * @param parent
+ */
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+
+ setControl(container);
+ container.setLayout(new GridLayout(1, true));
+
+ Group grpRequiredDetails = new Group(container, SWT.NONE);
+ grpRequiredDetails.setLayout(new GridLayout(4, false));
+ GridData gd_grpRequiredDetails = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1);
+ gd_grpRequiredDetails.heightHint = 187;
+ grpRequiredDetails.setLayoutData(gd_grpRequiredDetails);
+ grpRequiredDetails.setText("Header:");
+
+ Label lblTitle = new Label(grpRequiredDetails, SWT.NONE);
+ lblTitle.setText("Title:");
+
+ titleText = new Text(grpRequiredDetails, SWT.BORDER);
+ titleText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
+
+ Label lblAuthor = new Label(grpRequiredDetails, SWT.NONE);
+ lblAuthor.setText("Author:");
+
+ authorText = new Text(grpRequiredDetails, SWT.BORDER);
+ authorText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+ Label lblNewLabel_1 = new Label(grpRequiredDetails, SWT.NONE);
+ lblNewLabel_1.setText("Date:");
+
+ dateTime = new DateTime(grpRequiredDetails, SWT.BORDER | SWT.LONG);
+
+ Label lblIdentifier = new Label(grpRequiredDetails, SWT.NONE);
+ lblIdentifier.setText("Identifier:");
+
+ identifierText = new Text(grpRequiredDetails, SWT.BORDER);
+ identifierText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+ Label lblScheme = new Label(grpRequiredDetails, SWT.NONE);
+ lblScheme.setText("Scheme:");
+
+ schemeText = new Combo(grpRequiredDetails, SWT.BORDER);
+ schemeText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ schemeText.add("UUID");
+
+ Label lblCopyright = new Label(grpRequiredDetails, SWT.NONE);
+ lblCopyright.setText("Copyright:");
+
+ copyrightText = new Text(grpRequiredDetails, SWT.BORDER);
+ copyrightText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+ Label lblLanguage = new Label(grpRequiredDetails, SWT.NONE);
+ lblLanguage.setText("Language:");
+
+ combo = new Combo(grpRequiredDetails, SWT.READ_ONLY);
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ Set<String> locales = bean.getLocales().keySet();
+ for (String name : locales) {
+ combo.add(name);
+ }
+
+ Label lblDescription = new Label(grpRequiredDetails, SWT.NONE);
+ lblDescription.setText("Subject:");
+
+ subjectText = new Text(grpRequiredDetails, SWT.BORDER);
+ subjectText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
+
+ Group grpCoverAndStyling = new Group(container, SWT.NONE);
+ grpCoverAndStyling.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
+ grpCoverAndStyling.setText("Cover and styling:");
+ grpCoverAndStyling.setLayout(new GridLayout(3, false));
+ Label lblNewLabel = new Label(grpCoverAndStyling, SWT.NONE);
+ lblNewLabel.setText("Cover image:");
+
+ coverText = new Text(grpCoverAndStyling, SWT.BORDER);
+ coverText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+
+ Button button = new Button(grpCoverAndStyling, SWT.NONE);
+ button.setText("...");
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // XXX: Replace with ResourceSelectionDialog?
+ FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN);
+ dialog.setFilterNames(new String[] { "Supported Image Formats" });
+ dialog.setFilterExtensions(new String[] { "*.png;*.gif;*.jpg;*.svg" });
+ dialog.setFilterPath(bean.getMarkupFile().getAbsolutePath());
+ String s = dialog.open();
+ if (s != null) {
+ coverText.setText(s);
+ }
+ }
+ });
+ Label lblStyleSheet = new Label(grpCoverAndStyling, SWT.NONE);
+ lblStyleSheet.setBounds(0, 0, 59, 14);
+ lblStyleSheet.setText("Style Sheet:");
+
+ styleSheetText = new Text(grpCoverAndStyling, SWT.BORDER);
+ styleSheetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+ Button button_1 = new Button(grpCoverAndStyling, SWT.NONE);
+ button_1.setText("...");
+ button_1.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // XXX: Replace with ResourceSelectionDialog?
+ FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.OPEN);
+ dialog.setFilterNames(new String[] { "Cascading Style Sheets" });
+ dialog.setFilterExtensions(new String[] { "*.css" });
+ dialog.setFilterPath(bean.getMarkupFile().getAbsolutePath());
+ String s = dialog.open();
+ if (s != null) {
+ styleSheetText.setText(s);
+ }
+
+ }
+ });
+ m_bindingContext = initDataBindings();
+ }
+ protected DataBindingContext initDataBindings() {
+ DataBindingContext bindingContext = new DataBindingContext();
+ //
+ IObservableValue beanCoverObserveValue = PojoObservables.observeValue(bean, "cover");
+ IObservableValue coverTextTextObserveValue = PojoObservables.observeValue(coverText, "text");
+ bindingContext.bindValue(beanCoverObserveValue, coverTextTextObserveValue, null, null);
+ //
+ IObservableValue textObserveTextObserveWidget = SWTObservables.observeText(titleText, SWT.Modify);
+ IObservableValue beanTitleObserveValue = PojoObservables.observeValue(bean, "title");
+ bindingContext.bindValue(textObserveTextObserveWidget, beanTitleObserveValue, null, null);
+ //
+ IObservableValue subjectTextObserveTextObserveWidget = SWTObservables.observeText(subjectText, SWT.Modify);
+ IObservableValue beanSubjectObserveValue = PojoObservables.observeValue(bean, "subject");
+ bindingContext.bindValue(subjectTextObserveTextObserveWidget, beanSubjectObserveValue, null, null);
+ //
+ IObservableValue text_4ObserveTextObserveWidget = SWTObservables.observeText(identifierText, SWT.Modify);
+ IObservableValue beanIdentifierObserveValue = PojoObservables.observeValue(bean, "identifier");
+ bindingContext.bindValue(text_4ObserveTextObserveWidget, beanIdentifierObserveValue, null, null);
+ //
+ IObservableValue text_1ObserveTextObserveWidget = SWTObservables.observeText(copyrightText, SWT.Modify);
+ IObservableValue beanRightsObserveValue = PojoObservables.observeValue(bean, "rights");
+ bindingContext.bindValue(text_1ObserveTextObserveWidget, beanRightsObserveValue, null, null);
+ //
+ IObservableValue text_3ObserveTextObserveWidget = SWTObservables.observeText(authorText, SWT.Modify);
+ IObservableValue beanCreatorObserveValue = PojoObservables.observeValue(bean, "creator");
+ bindingContext.bindValue(text_3ObserveTextObserveWidget, beanCreatorObserveValue, null, null);
+ //
+ IObservableValue schemeTextObserveTextObserveWidget = SWTObservables.observeText(schemeText);
+ IObservableValue beanIdSchemeObserveValue = PojoObservables.observeValue(bean, "scheme");
+ bindingContext.bindValue(schemeTextObserveTextObserveWidget, beanIdSchemeObserveValue, null, null);
+ //
+ IObservableValue comboObserveTextObserveWidget = SWTObservables.observeText(combo);
+ IObservableValue beanLanguageObserveValue = PojoObservables.observeValue(bean, "language");
+ bindingContext.bindValue(comboObserveTextObserveWidget, beanLanguageObserveValue, null, null);
+ //
+ IObservableValue coverTextObserveTextObserveWidget = SWTObservables.observeText(coverText, SWT.Modify);
+ bindingContext.bindValue(coverTextObserveTextObserveWidget, beanCoverObserveValue, null, null);
+ //
+ IObservableValue styleSheetTextObserveTextObserveWidget = SWTObservables
+ .observeText(styleSheetText, SWT.Modify);
+ IObservableValue beanStyleSheetObserveValue = PojoObservables.observeValue(bean, "styleSheet");
+ bindingContext.bindValue(styleSheetTextObserveTextObserveWidget, beanStyleSheetObserveValue, null, null);
+ //
+ IObservableValue dateTimeObserveSelectionObserveWidget = SWTObservables.observeSelection(dateTime);
+ IObservableValue beanPublicationDateObserveValue = PojoObservables.observeValue(bean, "publicationDate");
+ bindingContext.bindValue(dateTimeObserveSelectionObserveWidget, beanPublicationDateObserveValue, null, null);
+ //
+ return bindingContext;
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/Messages.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/Messages.java
new file mode 100644
index 000000000..62c3e83dd
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/Messages.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.docs.epub.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Torkild U. Resheim
+ */
+class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.docs.epub.ui.messages"; //$NON-NLS-1$
+
+ public static String AbstractMarkupResourceHandler_markupLanguageMappingFailed;
+
+ public static String AbstractMarkupResourceHandler_unexpectedError;
+
+ public static String ConvertMarkupToEPUB_cannotCompleteOperation;
+
+ public static String ConvertMarkupToEPUB_cannotConvert;
+
+ public static String ConvertMarkupToEPUB_detailsFollow;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/ConvertMarkupToEPUB.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/ConvertMarkupToEPUB.java
new file mode 100644
index 000000000..6148164f3
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/ConvertMarkupToEPUB.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.docs.epub.ui.commands;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.mylyn.internal.docs.epub.ui.ConvertFromMarkupWizard;
+import org.eclipse.mylyn.wikitext.ui.commands.AbstractMarkupResourceHandler;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+public class ConvertMarkupToEPUB extends AbstractMarkupResourceHandler {
+
+ @Override
+ protected void handleFile(final IFile file, String name)
+ throws ExecutionException {
+ final IFile newFile = file.getParent()
+ .getFile(new Path(name + ".epub")); //$NON-NLS-1$
+ if (newFile.exists()) {
+ if (!MessageDialog.openQuestion(PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getShell(),
+ Messages.ConvertMarkupToEPUB_overwrite, NLS.bind(
+ Messages.ConvertMarkupToEPUB_fileExistsOverwrite,
+ new Object[] { newFile.getFullPath() }))) {
+ return;
+ }
+ }
+
+ ConvertFromMarkupWizard wizard = new ConvertFromMarkupWizard();
+ wizard.init(file, newFile, markupLanguage);
+ // Instantiates the wizard container with the wizard and opens it
+ WizardDialog dialog = new WizardDialog(Display.getDefault().getActiveShell(), wizard);
+ dialog.create();
+ dialog.open();
+
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/Messages.java b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/Messages.java
new file mode 100644
index 000000000..4216f3129
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/Messages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Torkild U. Resheim.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Torkild U. Resheim - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.docs.epub.ui.commands;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Torkild U. Resheim
+ */
+class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.docs.epub.ui.commands.messages"; //$NON-NLS-1$
+
+ public static String ConvertMarkupToEPUB_fileExistsOverwrite;
+
+ public static String ConvertMarkupToEPUB_overwrite;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/messages.properties b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/messages.properties
new file mode 100644
index 000000000..df067f297
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/commands/messages.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2011 Torkild U. Resheim and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Torkild U. Resheim - initial API and implementation
+###############################################################################
+ConvertMarkupToEPUB_fileExistsOverwrite=File ''{0}'' exists: overwrite?
+ConvertMarkupToEPUB_overwrite=Overwrite?
diff --git a/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/messages.properties b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/messages.properties
new file mode 100644
index 000000000..c23d7efb1
--- /dev/null
+++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/messages.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2011 Torkild U. Resheim and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Torkild U. Resheim - initial API and implementation
+###############################################################################
+AbstractMarkupResourceHandler_markupLanguageMappingFailed=Cannot determine markup language for file ''{0}''
+AbstractMarkupResourceHandler_unexpectedError=Unexpected Error
+ConvertMarkupToEPUB_cannotCompleteOperation=Cannot complete operation
+ConvertMarkupToEPUB_cannotConvert=Cannot convert to EPUB:
+ConvertMarkupToEPUB_detailsFollow=Details follow:
diff --git a/pom.xml b/pom.xml
index 5b2e9544c..178583760 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,8 +73,10 @@
<modules>
<module>org.eclipse.mylyn.docs-site</module>
<module>org.eclipse.mylyn.docs.sdk-feature</module>
+
<module>org.eclipse.mylyn.htmltext-feature</module>
<module>org.eclipse.mylyn.htmltext.ui</module>
+
<module>org.eclipse.mylyn.wikitext-feature</module>
<module>org.eclipse.mylyn.wikitext.confluence.core</module>
<module>org.eclipse.mylyn.wikitext.confluence.ui</module>
@@ -99,5 +101,12 @@
<module>org.eclipse.mylyn.wikitext.creole.tests</module>
<!-- needs to be last -->
<module>org.eclipse.mylyn.wikitext-standalone</module>
+
+ <module>org.eclipse.mylyn.docs.epub.core</module>
+ <module>org.eclipse.mylyn.docs.epub.ant.core</module>
+ <module>org.eclipse.mylyn.docs.epub.ui</module>
+ <module>org.eclipse.mylyn.docs.epub.help</module>
+ <module>org.eclipse.mylyn.docs.epub.tests</module>
+ <module>org.eclipse.mylyn.docs.epub-feature</module>
</modules>
</project>

Back to the top