<commit_before>/**
 * Copyright (C) 2012 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.processor.converter

import org.orbeon.oxf.pipeline.api.{XMLReceiver, PipelineContext}
import org.orbeon.oxf.processor.impl.CacheableTransformerOutputImpl
import org.orbeon.oxf.processor.{ProcessorInputOutputInfo, ProcessorImpl}
import org.orbeon.oxf.xml.ForwardingXMLReceiver
import org.orbeon.oxf.xml.XMLConstants.{XHTML_NAMESPACE_URI ⇒ HtmlURI}
import org.xml.sax.Attributes
import org.xml.sax.helpers.AttributesImpl

// Perform the following transformation on the input document:
//
// - remove all elements not in the XHTML namespace
// - remove all attributes in a namespace
// - remove the prefix of all XHTML elements
// - remove all other namespace information on elements
// - for XHTML, if the root element of the document is "{http://www.w3.org/1999/xhtml}html"
//   - add the XHTML namespace as default namespace on the root element
//   - all elements in the document are in the XHTML namespace
// - otherwise (including HTML as well as XHTML fragments)
//   - don't output any namespace declaration
//   - all elements in the document are in no namespace
//
class PlainHTMLConverter  extends Converter("")
class PlainXHTMLConverter extends Converter(HtmlURI)

abstract class Converter(targetURI: String) extends ProcessorImpl {

    self ⇒

    addInputInfo(new ProcessorInputOutputInfo(ProcessorImpl.INPUT_DATA))
    addOutputInfo(new ProcessorInputOutputInfo(ProcessorImpl.OUTPUT_DATA))

    override def createOutput(outputName: String) =
        addOutput(outputName, new CacheableTransformerOutputImpl(self, outputName) {
            def readImpl(pipelineContext: PipelineContext, xmlReceiver: XMLReceiver): Unit = {

                readInputAsSAX(pipelineContext, ProcessorImpl.INPUT_DATA, new ForwardingXMLReceiver(xmlReceiver) {

                    var level = 0
                    var inXHTMLNamespace = false

                    override def startElement(uri: String, localname: String, qName: String, attributes: Attributes) = {

                        // Only output the top-level namespace if the element is "{http://www.w3.org/1999/xhtml}html",
                        // following http://www.w3.org/TR/xslt-xquery-serialization/#xhtml-output: "The serializer
                        // SHOULD output namespace declarations in a way that is consistent with the requirements of the
                        // XHTML DTD if this is possible".
                        if (level == 0 && targetURI == HtmlURI && uri == HtmlURI && localname == "html") {
                            inXHTMLNamespace = true<commit_msg>Revert outputting XHTML fragments in no namespace<commit_after>/**
 * Copyright (C) 2012 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.processor.converter

import org.orbeon.oxf.pipeline.api.{XMLReceiver, PipelineContext}
import org.orbeon.oxf.processor.impl.CacheableTransformerOutputImpl
import org.orbeon.oxf.processor.{ProcessorInputOutputInfo, ProcessorImpl}
import org.orbeon.oxf.xml.ForwardingXMLReceiver
import org.orbeon.oxf.xml.XMLConstants.{XHTML_NAMESPACE_URI ⇒ HtmlURI}
import org.xml.sax.Attributes
import org.xml.sax.helpers.AttributesImpl

// Perform the following transformation on the input document:
//
// - remove all elements not in the XHTML namespace
// - remove all attributes in a namespace
// - remove the prefix of all XHTML elements
// - remove all other namespace information on elements
// - for XHTML
//   - add the XHTML namespace as default namespace on the root element
//   - all elements in the document are in the XHTML namespace
// - otherwise
//   - don't output any namespace declaration
//   - all elements in the document are in no namespace
//
class PlainHTMLConverter  extends Converter("")
class PlainXHTMLConverter extends Converter(HtmlURI)

abstract class Converter(targetURI: String) extends ProcessorImpl {

    self ⇒

    addInputInfo(new ProcessorInputOutputInfo(ProcessorImpl.INPUT_DATA))
    addOutputInfo(new ProcessorInputOutputInfo(ProcessorImpl.OUTPUT_DATA))

    override def createOutput(outputName: String) =
        addOutput(outputName, new CacheableTransformerOutputImpl(self, outputName) {
            def readImpl(pipelineContext: PipelineContext, xmlReceiver: XMLReceiver): Unit = {

                readInputAsSAX(pipelineContext, ProcessorImpl.INPUT_DATA, new ForwardingXMLReceiver(xmlReceiver) {

                    var level = 0
                    var inXHTMLNamespace = false

                    override def startElement(uri: String, localname: String, qName: String, attributes: Attributes) = {

                        // http://www.w3.org/TR/xslt-xquery-serialization/#xhtml-output: "The serializer SHOULD output
                        // namespace declarations in a way that is consistent with the requirements of the XHTML DTD if
                        // this is possible". We tried to output the document in the XHTML namespace only if the root
                        // element is "{http://www.w3.org/1999/xhtml}html", however the issue then is that in the case
                        // of a fragment, the resulting document is not in the XHTML namespace and the XHTML serializer
                        // is unable to output elements such as <br />. So we have reverted this change and when the
                        // HTML namespace is specified we now always output the document in the XHTML namespace.
                        if (level == 0 && targetURI == HtmlURI) {
                            inXHTMLNamespace = true
{'fraction_non_alphanumeric': 0.07339857651245552, 'fraction_numerical': 0.004893238434163701, 'mean_word_length': 3.031679617453676, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 7, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6962260', 'n_tokens_mistral': 1763, 'n_tokens_neox': 1697, 'n_words': 661}