diff --git a/html2xdoc/.cvsignore b/html2xdoc/.cvsignore new file mode 100644 index 00000000..5d21c883 --- /dev/null +++ b/html2xdoc/.cvsignore @@ -0,0 +1,2 @@ +target +maven.log diff --git a/html2xdoc/maven.xml b/html2xdoc/maven.xml new file mode 100644 index 00000000..14295e0a --- /dev/null +++ b/html2xdoc/maven.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/html2xdoc/plugin.jelly b/html2xdoc/plugin.jelly new file mode 100644 index 00000000..bda37432 --- /dev/null +++ b/html2xdoc/plugin.jelly @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Generating ${outFile} from ${file} + + + + + + + + + + + + + + + diff --git a/html2xdoc/project.xml b/html2xdoc/project.xml new file mode 100644 index 00000000..13228c6a --- /dev/null +++ b/html2xdoc/project.xml @@ -0,0 +1,106 @@ + + + + ${basedir}/../project.xml + 3 + maven-html2xdoc-plugin + Maven Html2XDoc Plug-in + 1.0 + + + jakarta + Creates XDoc documentation from normal HTML documentation. + + http://jakarta.apache.org/turbine/maven/reference/plugins/html2xdoc/ + + /www/jakarta.apache.org/turbine/maven/reference/plugins/html2xdoc/ + + + scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-turbine-maven/src/plugins-build/html2xdoc/ + http://cvs.apache.org/viewcvs/jakarta-turbine-maven/src/plugins-build/html2xdoc/ + + + + + James Strachan + jstrachan + jstrachan@apache.org + SpiritSoft, Inc. + + Java Developer + + + + + + + commons-jelly + commons-jelly-tags-xml + 20030211.142705 + http://jakarta.apache.org/commons/jelly/tags/xml/ + + root.maven + + + + commons-jelly + commons-jelly-tags-html + SNAPSHOT + http://jakarta.apache.org/commons/jelly/tags/html/ + + root.maven + + + + nekohtml + 0.7.1 + + root.maven + + + + + + commons-logging + 1.0.1 + + root.maven + + + + dom4j + 1.4-dev-8 + http://www.dom4j.org/ + + + xml-apis + 1.0.b2 + http://xml.apache.org/xerces2-j/ + + + xerces + 2.2.1 + http://xml.apache.org/xerces2-j/ + + + + + src/main + src/test + + + **/Test*.java + + + + src/test + + *.xml + *.html + + + + + + + \ No newline at end of file diff --git a/html2xdoc/src/main/org/apache/maven/html2xdoc/Html2XdocBean.java b/html2xdoc/src/main/org/apache/maven/html2xdoc/Html2XdocBean.java new file mode 100644 index 00000000..89d8a4f6 --- /dev/null +++ b/html2xdoc/src/main/org/apache/maven/html2xdoc/Html2XdocBean.java @@ -0,0 +1,271 @@ +/* + * /home/cvs/jakarta-turbine-maven/src/plugins-build/jellydoc/src/main/org/apache/maven/jellydoc/TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp + * 1.1 + * 2003/02/07 12:10:44 + * + * ==================================================================== + * + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR + * ITS 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + * TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp + */ + +package org.apache.maven.html2xdoc; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.dom4j.CharacterData; +import org.dom4j.Document; +import org.dom4j.DocumentFactory; +import org.dom4j.Element; +import org.dom4j.Node; + +/** + * A simple bean for converting a HTML document into an XDoc compliant XML document. + * This could be done via XSLT but is a little more complex than it might first + * appear so its done via Java code instead. + * + * @author James Strachan + */ +public class Html2XdocBean { + + /** The Log to which logging calls will be made. */ + private static final Log log = LogFactory.getLog(Html2XdocBean.class); + + private DocumentFactory factory = new DocumentFactory(); + + /** + * Converts the given HTML document into the corresponding XDoc format + * of XML + * + * @param html + * @return Document + */ + public Document convert(Document html) { + Document doc = factory.createDocument(); + Element root = doc.addElement("document"); + Element properties = root.addElement("properties"); + Element title = properties.addElement("title"); + title.setText(html.valueOf("/html/head/title")); + + Element body = root.addElement("body"); + + Element htmlContent = (Element) html.selectSingleNode("/html/body"); + if (htmlContent == null) { + log.info("No body element found for HTML document: " + html.asXML()); + } + else { + addSections(body, htmlContent); + } + return doc; + } + + /** + * Iterates thorugh the given body looking for h1, h2, h3 nodes and + * creating the associated section elements. Any text nodes + * contained inside the body are wrapped in a <p> element + * + * @param output the output destination + * @param body the block of HTML markup to convert + */ + protected void addSections(Element output, Element body) { + List content = getBodyContent(body.content()); + Element section = null; + Element p = null; + + for (Iterator iter = content.iterator(); iter.hasNext(); ) { + Node node = (Node) iter.next(); + + String name = node.getName(); + if (name != null && name.startsWith("h")) { + /** @todo we should handle child headings as a nested section */ + section = output.addElement("section"); + section.addAttribute("name", node.getText()); + p = null; + } + else { + if (section == null ) { + // we have a section with no name + // should we default it to be the same as the document title? + section = output.addElement("section"); + } + + if (node instanceof CharacterData) { + // lets add a

+ if (p == null) { + p = section.addElement("p"); + } + p.addText( node.getText() ); + } + else { + section.add(cloneNode(node)); + p = null; + } + } + } + } + + /** + * @param node + * @return true if the given node is a heading element (h1, h2, h3 etc) + */ + protected boolean isHeading(Node node) { + String name = node.getName(); + return name != null && name.startsWith("h"); + } + + /** + * Returns a copy of the body content, removing any whitespace from the beginning and end + * @param body + * @return List + */ + protected List getBodyContent(List content) { + // lets turn

 into  and concatenate consective entries 
+        Element lastPre = null;
+        LinkedList  list = new LinkedList();
+        boolean lastWasElement = true;
+        for (Iterator iter = content.iterator(); iter.hasNext(); ) {
+            Node node = (Node) iter.next();
+            
+            if (isPre(node)) {
+                if (lastPre == null) {
+                    lastPre = factory.createElement("source");
+                    list.add(lastPre);
+                }
+                lastPre.addText(node.getText());
+            }
+            else {
+                if (isWhitespace(node) && lastWasElement) {
+                    if (lastPre != null) {
+                        lastPre.addText(node.getText());
+                    }
+                }
+                else {
+                    lastWasElement = node instanceof Element;
+                    if (lastWasElement) {
+                    	lastPre = null;
+                    }                
+	                list.add(node);
+                }
+            }
+        }        
+
+        // now lets remove any whitespace text nodes at the beginning and end
+        while (true) {
+            Node node = (Node) list.getFirst();
+            if (isWhitespace(node)) {
+                list.removeFirst();
+                continue;
+            }
+            break;
+        }
+        while (true) {
+            Node node = (Node) list.getLast();
+            if (isWhitespace(node)) {
+                list.removeLast();
+                continue;
+            }
+            break;
+        }
+        return list;
+    }
+    
+    protected boolean isPre(Node node) {
+        if (node instanceof Element) {
+            Element element = (Element) node;
+            return element.getName().equals("pre");
+        }
+        return false;
+    }
+
+    /**
+     * @return true if the given node is a whitespace text node 
+     */
+    protected boolean isWhitespace(Node node) {
+        if (node instanceof CharacterData) {
+            String text = node.getText();
+            return text.trim().length() <= 0;
+        }
+        if (node instanceof Element) {
+            String name = node.getName(); 
+			if (name.equals("p")) {
+                String text = node.getText();
+                return text.trim().length() <= 0;
+			}
+			if (name.equals("br")) {
+			    return true;
+			}
+        }
+        return false;
+    }
+
+	/**
+	 * Normalizes the whitespace of any Elements
+	 * @param node
+	 * @return Node
+	 */    
+    protected Node cloneNode(Node node) {
+        Node answer = (Node) node.clone(); 
+        if (answer instanceof Element) {
+            Element element = (Element) answer;
+            element.normalize();
+        }
+        return answer;
+    }
+        
+}
diff --git a/html2xdoc/src/test/org/apache/maven/html2xdoc/TestHtml2Xdoc.java b/html2xdoc/src/test/org/apache/maven/html2xdoc/TestHtml2Xdoc.java
new file mode 100644
index 00000000..53387fcd
--- /dev/null
+++ b/html2xdoc/src/test/org/apache/maven/html2xdoc/TestHtml2Xdoc.java
@@ -0,0 +1,203 @@
+/*
+ * /home/cvs/jakarta-turbine-maven/src/plugins-build/jellydoc/src/main/org/apache/maven/jellydoc/TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
+ * 1.1
+ * 2003/02/07 12:10:44
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * .
+ * 
+ * TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
+ */
+
+package org.apache.maven.html2xdoc;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.dom4j.CharacterData;
+import org.dom4j.Document;
+import org.dom4j.DocumentFactory;
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+
+import org.cyberneko.html.parsers.SAXParser;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * A test harness for the HTML to XDOC converter 
+ * 
+ * @author James Strachan
+ */
+public class TestHtml2Xdoc extends TestCase {
+    
+    public static void main( String[] args ) {
+        TestRunner.run( suite() );
+    }
+
+    public static Test suite() {
+        return new TestSuite( TestHtml2Xdoc.class );
+    }
+
+    public TestHtml2Xdoc(String testName) {
+        super(testName);
+    }
+
+    // Test cases
+    //-------------------------------------------------------------------------
+    public void testOne() throws Exception {
+		assertConversion("input1.html", "output1.xml");
+    }
+    
+    // Implementation methods
+    //-------------------------------------------------------------------------
+    protected void assertConversion(String input, String output) throws Exception {
+        Html2XdocBean converter = createConverter();
+        Document inputDoc = parseHtml(input);
+        Document expectedDoc = parse(output);
+        
+        Document actualDoc = converter.convert(inputDoc);
+        
+        assertEqual("Output for: " + input + " does not match: " + output, expectedDoc, actualDoc);
+    }
+
+    /**
+     * Asserts that the given two documents are equal
+     * 
+     * @param string
+     * @param expectedDoc
+     * @param actualDoc
+     */
+    protected void assertEqual(
+        String message,
+        Document expectedDoc,
+        Document actualDoc) throws IOException {
+
+		String expectedText = getPrettyPrintText(expectedDoc);
+		String actualText = getPrettyPrintText(actualDoc);
+		
+		if (!expectedText.equals(actualText)) {
+            System.out.println("Expected: " + expectedText);	
+            System.out.println("Actual: " + actualText);	
+		}
+        assertEquals(message, expectedText, actualText);    
+    }
+
+    /**
+     * @param expectedDoc
+     * @return Object
+     */
+    protected String getPrettyPrintText(Document doc) throws IOException {
+        OutputFormat format = OutputFormat.createPrettyPrint();
+        StringWriter buffer = new StringWriter();
+        XMLWriter writer = new XMLWriter(buffer, format);
+        writer.write(doc);
+        writer.close();
+        return buffer.toString();
+    }
+
+    /**
+     * Parses the given String URI on the classpath and returns the docuemnt
+     * 
+     * @param input
+     * @return Document
+     */
+    protected Document parse(String input) throws Exception {
+        URL url = getClassURL(input);
+        SAXReader saxReader = new SAXReader();   
+        return saxReader.read(url);
+    }
+
+    /**
+     * Parses the given HTML using a String URI on the classpath 
+     * and returns the docuemnt
+     * 
+     * @param input
+     * @return Document
+     */
+    protected Document parseHtml(String input) throws Exception {
+        URL url = getClassURL(input);
+        SAXParser htmlParser = new SAXParser();
+        htmlParser.setProperty(
+            "http://cyberneko.org/html/properties/names/elems",
+            "lower"
+        );
+        htmlParser.setProperty(
+            "http://cyberneko.org/html/properties/names/attrs",
+            "lower"
+        );
+        SAXReader saxReader = new SAXReader(htmlParser);
+        return saxReader.read(url);
+    }
+
+	protected URL getClassURL(String input) throws Exception {
+        URL url = getClass().getResource(input);
+        assertTrue("Could not find resource on classpath for: " + input, url != null);
+        return url;
+	}
+	
+    protected Html2XdocBean createConverter() {
+        return new Html2XdocBean();
+    }
+}
diff --git a/html2xdoc/src/test/org/apache/maven/html2xdoc/input1.html b/html2xdoc/src/test/org/apache/maven/html2xdoc/input1.html
new file mode 100644
index 00000000..7258110e
--- /dev/null
+++ b/html2xdoc/src/test/org/apache/maven/html2xdoc/input1.html
@@ -0,0 +1,19 @@
+
+
+
+  
+  A title
+
+
+	
+

A H1

+ +Some text +
+More text + +

Some consective pres

+
hi
+
there
+ + diff --git a/html2xdoc/src/test/org/apache/maven/html2xdoc/output1.xml b/html2xdoc/src/test/org/apache/maven/html2xdoc/output1.xml new file mode 100644 index 00000000..14a18e13 --- /dev/null +++ b/html2xdoc/src/test/org/apache/maven/html2xdoc/output1.xml @@ -0,0 +1,16 @@ + + + A title + + +
+

Some text +

+
+

More text +

+

Some consective pres

+ hi there +
+ +
\ No newline at end of file diff --git a/html2xdoc/xdocs/.cvsignore b/html2xdoc/xdocs/.cvsignore new file mode 100644 index 00000000..cb6131bb --- /dev/null +++ b/html2xdoc/xdocs/.cvsignore @@ -0,0 +1 @@ +stylesheets diff --git a/html2xdoc/xdocs/goals.xml b/html2xdoc/xdocs/goals.xml new file mode 100644 index 00000000..1595769c --- /dev/null +++ b/html2xdoc/xdocs/goals.xml @@ -0,0 +1,34 @@ + + + + + Html2XDoc Plugin Goals + James Strachan + + + +
+ + + + + + + + + +
GoalDescription
html2xdoc + The default goal. This goal generates xdoc documents from some basic + HTML documentation which can then be styled by the xdoc goal to use + a uniform CSS style and add the common navigation links etc. +
+ This goal means that normal vanilla HTML can be used to create documentation + using a WYSIWYG editing tool like Mozilla or MS FrontPage. +
+ Most end user documentation + only requires basic formatting (bold, italic, bullets) along with headings and images and + links so using normal HTML for docuemntation with a WYSIWYG tool seems like a good idea. +
+
+ +
diff --git a/html2xdoc/xdocs/index.xml b/html2xdoc/xdocs/index.xml new file mode 100644 index 00000000..099b0756 --- /dev/null +++ b/html2xdoc/xdocs/index.xml @@ -0,0 +1,39 @@ + + + + + Maven Html2XDoc Plug-in + James Strachan + + + +
+

+ This plugin generates xdoc documents from some basic + HTML documentation which can then be styled by the xdoc goal to use + a uniform CSS style and add the common navigation links etc. +

+

+ This goal means that normal vanilla HTML can be used to create documentation + using a WYSIWYG editing tool like Mozilla or MS FrontPage. +

+

+ Most end user documentation + only requires basic formatting (bold, italic, bullets) along with headings and images and + links so using normal HTML for documentation with a WYSIWYG tool is a good idea. +

+

+ The properties that allow you to customize the execution + are documented here. +

+

+ To enable HTML to xdoc conversion add the following to your maven.xml +

+ + <preGoal name="xdoc:jelly-transform"> + <attainGoal name="html2xdoc"/> + </preGoal> + +
+ + diff --git a/html2xdoc/xdocs/navigation.xml b/html2xdoc/xdocs/navigation.xml new file mode 100644 index 00000000..914daddb --- /dev/null +++ b/html2xdoc/xdocs/navigation.xml @@ -0,0 +1,16 @@ + + + + Maven Html2XDoc Plugin + + + + + + + + + + + + diff --git a/html2xdoc/xdocs/properties.xml b/html2xdoc/xdocs/properties.xml new file mode 100644 index 00000000..bfa2a0eb --- /dev/null +++ b/html2xdoc/xdocs/properties.xml @@ -0,0 +1,34 @@ + + + + + Html2XDoc Properties + James Strachan + + + +
+ + + + + + + + + + + + +
PropertyOptional?Description
maven.html2xdoc.dirYes (default=xdoc) + Specifies the directory containing HTML documents which will be + turned into xdoc XML documents in the + target/generated-xdoc directory + ready for use by the xdoc plugin. +
maven.html2xdoc.jslYes + Allows the JSL stylesheet to be specified to perform some custom + HTML to XDoc transformation. +
+
+ +