Re: [xwiki-devs] [xwiki-notifications] r11859 - in sandbox/xwiki-plugin-officeimporter/src: main/java/com/xpn/xwiki/plugin/officeconverter main/resources test/java/com/xpn/xwiki/plugin/officeconverter test/resources
Hi Wang,
I have some questions/remarks on the commit below:
1) It's hard to see what you're modifying from the default tag infos
(in default.xml). I think a better solution might be to extend
DefaultTagProvider and use the constructor accepting an info provider,
see http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner/HtmlCleaner.html#HtmlCleaner(org.htmlcleaner.ITagInfoProvider)
. In this manner we just extend the default and not duplicate it.
WDYT? Is this possible? Are you adding tags or redefining default one?
2) The following code is not required:
> + private void removeHead(TagNode node)
> + {
> + logger.debug("remove the head tag of the html");
> + TagNode head = node.findElementByName("head", true);
> + head.removeFromTree();
> + }
instead you can just use props.setOmitHtmlEnvelope(true);
3) Could you explain why we need convertAllAttribute2Lowercase?
4) Could you refactor your code to use the new HTMLCleaner code I have
put in xwiki-xml module?
Feel free to provide patches for CleaningFilters.
Thanks
-Vincent
On Aug 17, 2008, at 7:22 PM, daning (SVN) wrote:
> Author: daning
> Date: 2008-08-17 19:22:26 +0200 (Sun, 17 Aug 2008)
> New Revision: 11859
>
> Added:
> sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleaner.java
> sandbox/xwiki-plugin-officeimporter/src/main/resources/default.xml
> sandbox/xwiki-plugin-officeimporter/src/test/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleanerTest.java
> sandbox/xwiki-plugin-officeimporter/src/test/resources/default.xml
> Modified:
> sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/AbstractOfficeConverter.java
> sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/OfficeConverterPlugin.java
> Log:
> XSANDBOX-32: Office Converter
> * remove jdom but use htmlcleaner to clean the html code
> * add test case for htmlcleaner
> * add tag provider config file to resource
> * throw a expect if the user is not allowed to create the page.
>
> Modified: sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/
> xwiki/plugin/officeconverter/AbstractOfficeConverter.java
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/AbstractOfficeConverter.java 2008-08-17
> 16:00:27 UTC (rev 11858)
> +++ sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/AbstractOfficeConverter.java 2008-08-17
> 17:22:26 UTC (rev 11859)
> @@ -8,11 +8,14 @@
>
> import org.apache.log4j.Logger;
> import org.htmlcleaner.CleanerProperties;
> +import org.htmlcleaner.ConfigFileTagProvider;
> import org.htmlcleaner.HtmlCleaner;
> import org.htmlcleaner.JDomSerializer;
> +import org.htmlcleaner.PrettyXmlSerializer;
> import org.htmlcleaner.TagNode;
> import org.jdom.Document;
> import org.jdom.Element;
> +import org.xml.sax.InputSource;
> import org.xwiki.component.logging.AbstractLogEnabled;
>
> import com.xpn.xwiki.plugin.officeconverter.filter.FilterChain;
> @@ -46,63 +49,28 @@
> } catch (UnsupportedEncodingException e) {
> throw new OfficeConverterException("unsupported encoding
> in officeconverter", e);
> }
> - return cleanHtml(result, encoding);
> +
> + XHTMLCleaner xhtmlCleaner = new XHTMLCleaner();
> + String cleanXHTML = xhtmlCleaner.cleanXHTML(result);
> + String xwikiSyntax =
> this.convertXHTML2XWIKISyntax(cleanXHTML);
> + return xwikiSyntax;
> }
>
> - /**
> - * Clean the html code
> - *
> - * @param htmlContent the html code to clean
> - * @param charset the encoding of html code
> - * @return
> - */
> - private String cleanHtml(String htmlContent, String charset)
> - {
> -
> - HtmlCleaner htmlCleaner = new HtmlCleaner();
> - TagNode node = null;
> - CleanerProperties props = null;
> - try {
> - logger.info("start clean html");
> - props = htmlCleaner.getProperties();
> - // props.setOmitHtmlEnvelope(true);
> - node = htmlCleaner.clean(htmlContent);
> - logger.info("finish clean html");
> - } catch (IOException e) {
> - // TODO Auto-generated catch block
> - e.printStackTrace();
> - }
> - /*
> - * if (retainStyle) { // TODO do something to retain the
> style. Though I don't think that's necessary. }
> - */
> - // TODO Clean the html more
> - // 1. <p> in list (done)
> - // 2. <font> <family>
> - // 3. remove <html> <head> <body>
> - Document document = null;
> - document = new JDomSerializer(props, true).createJDom(node);
> -
> - Element root = document.getRootElement();
> -
> - // TODO more filter to be added
> -
> - XHTMLPinLiFilter pinLiFilter = new XHTMLPinLiFilter();
> - XHTMLImageTagFilter xhtmlImageTagFilter = new
> XHTMLImageTagFilter();
> - XHTMLBadLinkFilter xhtmlBadLinkFilter = new
> XHTMLBadLinkFilter();
> - FilterChain filterChain = new FilterChain();
> - filterChain.addFilter(pinLiFilter);
> - filterChain.addFilter(xhtmlImageTagFilter);
> - filterChain.addFilter(xhtmlBadLinkFilter);
> - filterChain.doFilter(root);
> -
> - String result = Util.document2String(document, charset);
> - return result;
> - }
> -
> protected void ensureNotNull(String argumentName, Object
> argumentValue)
> {
> if (argumentValue == null) {
> throw new IllegalArgumentException(argumentName + " is
> null");
> }
> }
> +
> + public String convertXHTML2XWIKISyntax(String inputXHTML)
> + {
> + /*
> + * WikiModelXHTMLParser parser = new
> WikiModelXHTMLParser(); Reader source = new
> StringReader(inputXHTML); XDOM
> + * xdom = null; try { xdom = parser.parse(source); } catch
> (ParseException e) { // TODO Auto-generated catch
> + * block e.printStackTrace(); } StringWriter sw = new
> StringWriter(); Listener listener = new
> + * XWikiSyntaxRenderer(sw); xdom.traverse(listener);
> System.out.println(sw.toString()); //don't return the xwiki
> + * syntax since it's not finish yet.
> + */return inputXHTML;
> + }
> }
>
> Modified: sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/
> xwiki/plugin/officeconverter/OfficeConverterPlugin.java
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/OfficeConverterPlugin.java 2008-08-17
> 16:00:27 UTC (rev 11858)
> +++ sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/OfficeConverterPlugin.java 2008-08-17
> 17:22:26 UTC (rev 11859)
> @@ -245,10 +245,13 @@
> }
> // check is the current user have the right the create doc
> if (!context.getWiki().getRightService().hasAdminRights(context)
> - && !context.getWiki().getRightService().checkAccess("create",
> + && !context.getWiki().getRightService().checkAccess("edit",
> newdoc, context))
> - // TODO maybe should throw access_deny exception
> - return;
> + // TODO how to redirect to "not allowed to edit page" view
> + throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
> + XWikiException.ERROR_XWIKI_ACCESS_DENIED,
> + "You are not allowed to edit " + newdoc.getFullName());
> +
>
> // clean the input file extension
> inputfileExtension = checkAndUpdateExtension(inputfileExtension);
>
> Added: sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/
> xwiki/plugin/officeconverter/XHTMLCleaner.java
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleaner.java
> (rev 0)
> +++ sandbox/xwiki-plugin-officeimporter/src/main/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleaner.java 2008-08-17 17:22:26 UTC
> (rev 11859)
> @@ -0,0 +1,148 @@
> +package com.xpn.xwiki.plugin.officeconverter;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.util.Iterator;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Set;
> +import java.util.Map.Entry;
> +
> +import org.apache.log4j.Logger;
> +import org.htmlcleaner.CleanerProperties;
> +import org.htmlcleaner.ConfigFileTagProvider;
> +import org.htmlcleaner.HtmlCleaner;
> +import org.htmlcleaner.SimpleXmlSerializer;
> +import org.htmlcleaner.TagNode;
> +import org.xml.sax.InputSource;
> +
> +public class XHTMLCleaner
> +{
> + private HtmlCleaner htmlCleaner = null;
> + private CleanerProperties props = null;
> + private final static Logger logger =
> Logger.getLogger(XHTMLCleaner.class);
> +
> + public XHTMLCleaner() {
> + logger.debug("try to use the tag provider config file
> default.xml in classpath");
> + InputStream tagProviderConfig =
> getClass().getClassLoader().getResourceAsStream("default.xml");
> + init(tagProviderConfig);
> + }
> +
> + public XHTMLCleaner(InputStream tagProviderConfig) {
> + logger.debug("try to use the customer tag provider config
> inputstream");
> + init(tagProviderConfig);
> + }
> +
> + private void init(InputStream tagProviderConfig) {
> + if (tagProviderConfig != null) {
> + ConfigFileTagProvider tagProvider = new
> ConfigFileTagProvider(new InputSource(tagProviderConfig));
> + htmlCleaner = new HtmlCleaner(tagProvider);
> + } else {
> + logger.debug("the tag config is invalid. use the
> default tag provider config");
> + htmlCleaner = new HtmlCleaner();
> + }
> + this.props = htmlCleaner.getProperties();
> + }
> +
> + /**
> + * Clean the html code
> + *
> + * @param htmlContent the html code to clean
> + * @return
> + * @throws OfficeConverterException
> + */
> + public String cleanXHTML(String htmlContent) throws
> OfficeConverterException
> + {
> + TagNode root = null;
> + try {
> + logger.debug("start clean html");
> + root = htmlCleaner.clean(htmlContent);
> + logger.debug("finish clean html");
> + } catch (IOException e) {
> + throw new OfficeConverterException("Something is worry
> when clean html code.", e);
> + }
> + // do some filter of the html
> + removeHead(root);
> + removeEmptyLink(root);
> + convertAllAttribute2Lowercase(root);
> +
> + String result = null;
> + try {
> + result = new
> SimpleXmlSerializer(props).getXmlAsString(root);
> + } catch (IOException e) {
> + throw new OfficeConverterException("Something is worry
> when write html code to String.", e);
> + }
> + return result;
> + }
> +
> + /**
> + * remove \<head\> tag from the html
> + *
> + * @param node the <code>TagNode</code> containing the html
> + */
> + private void removeHead(TagNode node)
> + {
> + logger.debug("remove the head tag of the html");
> + TagNode head = node.findElementByName("head", true);
> + head.removeFromTree();
> + }
> +
> + /**
> + * remove empty link, <a/> <a href=""></a> <a></a> from the
> html<br/> Because empty link should not display in page.
> + * And xwikirendering of html don't handle empty link very
> well. So here we just remove all the empty links.<br/>
> + * If the link is empty link but have label, then replace the
> link with \<span\>
> + * @param node the <code>TagNode</code> containing the html
> + */
> + private void removeEmptyLink(TagNode node)
> + {
> + logger.debug("remove Empty link from html");
> + TagNode[] links = node.getElementsByName("a", true);
> + for (TagNode link : links) {
> + if (link.getAttributeByName("href") == null ||
> link.getAttributeByName("href").trim().equals("")) {
> + if(link.getText() == null ||
> link.getText().toString().trim().equals("")) {
> + link.removeFromTree();
> + } else {
> + //TODO can't replace a tag in HTMLCleaner
> + //link.removeFromTree();
> + //replace it with span or <p> or else tag, need
> discussion.
> + //TagNode replace = new TagNode("span");
> + //this.htmlCleaner.setInnerHtml(replace,
> link.getText().toString());
> + //can't permit the order of the tags
> + //link.getParent().addChild(replace);
> + }
> + }
> + }
> + }
> +
> + /**
> + * change all the attributes' value to lowercase, except href
> and src, as this is url and some url is capital sensitive
> + * @param node
> + */
> + private void convertAllAttribute2Lowercase(TagNode node) {
> + logger.debug("convert all the uppercase attribute to
> lowercase");
> + TagNode[] all = node.getAllElements(true);
> + for(TagNode one : all) {
> + Map<String, String> atts = one.getAttributes();
> + Set entrySet = atts.entrySet();
> + Iterator it = entrySet.iterator();
> + while(it.hasNext()) {
> + Entry<String, String> entry = (Entry)it.next();
> + String key = entry.getKey();
> + String value = entry.getValue();
> + // don't lowercase the url in attribute, etc <a
> href="SomeUrl">link</a>
> + if(!key.equals("href") && !key.equals("src")) {
> + entry.setValue(value.toLowerCase());
> + }
> + }
> + }
> + }
> +
> + public void replaceTag(TagNode body) {
> + List nodeList = body.getAllElementsList(false);
> + for(int i=0; i< nodeList.size(); i++) {
> + TagNode node=(TagNode)nodeList.get(i);
> + node.removeFromTree();
> + }
> +
> + }
> +}
>
> Added: sandbox/xwiki-plugin-officeimporter/src/main/resources/
> default.xml
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/main/resources/
> default.xml (rev 0)
> +++ sandbox/xwiki-plugin-officeimporter/src/main/resources/
> default.xml 2008-08-17 17:22:26 UTC (rev 11859)
> @@ -0,0 +1,311 @@
> +<!--
> + General description of a tag is in the following format:
> +
> + <tag name="TAG NAME"
> + content="all | text | none"
> + section="all | head | body"
> + deprecated="true | false"
> + unique="true | false"
> + ignore-permitted="true | false">
> +
> + <fatal-tags>LIST OF COMMA-SEPARATED TAGS</fatal-tags>
> + <req-enclosing-tags>LIST OF COMMA-SEPARATED TAGS</req-
> enclosing-tags>
> + <forbidden-tags>LIST OF COMMA-SEPARATED TAGS</forbidden-tags>
> + <allowed-children-tags>LIST OF COMMA-SEPARATED TAGS</
> allowed-children-tags>
> + <higher-level-tags>LIST OF COMMA-SEPARATED TAGS</higher-
> level-tags>
> + <close-before-copy-inside-tags>LIST OF COMMA-SEPARATED
> TAGS</close-before-copy-inside-tags>
> + <close-inside-copy-after-tags>LIST OF COMMA-SEPARATED TAGS</
> close-inside-copy-after-tags>
> + <close-before-tags>LIST OF COMMA-SEPARATED TAGS</close-
> before-tags>
> +
> + </tag>
> +
> + Explanation of dependancies:
> +
> + * fatal tags - required outer tag - the tag will be ignored
> during parsing (will be skipped)
> + if this fatal tag is missing. For example, most web browsers
> ignore elements TD, TR, TBODY
> + if they are not in the context of TABLE tag.
> + * required enclosing tags - if there is no such, it is
> implicitely created. For example if TD
> + is out of TR - open TR is created before.
> + * forbidden tags - it is not allowed to occure inside - for
> example FORM cannot be inside
> + other FORM and it will be ignored during cleanup.
> + * allowed children tags - for example TR allowes TD and TH. If
> there are some dependant
> + allowed tags defined then cleaner ignores other tags,
> treating them as unallowed, unless
> + they are in some other relationship with this tag.
> + * higher level tags - for example for TR higher tags are THEAD,
> TBODY, TFOOT.
> + * close-before-copy-inside-tags - tags that must be closed and
> copied - for example, in
> + <a href="#"><div>.... tag A must be closed before DIV but
> copied again inside DIV.
> + * close-inside-copy-after-tags - tags that must be closed
> before closing this tag and copied
> + again after - for example, in <i><b>at</i> first</b> text tag
> B must be closed before
> + closing I, but it must be copied again after resulting
> finally in sequence:
> + <i><b>at</b></i&><b> first</b> text.
> + * close-before-tag - tags that simply must be closed before
> actual tag - for example TR will be closed
> + before open TABLE tag.
> +-->
> +
> +<tags>
> + <tag name="div" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="span" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="meta" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="link" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="title" content="text" section="head"
> deprecated="false" unique="true" ignore-permitted="false"/>
> + <tag name="style" content="text" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="bgsound" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="h1" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h2" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h3" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h4" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h5" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h6" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="p" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> p,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="strong" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="em" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="abbr" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="acronym" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="address" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="bdo" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="blockquote" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="cite" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="q" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="code" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="ins" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="del" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="dfn" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="kbd" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="pre" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="samp" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="listing" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="var" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="br" content="none" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="wbr" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="nobr" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>nobr</close-before-tags>
> + </tag>
> + <tag name="xmp" content="text" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="a" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>a</close-before-tags>
> + </tag>
> + <tag name="base" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="img" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="area" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>map</fatal-tags>
> + <close-before-tags>area</close-before-tags>
> + </tag>
> + <tag name="map" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>map</close-before-tags>
> + </tag>
> + <tag name="object" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="param" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="applet" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false"/>
> + <tag name="xml" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="ul" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="ol" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="li" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> li
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + <forbidden-tags>p</forbidden-tags>
> + </tag>
> + <tag name="dl" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="dt" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>dt,dd</close-before-tags>
> + </tag>
> + <tag name="dd" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>dt,dd</close-before-tags>
> + </tag>
> + <tag name="menu" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="dir" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="table" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <allowed-children-
> tags>tr,tbody,thead,tfoot,colgroup,caption,tr</allowed-children-tags>
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> tr
> ,thead
> ,tbody
> ,tfoot
> ,caption
> ,colgroup
> ,table
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="tr" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tbody</req-enclosing-tags>
> + <allowed-children-tags>td,th</allowed-children-tags>
> + <higher-level-tags>thead,tfoot</higher-level-tags>
> + <close-before-tags>tr,td,th,caption,colgroup</close-before-
> tags>
> + </tag>
> + <tag name="td" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tr</req-enclosing-tags>
> + <close-before-tags>td,th,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="th" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tr</req-enclosing-tags>
> + <close-before-tags>td,th,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="tbody" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="thead" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="tfoot" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="col" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>colgroup</fatal-tags>
> + </tag>
> + <tag name="colgroup" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>col</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="caption" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="form" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <forbidden-tags>form</forbidden-tags>
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> option
> ,optgroup
> ,textarea
> ,select
> ,fieldset
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="input" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="textarea" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="select" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <allowed-children-tags>option,optgroup</allowed-children-
> tags>
> + <close-before-tags>option,optgroup,select</close-before-tags>
> + </tag>
> + <tag name="option" content="text" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <fatal-tags>select</fatal-tags>
> + <close-before-tags>option</close-before-tags>
> + </tag>
> + <tag name="optgroup" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <fatal-tags>select</fatal-tags>
> + <allowed-children-tags>option</allowed-children-tags>
> + <close-before-tags>optgroup</close-before-tags>
> + </tag>
> + <tag name="button" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="label" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="fieldset" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="isindex" content="none" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="script" content="all" section="all"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="noscript" content="all" section="all"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="b" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>u,i,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="i" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="u" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,i,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="tt" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,sub,sup,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="sub" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sup,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="sup" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="big" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="small" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="strike" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,blink,s</close-inside-copy-after-tags>
> + </tag>
> + <tag name="blink" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,strike,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="marquee" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="s" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,strike,blink</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="hr" content="none" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="font" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false"/>
> + <tag name="basefont" content="none" section="body"
> deprecated="true" unique="false" ignore-permitted="false"/>
> + <tag name="center" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="comment" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="server" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="iframe" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="embed" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> +</tags>
> \ No newline at end of file
>
> Added: sandbox/xwiki-plugin-officeimporter/src/test/java/com/xpn/
> xwiki/plugin/officeconverter/XHTMLCleanerTest.java
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/test/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleanerTest.java
> (rev 0)
> +++ sandbox/xwiki-plugin-officeimporter/src/test/java/com/xpn/xwiki/
> plugin/officeconverter/XHTMLCleanerTest.java 2008-08-17 17:22:26 UTC
> (rev 11859)
> @@ -0,0 +1,72 @@
> +package com.xpn.xwiki.plugin.officeconverter;
> +
> +import junit.framework.TestCase;
> +
> +import org.htmlcleaner.TagNode;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +
> +public class XHTMLCleanerTest extends TestCase
> +{
> + XHTMLCleaner xhtmlCleaner = null;
> +
> + @Before
> + public void setUp() {
> + xhtmlCleaner = new XHTMLCleaner();
> + }
> +
> + @Test
> + public void testWellFormed() throws OfficeConverterException {
> + test("<p>a<ol><li>abc<hr>",
> + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
> + "<html><body><p>a</p><ol><li>abc<hr /></li></ol></
> body></html>");
> + }
> +
> + @Test
> + public void testRemoveHead() throws OfficeConverterException {
> + test("<html><head/><body><p>test</p></body></html>",
> + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
> + "<html><body><p>test</p></body></html>");
> + }
> +
> + @Test
> + public void testRemoveEmptyLink() throws
> OfficeConverterException {
> + test("<html><head/><body><a href=\"\"></a><a href=\"url\"></
> a>" +
> + "<a /><a></a><a>not null link</a><p>test</p></body></
> html>",
> + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
> + "<html><body><a href=\"url\" /><a>not null link</
> a><p>test</p></body></html>");
> + }
> +
> + @Test
> + public void testConvertAllAttribute2Lowercase() throws
> OfficeConverterException {
> + test("<html><head/><body><p algin=\"CENTER\">test</p>" +
> + "<ol color=\"RED\"><li COLOR=\"BLUE\">test</li></ol><a
> href=\"URL\">link</a><img src=\"imgURL\"/></body></html>",
> + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
> + "<html><body><p algin=\"center\">test</p>" +
> + "<ol color=\"red\"><li color=\"blue\">test</li></ol><a
> href=\"URL\">link</a><img src=\"imgURL\" /></body></html>");
> + }
> +
> + @Test
> + public void testReplaceTagNode() throws
> OfficeConverterException {
> +
> + //TODO 1. get all elements , modify, and add the elements
> list to the tag.
> + //2. get a list, modify, add to it. see if the order of the
> list change.
> + TagNode body = new TagNode("body");
> + TagNode h1 = new TagNode("h1");
> + TagNode h2 = new TagNode("h2");
> + TagNode h3 = new TagNode("h3");
> + TagNode h4 = new TagNode("h4");
> + body.addChild(h1);
> + body.addChild(h2);
> + body.addChild(h3);
> + body.addChild(h4);
> + xhtmlCleaner.replaceTag(body);
> + }
> +
> + private void test(String input, String expected) throws
> OfficeConverterException {
> + String result = xhtmlCleaner.cleanXHTML(input);
> + assertEquals(result, expected);
> + }
> +
> +}
>
> Added: sandbox/xwiki-plugin-officeimporter/src/test/resources/
> default.xml
> ===================================================================
> --- sandbox/xwiki-plugin-officeimporter/src/test/resources/
> default.xml (rev 0)
> +++ sandbox/xwiki-plugin-officeimporter/src/test/resources/
> default.xml 2008-08-17 17:22:26 UTC (rev 11859)
> @@ -0,0 +1,310 @@
> +<!--
> + General description of a tag is in the following format:
> +
> + <tag name="TAG NAME"
> + content="all | text | none"
> + section="all | head | body"
> + deprecated="true | false"
> + unique="true | false"
> + ignore-permitted="true | false">
> +
> + <fatal-tags>LIST OF COMMA-SEPARATED TAGS</fatal-tags>
> + <req-enclosing-tags>LIST OF COMMA-SEPARATED TAGS</req-
> enclosing-tags>
> + <forbidden-tags>LIST OF COMMA-SEPARATED TAGS</forbidden-tags>
> + <allowed-children-tags>LIST OF COMMA-SEPARATED TAGS</
> allowed-children-tags>
> + <higher-level-tags>LIST OF COMMA-SEPARATED TAGS</higher-
> level-tags>
> + <close-before-copy-inside-tags>LIST OF COMMA-SEPARATED
> TAGS</close-before-copy-inside-tags>
> + <close-inside-copy-after-tags>LIST OF COMMA-SEPARATED TAGS</
> close-inside-copy-after-tags>
> + <close-before-tags>LIST OF COMMA-SEPARATED TAGS</close-
> before-tags>
> +
> + </tag>
> +
> + Explanation of dependancies:
> +
> + * fatal tags - required outer tag - the tag will be ignored
> during parsing (will be skipped)
> + if this fatal tag is missing. For example, most web browsers
> ignore elements TD, TR, TBODY
> + if they are not in the context of TABLE tag.
> + * required enclosing tags - if there is no such, it is
> implicitely created. For example if TD
> + is out of TR - open TR is created before.
> + * forbidden tags - it is not allowed to occure inside - for
> example FORM cannot be inside
> + other FORM and it will be ignored during cleanup.
> + * allowed children tags - for example TR allowes TD and TH. If
> there are some dependant
> + allowed tags defined then cleaner ignores other tags,
> treating them as unallowed, unless
> + they are in some other relationship with this tag.
> + * higher level tags - for example for TR higher tags are THEAD,
> TBODY, TFOOT.
> + * close-before-copy-inside-tags - tags that must be closed and
> copied - for example, in
> + <a href="#"><div>.... tag A must be closed before DIV but
> copied again inside DIV.
> + * close-inside-copy-after-tags - tags that must be closed
> before closing this tag and copied
> + again after - for example, in <i><b>at</i> first</b> text tag
> B must be closed before
> + closing I, but it must be copied again after resulting
> finally in sequence:
> + <i><b>at</b></i&><b> first</b> text.
> + * close-before-tag - tags that simply must be closed before
> actual tag - for example TR will be closed
> + before open TABLE tag.
> +-->
> +
> +<tags>
> + <tag name="div" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="span" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="meta" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="link" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="title" content="text" section="head"
> deprecated="false" unique="true" ignore-permitted="false"/>
> + <tag name="style" content="text" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="bgsound" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="h1" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h2" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h3" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h4" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h5" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="h6" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> h1
> ,h2
> ,h3
> ,h4
> ,h5
> ,h6
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="p" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> p,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="strong" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="em" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="abbr" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="acronym" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="address" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="bdo" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="blockquote" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="cite" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="q" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="code" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="ins" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="del" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="dfn" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="kbd" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="pre" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="samp" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="listing" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="var" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="br" content="none" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="wbr" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="nobr" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>nobr</close-before-tags>
> + </tag>
> + <tag name="xmp" content="text" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="a" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>a</close-before-tags>
> + </tag>
> + <tag name="base" content="none" section="head"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="img" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="area" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>map</fatal-tags>
> + <close-before-tags>area</close-before-tags>
> + </tag>
> + <tag name="map" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>map</close-before-tags>
> + </tag>
> + <tag name="object" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="param" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="applet" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false"/>
> + <tag name="xml" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false"/>
> + <tag name="ul" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="ol" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="li" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> li
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="dl" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="dt" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>dt,dd</close-before-tags>
> + </tag>
> + <tag name="dd" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-tags>dt,dd</close-before-tags>
> + </tag>
> + <tag name="menu" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="dir" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="table" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <allowed-children-
> tags>tr,tbody,thead,tfoot,colgroup,caption,tr</allowed-children-tags>
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> tr
> ,thead
> ,tbody
> ,tfoot
> ,caption
> ,colgroup
> ,table
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="tr" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tbody</req-enclosing-tags>
> + <allowed-children-tags>td,th</allowed-children-tags>
> + <higher-level-tags>thead,tfoot</higher-level-tags>
> + <close-before-tags>tr,td,th,caption,colgroup</close-before-
> tags>
> + </tag>
> + <tag name="td" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tr</req-enclosing-tags>
> + <close-before-tags>td,th,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="th" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <req-enclosing-tags>tr</req-enclosing-tags>
> + <close-before-tags>td,th,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="tbody" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="thead" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="tfoot" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>tr,form</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="col" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>colgroup</fatal-tags>
> + </tag>
> + <tag name="colgroup" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <allowed-children-tags>col</allowed-children-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="caption" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <fatal-tags>table</fatal-tags>
> + <close-before-
> tags>td,th,tr,tbody,thead,tfoot,caption,colgroup</close-before-tags>
> + </tag>
> + <tag name="form" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <forbidden-tags>form</forbidden-tags>
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >
> option
> ,optgroup
> ,textarea
> ,select
> ,fieldset
> ,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="input" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="textarea" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="select" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <allowed-children-tags>option,optgroup</allowed-children-
> tags>
> + <close-before-tags>option,optgroup,select</close-before-tags>
> + </tag>
> + <tag name="option" content="text" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <fatal-tags>select</fatal-tags>
> + <close-before-tags>option</close-before-tags>
> + </tag>
> + <tag name="optgroup" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="true">
> + <fatal-tags>select</fatal-tags>
> + <allowed-children-tags>option</allowed-children-tags>
> + <close-before-tags>optgroup</close-before-tags>
> + </tag>
> + <tag name="button" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-tags>select,optgroup,option</close-before-tags>
> + </tag>
> + <tag name="label" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="fieldset" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="isindex" content="none" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="script" content="all" section="all"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="noscript" content="all" section="all"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="b" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>u,i,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="i" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="u" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,i,tt,sub,sup,big,small,strike,blink,s</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="tt" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,sub,sup,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="sub" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sup,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="sup" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,big,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="big" content="all" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,small,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="small" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,strike,blink,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="strike" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,blink,s</close-inside-copy-after-tags>
> + </tag>
> + <tag name="blink" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,strike,s</close-inside-copy-after-
> tags>
> + </tag>
> + <tag name="marquee" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="s" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false">
> + <close-inside-copy-after-
> tags>b,u,i,tt,sub,sup,big,small,strike,blink</close-inside-copy-
> after-tags>
> + </tag>
> + <tag name="hr" content="none" section="body" deprecated="false"
> unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="font" content="all" section="body" deprecated="true"
> unique="false" ignore-permitted="false"/>
> + <tag name="basefont" content="none" section="body"
> deprecated="true" unique="false" ignore-permitted="false"/>
> + <tag name="center" content="all" section="body"
> deprecated="true" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> + <tag name="comment" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="server" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="iframe" content="all" section="body"
> deprecated="false" unique="false" ignore-permitted="false"/>
> + <tag name="embed" content="none" section="body"
> deprecated="false" unique="false" ignore-permitted="false">
> + <close-before-copy-inside-
> tags>a,bdo,strong,em,q,b,i,u,tt,sub,sup,big,small,strike,s,font</
> close-before-copy-inside-tags>
> + <close-before-
> tags
> >p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml</
> close-before-tags>
> + </tag>
> +</tags>
> \ No newline at end of file
>
> _______________________________________________
> notifications mailing list
> [email protected]
> http://lists.xwiki.org/mailman/listinfo/notifications
Hi Vincent, On Mon, Aug 18, 2008 at 2:59 AM, Vincent Massol <[email protected]> wrote:
Hi Wang,
I have some questions/remarks on the commit below:
1) It's hard to see what you're modifying from the default tag infos (in default.xml). I think a better solution might be to extend DefaultTagProvider and use the constructor accepting an info provider, see http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner HtmlCleaner.html#HtmlCleaner(org.htmlcleaner.ITagInfoProvider) . In this manner we just extend the default and not duplicate it. WDYT? Is this possible? Are you adding tags or redefining default one?
I have seen this DefaultTagProvider, but I don't think it can provide what I want. I want to replace some tags with others. Such like replace <p> in <li> to <span>, replace deprecated tags with others. Like replace <s> to <del>. But the default.xml can define this.
2) The following code is not required:
+ private void removeHead(TagNode node) + { + logger.debug("remove the head tag of the html"); + TagNode head = node.findElementByName("head", true); + head.removeFromTree(); + }
instead you can just use props.setOmitHtmlEnvelope(true); I have tried props.setOmitHtmlEnvelope(true), but there are some errors. If input is <html> <head/> <body> <p>p1</p> <p>p2</p> </body> </html> the output TagNode is not <p>p1</p><p>p2</p> but only <p>p2</p>. So I have to use removeHead() to remove the head tag.
3) Could you explain why we need convertAllAttribute2Lowercase?
In xhtml, all the attributes value should be lowercase. And some attributes value in the conversion result of openoffice is uppercase, like algin="CENTER". I think lowercase will be better. But if xhtmlparser could handler uppercase attributes value, I will remove this method.
4) Could you refactor your code to use the new HTMLCleaner code I have put in xwiki-xml module? I will do it today.
Feel free to provide patches for CleaningFilters. [snip]
-- Thanks Wang Ning
On Aug 18, 2008, at 4:37 AM, Wang Ning wrote:
Hi Vincent,
On Mon, Aug 18, 2008 at 2:59 AM, Vincent Massol <[email protected]> wrote:
Hi Wang,
I have some questions/remarks on the commit below:
1) It's hard to see what you're modifying from the default tag infos (in default.xml). I think a better solution might be to extend DefaultTagProvider and use the constructor accepting an info provider, see http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner HtmlCleaner.html#HtmlCleaner(org.htmlcleaner.ITagInfoProvider) . In this manner we just extend the default and not duplicate it. WDYT? Is this possible? Are you adding tags or redefining default one?
I have seen this DefaultTagProvider, but I don't think it can provide what I want. I want to replace some tags with others.
public class MyProvider extends DefaultTagProvided { public TagInfo getTagInfo(String tagName) { if (tagName.equals("s") { return new TagInfo(....); } else { return super.getTagInfo(tagName) } } } or something like that. I guess it looks better if we have only a few changes to make. If we have a lot then the file solution might be better. In any case make sure you separate and document your changes from the default in default.xml.
Such like replace <p> in <li> to <span>, replace deprecated tags with others. Like replace <s> to <del>. But the default.xml can define this.
2) The following code is not required:
+ private void removeHead(TagNode node) + { + logger.debug("remove the head tag of the html"); + TagNode head = node.findElementByName("head", true); + head.removeFromTree(); + }
instead you can just use props.setOmitHtmlEnvelope(true); I have tried props.setOmitHtmlEnvelope(true), but there are some errors. If input is <html> <head/> <body> <p>p1</p> <p>p2</p> </body> </html> the output TagNode is not <p>p1</p><p>p2</p> but only <p>p2</p>. So I have to use removeHead() to remove the head tag.
htmlcleaner seems quite buggy... Even with setOmitHtmlEnvelope to false it still generate something strange with an extra line between the 2 paragraphs of your example. Do you think you could report an issue in the issue tracker of the htmlcleaner project so that they can fix it in the next release?
3) Could you explain why we need convertAllAttribute2Lowercase?
In xhtml, all the attributes value should be lowercase.
Do you have a link to the XHTML spec for this? I can only find http://www.w3.org/TR/xhtml1/#h-4.2 but this is different. I have only found this http://lists.xml.org/archives/xml-dev/200109/msg00718.html I'd like to know what we gain by transforming in lowercase. Since it's extra effort we need to rationalize it.
And some attributes value in the conversion result of openoffice is uppercase, like algin="CENTER". I think lowercase will be better. But if xhtmlparser could handler uppercase attributes value, I will remove this method.
4) Could you refactor your code to use the new HTMLCleaner code I have put in xwiki-xml module? I will do it today.
cool Thanks -Vincent
Feel free to provide patches for CleaningFilters.
[snip]
-- Thanks Wang Ning _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Aug 18, 2008, at 10:02 AM, Vincent Massol wrote:
On Aug 18, 2008, at 4:37 AM, Wang Ning wrote:
Hi Vincent,
On Mon, Aug 18, 2008 at 2:59 AM, Vincent Massol <[email protected]> wrote:
Hi Wang,
I have some questions/remarks on the commit below:
1) It's hard to see what you're modifying from the default tag infos (in default.xml). I think a better solution might be to extend DefaultTagProvider and use the constructor accepting an info provider, see http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner HtmlCleaner.html#HtmlCleaner(org.htmlcleaner.ITagInfoProvider) . In this manner we just extend the default and not duplicate it. WDYT? Is this possible? Are you adding tags or redefining default one?
I have seen this DefaultTagProvider, but I don't think it can provide what I want. I want to replace some tags with others.
public class MyProvider extends DefaultTagProvided { public TagInfo getTagInfo(String tagName) { if (tagName.equals("s") { return new TagInfo(....); } else { return super.getTagInfo(tagName) } } }
or something like that.
I guess it looks better if we have only a few changes to make. If we have a lot then the file solution might be better. In any case make sure you separate and document your changes from the default in default.xml.
Such like replace <p> in <li> to <span>, replace deprecated tags with others. Like replace <s> to <del>. But the default.xml can define this.
2) The following code is not required:
+ private void removeHead(TagNode node) + { + logger.debug("remove the head tag of the html"); + TagNode head = node.findElementByName("head", true); + head.removeFromTree(); + }
instead you can just use props.setOmitHtmlEnvelope(true); I have tried props.setOmitHtmlEnvelope(true), but there are some errors. If input is <html> <head/> <body> <p>p1</p> <p>p2</p> </body> </html> the output TagNode is not <p>p1</p><p>p2</p> but only <p>p2</p>. So I have to use removeHead() to remove the head tag.
htmlcleaner seems quite buggy... Even with setOmitHtmlEnvelope to false it still generate something strange with an extra line between the 2 paragraphs of your example. Do you think you could report an issue in the issue tracker of the htmlcleaner project so that they can fix it in the next release?
In the meantime would be good if you could submit a patch for our HTMLCleaner to add this new filter with good javadoc explaining why we need it, a reference to the issue URL you'd have created. I'll commit it in the xwiki-xml module. Thanks -Vincent
3) Could you explain why we need convertAllAttribute2Lowercase?
In xhtml, all the attributes value should be lowercase.
Do you have a link to the XHTML spec for this? I can only find http://www.w3.org/TR/xhtml1/#h-4.2 but this is different.
I have only found this http://lists.xml.org/archives/xml-dev/200109/msg00718.html
I'd like to know what we gain by transforming in lowercase. Since it's extra effort we need to rationalize it.
And some attributes value in the conversion result of openoffice is uppercase, like algin="CENTER". I think lowercase will be better. But if xhtmlparser could handler uppercase attributes value, I will remove this method.
4) Could you refactor your code to use the new HTMLCleaner code I have put in xwiki-xml module? I will do it today.
cool
Thanks -Vincent
Feel free to provide patches for CleaningFilters.
[snip]
-- Thanks Wang Ning _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Mon, Aug 18, 2008 at 4:02 PM, Vincent Massol <[email protected]> wrote:
On Aug 18, 2008, at 4:37 AM, Wang Ning wrote:
Hi Vincent,
On Mon, Aug 18, 2008 at 2:59 AM, Vincent Massol <[email protected]> wrote:
Hi Wang,
I have some questions/remarks on the commit below:
1) It's hard to see what you're modifying from the default tag infos (in default.xml). I think a better solution might be to extend DefaultTagProvider and use the constructor accepting an info provider, see http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner HtmlCleaner.html#HtmlCleaner(org.htmlcleaner.ITagInfoProvider) . In this manner we just extend the default and not duplicate it. WDYT? Is this possible? Are you adding tags or redefining default one?
I have seen this DefaultTagProvider, but I don't think it can provide what I want. I want to replace some tags with others.
public class MyProvider extends DefaultTagProvided { public TagInfo getTagInfo(String tagName) { if (tagName.equals("s") { return new TagInfo(....); } else { return super.getTagInfo(tagName) } } }
or something like that.
I guess it looks better if we have only a few changes to make. If we have a lot then the file solution might be better. In any case make sure you separate and document your changes from the default in default.xml.
Such like replace <p> in <li> to <span>, replace deprecated tags with others. Like replace <s> to <del>. But the default.xml can define this.
2) The following code is not required:
+ private void removeHead(TagNode node) + { + logger.debug("remove the head tag of the html"); + TagNode head = node.findElementByName("head", true); + head.removeFromTree(); + }
instead you can just use props.setOmitHtmlEnvelope(true); I have tried props.setOmitHtmlEnvelope(true), but there are some errors. If input is <html> <head/> <body> <p>p1</p> <p>p2</p> </body> </html> the output TagNode is not <p>p1</p><p>p2</p> but only <p>p2</p>. So I have to use removeHead() to remove the head tag.
htmlcleaner seems quite buggy... Even with setOmitHtmlEnvelope to false it still generate something strange with an extra line between the 2 paragraphs of your example. Do you think you could report an issue in the issue tracker of the htmlcleaner project so that they can fix it in the next release?
3) Could you explain why we need convertAllAttribute2Lowercase?
In xhtml, all the attributes value should be lowercase.
Do you have a link to the XHTML spec for this? I can only find http://www.w3.org/TR/xhtml1/#h-4.2 but this is different.
I have only found this http://lists.xml.org/archives/xml-dev/200109/msg00718.html
I'd like to know what we gain by transforming in lowercase. Since it's extra effort we need to rationalize it.
The lowercase of values of attribute in xhtml, I can't find the reference. Maybe it's not necessary, but I think "align="center" is better than align="CENTER". Anyway, I will remove this filter.
And some attributes value in the conversion result of openoffice is uppercase, like algin="CENTER". I think lowercase will be better. But if xhtmlparser could handler uppercase attributes value, I will remove this method.
4) Could you refactor your code to use the new HTMLCleaner code I have put in xwiki-xml module? I will do it today.
cool
Thanks -Vincent
Feel free to provide patches for CleaningFilters.
[snip]
-- Thanks Wang Ning _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thanks Wang Ning
participants (2)
-
Vincent Massol -
Wang Ning