summaryrefslogtreecommitdiff
path: root/xml2po
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2009-07-27 20:50:07 -0500
committerShaun McCance <shaunm@gnome.org>2009-07-27 20:51:27 -0500
commitbd021e35cec1db931a24afc53f61ab74d7e3d4c5 (patch)
treeddca0514347f3269663a215408769d8a5ddf2fb3 /xml2po
parent6591d7abf8d3f765686c69c1960e464a9ef4b45d (diff)
downloadgnome-doc-utils-bd021e35cec1db931a24afc53f61ab74d7e3d4c5.tar.gz
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.
Diffstat (limited to 'xml2po')
-rw-r--r--xml2po/modes/Makefile.am2
-rw-r--r--xml2po/modes/mallard.py134
-rw-r--r--xml2po/tests/mallard.xml142
-rwxr-xr-xxml2po/tests/test.py1
-rwxr-xr-xxml2po/xml2po.py2
5 files changed, 280 insertions, 1 deletions
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