# HG changeset patch
# User Michael Stahl <mst@openoffice.org>
# Date 1285330281 -7200
# Node ID c5985baef1ad3a0882457182b720b59fa8fb24e7
# Parent  2dde3e8f45f8225f427986e93798cfc72fd69f47
rtftok01: add rtfcontrols.xsl, for generating control-handling code

diff --git a/writerfilter/source/rtftok/RTFDestination.hxx b/writerfilter/source/rtftok/RTFDestination.hxx
new file mode 100644
--- /dev/null
+++ b/writerfilter/source/rtftok/RTFDestination.hxx
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_RTF_DESTINATION_HXX
+#define INCLUDED_RTF_DESTINATION_HXX
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <rtftok/RTFScannerHandler.hxx>
+
+
+namespace writerfilter {
+namespace rtftok {
+
+/** Value class with clone method (necessary because Value::Pointer_t=auto_ptr)
+ */
+class RTFValue
+    : public Value
+{
+public:
+    typedef ::boost::shared_ptr<RTFValue> Pointer_t;
+
+    virtual RTFValue * Clone() = 0;
+};
+
+/** Value class for Boolean
+ */
+class RTFValueBool
+    : public RTFValue
+{
+
+public:
+    explicit RTFValueBool(bool const i_Value)
+        : m_Value(i_Value)
+    { }
+    virtual ~RTFValueBool() { }
+    virtual RTFValue * Clone() { return new RTFValueBool(m_Value); }
+
+    virtual int getInt() const
+    {
+        return m_Value ? 1 : 0;
+    }
+    // don't throw exceptions, just return null values
+    virtual ::rtl::OUString getString() const
+    {
+        return ::rtl::OUString();
+    }
+    virtual uno::Any getAny() const
+    {
+        uno::Any ret;
+        ret <<= static_cast<sal_Bool>(m_Value);
+        return ret;
+    }
+    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
+    {
+        return writerfilter::Reference<Properties>::Pointer_t();
+    }
+    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
+    {
+        return writerfilter::Reference<Stream>::Pointer_t();
+    }
+    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
+    {
+        return writerfilter::Reference<BinaryObj>::Pointer_t();
+    }
+    virtual ::std::string toString() const
+    {
+        return ::rtl::OString::valueOf(static_cast<sal_Bool>(m_Value)).getStr();
+    }
+
+private:
+    bool const m_Value;
+};
+
+/** Value class for Integer (32 bit should be enough).
+ */
+class RTFValueInt
+    : public RTFValue
+{
+
+public:
+    explicit RTFValueInt(int const i_Value)
+        : m_Value(i_Value)
+    { }
+    virtual ~RTFValueInt() { }
+    virtual RTFValue * Clone() { return new RTFValueInt(m_Value); }
+
+    virtual int getInt() const
+    {
+        return m_Value;
+    }
+    // don't throw exceptions, just return null values
+    virtual ::rtl::OUString getString() const
+    {
+        return ::rtl::OUString();
+    }
+    virtual uno::Any getAny() const
+    {
+        uno::Any ret;
+        ret <<= static_cast<sal_Int32>(m_Value);
+        return ret;
+    }
+    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
+    {
+        return writerfilter::Reference<Properties>::Pointer_t();
+    }
+    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
+    {
+        return writerfilter::Reference<Stream>::Pointer_t();
+    }
+    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
+    {
+        return writerfilter::Reference<BinaryObj>::Pointer_t();
+    }
+    virtual ::std::string toString() const
+    {
+        return ::rtl::OString::valueOf(m_Value).getStr();
+    }
+
+private:
+    sal_Int32 const m_Value;
+};
+
+/** Value class for String.
+ */
+class RTFValueString
+    : public RTFValue
+{
+
+public:
+    explicit RTFValueString(::rtl::OUString const& rValue)
+        : m_Value(rValue)
+    { }
+    virtual ~RTFValueString() { }
+    virtual RTFValue * Clone() { return new RTFValueString(m_Value); }
+
+    // don't throw exceptions, just return null values
+    virtual int getInt() const
+    {
+        return 0;
+    }
+    virtual ::rtl::OUString getString() const
+    {
+        return m_Value;
+    }
+    virtual uno::Any getAny() const
+    {
+        uno::Any ret;
+        ret <<= m_Value;
+        return ret;
+    }
+    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
+    {
+        return writerfilter::Reference<Properties>::Pointer_t();
+    }
+    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
+    {
+        return writerfilter::Reference<Stream>::Pointer_t();
+    }
+    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
+    {
+        return writerfilter::Reference<BinaryObj>::Pointer_t();
+    }
+    virtual ::std::string toString() const
+    {
+        ::std::string mk("\"");
+        return mk
+            + ::rtl::OUStringToOString(m_Value, RTL_TEXTENCODING_UTF8).getStr()
+            +  mk;
+    }
+
+private:
+    ::rtl::OUString const m_Value;
+};
+
+
+/** what is this Sprm thing and why do we need it?
+ */
+class RTFSprm
+    : public Sprm
+{
+
+public:
+    virtual sal_uInt32 getId() const
+    {
+        return m_Id;
+    }
+
+    virtual Value::Pointer_t getValue()
+    {
+        return Value::Pointer_t(m_pValue->Clone());
+    }
+
+    virtual writerfilter::Reference<Properties>::Pointer_t getProps()
+    {
+        return (m_pValue.get())
+            ? m_pValue->getProperties()
+            : writerfilter::Reference<Properties>::Pointer_t();
+    }
+    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
+    {
+        return (m_pValue.get())
+            ? m_pValue->getStream()
+            : writerfilter::Reference<Stream>::Pointer_t();
+    }
+    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
+    {
+        return (m_pValue.get())
+            ? m_pValue->getBinary()
+            : writerfilter::Reference<BinaryObj>::Pointer_t();
+    }
+    virtual Kind getKind()
+    {
+        // FIXME this doesn't seem to be called anyway, so we don't worry about the fact that the WW8 and OOXML Id<->Kind mapping are different...
+//        return m_Kind;
+        return Sprm::UNKNOWN;
+    }
+
+    virtual ::std::string getName() const
+    {
+        //FIXME this isn't called by the domainmapper...
+//        return m_Name;
+        return "";
+    }
+
+    virtual ::std::string toString() const
+    {
+        return ::std::string("(")
+            + getName()
+            + ::std::string(", ")
+            + ((m_pValue.get()) ? m_pValue->toString() : ::std::string("null"))
+            + ::std::string(")");
+    }
+
+    explicit RTFSprm(Id const Id, RTFValue::Pointer_t const& pValue //,
+            /*Kind const kind,*/ /*::std::string const name*/)
+        : m_Id(Id)
+        , m_pValue(pValue)
+#if 0
+        , m_Kind(kind)
+        , m_Name(name)
+#endif
+    {
+    }
+
+private:
+    Id const m_Id;
+    RTFValue::Pointer_t const m_pValue;
+#if 0
+    Kind const m_Kind;
+    ::std::string const m_Name; // ???
+#endif
+};
+
+
+class RTFScannerHandlerImpl;
+
+/** Base class for destinations.
+ */
+class RTFDestination
+{
+public:
+    typedef ::boost::shared_ptr<RTFDestination> Pointer_t;
+    explicit RTFDestination(RTFScannerHandlerImpl & rHandler)
+        : m_rHandler(rHandler)
+    { }
+    virtual ~RTFDestination() { }
+
+    virtual Pointer_t dest(Token_t const token, char const*const /*value*/)
+    {
+fprintf(stderr, "RTFDestination::dest: creating default context for \\%s\n", TokenToId(token));
+        return Pointer_t(new RTFDestination(m_rHandler));
+    }
+    virtual void ctrl(Token_t const token, char const*const /*value*/)
+    {
+fprintf(stderr, "RTFDestination::ctrl: ignoring control: \\%s\n", TokenToId(token));
+    }
+    virtual void lbrace()
+    {
+    }
+    virtual void rbrace()
+    {
+    }
+    virtual void HandleString (::rtl::OStringBuffer  & /*rBuf*/)
+    {
+fprintf(stderr, "RTFDestination::HandleString: ignoring string\n");
+    }
+    virtual void HandleStringU(::rtl::OUStringBuffer & /*rBuf*/)
+    {
+fprintf(stderr, "RTFDestination::HandleStringU: ignoring stringU\n");
+    }
+
+    void SetAttribute(Id const id, RTFValue::Pointer_t const& pValue);
+    void SetSprm(Id const id, RTFValue::Pointer_t const& pValue);
+
+protected:
+    RTFScannerHandlerImpl & GetHandler() { return m_rHandler; }
+private:
+    RTFScannerHandlerImpl & m_rHandler;
+};
+
+} // namespace writerfilter
+} // namespace rtftok
+
+#endif // INCLUDED_RTF_DESTINATION_HXX
+
diff --git a/writerfilter/source/rtftok/RTFDocumentImpl.cxx b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
--- a/writerfilter/source/rtftok/RTFDocumentImpl.cxx
+++ b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
@@ -44,6 +44,8 @@
 #include <rtftok/RTFScannerHandler.hxx>
 #include <rtftok/RTFInputSource.hxx>
 
+#include <RTFDestination.hxx>
+
 
 using namespace ::com::sun::star;
 
@@ -56,104 +58,11 @@
     return *TagLogger::getInstance("DEBUG");
 }
 
+// implementation is generated by rtftokens.xsl
+bool handleControl(RTFDestination & rDestination,
+        Token_t const token, char const*const value);
 
 
-/** Value class for Integer (32 bit should be enough).
- */
-class RTFValueInt
-    : public Value
-{
-
-public:
-    explicit RTFValueInt(int const i_Value)
-        : m_Value(i_Value)
-    { }
-    virtual ~RTFValueInt() { }
-    virtual int getInt() const
-    {
-        return m_Value;
-    }
-    // don't throw exceptions, just return null values
-    virtual ::rtl::OUString getString() const
-    {
-        return ::rtl::OUString();
-    }
-    virtual uno::Any getAny() const
-    {
-        uno::Any ret;
-        ret <<= static_cast<sal_Int32>(m_Value);
-        return ret;
-    }
-    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
-    {
-        return writerfilter::Reference<Properties>::Pointer_t();
-    }
-    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
-    {
-        return writerfilter::Reference<Stream>::Pointer_t();
-    }
-    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
-    {
-        return writerfilter::Reference<BinaryObj>::Pointer_t();
-    }
-    virtual ::std::string toString() const
-    {
-        return ::rtl::OString::valueOf(m_Value).getStr();
-    }
-
-private:
-    sal_Int32 const m_Value;
-};
-
-/** Value class for String.
- */
-class RTFValueString
-    : public Value
-{
-
-public:
-    explicit RTFValueString(::rtl::OUString const& rValue)
-        : m_Value(rValue)
-    { }
-    virtual ~RTFValueString() { }
-    // don't throw exceptions, just return null values
-    virtual int getInt() const
-    {
-        return 0;
-    }
-    virtual ::rtl::OUString getString() const
-    {
-        return m_Value;
-    }
-    virtual uno::Any getAny() const
-    {
-        uno::Any ret;
-        ret <<= m_Value;
-        return ret;
-    }
-    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
-    {
-        return writerfilter::Reference<Properties>::Pointer_t();
-    }
-    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
-    {
-        return writerfilter::Reference<Stream>::Pointer_t();
-    }
-    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
-    {
-        return writerfilter::Reference<BinaryObj>::Pointer_t();
-    }
-    virtual ::std::string toString() const
-    {
-        ::std::string mk("\"");
-        return mk
-            + ::rtl::OUStringToOString(m_Value, RTL_TEXTENCODING_UTF8).getStr()
-            +  mk;
-    }
-
-private:
-    ::rtl::OUString const m_Value;
-};
 
 
 /** Implementation of Reference<Properties>.
@@ -163,10 +72,12 @@
 {
 
 public:
-    typedef ::std::map<Id, ::boost::shared_ptr<Value> > Attributes_t;
+    typedef ::std::map<Id, RTFValue::Pointer_t > Attributes_t;
 
-    explicit RTFRefProperties(Attributes_t const& rAttributes)
+    explicit RTFRefProperties(Attributes_t const& rAttributes,
+            Attributes_t const& rSprms)
         : m_Attributes(rAttributes)
+        , m_Sprms(rSprms)
     { }
     virtual ~RTFRefProperties() { }
     virtual void resolve(Properties & rHandler)
@@ -177,6 +88,13 @@
 fprintf(stderr, "RTFRefProperties::resolve: %ld -> %s\n", iter->first, iter->second->toString().c_str());
             rHandler.attribute(iter->first, *iter->second.get());
         }
+        for (Attributes_t::const_iterator iter = m_Sprms.begin();
+                iter != m_Sprms.end(); ++iter)
+        {
+fprintf(stderr, "RTFRefProperties::resolve: sprm: %ld -> %s\n", iter->first, iter->second->toString().c_str());
+            RTFSprm sprm(iter->first, iter->second);
+            rHandler.sprm(sprm);
+        }
     }
     ::std::string getType() const
     {
@@ -185,6 +103,7 @@
 
 private:
     Attributes_t const m_Attributes;
+    Attributes_t const m_Sprms;
 };
 
 
@@ -246,48 +165,6 @@
 };
 
 
-class RTFScannerHandlerImpl;
-
-/** Base class for destinations.
- */
-class RTFDestination
-{
-public:
-    typedef ::boost::shared_ptr<RTFDestination> Pointer_t;
-    explicit RTFDestination(RTFScannerHandlerImpl & rHandler)
-        : m_rHandler(rHandler)
-    { }
-    virtual ~RTFDestination() { }
-
-    virtual Pointer_t dest(Token_t const token, char const*const /*value*/)
-    {
-fprintf(stderr, "RTFDestination::dest: creating default context for \\%s\n", TokenToId(token));
-        return Pointer_t(new RTFDestination(m_rHandler));
-    }
-    virtual void ctrl(Token_t const token, char const*const /*value*/)
-    {
-fprintf(stderr, "RTFDestination::ctrl: ignoring control: \\%s\n", TokenToId(token));
-    }
-    virtual void lbrace()
-    {
-    }
-    virtual void rbrace()
-    {
-    }
-    virtual void HandleString (::rtl::OStringBuffer  & /*rBuf*/)
-    {
-fprintf(stderr, "RTFDestination::HandleString: ignoring string\n");
-    }
-    virtual void HandleStringU(::rtl::OUStringBuffer & /*rBuf*/)
-    {
-fprintf(stderr, "RTFDestination::HandleStringU: ignoring stringU\n");
-    }
-
-protected:
-    RTFScannerHandlerImpl & GetHandler() { return m_rHandler; }
-private:
-    RTFScannerHandlerImpl & m_rHandler;
-};
 
 static RTFDestination::Pointer_t
 createRootDestination(RTFScannerHandlerImpl &);
@@ -303,13 +180,16 @@
     explicit RTFGroup()
         : m_TextEncoding(osl_getThreadTextEncoding())
         , m_UnicodeCharacters(1)
+#if 0
         , m_CharacterProperties()
+#endif
     { }
 
     // general properties
     rtl_TextEncoding m_TextEncoding;
     unsigned int m_UnicodeCharacters;
 
+#if 0
     // character properties
     class CharacterProperties
     {
@@ -332,6 +212,17 @@
     void Reset() {
         ResetCharacterProperties();
     }
+#else
+    typedef ::std::map<Id, RTFValue::Pointer_t > Attributes_t;
+
+    Attributes_t m_Attributes;
+    Attributes_t m_Sprms;
+
+    void Reset() {
+        m_Attributes.clear();
+        m_Sprms.clear();
+    }
+#endif
 };
 
 
@@ -513,6 +404,12 @@
             OSL_TRACE("RTFScannerHandlerImpl: invalid font: %d", i);
         }
     }
+    void SetAttribute(Id const id, RTFValue::Pointer_t const& pValue) {
+        GetCurrentGroup().m_Attributes[id] = pValue;
+    }
+    void SetSprm(Id const id, RTFValue::Pointer_t const& pValue) {
+        GetCurrentGroup().m_Sprms[id] = pValue;
+    }
 
 private:
     void checkStrings()
@@ -536,7 +433,7 @@
     }
     Stream & m_rStream;
     /* use 2 buffers here, because it's not possible to convert 8-bit char
-       to unicode individually (could be mult-byte enconding!) */
+       to unicode individually (could be multi-byte encoding!) */
     ::rtl::OStringBuffer m_String;
     ::rtl::OUStringBuffer m_UString;
     unsigned int m_NegativeCharacters;
@@ -546,6 +443,18 @@
 };
 
 
+void
+RTFDestination::SetAttribute(Id const id, RTFValue::Pointer_t const& pValue)
+{
+    GetHandler().SetAttribute(id, pValue);
+}
+
+void
+RTFDestination::SetSprm(Id const id, RTFValue::Pointer_t const& pValue)
+{
+    GetHandler().SetSprm(id, pValue);
+}
+
 
 static sal_uInt32
 lcl_CharsetToCodePage(sal_Int32 const charset)
@@ -717,8 +626,9 @@
                     attrmap.insert(::std::make_pair(NS_rtf::LN_XSZFFN, pName));
                 }
 
+                RTFRefProperties::Attributes_t dummy;
                 writerfilter::Reference<Properties>::Pointer_t const pProperties(
-                        new RTFRefProperties(attrmap) );
+                        new RTFRefProperties(attrmap, dummy) );
                 m_Properties.insert(
                         ::std::make_pair(m_Entry.m_Index, pProperties));
                 m_FontTable.insert(
@@ -846,6 +756,7 @@
             break;
             default:
             {
+                if (!handleControl(*this, token, value))
 fprintf(stderr, "RTFDestinationRTF::ctrl: ignoring control: \\%s\n", TokenToId(token));
             }
             break;
@@ -863,18 +774,28 @@
     {
         ::rtl::OUString const s(::rtl::OStringToOUString(
                     rBuf.makeStringAndClear(), GetHandler().GetEncoding()));
-        GetHandler().GetStream().utext(
+        SendString(
             reinterpret_cast<sal_uInt8 const*>(s.getStr()),
             s.getLength());
     }
     virtual void HandleStringU(::rtl::OUStringBuffer & rBuf)
     {
-        GetHandler().GetStream().utext(
+        SendString(
             reinterpret_cast<sal_uInt8 const*>(rBuf.getStr()),
             rBuf.getLength());
     }
 
 private:
+    void SendString(sal_uInt8 const*const pStr, sal_Int32 const n)
+    {
+        GetHandler().GetStream().startCharacterGroup();
+        writerfilter::Reference<Properties>::Pointer_t const pProperties(
+            new RTFRefProperties(GetHandler().GetCurrentGroup().m_Attributes,
+                    GetHandler().GetCurrentGroup().m_Sprms) );
+        GetHandler().GetStream().props(pProperties);
+        GetHandler().GetStream().utext(pStr, n);
+        GetHandler().GetStream().endCharacterGroup();
+    }
 };
 
 
diff --git a/writerfilter/source/rtftok/makefile.mk b/writerfilter/source/rtftok/makefile.mk
--- a/writerfilter/source/rtftok/makefile.mk
+++ b/writerfilter/source/rtftok/makefile.mk
@@ -49,6 +49,7 @@
 	$(SLO)$/RTFScanner.obj \
 	$(SLO)$/RTFParseException.obj \
 	$(SLO)$/RTFDocumentImpl.obj \
+	$(SLO)$/RTFControls.obj \
 
 
 SHL1TARGET=$(TARGET)
@@ -92,11 +93,13 @@
 RTFTOKENSHXX=$(RTFHXXOUTDIR)/RTFTokens.hxx
 RTFGPERFFASTTOKENHXX=$(RTFHXXOUTDIR)/gperffasttoken.hxx
 RTFTOKENTOIDCXX=$(MISC)/RTFTokenToId.cxx
+RTFCONTROLSCXX=$(MISC)/RTFControls.cxx
 
 RTFTOKENXSL=rtftoken.xsl
 RTFTOKENHEADERXSL=rtftokenheader.xsl
 RTFGPERFFASTTOKENXSL=rtfgperf.xsl
 RTFTOKENTOIDXSL=rtftokentoid.xsl
+RTFCONTROLSXSL=rtfcontrols.xsl
 
 MODELPROCESSED=rtfmodel.xml
 
@@ -108,6 +111,7 @@
     $(GENERATEDHEADERS) \
 	$(RTFTOKENTOIDCXX) \
     $(RTFSCANNERCXX) \
+    $(RTFCONTROLSCXX) \
 
 $(RTFHXXOUTDIRCREATED):
 	$(MKDIRHIER) $(RTFHXXOUTDIR)
@@ -132,6 +136,10 @@
 	@echo "Making:   " $(@:f)
 	$(COMMAND_ECHO)$(XSLTPROC) $(RTFTOKENTOIDXSL) $(RTFTOKENS) > $@
 
+$(RTFCONTROLSCXX): $(RTFCONTROLSXSL) $(RTFTOKENS) $(MODELPROCESSED)
+	@echo "Making:   " $(@:f)
+	$(COMMAND_ECHO)$(XSLTPROC) $(RTFCONTROLSXSL) $(MODELPROCESSED) > $@
+
 $(RTFSCANNERCXX): RTFScanner.lex
 	/usr/bin/flex -o$@ RTFScanner.lex
 
@@ -139,6 +147,8 @@
 
 $(SLO)/RTFTokenToId.obj: $(RTFTOKENTOIDCXX)
 
+$(SLO)/RTFControls.obj: $(RTFCONTROLSCXX)
+
 $(SLOFILES): $(GENERATEDHEADERS)
 
 
diff --git a/writerfilter/source/rtftok/rtfcontrols.xsl b/writerfilter/source/rtftok/rtfcontrols.xsl
new file mode 100644
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfcontrols.xsl
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+   DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+   Copyright 2000, 2010 Oracle and/or its affiliates.
+
+   OpenOffice.org - a multi-platform office productivity suite
+
+   This file is part of OpenOffice.org.
+
+   OpenOffice.org is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License version 3
+   only, as published by the Free Software Foundation.
+
+   OpenOffice.org 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 version 3 for more details
+   (a copy is included in the LICENSE file that accompanied this code).
+
+   You should have received a copy of the GNU Lesser General Public License
+   version 3 along with OpenOffice.org.  If not, see
+   <http://www.openoffice.org/license.html>
+   for a copy of the LGPLv3 License.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="text"/>
+
+  <xsl:template match="*">
+  </xsl:template>
+
+  <xsl:key name="names" match="//control|//destination|//flag|//toggle|//value|//symbol" use="@name"/>
+
+  <xsl:template match="/">
+
+    <!-- header -->
+<xsl:text>
+/*
+    THIS FILE IS GENERATED! DO NOT EDIT!
+*/
+
+#include &lt;string&gt;
+
+#include &lt;sal/types.h&gt;
+
+#include &lt;doctok/resourceids.hxx&gt;
+#include &lt;doctok/sprmids.hxx&gt;
+
+#include &lt;rtftok/RTFTokens.hxx&gt;
+
+#include &lt;RTFDestination.hxx&gt;
+
+
+namespace writerfilter {
+namespace rtftok {
+
+
+bool handleControl(RTFDestination &amp; rDestination,
+        Token_t const token, char const*const value)
+{
+    OSL_ASSERT(token != RTF_TOKENS_END);
+    OSL_ASSERT(value);
+    switch (token)
+    {
+</xsl:text>
+
+    <!-- stuff -->
+    <xsl:for-each select="/out/charprops/ref">
+      <xsl:variable name="name">
+          <xsl:value-of select="@name"/>
+      </xsl:variable>
+      <xsl:variable name="type">
+          <xsl:value-of select="name(key('names', @name))" />
+      </xsl:variable>
+      <xsl:variable name="token">
+        <xsl:choose>
+            <xsl:when test="starts-with(@tokenid, 'sprm')">
+              <xsl:text>NS_sprm::LN_</xsl:text>
+              <xsl:value-of select="substring(@tokenid, 6)"/>
+            </xsl:when>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:text>case RTF_</xsl:text>
+      <xsl:value-of select="@name"/>
+      <xsl:text>:&#xA;</xsl:text>
+      <xsl:text>{&#xA;</xsl:text>
+      <xsl:choose>
+        <xsl:when test="$type=flag">
+        </xsl:when>
+        <xsl:when test="$type='toggle'">
+          <xsl:text>sal_Int32 const n( ('\0' == *value) ? 1 : ::rtl::OString(value).toInt32() );&#xA;</xsl:text>
+          <xsl:text>RTFValue::Pointer_t const pValue(new RTFValueBool(0 != n));&#xA;</xsl:text>
+        </xsl:when>
+        <xsl:when test="$type='value'">
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>ERROR: type is:</xsl:text>
+          <xsl:value-of select="$type"/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:choose>
+        <xsl:when test="starts-with(@tokenid, 'sprm')">
+          <xsl:text>rDestination.SetSprm(</xsl:text>
+          <xsl:value-of select="$token"/>
+          <xsl:text>, pValue);&#xA;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>rDestination.SetAttribute(</xsl:text>
+          <xsl:value-of select="$token"/>
+          <xsl:text>, pValue);&#xA;</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:text>return true;&#xA;</xsl:text>
+      <xsl:text>}&#xA;</xsl:text>
+      <xsl:text>break;&#xA;</xsl:text>
+    </xsl:for-each>
+
+    <!-- footer -->
+<xsl:text>
+    }
+    return false;
+}
+
+
+} } // namespace writerfilter::rtftok
+
+</xsl:text>
+
+  </xsl:template>
+
+</xsl:stylesheet>
