[gnome-doc-utils] Adding xml2po mode for Mallard documents



commit bd021e35cec1db931a24afc53f61ab74d7e3d4c5
Author: Shaun McCance <shaunm gnome org>
Date:   Mon Jul 27 20:50:07 2009 -0500

    Adding xml2po mode for Mallard documents
    
    This isn't entirely complete, but it's better than the default
    behavior.  I had to modify xml2po some for this mode, because
    you can't determine whether a node is "final" based on its name
    alone; you need context.

 tools/gnome-doc-utils.make |   13 ++--
 xml2po/modes/Makefile.am   |    2 +-
 xml2po/modes/mallard.py    |  134 +++++++++++++++++++++++++++++++++++++++++
 xml2po/tests/mallard.xml   |  142 ++++++++++++++++++++++++++++++++++++++++++++
 xml2po/tests/test.py       |    1 +
 xml2po/xml2po.py           |    2 +
 6 files changed, 287 insertions(+), 7 deletions(-)
---
diff --git a/tools/gnome-doc-utils.make b/tools/gnome-doc-utils.make
index ecbd4ac..2df897c 100644
--- a/tools/gnome-doc-utils.make
+++ b/tools/gnome-doc-utils.make
@@ -131,6 +131,7 @@ _DOC_ABS_SRCDIR = @abs_srcdir@
 ## Variables for Bootstrapping
 
 _xml2po ?= `which xml2po`
+_xml2po_mode = $(if $(DOC_ID),mallard,docbook)
 
 _db2html ?= `$(PKG_CONFIG) --variable db2html gnome-doc-utils`
 _db2omf  ?= `$(PKG_CONFIG) --variable db2omf gnome-doc-utils`
@@ -319,16 +320,16 @@ $(_DOC_POFILES):
 	done; \
 	if ! test -f $@; then \
 	  echo "(cd $(dir $@) && \
-	    $(_xml2po) -e $$docs > $(notdir $@).tmp && \
+	    $(_xml2po) -m $(_xml2po_mode) -e $$docs > $(notdir $@).tmp && \
 	    cp $(notdir $@).tmp $(notdir $@) && rm -f $(notdir $@).tmp)"; \
 	  (cd $(dir $@) && \
-	    $(_xml2po) -e $$docs > $(notdir $@).tmp && \
+	    $(_xml2po) -m $(_xml2po_mode) -e $$docs > $(notdir $@).tmp && \
 	    cp $(notdir $@).tmp $(notdir $@) && rm -f $(notdir $@).tmp); \
 	else \
 	  echo "(cd $(dir $@) && \
-	    $(_xml2po) -e -u $(notdir $@) $$docs)"; \
+	    $(_xml2po) -m $(_xml2po_mode) -e -u $(notdir $@) $$docs)"; \
 	  (cd $(dir $@) && \
-	    $(_xml2po) -e -u $(notdir $@) $$docs); \
+	    $(_xml2po) -m $(_xml2po_mode) -e -u $(notdir $@) $$docs); \
 	fi
 
 # FIXME: fix the dependancy
@@ -340,7 +341,7 @@ $(_DOC_LC_DOCS) : $(_DOC_C_DOCS)
 	po="$(dir $@)$(patsubst %/$(notdir $@),%,$@).po"; \
 	if [ -f "$${po}" ]; then po="../$${po}"; else po="$(_DOC_ABS_SRCDIR)/$${po}"; fi; \
 	(cd $(dir $@) && \
-	  $(_xml2po) -e -p "$${po}" \
+	  $(_xml2po) -m $(_xml2po_mode) -e -p "$${po}" \
 	    "$${d}C/$(notdir $@)" > $(notdir $@).tmp && \
 	    cp $(notdir $@).tmp $(notdir $@) && rm -f $(notdir $@).tmp)
 
@@ -350,7 +351,7 @@ _DOC_POT = $(if $(DOC_MODULE),$(DOC_MODULE).pot)
 .PHONY: pot
 pot: $(_DOC_POT)
 $(_DOC_POT): $(_DOC_C_DOCS_NOENT)
-	$(_xml2po) -e -o $@ $^
+	$(_xml2po) -m $(_xml2po_mode) -e -o $@ $^
 
 
 ################################################################################
diff --git a/xml2po/modes/Makefile.am b/xml2po/modes/Makefile.am
index f9bc720..82cd88a 100644
--- a/xml2po/modes/Makefile.am
+++ b/xml2po/modes/Makefile.am
@@ -1,4 +1,4 @@
 commondir = $(pythondir)/xml2po
-common_DATA = basic.py docbook.py gs.py ubuntu.py xhtml.py
+common_DATA = basic.py docbook.py gs.py mallard.py ubuntu.py xhtml.py
 
 EXTRA_DIST = $(common_DATA)
diff --git a/xml2po/modes/mallard.py b/xml2po/modes/mallard.py
new file mode 100644
index 0000000..2dac38a
--- /dev/null
+++ b/xml2po/modes/mallard.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2004, 2005, 2006 Danilo Segan <danilo gnome org>.
+# Copyright (c) 2009 Shaun McCance <shaunm gnome org>
+#
+# This file is part of xml2po.
+#
+# xml2po is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# xml2po 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with xml2po; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+# This implements special instructions for handling DocBook XML documents
+# in a better way.
+#
+#  This means:
+#   â?? better handling of nested complicated tags (i.e. definitions of
+#     ignored-tags and final-tags)
+#   â?? support for merging translator-credits back into DocBook articles
+#   â?? support for setting a language
+#
+
+import re
+import libxml2
+import os
+import sys
+try:
+    # Hashlib is new in Python 2.5
+    from hashlib import md5 as md5_new
+except ImportError:
+    from md5 import new as md5_new
+
+from basic import basicXmlMode
+
+class mallardXmlMode(basicXmlMode):
+    """Class for special handling of Mallard document types."""
+    def __init__(self):
+        pass
+
+    def isBlockContext(self, node):
+        if node.type == 'element' and node.parent.type == 'element':
+            if node.parent.name in ('section', 'example', 'comment', 'figure',
+                                    'listing', 'note', 'quote', 'synopsis'):
+                return True
+            elif node.parent.name == 'media':
+                return self.isBlockContext(node.parent)
+        return False
+
+    def isFinalNode(self, node):
+        if node.type == 'element':
+            # Always block
+            if node.name in ('p', 'screen', 'title', 'desc', 'cite', 'item'):
+                return True
+            # Always inline
+            elif node.name in ('app', 'cmd', 'em', 'file', 'gui', 'guiseq', 'input',
+                               'key', 'keyseq', 'output', 'span', 'sys', 'var'):
+                return False
+            # Block or inline
+            elif node.name in ('code', 'media'):
+                return self.isBlockContext(node)
+            # Inline or info
+            elif node.name == 'link':
+                return node.parent.name == 'info'
+        return False
+
+    def getIgnoredTags(self):
+        "Returns array of tags to be ignored."
+        return []
+
+    def getFinalTags(self):
+        "Returns array of tags to be considered 'final'."
+        return []
+
+    def getSpacePreserveTags(self):
+        "Returns array of tags in which spaces are to be preserved."
+        return ['code', 'screen']
+
+    def getStringForTranslators(self):
+        """Returns string which will be used to credit translators."""
+        return "translator-credits"
+
+    def getCommentForTranslators(self):
+        """Returns a comment to be added next to string for crediting translators."""
+        return """Put one translator per line, in the form of NAME <EMAIL>, YEAR1, YEAR2"""
+
+    def _md5_for_file(self, filename):
+        hash = md5_new()
+        input = open(filename, "rb")
+        read = input.read(4096)
+        while read:
+            hash.update(read)
+            read = input.read(4096)
+        input.close()
+        return hash.hexdigest()
+
+    def _output_images(self, node, msg):
+        if node and node.type=='element' and node.name=='media':
+            attr = node.prop("src")
+            if attr:
+                dir = os.path.dirname(msg.filename)
+                fullpath = os.path.join(dir, attr)
+                if os.path.exists(fullpath):
+                    hash = self._md5_for_file(fullpath)
+                else:
+                    hash = "THIS FILE DOESN'T EXIST"
+                    print >>sys.stderr, "Warning: image file '%s' not found." % fullpath
+                    
+                msg.outputMessage("@@image: '%s'; md5=%s" % (attr, hash), node.lineNo(),
+                                  "When image changes, this message will be marked fuzzy or untranslated for you.\n"+
+                                  "It doesn't matter what you translate it to: it's not used at all.")
+        if node and node.children:
+            child = node.children
+            while child:
+                self._output_images(child,msg)
+                child = child.next
+
+
+    def preProcessXml(self, doc, msg):
+        """Add additional messages of interest here."""
+        root = doc.getRootElement()
+        self._output_images(root,msg)
+
+    def postProcessXmlTranslation(self, doc, language, translators):
+        # FIXME: add translator credits
+        return
diff --git a/xml2po/tests/mallard.xml b/xml2po/tests/mallard.xml
new file mode 100644
index 0000000..9e66aab
--- /dev/null
+++ b/xml2po/tests/mallard.xml
@@ -0,0 +1,142 @@
+<page xmlns="http://projectmallard.org/1.0/";
+      type="guide"
+      id="index">
+
+<info>
+  <copyright>
+    <year>2009</year>
+    <name>Drake Mallard</name>
+  </copyright>
+
+  <credit type="author">Drake Mallard</credit>
+
+  <link type="topic" xref="drake"/>
+
+  <title type="link">Drake the Mallard</title>
+</info>
+
+<title>Drake Mallard</title>
+
+<p>This is a paragraph with <app>application</app>, <cmd>command</cmd>, <code>code</code>,
+<em>emphasis</em>, <file>file name</file>, <gui>interface element</gui>, <input>user input</input>,
+<key>keyboard key</key>, <link xref="drake">link</link>, <output>computer output</output>,
+<span>span</span>, <sys>system item</sys>, and <var>variable</var> inline elements.</p>
+
+<p>Here is a key sequence: <keyseq><key>Ctrl</key><key>A</key></keyseq>.
+Here is a gui sequence: <guiseq><gui>File</gui><gui>New</gui></guiseq>.</p>
+
+<p>Here is inline media: <media type="image" mime="image/png" src="drake.png"/></p>
+
+<code>
+SMALL
+<span>BLOCK</span>
+OF
+<code>CODE</code>
+</code>
+
+<example>
+  <p>First example paragraph</p>
+  <p>Second example paragraph</p>
+</example>
+
+<p>Block media should follow:</p>
+
+<media type="image" mime="image/png" src="drake.png"/>
+
+<screen>
+This is a screen /
+It has a <cmd>command</cmd>
+</screen>
+
+<comment>
+  <title>Comment</title>
+  <cite>Drake</cite>
+  <p>Drake makes a comment!</p>
+</comment>
+
+<figure>
+  <title>Figure</title>
+  <desc>Here is a figure</desc>
+  <p>A paragraph in a figure?  How odd.</p>
+</figure>
+
+<listing>
+  <title>Listing</title>
+  <desc>Here is a listing</desc>
+  <p>A paragraph in a listing?  How odd.</p>
+</listing>
+
+<note>
+  <title>Note</title>
+  <p>This is the text of a note.</p>
+</note>
+
+<quote>
+  <title>Quote</title>
+  <cite>Drake</cite>
+  <p>Quack</p>
+</quote>
+
+<synopsis>
+  <title>Synopsis</title>
+  <desc>A synopsis with code</desc>
+  <code>
+    fe
+    fi
+    fo
+    fum
+  </code>
+</synopsis>
+
+<list>
+  <title>List Title</title>
+  <item><p>List 1</p></item>
+  <item><p>List 2</p></item>
+  <item><p>List 3.0</p><p>List 3.5</p></item>
+</list>
+
+<steps>
+  <title>Steps Title</title>
+  <item><p>Step 1</p></item>
+  <item><p>Step 2.0</p><p>Step 2.5</p></item>
+  <item><p>Step 3</p></item>
+</steps>
+
+<terms>
+  <title>Terms Title</title>
+  <item>
+    <title>Term One</title>
+    <p>Def One</p>
+  </item>
+  <item>
+    <title>Term Two</title>
+    <p>Def Two</p>
+  </item>
+</terms>
+
+<section id="tables">
+  <info>
+  </info>
+  <title>Tables</title>
+
+  <table frame="all" rules="rows">
+    <tr>
+      <td><p>Mallard</p></td>  <td><p>Anas platyrhynchos</p></td>
+      <td><p>56-65 cm</p></td> <td><p>900-1200 g</p></td>
+    </tr>
+    <tr>
+      <td><p>Eurasian Wigeon</p></td> <td><p>Anas penelope</p></td>
+      <td><p>45-50 cm</p></td>        <td><p>680 g</p></td>
+    </tr>
+    <tr>
+      <td><p>Common Teal</p></td>     <td><p>Anas crecca</p></td>
+      <td><p>34-43 cm</p></td>        <td><p>360 g</p></td>
+    </tr>
+    <tr>
+      <td><p>Northern Pintail</p></td> <td><p>Anas acuta</p></td>
+      <td><p>59-76 cm</p></td>         <td><p>450-1360 g</p></td>
+    </tr>
+  </table>
+</section>
+
+</page>
diff --git a/xml2po/tests/test.py b/xml2po/tests/test.py
index b5d6e88..1875790 100755
--- a/xml2po/tests/test.py
+++ b/xml2po/tests/test.py
@@ -5,6 +5,7 @@ SIMPLETESTS = { 'deep-finals.xml' : {},
                 'deep-nonfinals.xml': {},
                 'attribute-entities.xml': {},
                 'docbook.xml' : {},
+                'mallard.xml' : {'options': '-m mallard' },
                 'utf8-original.xml': {},
                 'footnotes.xml': {},
                 'keepents.xml': { "options" : "-k" },
diff --git a/xml2po/xml2po.py b/xml2po/xml2po.py
index 5622635..4a9894c 100755
--- a/xml2po/xml2po.py
+++ b/xml2po/xml2po.py
@@ -304,6 +304,8 @@ def isFinalNode(node):
             auto = not autoNodeIsFinal(parent)
             parent = parent.parent
         return auto
+    if CurrentXmlMode and hasattr(CurrentXmlMode, 'isFinalNode'):
+        return CurrentXmlMode.isFinalNode(node)
     #node.type =='text' or not node.children or
     if node.type == 'element' and node.name in ultimate_tags:
         return 1



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]