diff --git a/.gitignore b/.gitignore index fcb5ef8..d0444c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /org.eclipse*/bin /org.eclipse*/target +/org.eclipse*/.DS_Store \ No newline at end of file diff --git a/org.eclipse.mylyn.docs-site/site.xml b/org.eclipse.mylyn.docs-site/site.xml index baf79ad..6b835ab 100644 --- a/org.eclipse.mylyn.docs-site/site.xml +++ b/org.eclipse.mylyn.docs-site/site.xml @@ -1,36 +1,39 @@ - - - - Mylyn Docs - - - - - - - - - - - - - - - - - - - Tools. - - - - - Connectors that integrate with ALM systems. - - - - - Source code and documentation for integrators. - - - + + + + Mylyn Docs + + + + + + + + + + + + + + + + + + + + + + Tools. + + + + + Connectors that integrate with ALM systems. + + + + + Source code and documentation for integrators. + + + diff --git a/org.eclipse.mylyn.docs.epub-feature/.project b/org.eclipse.mylyn.docs.epub-feature/.project new file mode 100644 index 0000000..619ed2c --- /dev/null +++ b/org.eclipse.mylyn.docs.epub-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.mylyn.docs.epub-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + 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 0000000..854cdca --- /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/=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 0000000..52cedf7 --- /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/build.properties b/org.eclipse.mylyn.docs.epub-feature/build.properties new file mode 100644 index 0000000..b74af86 --- /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 0000000..ed4b196 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub-feature/epl-v10.html @@ -0,0 +1,328 @@ + + + + + + + + +Eclipse Public License - Version 1.0 + + + + + + +
+ +

Eclipse Public License - v 1.0 +

+ +

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, +REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT.

+ +

1. DEFINITIONS

+ +

"Contribution" means:

+ +

a) +in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and
+b) in the case of each subsequent Contributor:

+ +

i) +changes to the Program, and

+ +

ii) +additions to the Program;

+ +

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.

+ +

"Contributor" means any person or +entity that distributes the Program.

+ +

"Licensed Patents " 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.

+ +

"Program" means the Contributions +distributed in accordance with this Agreement.

+ +

"Recipient" means anyone who +receives the Program under this Agreement, including all Contributors.

+ +

2. GRANT OF RIGHTS

+ +

a) +Subject to the terms of this Agreement, each Contributor hereby grants Recipient +a non-exclusive, worldwide, royalty-free copyright license to 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.

+ +

b) +Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, 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.

+ +

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.

+ +

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.

+ +

3. REQUIREMENTS

+ +

A Contributor may choose to distribute the +Program in object code form under its own license agreement, provided that: +

+ +

a) +it complies with the terms and conditions of this Agreement; and

+ +

b) +its license agreement:

+ +

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;

+ +

ii) +effectively excludes on behalf of all Contributors all liability for damages, +including direct, indirect, special, incidental and consequential damages, such +as lost profits;

+ +

iii) +states that any provisions which differ from this Agreement are offered by that +Contributor alone and not by any other party; and

+ +

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.

+ +

When the Program is made available in source +code form:

+ +

a) +it must be made available under this Agreement; and

+ +

b) a +copy of this Agreement must be included with each copy of the Program.

+ +

Contributors may not remove or alter any +copyright notices contained within the Program.

+ +

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.

+ +

4. COMMERCIAL DISTRIBUTION

+ +

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 ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages and +costs (collectively "Losses") 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.

+ +

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.

+ +

5. NO WARRANTY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" 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.

+ +

6. DISCLAIMER OF LIABILITY

+ +

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.

+ +

7. GENERAL

+ +

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.

+ +

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.

+ +

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.

+ +

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.

+ +

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.

+ +

 

+ +
+ + + + \ 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 0000000..d5b13d1 --- /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 Docs EPUB Core +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 0000000..9d98553 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub-feature/feature.xml @@ -0,0 +1,73 @@ + + + + + %description + + + + %copyright + + + + %license + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..f19c483 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub-feature/license.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

February 1, 2011

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). 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.

+ +

Applicable Licenses

+ +

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 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ + + +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ + + +

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 ("Feature Update License") 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 "license" property of files named "feature.properties" 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.

+ +

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):

+ + + +

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.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). 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 http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

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:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. 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.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") 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.
  6. +
+ +

Cryptography

+ +

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.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + 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 0000000..f7549bc --- /dev/null +++ b/org.eclipse.mylyn.docs.epub-feature/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub + 0.8.0-SNAPSHOT + eclipse-feature + org.eclipse.mylyn.docs.epub + 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 0000000..64c5e31 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/.classpath @@ -0,0 +1,7 @@ + + + + + + + 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 0000000..502167f --- /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 0000000..89aab4e --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/.project @@ -0,0 +1,28 @@ + + + org.eclipse.mylyn.docs.epub.ant.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 0000000..1063002 --- /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/=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 0000000..d8f9d71 --- /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 0000000..2aaecd3 --- /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/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF new file mode 100644 index 0000000..19ecabd --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +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.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 0000000..8e17512 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/build-ant-jar.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..cd4fb45 --- /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 0000000..846fa76 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/plugin.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + 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 0000000..91077b5 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub.ant.core + 0.8.0-SNAPSHOT + eclipse-plugin + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.6 + + + package + + + + + + + run + + + + + + org.eclipse.tycho + tycho-source-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-pmd-plugin + + + + org.eclipse.mylyn.docs.epub + 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 0000000..7f99ef2 --- /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 0000000..bdd900f --- /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 0000000..a254d21 --- /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 0000000..c75f211 --- /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 0000000..dbb0581 --- /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 0000000..e47d8c0 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/EpubTask.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * 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 filesets = null; + + private TocType toc = null; + + private File workingFolder; + + private File epubFile; + + public EpubTask() { + super(); + try { + ops = new OPS2Publication(); + filesets = new ArrayList(); + } 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) { + 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/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 0000000..10f38a4 --- /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 0000000..9d072cd --- /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 0000000..9d60f25 --- /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 0000000..954aed1 --- /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 0000000..e852725 --- /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 0000000..5e612e2 --- /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 0000000..689dad6 --- /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 0000000..954eb85 --- /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 0000000..f3b6683 --- /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 0000000..c4a6ec0 --- /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 0000000..b9fca9d --- /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 0000000..e877af3 --- /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 0000000..0e02e8b --- /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 0000000..44fa127 --- /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 0000000..594c5bb --- /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 0000000..828bad0 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ant.core/src/org/eclipse/mylyn/docs/epub/ant/core/tasks.xml @@ -0,0 +1,4 @@ + + + + diff --git a/org.eclipse.mylyn.docs.epub.core/.classpath b/org.eclipse.mylyn.docs.epub.core/.classpath new file mode 100644 index 0000000..ea6aae6 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.core/.gitignore b/org.eclipse.mylyn.docs.epub.core/.gitignore new file mode 100644 index 0000000..934e0e0 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/.gitignore @@ -0,0 +1,2 @@ +/bin +/target diff --git a/org.eclipse.mylyn.docs.epub.core/.project b/org.eclipse.mylyn.docs.epub.core/.project new file mode 100644 index 0000000..8a3daae --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/.project @@ -0,0 +1,28 @@ + + + org.eclipse.mylyn.docs.epub.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 0000000..d12e78f --- /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/=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 0000000..2d2366b --- /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 0000000..b367ad2 --- /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/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF new file mode 100644 index 0000000..91d7bca --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/META-INF/MANIFEST.MF @@ -0,0 +1,73 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: EPUB Core +Bundle-SymbolicName: org.eclipse.mylyn.docs.epub.core;singleton:=true +Bundle-Version: 0.8.0.qualifier +Bundle-Vendor: Torkild U. Resheim +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.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/build.ant b/org.eclipse.mylyn.docs.epub.core/build.ant new file mode 100644 index 0000000..6d974a1 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/build.ant @@ -0,0 +1,34 @@ + + + + + + + + + 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 0000000..f76ae9b --- /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,\ + plugin.properties +src.includes = model/,\ + build.ant + 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 0000000..9d96209 --- /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 0000000..711b66d --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/dc.ecore @@ -0,0 +1,153 @@ + + + + +
+ + + + +
+ + + +
+ + + + +
+
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + +
+
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + +
+ + + + +
+ + + + +
+
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+
+ + + + + + +
+ + + + 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 0000000..20d61e6 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/ncx.ecore @@ -0,0 +1,695 @@ + + + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+
+ + + + + +
+
+ + + + +
+
+ + + + + + + + + +
+
+ + + + + + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+ + + + + + +
+
+ + + + +
+
+
+
+ + + + +
+
+
+
+ + + + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + + + +
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + +
+ + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+
+ + + + +
+
+ + + + + + + + + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + + + + + + + +
+
+ + + + +
+
+ + + 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 0000000..4a28a21 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/ncx.genmodel @@ -0,0 +1,168 @@ + + + ncx.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..11ee500 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/ocf.ecore @@ -0,0 +1,45 @@ + + + + +
+
+ + + +
+
+ + + + + + + +
+
+ + + + + + +
+ + + + +
+ + + + + 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 0000000..90d7704 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/ocf.genmodel @@ -0,0 +1,21 @@ + + + ocf.ecore + + + + + + + + + + + + + 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 0000000..5c23170 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/opf.ecore @@ -0,0 +1,498 @@ + + + + +
+
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + + + +
+
+ + + + + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..f9d771e --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/opf.genmodel @@ -0,0 +1,371 @@ + + + opf.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..55f410f --- /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 0000000..5dd8e2d --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/model/relacode.ant @@ -0,0 +1,28 @@ + + + + + + + + + + + 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 0000000..39d14ef --- /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.properties b/org.eclipse.mylyn.docs.epub.core/plugin.properties new file mode 100644 index 0000000..94e57af --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/plugin.properties @@ -0,0 +1,12 @@ +############################################################################### +# 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 +############################################################################### +pluginName = ePUB Model +providerName = www.example.org 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 0000000..eb9ea4f --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/plugin.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + 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 0000000..e1d84b3 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub.core + 0.8.0-SNAPSHOT + eclipse-plugin + + + + org.eclipse.tycho + tycho-source-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-pmd-plugin + + + + org.eclipse.mylyn.docs.epub + 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 0000000..f49f95c --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/EPUB.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * 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.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. One or more publications can be added and will be a + * part of the distribution when packed. See the OPS + * specification for definitions of words and terms. + * + * @author Torkild U. Resheim + * @see http://idpf.org/epub/20/spec/OPS_2.0.1_draft.html + * @see http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm + */ +public class EPUB { + + /** 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"; + + private Container ocfContainer; + + /** + * Creates a new empty 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("2.0"); + registerOCFResourceFactory(); + } + + /** + * Returns the container instance of the EPUB. + * + * @return the container instance + */ + public Container getContainer() { + return ocfContainer; + } + + /** + * Adds a new OPS publication to the EPUB. + * + * @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 to the EPUB + * + * @param file + * the publication to add + * @param type + * the MIME type of the publication + */ + 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 OPS publications contained within the EPUB. + * + * @return a list of all OPS publications + */ + public List getOPSPublications() { + ArrayList publications = new ArrayList(); + EList 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. + * + * @param epubFile + * the target EPUB file + * @param workingFolder + * the working folder + * @throws Exception + */ + 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 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 Open Container Format formatted list of the contents of + * this EPUB. + * + * @param workingFolder + * the folder where the EPUB was unpacked + * @throws IOException + * @see {@link #unpack(File)} + * @see {@link #unpack(File, File)} + */ + private 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 loadOptions = xmiResource.getDefaultLoadOptions(); + Map 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); + 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 + */ + 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 + */ + public void unpack(File epubFile, File destination) throws Exception { + EPUBFileUtil.unzip(epubFile, destination); + readOCF(destination); + EList 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 + * container.xml in that folder. + * + * @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); + } + } + + /** + * Delete the folder recursively. + * + * @param folder + * the folder to delete + * @return + */ + 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 0000000..c7c7164 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPS2Publication.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * 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.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. + *

+ * Please note that this API is provisional and should not yet be used to + * build applications. + *

+ * + * @author Torkild U. Resheim + */ +public class OPS2Publication extends OPSPublication { + + /** Default name for the table of contents */ + private static final String TOCFILE_NAME = "toc.ncx"; + + /** MIME type for NCX documents */ + private static final String MIMETYPE_NCX = "application/x-dtbncx+xml"; + + 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 spineItems = getSpine().getSpineItems(); + EList 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()); + FileReader fr = new FileReader(file); + playOrder = TOCGenerator.parse(new InputSource(fr), referencedItem.getHref(), ncxTOC, playOrder); + } + } + } + + /** + * This method will only validate items that are in the spine, or in reading + * order. + */ + @Override + protected List validateContents() throws Exception { + EList spineItems = getSpine().getSpineItems(); + EList manifestItems = opfPackage.getManifest().getItems(); + ArrayList messages = new ArrayList(); + 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; + } + + /** Identifier of the table of contents file */ + protected static final String TABLE_OF_CONTENTS_ID = "ncx"; + + protected static final String NCX_FILE_SUFFIX = "ncx"; + + /** + * 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 loadOptions = xmiResource.getDefaultLoadOptions(); + Map 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); + 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); + + } + + /** + * 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 options = new HashMap(); + // 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); + } + } + + @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); + } + + @Override + public Object getTableOfContents() { + return ncxTOC; + } + +} 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 0000000..fef7717 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/OPSPublication.java @@ -0,0 +1,1157 @@ +/******************************************************************************* + * 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 OPS publication. This includes the OPF + * package document and OPS content documents. It maintains a data + * structure representing the entire publication and API for building it. + *

+ * Please note that this API is provisional and should not yet be used to build + * applications. + *

+ * + * @author Torkild U. Resheim + */ +public abstract class OPSPublication { + // Rules of engagement: + // * Keep all data in the model, use "transient" for temporary variables + // * Do not create 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(); + } + + public List 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. + *
    + *
  • The creation date.
  • + *
  • Eclipse committers and contributors as contributor redactor + * role.
  • + *
  • A unique identifier if none has been specified.
  • + *
  • A empty description if none has been specified.
  • + *
  • Language "English" if none has been specified.
  • + *
  • A dummy title if none has been specified.
  • + *
  • The publication format if none has been specified.
  • + *
+ */ + private void addCompulsoryData() { + addDate(null, new java.util.Date(System.currentTimeMillis()), CREATION_DATE_ID); + addContributor(null, null, "Eclipse Committers and Contributors", Role.REDACTOR, null); + if (getIdentifier() == null) { + addIdentifier(UUID_SCHEME, "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 null + * @param name + * name of the creator + * @param role + * the role or null + * @param fileAs + * name to file the creator under or null + * @param lang + * the language code or null + * @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 "coverage" for the publication. + * + * @param id + * an identifier or null + * @param lang + * the language code or null + * @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 null + * @param lang + * the language code or null + * @param name + * name of the creator + * @param role + * the role or null + * @param fileAs + * name to file the creator under or null + * @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 "Date and Time Formats" at + * http://www.w3.org/TR/NOTE-datetime 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 null + * @param lang + * the language code or null + * @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 null + * @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 + * addItem(null, null, file, null, null, true, false);. + * + * @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. + * + *

+ * The spine defines the reading order, so the order items are added + * and whether or not spine is true 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 + * noToc attribute has been set to true. + *

+ * + * @param file + * the file to add + * @param dest + * the destination sub-folder or null + * @param id + * identifier or null + * @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 null + * @param lang + * the language code or null + * @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 null + * @param lang + * the language code or null + * @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 relation specification to the publication. + * + * @param id + * identifier or null + * @param lang + * the language code or null + * @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 rights specification to the publication. + * + * @param id + * identifier or null + * @param lang + * the language code or null + * @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 source specification to the publication. + * + * @param id + * identifier or null + * @param lang + * the language code or null + * @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 subject specification to the publication. + * + * @param id + * identifier or null + * @param lang + * the language code or null + * @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 title specification to the publication. + * + * @param id + * identifier or null + * @param lang + * the language code or null + * @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 type specification to the publication. + * + * @param id + * identifier or null + * @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 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 spine. + * + * @throws Exception + */ + protected abstract void generateTableOfContents() throws Exception; + + /** + * Returns the main identifier of the publication or null if it + * could not be determined. + * + * @return the main identifier or null + */ + protected Identifier getIdentifier() { + EList 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 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 getItemsByMIMEType(String mimetype) { + ArrayList stylesheets = new ArrayList(); + EList 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 null + */ + 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 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 manifestItems = opfPackage.getManifest().getItems(); + // Compose a list of file references + HashMap> references = new HashMap>(); + 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 images = references.get(root); + for (File image : images) { + File relativePath = new File(EPUBFileUtil.getRelativePath(root, image)); + addItem(null, null, image, 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 + */ + private 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 loadOptions = xmiResource.getDefaultLoadOptions(); + Map 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); + 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 Dublin Core 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 Dublin Core 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 true + * + * @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 false. + * + * @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 validateContents() throws Exception; + + /** + * Validates the data model contents. + * + * @return a list of EMF diagnostics + */ + public List validateMetadata() { + EValidator.Registry.INSTANCE.put(OPFPackage.eINSTANCE, new EcoreValidator()); + BasicDiagnostic diagnostics = new BasicDiagnostic(); + for (EObject eo : opfPackage.eContents()) { + Map context = new HashMap(); + 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("\n"); + fw.append("\n"); + fw.append("\n"); + fw.append(" \n"); + fw.append(" " + coverImage.getTitle() + "\n"); + fw.append(" \n"); + fw.append(" \n"); + fw.append(" \n"); + fw.append("
\n"); + fw.append(" \""\n"); + fw.append("
\n"); + fw.append(" \n"); + fw.append("\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 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 content.opf 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 0000000..fd97d67 --- /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 0000000..ef8e7f9 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/docs/epub/core/wikitext/MarkupToOPS.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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 stylesheets = ops.getItemsByMIMEType(OPSPublication.MIMETYPE_CSS); + for (Item item : stylesheets) { + File file = new File(item.getFile()); + Stylesheet css = new Stylesheet(file); + builder.addCssStylesheet(css); + } + + 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 0000000..c6927ae --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/AbstractXHTMLScanner.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * 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; + + 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 true 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 0000000..16c89fd --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.core/src/org/eclipse/mylyn/internal/docs/epub/core/EPUBFileUtil.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * 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 source to the new destination 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 null + */ + public static String getMimeType(File file) { + String name = file.getName().toLowerCase(); + // These are not (correctly) detected by URLConnection + if (name.endsWith("xhtml")) { + return "application/xhtml+xml"; + } + if (name.endsWith(".otf")) { + return "font/opentype"; + } + if (name.endsWith(".svg")) { + return "image/svg+xml"; + } + if (name.endsWith(".css")) { + return "text/css"; + } + // Use URLConnection or content type detection + String mimeType = URLConnection.guessContentTypeFromName(file.getName()); + if (mimeType == null) { + try { + InputStream is = new BufferedInputStream(new FileInputStream(file)); + mimeType = URLConnection.guessContentTypeFromStream(is); + is.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return mimeType; + } + + /** + * 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 segments) { + if (root.equals(file)) { + return; + } + segments.add(0, file.getName()); + getPathSegments(root, file.getParentFile(), segments); + } + + /** + * Determines the root relative path of file in a platform + * independent manner. The returned string is a path starting from but + * excluding root using the '/' character as a directory separator. + * If the file argument is a folder a trailing directory separator is + * added. if the root 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 segments = new ArrayList(); + 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 epubfile to the destination 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 + * mimetype that is placed at the beginning. The contents of this + * file must be the ASCII-encoded string application/epub+zip. 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 0000000..b04e4ec --- /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 0000000..5ef69ff --- /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 0000000..b2e10b3 --- /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 preferred + * 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 messages; + + public StringBuilder getContents() { + return contents; + } + + public ArrayList getMessages() { + return messages; + } + + public static List 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(); + 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(""); + buffer.setLength(0); + } + recording = false; + } + + /** + * Returns true 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 0000000..8ef9514 --- /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 img tag or a link. + * + * @author Torkild U. Resheim + */ +public class ReferenceScanner extends AbstractXHTMLScanner { + + public static List 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 files; + + public ReferenceScanner(Item item) { + super(); + files = new ArrayList(); + currentItem = item; + } + + /** + * Case-insensitive method for obtaining an attribute. + * + * @param attributes + * SAX attributes + * @param name + * the attribute name + * @return the attribute value or null + */ + 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 0000000..10dc7a2 --- /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.examples/.project b/org.eclipse.mylyn.docs.epub.examples/.project new file mode 100644 index 0000000..dff4754 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/.project @@ -0,0 +1,11 @@ + + + org.eclipse.mylyn.docs.epub.examples + + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..00782c7 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Fri Oct 07 19:59:34 CEST 2011 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 0000000..8e535d2 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,3 @@ +#Sat Oct 08 16:01:31 CEST 2011 +eclipse.preferences.version=1 +line.separator=\n diff --git a/org.eclipse.mylyn.docs.epub.examples/book/build-book.xml b/org.eclipse.mylyn.docs.epub.examples/book/build-book.xml new file mode 100644 index 0000000..bbd6c7c --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/book/build-book.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 70ce7c20-8f9e-11e0-91e4-0800200c9a66 + Building EPUBs + Computing, Eclipse, Mylyn, EPUB + Eclipse.Org + + Copyright (c) 2011, Torkild Ulvøy Resheim. Licensed under the Eclipse Public License version 1.0 + Technical article. + + + Cover page + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.examples/book/copyright.textile b/org.eclipse.mylyn.docs.epub.examples/book/copyright.textile new file mode 100644 index 0000000..9bff3f2 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/book/copyright.textile @@ -0,0 +1,9 @@ +h1. Copyrights + +p. The EPUB 2.0.1 Specification is Copyright © 2007 by International Digital Publishing Forum(tm). + +p. The Dublin Core Specification is Copyright © 1995-2011 DCMI. All Rights Reserved. Licensed under a Creative Commons Attribution 3.0 Unported License. + +p. The DejaVu Sans Mono fonts used in this publication are Copyright © 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. + +p. This book is Copyright © 2011 by Torkild U. Resheim diff --git a/org.eclipse.mylyn.docs.epub.examples/book/cover.jpg b/org.eclipse.mylyn.docs.epub.examples/book/cover.jpg new file mode 100644 index 0000000..5554d7f Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/cover.jpg differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Bold.otf b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Bold.otf new file mode 100644 index 0000000..8d80d91 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Bold.otf differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-BoldOblique.otf b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-BoldOblique.otf new file mode 100644 index 0000000..d8d1a27 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-BoldOblique.otf differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Oblique.otf b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Oblique.otf new file mode 100644 index 0000000..14ce61e Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono-Oblique.otf differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.license b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.license new file mode 100644 index 0000000..2ecb8cf --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.license @@ -0,0 +1,97 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +——————————————— + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation files (the “Font Software”), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words “Bitstream” or the word +“Vera”. + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the “Bitstream +Vera” names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +——————————————— + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license (“Fonts”) and +associated documentation files (the “Font Software”), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words “Tavmjong Bah” or the word “Arev”. + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +“Tavmjong Bah Arev” names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.otf b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.otf new file mode 100644 index 0000000..8af6866 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/fonts/DejaVuSansMono.otf differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/source/cover.psd b/org.eclipse.mylyn.docs.epub.examples/book/source/cover.psd new file mode 100644 index 0000000..ff2928e Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/source/cover.psd differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/source/palette.cs b/org.eclipse.mylyn.docs.epub.examples/book/source/palette.cs new file mode 100644 index 0000000..409f130 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.examples/book/source/palette.cs differ diff --git a/org.eclipse.mylyn.docs.epub.examples/book/style.css b/org.eclipse.mylyn.docs.epub.examples/book/style.css new file mode 100644 index 0000000..3c25994 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/book/style.css @@ -0,0 +1,204 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ + +@page { + margin-left: 0px; + margin-right: 0px; +} + +p { + text-align: justify; + line-height: 1.5em; +} + +/* + * PREFORMATTED TEXT + */ +code strong em, code em strong, pre strong em, pre em strong, tt strong em, tt em strong { + font-weight: bold; + font-style: italic; + font-family: "DejaVu Sans Mono Bold Oblique", monospace; + color: #3a587a; + font-size: 0.8em; +} + +code em, em code, pre em, em pre, tt em, em tt { + font-style: italic; + font-family: "DejaVu Sans Mono Oblique", monospace; + color: #3a587a; + font-size: 0.8em; +} + +code strong, strong code, pre strong, strong pre, tt strong, strong tt { + font-weight: bold; + font-family: "DejaVu Sans Mono Bold", monospace; + color: #3a587a; + font-size: 0.8em; +} + +code, pre, tt { + font-family: "DejaVu Sans Mono", monospace; + color: #3a587a; + font-size: 0.8em; +} + +/* + * TABLES + */ +table, td, th { + border-color: #d5d399; + border-style: solid; +} + +table { + width: 100%; + border-width: 0 0 1px 1px; + border-spacing: 0; + border-collapse: collapse; +} + +td, th { + margin: 0; + padding: 4px; + border-width: 1px 1px 0 0; + font-size: 0.9em; +} + +th { + background-color: #e4e3bd; + font-family: "Helvetica", sans-serif; + font-weight: bold; +} + +td { + background-color: #f3f2e1; + font-family: "Helvetica", sans-serif; +} + +.logo { + display: block; margin-left: auto; margin-right: auto; +} + +.title { + color: #000000; + font-size: 2em; + text-align: center; + border-bottom: 1px black solid; + font-family: "Palatino", serif; + font-weight: bold; +} + +.author, .copyright { + font-size: 1em; color: #000000; + font-family: "Palatino", serif; + font-weight: bold; + text-align: center; +} + +/* + * HEADERS + */ +h1, h2, h3, h4, h5, h6 { + text-align: left; + page-break-inside: avoid; + page-break-after: avoid; + font-weight: bold; + display: block; +} + +h1 { + font-size: 1.7em; + text-align: center; + border-top: 1px #000000 solid; + border-bottom: 1px #000000 solid; + padding-top: 0.5em; + padding-bottom: 0.5em; + margin-bottom: 1.5em; + font-family: "Palatino", serif; + font-weight: bold; +} + +h2 { + font-size: 1.5em; + font-family: "Palatino", serif; + font-weight: bold; +} + +h3 { + font-size: 1.3em; + font-family: "Palatino", serif; + font-weight: bold; +} + +h4 { + font-size: 1.2em; + font-style: italic; + font-family: "Palatino", serif; + font-weight: bold; +} + +h5 { + font-size: 1em; + font-style: italic; + font-family: "Palatino", serif; +} + +h6 { + font-size: 1em; + font-style: italic; + font-family: "Palatino", serif; +} + +hr { + width: 80%; + backgrund-color: #aaaaaa; + height: 1px; +} + +/* + * fonts (keep at bottom); using DejaVu for its rich set of glyphs (and being + * free for use) + */ +@font-face { + font-family: "DejaVu Sans Mono"; + font-weight: normal; + font-style: normal; + src: url(DejaVuSansMono.otf); +} + +@font-face { + font-family: "DejaVu Sans Mono Bold"; + font-weight: bold; + font-style: normal; + src: url(DejaVuSansMono-Bold.otf); +} + +@font-face { + font-family: "DejaVu Sans Mono Oblique"; + font-weight: normal; + font-style: italic; + src: url(DejaVuSansMono-Oblique.otf); +} + +@font-face { + font-family: "DejaVu Sans Mono Bold Oblique"; + font-weight: bold; + font-style: italic; + src: url(DejaVuSansMono-BoldOblique.otf); +} + +body { + font-size: 1em; + margin: 0; + padding: 0; + text-align: left; + font-family: "Palatino" +} \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.examples/book/title-page.html b/org.eclipse.mylyn.docs.epub.examples/book/title-page.html new file mode 100644 index 0000000..5b16d0f --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/book/title-page.html @@ -0,0 +1,20 @@ + + + + + +Building EPUBs + + + +

+ Building EPUBs +

+

+ by Torkild U. Resheim +

+ + + \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.examples/simple/my_chapter.xhtml b/org.eclipse.mylyn.docs.epub.examples/simple/my_chapter.xhtml new file mode 100644 index 0000000..9a74fed --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/simple/my_chapter.xhtml @@ -0,0 +1,39 @@ + + + + +My Chapter + + + +

Lorem Ipsum

+

Lorem ipsum dolor sit amet feugiat in gravida felis. Et pede erat + curabitur faucibus nec condimentum turpis risus ipsum rutrum lorem mi augue + donec. Consectetuer quam cursus feugiat amet eget. Lacus id pulvinar nec eu + phasellus. Eu ut nullam. Inceptos lorem malesuada sed vitae augue erat in eu. + Ac mauris vel. In et elit et sit donec. Convallis at ac qui fermentum purus. + Sodales vulputate eu. Sed massa amet dui ut pharetra vel nec in. Magna donec + ut eget duis natoque. Amet suscipit et. Consequat facilisi inceptos. Nunc + nulla orci. Donec conubia est amet venenatis risus. Quisque mauris porta. At + est ut pede est accumsan mauris eu mauris dui augue cras. Augue volutpat sit + nibh malesuada mus. Integer odio suscipit elit metus blandit adipiscing lorem + pede. Venenatis magna nulla. Nec at in. Praesent rhoncus malesuada. Felis + gravida donec morbi aliquam do. Suspendisse risus ut condimentum fusce id + enim facilisi sem.

+

Condimentum sit rhoncus sed integer semper sollicitudin id dictum. + Viverra tincidunt a. Nec leo est dui aenean lacus suspendisse eros euismod + rutrum eget ea. Aenean libero quisque. Wisi nonummy sit.

+

Amet augue nec sapien luctus turpis. Enim donec mollis suspendisse non + maecenas. Aptent nullam sed arcu sociosqu pede a vehicula faucibus massa + laoreet pellentesque wisi morbi expedita laoreet praesent hendrerit. + Hymenaeos elit sed. Luctus venenatis odio aenean orci vestibulum vehicula + dolorem ac ipsum neque urna. Elit deleniti vulputate. Consequat nibh sem + neque nec duis aptent vitae montes. Eget nisl pellentesque eu felis quis. Sed + enim magna. Sed urna tempus ultricies id sociis mollis ullamcorper ut + elementum maecenas eget. In lectus accumsan eget amet voluptate. Eu sed + justo. Et pellentesque lectus aliquam id laoreet. Cupidatat placerat urna + malesuada massa posuere. Viverra sed egestas. Habitasse tempus sit. Ipsum + vestibulum dui. Potenti tincidunt ut nullam dolor lorem. Suspendisse at elit. + Tortor eget vulputate.

+ + \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.examples/simple/simple.xml b/org.eclipse.mylyn.docs.epub.examples/simple/simple.xml new file mode 100644 index 0000000..c521b17 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.examples/simple/simple.xml @@ -0,0 +1,18 @@ + + + + + + + + My Book + My Book's subject + + + + + \ 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 0000000..ad32c83 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.help/.gitignore b/org.eclipse.mylyn.docs.epub.help/.gitignore new file mode 100644 index 0000000..4c93aec --- /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 0000000..13962a4 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/.project @@ -0,0 +1,28 @@ + + + org.eclipse.mylyn.docs.epub.help + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 0000000..0068c6f --- /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/=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 0000000..b8bf216 --- /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 0000000..6d8c9a6 --- /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/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.help/META-INF/MANIFEST.MF new file mode 100644 index 0000000..4de12cc --- /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 0000000..9f3242f --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/build-docs.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000..0a74da0 --- /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 0000000..d125677 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.help/docs/Illustrations.002.jpg 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 0000000..3af6af7 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/docs/epub-ant-task.textile @@ -0,0 +1,361 @@ +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.. + + + + +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.. + + + +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.. + + + +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. + +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.. + + + +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.. + + +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.. + + + +h3. Contributors and Creators + +p. Examples of a contributor and creator include a person, an organization, or a service. + +bc.. + + + + + + +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.. + + + +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. + +p. Type includes terms describing general categories, functions, genres, or aggregation levels for content. Recommended best practice is to select a value from a controlled vocabulary (for example, the DCMI Type Vocabulary [DCT1]). To describe the physical or digital manifestation of the resource, use the FORMAT element. + +bc.. + + + +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.. + + + +h3. Source + +p. The publication may be derived from another resource in whole or part. Recommended best practice is to identify the referenced resource 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.. + + + +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.. + + + +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). Recommended best practice is to select a value from a controlled vocabulary (for example, the Thesaurus of Geographic Names [TGN]) and to use, where appropriate, named places or time periods in preference to numeric identifiers such as sets of coordinates or date ranges. + +bc.. + + + + +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.. + + + +h3. Meta + +p. This type is used to express arbitrary metadata beyond the data described by the Dublin Core specification. + +bc.. + + + +h3. Cover + +bc.. + + + +p. Adds a cover page using the supplied image file. + +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.. + + + +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 __<mimetype>-<filename>__. 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.. + + + + + + + +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.. + + +p. +* **id** - optional unique identifier. +* **href** - the file that is referenced. +* **type** - the role. +* **title** - title of the reference. + +bc.. + + + + + +p. The following types are allowed: + +|_. Type |_. Description | +|cover|The book cover(s), jacket information, etc.| +|title-page|Page with possibly title, author, publisher, and other metadata| +|toc|table of contents| +|index|Back-of-book style index| +|glossary|An alphabetical list of terms peculiar to the publication with definitions or explanations| +|acknowledgements|Author’s statement acknowledging his use of the 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|To address or inscribe (a book, artistic performance, etc) 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, esp a jotting for future reference| +|preface|A statement written as an introduction to a literary or other work, typically explaining its scope, intention, method, etc; foreword.| +|text|First "real" page of content (e.g. "Chapter 1").| + +h3. Table of contents + +bc.. + + + +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. \ No newline at end of file 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 0000000..364ffa7 --- /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. \ No newline at end of file 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 0000000..6f6c69a --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/docs/examples.textile @@ -0,0 +1,89 @@ +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. + +bc.. + + + 70ce7c20-8f9e-11e0-91e4-0800200c9a66 + Building EPUBs + Computing, Eclipse, Mylyn, EPUB + Eclipse.Org + + Copyright (c) 2011, Torkild Ulvøy Resheim. Licensed under the Eclipse Public License version 1.0 + Technical article. + + + Cover page + + + + + + + + + + + + + + + + + + + + + + +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.. + + +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.. + + +p. Next we add a XHTML file (named __cover.html__) to the publication. This will be used by some reading systems. + +bc.. + + + + + Cover Page + + + +
+ Building EPUBs +
+ + + +p. Then some more Ant code: + +bc.. + + + + +p. This method will produce a cover page that will work with all the tested reading systems; including Calibre, iBooks, Nook for Mac, Adobe Digital Editions 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. \ No newline at end of file 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 0000000..a88e83a --- /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. + + + + + My Book + My Book's subject + + + + + +p. In this example only some of the required fields 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. + +!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 0000000..bdd8493 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.help/docs/generate-epub.png 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 0000000..2fc4323 --- /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**. \ No newline at end of file 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 0000000..8ab0f99 --- /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.. + + My Book + My Book's subject + + + +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 0000000..8c98525 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.help/docs/nook-cover.png differ 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 0000000..44fef40 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.help/docs/runtime-jre.png 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 0000000..733d993 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.help/docs/source/Illustrations.key 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 0000000..45748bc --- /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 0000000..72a86d5 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/plugin.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + 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 0000000..0711a7d --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub.help + 0.8.0-SNAPSHOT + eclipse-plugin + + + ${project.artifactId}.AllTests + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.6 + + + generate-sources + + + + + + + + run + + + + + + + org.eclipse.mylyn.docs + org.eclipse.mylyn.wikitext.core + 1.6.0-SNAPSHOT + + + org.eclipse.mylyn.docs + org.eclipse.mylyn.wikitext.textile.core + 1.6.0-SNAPSHOT + + + + + org.eclipse.tycho + tycho-source-plugin + + + org.eclipse.tycho + target-platform-configuration + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-pmd-plugin + + + + + org.eclipse.mylyn.docs.epub + 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 0000000..c98429c --- /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 0000000..2ed5043 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.help/toc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.tests/.classpath b/org.eclipse.mylyn.docs.epub.tests/.classpath new file mode 100644 index 0000000..bfbbc31 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.tests/.gitignore b/org.eclipse.mylyn.docs.epub.tests/.gitignore new file mode 100644 index 0000000..3ade8e2 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/.gitignore @@ -0,0 +1,3 @@ +/test +/org.eclipse*/bin +/org.eclipse*/target diff --git a/org.eclipse.mylyn.docs.epub.tests/.project b/org.eclipse.mylyn.docs.epub.tests/.project new file mode 100644 index 0000000..18f2119 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/.project @@ -0,0 +1,28 @@ + + + org.eclipse.mylyn.docs.epub.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 0000000..9d8c255 --- /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/=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 0000000..b32a054 --- /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 0000000..21a6000 --- /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/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF new file mode 100644 index 0000000..d4f9a0c --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +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: ., + lib/saxon.jar, + lib/jing.jar, + lib/epubcheck-1.2.jar 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 0000000..a79ad13 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/ant-test.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mylyn Docs Test EPUB + + urn:uuid:15bcb770-882d-11e0-9d78-0800200c9a66 + Testing + + Eclipse.org + + + + + \ 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 0000000..d7b8480 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + lib/saxon.jar,\ + lib/epubcheck-1.2.jar,\ + lib/jing.jar diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/COPYING.txt b/org.eclipse.mylyn.docs.epub.tests/lib/COPYING.txt new file mode 100644 index 0000000..bdfe74d --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/lib/COPYING.txt @@ -0,0 +1,19 @@ +Copyright (c) 2007 Adobe Systems Incorporated + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/README.txt b/org.eclipse.mylyn.docs.epub.tests/lib/README.txt new file mode 100644 index 0000000..6952865 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/lib/README.txt @@ -0,0 +1,61 @@ +This folder contains the distribution of epubcheck project. + +EpubCheck is a tool to validate IDPF Epub files. It can detect many +types of errors in Epub. OCF container structure, OPF and OPS mark-up, +and internal reference consistency are checked. EpubCheck can be run +as a standalone command-line tool, installed as a web application or +used as a library. + +Epubcheck project home: http://code.google.com/p/epubcheck/ + +BUILDING + +To build epubcheck from the sources you need Java Development Kit (JDK) 1.5 or above +and Apache ant (http://ant.apache.org/) 1.6 or above installed + +Run + +ant -f build.xml + +RUNNING + +To run the tool you need Java Runtime (1.5 or above). Any OS should do. Run +it from the command line: + +java -jar epubcheck-x.x.x.jar file.epub + +All detected errors are simply printed to stderr. + +USING AS A LIBRARY + +You can also use EpubCheck as a library in your Java application. EpubCheck +public interfaces can be found in com.adobe.epubcheck.api package. EpubCheck +class can be used to instantiate a validation engine. Use one of its +constructors and then call validate() method. Report is an interface that +you can implement to get a list of the errors and warnings reported by the +validation engine (instead of the error list being printed out). + +LICENSING + +See COPYING.txt + +AUTHORS + +Peter Sorotokin +Garth Conboy +Markus Gylling +Piotr Kula + +Most of the EpubCheck functionality comes from the schema validation tool Jing +and schemas that were developed by IDPF and DAISY. EpubCheck development was +largely done at Adobe Systems. + + + + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck-1.2.jar b/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck-1.2.jar new file mode 100644 index 0000000..1f6380d Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck-1.2.jar differ diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck_license.txt b/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck_license.txt new file mode 100644 index 0000000..bdfe74d --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/lib/epubcheck_license.txt @@ -0,0 +1,19 @@ +Copyright (c) 2007 Adobe Systems Incorporated + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/jing.jar b/org.eclipse.mylyn.docs.epub.tests/lib/jing.jar new file mode 100644 index 0000000..fe01514 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.tests/lib/jing.jar differ diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/jing_license.txt b/org.eclipse.mylyn.docs.epub.tests/lib/jing_license.txt new file mode 100644 index 0000000..57d36a3 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/lib/jing_license.txt @@ -0,0 +1,12 @@ +Jing Copying Conditions + +Copyright (c) 2001-2003 Thai Open Source Software Center Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the Thai Open Source Software Center Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/org.eclipse.mylyn.docs.epub.tests/lib/saxon.jar b/org.eclipse.mylyn.docs.epub.tests/lib/saxon.jar new file mode 100644 index 0000000..95c6815 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.tests/lib/saxon.jar differ 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 0000000..11ca66b --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub.tests + 0.8.0-SNAPSHOT + eclipse-test-plugin + + + indigo + http://download.eclipse.org/releases/${platform-version-name} + ${project.artifactId}.AllTests + + + + + indigo + Eclipse Indigo p2 Repository + p2 + ${eclipse-site} + + + + + + + org.eclipse.tycho + tycho-surefire-plugin + ${tycho-version} + + false + ${project.artifactId} + ${test.suite} + + + + org.eclipse.tycho + tycho-source-plugin + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + p2 + + + + + org.eclipse.mylyn.docs.epub + 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 0000000..89fb97b --- /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 0000000..064acbf --- /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. + *
    + *
  • Wrong number of attributes due to EMF default value handling.
  • + *
  • Unexpected attribute names and or values.
  • + *
  • Wrong element value.
  • + *
+ * + * @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. + *
    + *
  • There should be a table of contents
  • + *
  • The metadata, manifest, spine and guide elements should exist.
  • + *
+ * + * @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. + *
    + *
  • Wrong number of attributes due to EMF default value handling.
  • + *
  • Unexpected attribute names and or values
  • + *
+ * + * @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/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 0000000..6e26cf8 --- /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 epub 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 0000000..d1a7485 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/AbstractTest.java @@ -0,0 +1,87 @@ +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; + } + + 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 0000000..a88a702 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestEPUB.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * 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 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()}. + *

+ * It must be possible to obtain the publication list which must be empty. + *

+ */ + @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)} + * . + *
    + *
  • Publication MIME-type shall be correct
  • + *
  • Rootfile path shall be correct
  • + *
  • Rootfile object shall be correct.
  • + *
+ * + * @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 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)}. + *
    + *
  • Shall throw exception when unknown publication type is added.
  • + *
+ * + * @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 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)} + * . + *
    + *
  • Container shall hold more than one OPS publication
  • + *
  • OPS structures shall follow naming conventions.
  • + *
  • OPS MIME-type shall be correct
  • + *
  • Rootfile object shall be correct.
  • + *
+ * + * @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 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()}. + *

+ * One OPS-publication and one SVG drawing are added. Only the + * OPS-publication shall be returned. + *

+ * + * @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)}. + *
    + *
  • Temporary folder shall not exist when job is done.
  • + *
+ * + * @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)} + * . + *
    + *
  • Work folder shall exist when job is done.
  • + *
  • Work folder shall contain EPUB artifacts.
  • + *
  • Exception shall be thrown if working folder already exist.
  • + *
+ * + * @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)} + * . + *
    + *
  • Exception shall be thrown if working folder already exist.
  • + *
+ * + * @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)} . + *
    + *
  • Exception shall be thrown if the EPUB is empty.
  • + *
+ * + * @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)}. + *
    + *
  • Unpacked EPUB shall have the same contents as the packed one.
  • + *
+ * + * @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()); + } + +} 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 0000000..46e9f45 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPS2Publication.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.tests.api; + +import java.io.File; + +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()} + * . + *
    + *
  • Table of contents shall be generated from content per default.
  • + *
  • Table of contents shall exist but be empty if not otherwise + * specified.
  • + *
+ * + * @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()} + * . + *
    + *
  • There shall be a table of contents, even if empty.
  • + *
+ * + * @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()} + * . + *
    + *
  • There shall be a warning message
  • + *
+ * + * @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()); + } + +} 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 0000000..ce995cd --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/src/org/eclipse/mylyn/docs/epub/tests/api/TestOPSPublication.java @@ -0,0 +1,738 @@ +/** + * + */ +package org.eclipse.mylyn.docs.epub.tests.api; + +import java.io.File; +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.dc.impl.DCTypeImpl; +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 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((DCTypeImpl) Coverages.get(0))); + Assert.assertEquals(null, Coverages.get(1).getId()); + Assert.assertEquals("fr_CA", Coverages.get(1).getLang()); + Assert.assertEquals("My Coverage", getText((DCTypeImpl) Coverages.get(1))); + Assert.assertEquals(null, Coverages.get(2).getId()); + Assert.assertEquals(null, Coverages.get(2).getLang()); + Assert.assertEquals("My Coverage", getText((DCTypeImpl) 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 dates = oebps.getOpfPackage().getMetadata().getDates(); + assertEquals("1969", getText((DCTypeImpl) dates.get(0))); + assertEquals("1969-03", getText((DCTypeImpl) dates.get(1))); + assertEquals("1969-03-14", getText((DCTypeImpl) 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 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((DCTypeImpl) Descriptions.get(0))); + Assert.assertEquals(null, Descriptions.get(1).getId()); + Assert.assertEquals("fr_CA", Descriptions.get(1).getLang()); + Assert.assertEquals("My Description", getText((DCTypeImpl) Descriptions.get(1))); + Assert.assertEquals(null, Descriptions.get(2).getId()); + Assert.assertEquals(null, Descriptions.get(2).getLang()); + Assert.assertEquals("My Description", getText((DCTypeImpl) 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 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((DCTypeImpl) Descriptions.get(0))); + Assert.assertEquals(null, Descriptions.get(1).getId()); + Assert.assertEquals("fr_CA", Descriptions.get(1).getLang()); + Assert.assertEquals("My Description", getText((DCTypeImpl) Descriptions.get(1))); + Assert.assertEquals(null, Descriptions.get(2).getId()); + Assert.assertEquals(null, Descriptions.get(2).getLang()); + Assert.assertEquals("My Description", getText((DCTypeImpl) 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 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((DCTypeImpl) 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 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((DCTypeImpl) Publishers.get(0))); + Assert.assertEquals(null, Publishers.get(1).getId()); + Assert.assertEquals("fr_CA", Publishers.get(1).getLang()); + Assert.assertEquals("My Publisher", getText((DCTypeImpl) Publishers.get(1))); + Assert.assertEquals(null, Publishers.get(2).getId()); + Assert.assertEquals(null, Publishers.get(2).getLang()); + Assert.assertEquals("My Publisher", getText((DCTypeImpl) 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 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((DCTypeImpl) Relations.get(0))); + Assert.assertEquals(null, Relations.get(1).getId()); + Assert.assertEquals("fr_CA", Relations.get(1).getLang()); + Assert.assertEquals("My Relation", getText((DCTypeImpl) Relations.get(1))); + Assert.assertEquals(null, Relations.get(2).getId()); + Assert.assertEquals(null, Relations.get(2).getLang()); + Assert.assertEquals("My Relation", getText((DCTypeImpl) 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 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((DCTypeImpl) Rightss.get(0))); + Assert.assertEquals(null, Rightss.get(1).getId()); + Assert.assertEquals("fr_CA", Rightss.get(1).getLang()); + Assert.assertEquals("My Rights", getText((DCTypeImpl) Rightss.get(1))); + Assert.assertEquals(null, Rightss.get(2).getId()); + Assert.assertEquals(null, Rightss.get(2).getLang()); + Assert.assertEquals("My Rights", getText((DCTypeImpl) 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 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((DCTypeImpl) Sources.get(0))); + Assert.assertEquals(null, Sources.get(1).getId()); + Assert.assertEquals("fr_CA", Sources.get(1).getLang()); + Assert.assertEquals("My Source", getText((DCTypeImpl) Sources.get(1))); + Assert.assertEquals(null, Sources.get(2).getId()); + Assert.assertEquals(null, Sources.get(2).getLang()); + Assert.assertEquals("My Source", getText((DCTypeImpl) 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 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((DCTypeImpl) subjects.get(0))); + Assert.assertEquals(null, subjects.get(1).getId()); + Assert.assertEquals("fr_CA", subjects.get(1).getLang()); + Assert.assertEquals("My Subject", getText((DCTypeImpl) subjects.get(1))); + Assert.assertEquals(null, subjects.get(2).getId()); + Assert.assertEquals(null, subjects.get(2).getLang()); + Assert.assertEquals("My Subject", getText((DCTypeImpl) 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 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((DCTypeImpl) titles.get(0))); + Assert.assertEquals(null, titles.get(1).getId()); + Assert.assertEquals("fr_CA", titles.get(1).getLang()); + Assert.assertEquals("My Title", getText((DCTypeImpl) titles.get(1))); + Assert.assertEquals(null, titles.get(2).getId()); + Assert.assertEquals(null, titles.get(2).getLang()); + Assert.assertEquals("My Title", getText((DCTypeImpl) 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((DCTypeImpl) Types.get(0))); + Assert.assertEquals(null, Types.get(1).getId()); + Assert.assertEquals("My Type", getText((DCTypeImpl) 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 html = new File(root.getAbsolutePath() + File.separator + "plain-page_no-header.xhtml"); + 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 + } + +} 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 0000000..dc733ac --- /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 0000000..3d01d0a --- /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/book.css b/org.eclipse.mylyn.docs.epub.tests/testdata/book.css new file mode 100644 index 0000000..e69de29 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 0000000..44a7f88 --- /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/plain-page.xhtml b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page.xhtml new file mode 100644 index 0000000..4d9bff0 --- /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 + + +

First item

+

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.

+

+ Curabitur sodales ligula in libero. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. 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. +

+

First sub-item

+

+ 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. Aenean + quam. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin + quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed + lectus. +

+

Second sub-item

+

+ Integer euismod lacus luctus magna. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. 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. Ut fringilla. 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. +

+

Second item

+

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.

+ + \ 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 0000000..39b9358 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_link.xhtml @@ -0,0 +1,59 @@ + + + + +XHTML Test + + +

First item

+

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.

+

+ drawing + Link to another page + Curabitur sodales ligula in libero. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. 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. +

+

First sub-item

+

+ 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. Aenean + quam. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin + quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed + lectus. +

+

Second sub-item

+

+ Integer euismod lacus luctus magna. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. 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. Ut fringilla. 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. +

+

Second item

+

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.

+ + \ 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 0000000..d7486c2 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_no-header.xhtml @@ -0,0 +1,55 @@ + + + + +XHTML Test + + + + +

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.

+

+ Curabitur sodales ligula in libero. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. 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. +

+

+ 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. Aenean + quam. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin + quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed + lectus. +

+

+ Integer euismod lacus luctus magna. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. 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. Ut fringilla. 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. +

+

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.

+ + \ 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 0000000..4334504 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/testdata/plain-page_warnings.xhtml @@ -0,0 +1,58 @@ + + + + +XHTML Test + + + Not a XHTML 1.1 element +

First item

+

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.

+

+ Curabitur sodales ligula in libero. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. 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. +

+

First sub-item

+

+ 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. Aenean + quam. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin + quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed + lectus. +

+

Second sub-item

+

+ Integer euismod lacus luctus magna. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. 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. Ut fringilla. 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. +

+

Second item

+

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.

+ + \ 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 0000000..51c5fe8 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.tests/testdata/toc.ncx @@ -0,0 +1,35 @@ + + + + + + + Table of contents + + + + + First item + + + + + First sub-item + + + + + + Second sub-item + + + + + + + Second item + + + + + diff --git a/org.eclipse.mylyn.docs.epub.ui/.classpath b/org.eclipse.mylyn.docs.epub.ui/.classpath new file mode 100644 index 0000000..64c5e31 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.mylyn.docs.epub.ui/.gitignore b/org.eclipse.mylyn.docs.epub.ui/.gitignore new file mode 100644 index 0000000..4c93aec --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/.gitignore @@ -0,0 +1,4 @@ +/build +/bin +/Building_EPUBs.epub +/help diff --git a/org.eclipse.mylyn.docs.epub.ui/.project b/org.eclipse.mylyn.docs.epub.ui/.project new file mode 100644 index 0000000..92fe4c8 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/.project @@ -0,0 +1,29 @@ + + + org.eclipse.mylyn.docs.epub.ui + + + + + + org.eclipse.mylyn.wikitext.ui.wikiTextValidationBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.mylyn.wikitext.ui.wikiTextNature + org.eclipse.jdt.core.javanature + + 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 0000000..3e4d701 --- /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/=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 0000000..8a54ffe --- /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 0000000..b367ad2 --- /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/META-INF/MANIFEST.MF b/org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF new file mode 100644 index 0000000..1556aef --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +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 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 0000000..3ae9acd --- /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 0000000..050614d --- /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/,\ + OSGI-INF/l10n/bundle.properties,\ + OSGI-INF/,\ + icons/ +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 0000000..dcf0b0a Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.ui/icons/wizard-banner.png 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 0000000..b68b3d1 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/plugin.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + 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 0000000..49c6e3e --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + org.eclipse.mylyn.docs-parent + org.eclipse.mylyn.docs + 1.6.0-SNAPSHOT + + org.eclipse.mylyn.docs.epub.ui + 0.8.0-SNAPSHOT + eclipse-plugin + + + + org.eclipse.tycho + tycho-source-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-pmd-plugin + + + + org.eclipse.mylyn.docs.epub + 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 0000000..507f9e6 Binary files /dev/null and b/org.eclipse.mylyn.docs.epub.ui/src-images/wizard-banner.psd 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 0000000..ef2e957 --- /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 true 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 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) { + e.printStackTrace(); + ms.add(new Status(IStatus.ERROR, EPUBUIPlugin.PLUGIN_ID, "Could not convert to EPUB", e)); + monitor.setCanceled(true); + 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 0000000..8440963 --- /dev/null +++ b/org.eclipse.mylyn.docs.epub.ui/src/org/eclipse/mylyn/internal/docs/epub/ui/EPUB2Bean.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * 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 { + + Map base; + + public ValueComparator(Map 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 sorted_locales; + + public EPUB2Bean(OPSPublication epub, File markupFile, File epubFile, File workingFolder) { + this.epub = epub; + this.markupFile = markupFile; + id = epub.getOpfPackage().getUniqueIdentifier(); + if (id == null || id.trim().length() == 0) { + id = "id"; + epub.getOpfPackage().setUniqueIdentifier(id); + epub.addIdentifier(id, "UUID", UUID.randomUUID().toString()); + } + // Keep the cover image reference + Item item = epub.getItemById(OPSPublication.COVER_IMAGE_ID); + // Clear everything except the metadata + epub.getOpfPackage().getManifest().getItems().clear(); + epub.getOpfPackage().getGuide().getGuideItems().clear(); + epub.getOpfPackage().getSpine().getSpineItems().clear(); + + // if (epubFile.exists()) { + // // Try to restore some information + // File rootFolder = new File(workingFolder.getAbsolutePath() + + // File.separator + epub.getRootFolder()[0]); + // if (item != null) { + // epub.setCover(new File(rootFolder.getAbsolutePath() + File.separator + // + item.getHref()), item.getTitle()); + // } + // } + + sorted_locales = new TreeMap(); + 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 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 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 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 = 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 stylesheets = epub.getItemsByMIMEType(OPSPublication.MIMETYPE_CSS); + if (stylesheets.isEmpty()) { + return EMPTY_STRING; + } else { + return stylesheets.get(0).getHref(); + } + } + + @SuppressWarnings("rawtypes") + public String getSubject() { + EList 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 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 String id = "id"; + + public void setIdentifier(String identifier) { + epub.getOpfPackage().getMetadata().getIdentifiers().clear(); + epub.addIdentifier(id, getIdScheme(), identifier); + } + + public void setIdScheme(String schemeName) { + String identifier = getIdentifier(); + epub.getOpfPackage().getMetadata().getIdentifiers().clear(); + epub.addIdentifier(id, schemeName, identifier); + } + + public String getIdScheme() { + 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 0000000..81d6af9 --- /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 0000000..fc43f1f --- /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, "idScheme"); + 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 0000000..62c3e83 --- /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 0000000..6148164 --- /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 0000000..4216f31 --- /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 0000000..df067f2 --- /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 0000000..c23d7ef --- /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/org.eclipse.mylyn.wikitext-feature/feature.xml b/org.eclipse.mylyn.wikitext-feature/feature.xml index decb0ca..3411c86 100644 --- a/org.eclipse.mylyn.wikitext-feature/feature.xml +++ b/org.eclipse.mylyn.wikitext-feature/feature.xml @@ -29,8 +29,8 @@ </license> <requires> - <import feature="org.eclipse.mylyn_feature" version="3.6.0" match="compatible"/> - <import plugin="org.eclipse.mylyn.commons.ui" version="3.6.0" match="compatible"/> + <import feature="org.eclipse.mylyn_feature" version="3.7.0" match="compatible"/> + <import plugin="org.eclipse.mylyn.commons.ui" version="3.7.0" match="compatible"/> </requires> <plugin diff --git a/pom.xml b/pom.xml index 89bf934..9e1acc7 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,13 @@ </profile> </profiles> <modules> + <!-- EPUB support --> + <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> <module>org.eclipse.mylyn.docs-site</module> <module>org.eclipse.mylyn.docs.sdk-feature</module> <module>org.eclipse.mylyn.htmltext-feature</module> @@ -93,7 +100,7 @@ <module>org.eclipse.mylyn.wikitext.twiki.core</module> <module>org.eclipse.mylyn.wikitext.twiki.ui</module> <module>org.eclipse.mylyn.wikitext.ui</module> - <!-- needs to be last --> + <!-- needs to be last --> <module>org.eclipse.mylyn.wikitext-standalone</module> </modules> </project>