Blame SOURCES/dblatex-0.3.10-enable-python3.patch

38f0c6
From 8501eb89584b2ad51d3a8e21c8235a81ce01b871 Mon Sep 17 00:00:00 2001
38f0c6
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
38f0c6
Date: Tue, 26 Jun 2018 19:12:18 +0200
38f0c6
Subject: [PATCH 1/4] Make dblatex compatible with Python 3
38f0c6
38f0c6
---
38f0c6
 lib/dbtexmf/core/commander.py             |  3 +-
38f0c6
 lib/dbtexmf/core/confparser.py            | 18 +++--
38f0c6
 lib/dbtexmf/core/dbtex.py                 | 99 ++++++++++++++---------
38f0c6
 lib/dbtexmf/core/error.py                 |  4 +-
38f0c6
 lib/dbtexmf/core/imagedata.py             | 28 ++++---
38f0c6
 lib/dbtexmf/core/sgmlxml.py               | 11 +--
38f0c6
 lib/dbtexmf/core/txtparser.py             |  5 +-
38f0c6
 lib/dbtexmf/core/xmlparser.py             |  2 +-
38f0c6
 lib/dbtexmf/dblatex/dblatex.py            |  4 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/bibtex.py     | 21 ++---
38f0c6
 lib/dbtexmf/dblatex/grubber/bibtopic.py   |  4 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/dvips.py      |  6 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/index.py      | 35 ++++----
38f0c6
 lib/dbtexmf/dblatex/grubber/latex.py      | 15 ++--
38f0c6
 lib/dbtexmf/dblatex/grubber/logparser.py  |  7 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/makeidx.py    |  2 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/maker.py      |  5 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/msg.py        | 23 +++---
38f0c6
 lib/dbtexmf/dblatex/grubber/pdftex.py     |  7 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/plugins.py    | 16 ++--
38f0c6
 lib/dbtexmf/dblatex/grubber/ps2pdf.py     |  6 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/texbuilder.py |  8 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/util.py       |  6 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/xetex.py      |  2 +-
38f0c6
 lib/dbtexmf/dblatex/grubber/xr-hyper.py   |  8 +-
38f0c6
 lib/dbtexmf/dblatex/rawparse.py           | 12 +--
38f0c6
 lib/dbtexmf/dblatex/rawtex.py             | 21 ++---
38f0c6
 lib/dbtexmf/dblatex/rawverb.py            | 50 ++++++------
38f0c6
 lib/dbtexmf/dblatex/runtex.py             | 13 +--
38f0c6
 lib/dbtexmf/dblatex/texcodec.py           | 47 ++++++-----
38f0c6
 lib/dbtexmf/dblatex/texhyphen.py          | 22 ++---
38f0c6
 lib/dbtexmf/dblatex/xetex/codec.py        |  2 +-
38f0c6
 lib/dbtexmf/dblatex/xetex/fcfallback.py   | 10 ++-
38f0c6
 lib/dbtexmf/dblatex/xetex/fcmanager.py    |  3 +
38f0c6
 lib/dbtexmf/dblatex/xetex/fontspec.py     |  4 +-
38f0c6
 lib/dbtexmf/dblatex/xetex/fsconfig.py     |  4 +-
38f0c6
 lib/dbtexmf/dblatex/xetex/fsencoder.py    |  8 +-
38f0c6
 lib/dbtexmf/xslt/4xslt.py                 |  3 +-
38f0c6
 lib/dbtexmf/xslt/xsltproc.py              |  3 +
38f0c6
 setup.py                                  | 53 ++++++------
38f0c6
 40 files changed, 337 insertions(+), 263 deletions(-)
38f0c6
38f0c6
diff --git a/lib/dbtexmf/core/commander.py b/lib/dbtexmf/core/commander.py
38f0c6
index 6319200..5efa074 100644
38f0c6
--- a/lib/dbtexmf/core/commander.py
38f0c6
+++ b/lib/dbtexmf/core/commander.py
38f0c6
@@ -1,5 +1,6 @@
38f0c6
 import os
38f0c6
 from subprocess import Popen, PIPE
38f0c6
+from io import open
38f0c6
 
38f0c6
 class Command:
38f0c6
     """Contains the needed data to run a command"""
38f0c6
@@ -59,7 +60,7 @@ class CommandRunner:
38f0c6
             if cmd.stdout == "PIPE":
38f0c6
                 stdout = PIPE
38f0c6
             elif cmd.stdout:
38f0c6
-                stdout = open(cmd.stdout % kw, "w")
38f0c6
+                stdout = open(cmd.stdout % kw, "wb")
38f0c6
 
38f0c6
             if kw: args = [a % kw for a in cmd.arguments]
38f0c6
             else: args = cmd.arguments
38f0c6
diff --git a/lib/dbtexmf/core/confparser.py b/lib/dbtexmf/core/confparser.py
38f0c6
index bf0b931..fc01786 100644
38f0c6
--- a/lib/dbtexmf/core/confparser.py
38f0c6
+++ b/lib/dbtexmf/core/confparser.py
38f0c6
@@ -1,11 +1,13 @@
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import os
38f0c6
 import sys
38f0c6
 from xml.etree.ElementTree import ParseError
38f0c6
-from xmlparser import XmlConfig
38f0c6
-from txtparser import TextConfig
38f0c6
-from imagedata import ImageConverterPool, ImageConverter
38f0c6
-from imagedata import ImageFormatPool, FormatRule
38f0c6
-from imagedata import image_setup
38f0c6
+from dbtexmf.core.xmlparser import XmlConfig
38f0c6
+from dbtexmf.core.txtparser import TextConfig
38f0c6
+from dbtexmf.core.imagedata import ImageConverterPool, ImageConverter
38f0c6
+from dbtexmf.core.imagedata import ImageFormatPool, FormatRule
38f0c6
+from dbtexmf.core.imagedata import image_setup
38f0c6
 from dbtexmf.xslt.xsltconf import XsltCommandPool, XsltEngine
38f0c6
 from dbtexmf.xslt import xslt_setup
38f0c6
 
38f0c6
@@ -76,16 +78,16 @@ class DbtexConfig:
38f0c6
         self.style_exts = ["", ".xml", ".specs", ".conf"]
38f0c6
 
38f0c6
     def warn(self, text):
38f0c6
-        print >>sys.stderr, text
38f0c6
+        print(text, file=sys.stderr)
38f0c6
 
38f0c6
     def fromfile(self, filename):
38f0c6
         try:
38f0c6
             self.fromxmlfile(filename)
38f0c6
-        except ParseError, e:
38f0c6
+        except ParseError as e:
38f0c6
             self.warn("Text configuration files are deprecated. "\
38f0c6
                       "Use the XML format instead")
38f0c6
             self.fromtxtfile(filename)
38f0c6
-        except Exception, e:
38f0c6
+        except Exception as e:
38f0c6
             raise e
38f0c6
 
38f0c6
     def fromxmlfile(self, filename):
38f0c6
diff --git a/lib/dbtexmf/core/dbtex.py b/lib/dbtexmf/core/dbtex.py
38f0c6
index 92b84f2..b12fafe 100644
38f0c6
--- a/lib/dbtexmf/core/dbtex.py
38f0c6
+++ b/lib/dbtexmf/core/dbtex.py
38f0c6
@@ -2,16 +2,18 @@
38f0c6
 # DbTex base class handling the compilation of a DocBook file via
38f0c6
 # XSL Transformation and some TeX engine compilation.
38f0c6
 #
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import sys
38f0c6
 import os
38f0c6
 import re
38f0c6
 import shlex
38f0c6
 import tempfile
38f0c6
 import shutil
38f0c6
-import urllib
38f0c6
 import glob
38f0c6
 import imp
38f0c6
 from optparse import OptionParser
38f0c6
+from io import open
38f0c6
 
38f0c6
 from dbtexmf.core.txtparser import texinputs_parse, texstyle_parse
38f0c6
 from dbtexmf.core.confparser import DbtexConfig
38f0c6
@@ -19,6 +21,11 @@ from dbtexmf.xslt import xslt
38f0c6
 import dbtexmf.core.logger as logger
38f0c6
 from dbtexmf.core.error import signal_error, failed_exit, dump_stack
38f0c6
 
38f0c6
+try:
38f0c6
+    from urllib import pathname2url
38f0c6
+except ImportError:
38f0c6
+    from urllib.request import pathname2url
38f0c6
+
38f0c6
 
38f0c6
 def suffix_replace(path, oldext, newext=""):
38f0c6
     (root, ext) = os.path.splitext(path)
38f0c6
@@ -29,9 +36,9 @@ def suffix_replace(path, oldext, newext=""):
38f0c6
 
38f0c6
 def path_to_uri(path):
38f0c6
     if os.name == 'nt':
38f0c6
-        return 'file:' + urllib.pathname2url(path).replace('|', ':', 1)
38f0c6
+        return 'file:' + pathname2url(path).replace('|', ':', 1)
38f0c6
     else:
38f0c6
-        return urllib.pathname2url(path)
38f0c6
+        return pathname2url(path)
38f0c6
 
38f0c6
 
38f0c6
 class Document:
38f0c6
@@ -48,24 +55,36 @@ class Document:
38f0c6
     def has_subext(self, ext):
38f0c6
         return (os.path.splitext(self.basename)[1] == ext)
38f0c6
 
38f0c6
-    def __cmp__(self, other):
38f0c6
-        """
38f0c6
-        Comparaison method mainly to check if the document is in a list
38f0c6
-        """
38f0c6
-        if cmp(self.rawfile, other) == 0:
38f0c6
-            return 0
38f0c6
-        if cmp(self.texfile, other) == 0:
38f0c6
-            return 0
38f0c6
-        if cmp(self.binfile, other) == 0:
38f0c6
-            return 0
38f0c6
-        return -1
38f0c6
+    def __eq__(self, other):
38f0c6
+        if self.rawfile == other:
38f0c6
+            return True
38f0c6
+        if self.texfile == other:
38f0c6
+            return True
38f0c6
+        if self.binfile == other:
38f0c6
+            return True
38f0c6
+        return False
38f0c6
+
38f0c6
+    def __ne__(self, other):
38f0c6
+        return not self.__eq__(other)
38f0c6
+
38f0c6
+    def __lt__(self, other):
38f0c6
+        return self.__ne__(other)
38f0c6
+
38f0c6
+    def __le__(self, other):
38f0c6
+        return False
38f0c6
+
38f0c6
+    def __gt__(self, other):
38f0c6
+        return False
38f0c6
+
38f0c6
+    def __ge__(self, other):
38f0c6
+        return False
38f0c6
 
38f0c6
 
38f0c6
 class DbTex:
38f0c6
     USE_MKLISTINGS = 1
38f0c6
 
38f0c6
     xsl_header = \
38f0c6
-"""
38f0c6
+u"""
38f0c6
 
38f0c6
                 xmlns:m="http://www.w3.org/1998/Math/MathML"
38f0c6
                 version="1.0">
38f0c6
@@ -183,7 +202,7 @@ class DbTex:
38f0c6
         self.flags &= ~what
38f0c6
 
38f0c6
     def get_version(self):
38f0c6
-        f = file(os.path.join(self.topdir, "xsl", "version.xsl"))
38f0c6
+        f = open(os.path.join(self.topdir, "xsl", "version.xsl"), "rt", encoding="latin-1")
38f0c6
         versions = re.findall("<xsl:variable[^>]*>([^<]*)<", f.read())
38f0c6
         f.close()
38f0c6
         if versions:
38f0c6
@@ -196,11 +215,11 @@ class DbTex:
38f0c6
             self.xslbuild = self.xslmain
38f0c6
             return
38f0c6
 
38f0c6
-        f = file(wrapper, "w")
38f0c6
+        f = open(wrapper, "wt", encoding="latin-1")
38f0c6
         f.write(self.xsl_header)
38f0c6
-        f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslmain))
38f0c6
+        f.write(u'<xsl:import href="%s"/>\n' % path_to_uri(self.xslmain))
38f0c6
         for xsluser in self.xslusers:
38f0c6
-            f.write('<xsl:import href="%s"/>\n' % path_to_uri(xsluser))
38f0c6
+            f.write(u'<xsl:import href="%s"/>\n' % path_to_uri(xsluser))
38f0c6
 
38f0c6
         # Reverse to set the latest parameter first (case of overriding)
38f0c6
         self.xslparams.reverse()
38f0c6
@@ -231,8 +250,8 @@ class DbTex:
38f0c6
                               self.listings, opts=self.xslopts, params=param)
38f0c6
         else:
38f0c6
             self.log.info("No external file support")
38f0c6
-            f = file(self.listings, "w")
38f0c6
-            f.write("<listings/>\n")
38f0c6
+            f = open(self.listings, "wt", encoding="latin-1")
38f0c6
+            f.write(u"<listings/>\n")
38f0c6
             f.close()
38f0c6
 
38f0c6
     def _single_setup(self):
38f0c6
@@ -254,7 +273,7 @@ class DbTex:
38f0c6
                           "Use the working directory")
38f0c6
             self.outputdir = self.cwdir
38f0c6
 
38f0c6
-        f = open(doclist)
38f0c6
+        f = open(doclist, "rt", encoding="latin-1")
38f0c6
         books = f.readlines()
38f0c6
         f.close()
38f0c6
 
38f0c6
@@ -268,11 +287,11 @@ class DbTex:
38f0c6
         # set list
38f0c6
         self.log.info("Build the book set list...")
38f0c6
         xslset = "doclist.xsl"
38f0c6
-        f = file(xslset, "w")
38f0c6
+        f = open(xslset, "wt", encoding="latin-1")
38f0c6
         f.write(self.xsl_header)
38f0c6
-        f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslbuild))
38f0c6
-        f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslset))
38f0c6
-        f.write('</xsl:stylesheet>\n')
38f0c6
+        f.write(u'<xsl:import href="%s"/>\n' % path_to_uri(self.xslbuild))
38f0c6
+        f.write(u'<xsl:import href="%s"/>\n' % path_to_uri(self.xslset))
38f0c6
+        f.write(u'</xsl:stylesheet>\n')
38f0c6
         f.close()
38f0c6
 
38f0c6
         doclist = os.path.join(self.tmpdir, "doclist.txt")
38f0c6
@@ -369,7 +388,7 @@ class DbTex:
38f0c6
 
38f0c6
         # Need to dump the stdin input, because of the two passes
38f0c6
         self.input = os.path.join(self.tmpdir, "stdin.xml")
38f0c6
-        f = open(self.input, "w")
38f0c6
+        f = open(self.input, "wt", encoding="latin-1")
38f0c6
         for line in sys.stdin:
38f0c6
             f.write(line)
38f0c6
         f.close()
38f0c6
@@ -395,15 +414,15 @@ class DbTex:
38f0c6
         self.update_texinputs()
38f0c6
 
38f0c6
         # For easy debug
38f0c6
-        if self.debug and os.environ.has_key("TEXINPUTS"):
38f0c6
+        if self.debug and "TEXINPUTS" in os.environ:
38f0c6
             if os.name != "nt":
38f0c6
-                f = file("env_tex", "w")
38f0c6
-                f.write("TEXINPUTS=%s\nexport TEXINPUTS\n" % \
38f0c6
+                f = open("env_tex", "wt")
38f0c6
+                f.write(u"TEXINPUTS=%s\nexport TEXINPUTS\n" % \
38f0c6
                         os.environ["TEXINPUTS"])
38f0c6
                 f.close()
38f0c6
             else:
38f0c6
-                f = file("env_tex.bat", "w")
38f0c6
-                f.write("set TEXINPUTS=%s\n" % os.environ["TEXINPUTS"])
38f0c6
+                f = open("env_tex.bat", "wt")
38f0c6
+                f.write(u"set TEXINPUTS=%s\n" % os.environ["TEXINPUTS"])
38f0c6
                 f.close()
38f0c6
 
38f0c6
         # Build the tex file(s), and compile it(them)
38f0c6
@@ -544,13 +563,13 @@ class DbTexCommand:
38f0c6
         if options.format:
38f0c6
             try:
38f0c6
                 run.set_format(options.format)
38f0c6
-            except Exception, e:
38f0c6
+            except Exception as e:
38f0c6
                 failed_exit("Error: %s" % e)
38f0c6
 
38f0c6
         # Always set the XSLT (default or not)
38f0c6
         try:
38f0c6
             run.set_xslt(options.xslt)
38f0c6
-        except Exception, e:
38f0c6
+        except Exception as e:
38f0c6
             failed_exit("Error: %s" % e)
38f0c6
 
38f0c6
         if options.xslopts:
38f0c6
@@ -575,7 +594,7 @@ class DbTexCommand:
38f0c6
         if options.texstyle:
38f0c6
             try:
38f0c6
                 xslparam, texpath = texstyle_parse(options.texstyle)
38f0c6
-            except Exception, e:
38f0c6
+            except Exception as e:
38f0c6
                 failed_exit("Error: %s" % e)
38f0c6
             run.xslparams.append(xslparam)
38f0c6
             if texpath: run.texinputs.append(texpath)
38f0c6
@@ -630,7 +649,7 @@ class DbTexCommand:
38f0c6
             if not(os.path.exists(options.tmpdir)):
38f0c6
                 try:
38f0c6
                     os.mkdir(options.tmpdir)
38f0c6
-                except Exception, e:
38f0c6
+                except Exception as e:
38f0c6
                     failed_exit("Error: %s" % e)
38f0c6
             run.tmpdir_user = os.path.abspath(options.tmpdir)
38f0c6
 
38f0c6
@@ -665,7 +684,7 @@ class DbTexCommand:
38f0c6
 
38f0c6
         if options.version:
38f0c6
             version = run.get_version()
38f0c6
-            print "%s version %s" % (self.prog, version)
38f0c6
+            print("%s version %s" % (self.prog, version))
38f0c6
             if not(args):
38f0c6
                 sys.exit(0)
38f0c6
 
38f0c6
@@ -682,14 +701,14 @@ class DbTexCommand:
38f0c6
             try:
38f0c6
                 conf.paths = self.get_config_paths()
38f0c6
                 conf.fromstyle(options.style)
38f0c6
-            except Exception, e:
38f0c6
+            except Exception as e:
38f0c6
                 failed_exit("Error: %s" % e)
38f0c6
             
38f0c6
         if options.config:
38f0c6
             try:
38f0c6
                 for config in options.config:
38f0c6
                     conf.fromfile(config)
38f0c6
-            except Exception, e:
38f0c6
+            except Exception as e:
38f0c6
                 failed_exit("Error: %s" % e)
38f0c6
 
38f0c6
         if conf.options:
38f0c6
@@ -735,7 +754,7 @@ class DbTexCommand:
38f0c6
         # Try to buid the file
38f0c6
         try:
38f0c6
             run.compile()
38f0c6
-        except Exception, e:
38f0c6
+        except Exception as e:
38f0c6
             signal_error(self, e)
38f0c6
             failed_exit("Error: %s" % e)
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/core/error.py b/lib/dbtexmf/core/error.py
38f0c6
index 4bf44ee..2d71599 100644
38f0c6
--- a/lib/dbtexmf/core/error.py
38f0c6
+++ b/lib/dbtexmf/core/error.py
38f0c6
@@ -4,6 +4,8 @@
38f0c6
 #   error handler.
38f0c6
 # - A general API.
38f0c6
 #
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import sys
38f0c6
 import traceback
38f0c6
 
38f0c6
@@ -49,7 +51,7 @@ def signal_error(*args, **kwargs):
38f0c6
 
38f0c6
 def failure_track(msg):
38f0c6
     global _dump_stack
38f0c6
-    print >>sys.stderr, (msg)
38f0c6
+    print((msg), file=sys.stderr)
38f0c6
     if _dump_stack:
38f0c6
         traceback.print_exc()
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/core/imagedata.py b/lib/dbtexmf/core/imagedata.py
38f0c6
index ebbd5c7..d01d93a 100644
38f0c6
--- a/lib/dbtexmf/core/imagedata.py
38f0c6
+++ b/lib/dbtexmf/core/imagedata.py
38f0c6
@@ -3,9 +3,13 @@ import os
38f0c6
 import re
38f0c6
 import shutil
38f0c6
 import logging
38f0c6
-import urllib
38f0c6
 from dbtexmf.core.error import signal_error
38f0c6
-from commander import CommandRunner
38f0c6
+from dbtexmf.core.commander import CommandRunner
38f0c6
+
38f0c6
+try:
38f0c6
+    from urllib import url2pathname
38f0c6
+except ImportError:
38f0c6
+    from urllib.request import url2pathname
38f0c6
 
38f0c6
 class ObjectFilter:
38f0c6
     """
38f0c6
@@ -258,8 +262,10 @@ class Imagedata:
38f0c6
                                                       backend=backend)
38f0c6
 
38f0c6
     def convert(self, fig):
38f0c6
+        fig = fig.decode("utf-8")
38f0c6
+
38f0c6
         # Translate the URL to an actual local path
38f0c6
-        fig = urllib.url2pathname(fig)
38f0c6
+        fig = url2pathname(fig)
38f0c6
 
38f0c6
         # Always use '/' in path: work even on windows and is required by tex
38f0c6
         if os.path.sep != '/': fig = fig.replace(os.path.sep, '/')
38f0c6
@@ -273,7 +279,7 @@ class Imagedata:
38f0c6
             return fig
38f0c6
 
38f0c6
         # Check if this image has been already converted
38f0c6
-        if self.converted.has_key(realfig):
38f0c6
+        if realfig in self.converted:
38f0c6
             self.log.info("Image '%s' already converted as %s" % \
38f0c6
                   (fig, self.converted[realfig]))
38f0c6
             return self.converted[realfig]
38f0c6
@@ -306,7 +312,7 @@ class Imagedata:
38f0c6
         conv.log = self.log
38f0c6
         conv.convert(realfig, newfig, self.output_format)
38f0c6
         self.converted[realfig] = newfig
38f0c6
-        return newfig
38f0c6
+        return self._path_encode(newfig)
38f0c6
 
38f0c6
     def _safe_file(self, fig, realfig, ext):
38f0c6
         """
38f0c6
@@ -316,7 +322,7 @@ class Imagedata:
38f0c6
         # Encode to expected output format. If encoding is OK and 
38f0c6
         # supported by tex, just return the encoded path
38f0c6
         newfig = self._path_encode(fig)
38f0c6
-        if newfig and newfig.find(" ") == -1:
38f0c6
+        if newfig and newfig.find(b" ") == -1:
38f0c6
             return newfig
38f0c6
 
38f0c6
         # Added to the converted list
38f0c6
@@ -326,17 +332,17 @@ class Imagedata:
38f0c6
 
38f0c6
         # Do the copy
38f0c6
         shutil.copyfile(realfig, newfig)
38f0c6
-        return newfig
38f0c6
+        return self._path_encode(newfig)
38f0c6
 
38f0c6
     def _path_encode(self, fig):
38f0c6
         # Actually, only ASCII characters are sure to match filesystem encoding
38f0c6
         # so let's be conservative
38f0c6
-        if self.output_encoding == "utf8":
38f0c6
-            return fig
38f0c6
+        if self.output_encoding == "utf-8":
38f0c6
+            return fig.encode("utf-8")
38f0c6
         try:
38f0c6
-            newfig = fig.decode("utf8").encode("ascii")
38f0c6
+            newfig = fig.encode("ascii")
38f0c6
         except:
38f0c6
-            newfig = ""
38f0c6
+            newfig = b""
38f0c6
         return newfig
38f0c6
 
38f0c6
     def scanformat(self, fig):
38f0c6
diff --git a/lib/dbtexmf/core/sgmlxml.py b/lib/dbtexmf/core/sgmlxml.py
38f0c6
index 30e6b84..80b28b3 100644
38f0c6
--- a/lib/dbtexmf/core/sgmlxml.py
38f0c6
+++ b/lib/dbtexmf/core/sgmlxml.py
38f0c6
@@ -7,6 +7,7 @@ import sys
38f0c6
 import re
38f0c6
 import logging
38f0c6
 from subprocess import call
38f0c6
+from io import open
38f0c6
 
38f0c6
 class Osx:
38f0c6
     def __init__(self):
38f0c6
@@ -20,7 +21,7 @@ class Osx:
38f0c6
     def replace_entities(self, entfile, mapfile, outfile=None):
38f0c6
         # Find out the SDATA entities to replace
38f0c6
         re_ent = re.compile('')
38f0c6
-        f = open(entfile)
38f0c6
+        f = open(entfile, "rt", encoding="latin-1")
38f0c6
         lines = f.readlines()
38f0c6
         f.close()
38f0c6
 
38f0c6
@@ -37,7 +38,7 @@ class Osx:
38f0c6
         entpat = "^(%s)\s+[^\s]+\s+0(x[^\s]+)" % "|".join([x for x, y in ents])
38f0c6
         re_map = re.compile(entpat)
38f0c6
         entmap = []
38f0c6
-        f = open(mapfile)
38f0c6
+        f = open(mapfile, "rt", encoding="latin-1")
38f0c6
         for line in f:
38f0c6
             entmap += re_map.findall(line.split("#")[0])
38f0c6
         f.close()
38f0c6
@@ -63,18 +64,18 @@ class Osx:
38f0c6
                 del entdict[ent]
38f0c6
 
38f0c6
         if not(outfile): outfile = entfile
38f0c6
-        f = open(outfile, "w")
38f0c6
+        f = open(outfile, "wt", encoding="latin-1")
38f0c6
         f.writelines(nlines)
38f0c6
         f.close()
38f0c6
 
38f0c6
     def run(self, sgmlfile, xmlfile):
38f0c6
         errfile = "errors.osx"
38f0c6
-        f = open(xmlfile, "w")
38f0c6
+        f = open(xmlfile, "wb")
38f0c6
         rc = call(["osx"] + self.opts + ["-f", errfile, sgmlfile], stdout=f)
38f0c6
         f.close()
38f0c6
         if rc != 0:
38f0c6
             i = 0
38f0c6
-            f = open(errfile)
38f0c6
+            f = open(errfile, "rt")
38f0c6
             for line in f:
38f0c6
                 sys.stderr.write(line)
38f0c6
                 i += 1
38f0c6
diff --git a/lib/dbtexmf/core/txtparser.py b/lib/dbtexmf/core/txtparser.py
38f0c6
index 709d877..cc0c4bd 100644
38f0c6
--- a/lib/dbtexmf/core/txtparser.py
38f0c6
+++ b/lib/dbtexmf/core/txtparser.py
38f0c6
@@ -3,6 +3,7 @@
38f0c6
 #
38f0c6
 import os
38f0c6
 import re
38f0c6
+from io import open
38f0c6
 
38f0c6
 #
38f0c6
 # Functions used by the config parsers and by the dbtex command parser
38f0c6
@@ -86,7 +87,7 @@ class TextConfig:
38f0c6
 
38f0c6
     def fromfile(self, file):
38f0c6
         dir = os.path.dirname(os.path.realpath(file))
38f0c6
-        f = open(file)
38f0c6
+        f = open(file, "rt")
38f0c6
 
38f0c6
         for line in f:
38f0c6
             # Remove the comment
38f0c6
@@ -96,7 +97,7 @@ class TextConfig:
38f0c6
                 continue
38f0c6
             key = m.group(1)
38f0c6
             value = m.group(2).strip()
38f0c6
-            if not self.conf_mapping.has_key(key):
38f0c6
+            if key not in self.conf_mapping:
38f0c6
                 continue
38f0c6
             o = self.conf_mapping[key]
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/core/xmlparser.py b/lib/dbtexmf/core/xmlparser.py
38f0c6
index 501b7f7..25b1230 100644
38f0c6
--- a/lib/dbtexmf/core/xmlparser.py
38f0c6
+++ b/lib/dbtexmf/core/xmlparser.py
38f0c6
@@ -1,7 +1,7 @@
38f0c6
 import os
38f0c6
 import re
38f0c6
 import xml.etree.ElementTree as ET
38f0c6
-from txtparser import texinputs_parse
38f0c6
+from dbtexmf.core.txtparser import texinputs_parse
38f0c6
 
38f0c6
 class BaseOption:
38f0c6
     def __init__(self, config, optname):
38f0c6
diff --git a/lib/dbtexmf/dblatex/dblatex.py b/lib/dbtexmf/dblatex/dblatex.py
38f0c6
index 0e9ae71..e22b965 100644
38f0c6
--- a/lib/dbtexmf/dblatex/dblatex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/dblatex.py
38f0c6
@@ -7,8 +7,8 @@ import os
38f0c6
 from dbtexmf.core.sgmlxml import Osx
38f0c6
 from dbtexmf.core.dbtex import DbTex, DbTexCommand
38f0c6
 
38f0c6
-from rawtex import RawLatex
38f0c6
-from runtex import RunLatex
38f0c6
+from dbtexmf.dblatex.rawtex import RawLatex
38f0c6
+from dbtexmf.dblatex.runtex import RunLatex
38f0c6
 
38f0c6
 
38f0c6
 class DbLatex(DbTex):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/bibtex.py b/lib/dbtexmf/dblatex/grubber/bibtex.py
38f0c6
index 7615cfc..296a992 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/bibtex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/bibtex.py
38f0c6
@@ -18,11 +18,12 @@ import os, sys
38f0c6
 from os.path import *
38f0c6
 import re, string
38f0c6
 import subprocess
38f0c6
+from io import open
38f0c6
 
38f0c6
 #from grubber import _
38f0c6
 #from grubber import *
38f0c6
-from msg import _, msg
38f0c6
-from plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
 
38f0c6
 re_bibdata = re.compile(r"\\bibdata{(?P<data>.*)}")
38f0c6
 re_citation = re.compile(r"\\citation{(?P.*)}")
38f0c6
@@ -111,7 +112,7 @@ class BibTex(TexModule):
38f0c6
         """
38f0c6
         if self.style:
38f0c6
             old_bst = self.style + ".bst"
38f0c6
-            if exists(old_bst) and self.doc.sources.has_key(old_bst):
38f0c6
+            if exists(old_bst) and old_bst in self.doc.sources:
38f0c6
                 del self.doc.sources[old_bst]
38f0c6
 
38f0c6
         self.style = style
38f0c6
@@ -174,7 +175,7 @@ class BibTex(TexModule):
38f0c6
                         pkg="bibtex")
38f0c6
                 return 1
38f0c6
 
38f0c6
-        blg = open(self.blgfile)
38f0c6
+        blg = open(self.blgfile, "rt", encoding="latin-1")
38f0c6
         for line in blg.readlines():
38f0c6
             if re_error.search(line):
38f0c6
                 blg.close()
38f0c6
@@ -202,12 +203,12 @@ class BibTex(TexModule):
38f0c6
             auxfiles.append(self.auxfile)
38f0c6
 
38f0c6
         for auxname in auxfiles:
38f0c6
-            aux = open(auxname)
38f0c6
+            aux = open(auxname, "rt", encoding="latin-1")
38f0c6
             for line in aux:
38f0c6
                 m = re_citation.match(line)
38f0c6
                 if m:
38f0c6
                     cite = m.group("cite")
38f0c6
-                    if not cites.has_key(cite):
38f0c6
+                    if cite not in cites:
38f0c6
                         last = last + 1
38f0c6
                         cites[cite] = last
38f0c6
                     continue
38f0c6
@@ -358,7 +359,7 @@ class BibTex(TexModule):
38f0c6
         """
38f0c6
         if not exists(self.blgfile):
38f0c6
             return 0
38f0c6
-        log = open(self.blgfile)
38f0c6
+        log = open(self.blgfile, "rt", encoding="latin-1")
38f0c6
         line = log.readline()
38f0c6
         while line != "":
38f0c6
             if line.startswith("The style file: "):
38f0c6
@@ -376,7 +377,7 @@ class BibTex(TexModule):
38f0c6
         """
38f0c6
         if not exists(self.blgfile):
38f0c6
             return
38f0c6
-        log = open(self.blgfile)
38f0c6
+        log = open(self.blgfile, "rt", encoding="latin-1")
38f0c6
         last_line = ""
38f0c6
         for line in log:
38f0c6
             m = re_error.search(line)
38f0c6
@@ -400,9 +401,9 @@ class BibTex(TexModule):
38f0c6
                 file = d["file"]
38f0c6
                 if file[-4:] == ".bib":
38f0c6
                     file = file[:-4]
38f0c6
-                if self.db.has_key(file):
38f0c6
+                if file in self.db:
38f0c6
                     d["file"] = self.db[file]
38f0c6
-                elif self.db.has_key(file + ".bib"):
38f0c6
+                elif file + ".bib" in self.db:
38f0c6
                     d["file"] = self.db[file + ".bib"]
38f0c6
                 yield d
38f0c6
             last_line = line
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/bibtopic.py b/lib/dbtexmf/dblatex/grubber/bibtopic.py
38f0c6
index 4c1ef9f..af36830 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/bibtopic.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/bibtopic.py
38f0c6
@@ -1,6 +1,6 @@
38f0c6
 
38f0c6
-from plugins import TexModule
38f0c6
-from bibtex import BibTex
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.bibtex import BibTex
38f0c6
 
38f0c6
 
38f0c6
 class BibSect(BibTex):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/dvips.py b/lib/dbtexmf/dblatex/grubber/dvips.py
38f0c6
index 83bafa7..43f9326 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/dvips.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/dvips.py
38f0c6
@@ -13,9 +13,9 @@ import os
38f0c6
 from os.path import *
38f0c6
 import subprocess
38f0c6
 
38f0c6
-from msg import _ , msg
38f0c6
-from plugins import TexModule
38f0c6
-from maker import Depend
38f0c6
+from dbtexmf.dblatex.grubber.msg import _ , msg
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.maker import Depend
38f0c6
 
38f0c6
 class Dep (Depend):
38f0c6
     def __init__ (self, doc, target, source, node):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/index.py b/lib/dbtexmf/dblatex/grubber/index.py
38f0c6
index 2194b02..564ff8f 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/index.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/index.py
38f0c6
@@ -38,6 +38,7 @@ this argument, they apply to all indices declared at the point where they
38f0c6
 occur.
38f0c6
 """
38f0c6
 
38f0c6
+import sys
38f0c6
 import os
38f0c6
 from os.path import *
38f0c6
 import re, string
38f0c6
@@ -45,9 +46,11 @@ import subprocess
38f0c6
 import xml.dom.minidom
38f0c6
 
38f0c6
 from subprocess import Popen, PIPE
38f0c6
-from msg import _, msg
38f0c6
-from plugins import TexModule
38f0c6
-from util import md5_file
38f0c6
+from io import open
38f0c6
+
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.util import md5_file
38f0c6
 
38f0c6
 
38f0c6
 class Xindy:
38f0c6
@@ -133,7 +136,7 @@ class Xindy:
38f0c6
         # Texindy produces latin-* indexes. Try to find out which one from
38f0c6
         # the modules loaded by the script (language dependent)
38f0c6
         re_lang = re.compile("loading module \"lang/.*/(latin[^.-]*)")
38f0c6
-        logfile = open(logname)
38f0c6
+        logfile = open(logname, "rt", encoding="latin-1")
38f0c6
         encoding = ""
38f0c6
         for line in logfile:
38f0c6
             m = re_lang.search(line)
38f0c6
@@ -145,7 +148,7 @@ class Xindy:
38f0c6
         return encoding
38f0c6
 
38f0c6
     def _index_is_unicode(self):
38f0c6
-        f = file(self.target, "r")
38f0c6
+        f = open(self.target, "rb")
38f0c6
         is_unicode = True 
38f0c6
         for line in f:
38f0c6
             try:
38f0c6
@@ -162,20 +165,20 @@ class Xindy:
38f0c6
         # with Xindy. If not, the following error is raised by Xindy:
38f0c6
         # "WARNING: unknown cross-reference-class `hyperindexformat'! (ignored)"
38f0c6
         #
38f0c6
-        f = file(self.idxfile, "r")
38f0c6
+        f = open(self.idxfile, "rt", encoding="latin-1")
38f0c6
         data = f.read()
38f0c6
         f.close()
38f0c6
         data, nsub = self._re_hyperindex.subn(r"\1}{", data)
38f0c6
         if not(nsub):
38f0c6
             return
38f0c6
         msg.debug("Remove %d unsupported 'hyperindexformat' calls" % nsub)
38f0c6
-        f = file(self.idxfile, "w")
38f0c6
+        f = open(self.idxfile, "wt", encoding="latin-1")
38f0c6
         f.write(data)
38f0c6
         f.close()
38f0c6
 
38f0c6
     def _fix_invalid_ranges(self):
38f0c6
         if not(self.invalid_index_ranges): return
38f0c6
-        f = open(self.idxfile)
38f0c6
+        f = open(self.idxfile, "rt", encoding="latin-1")
38f0c6
         lines = f.readlines()
38f0c6
         f.close()
38f0c6
 
38f0c6
@@ -199,7 +202,7 @@ class Xindy:
38f0c6
         skip_lines.reverse()
38f0c6
         for line_num in skip_lines:
38f0c6
             del lines[line_num]
38f0c6
-        f = open(self.idxfile, "w")
38f0c6
+        f = open(self.idxfile, "wt", encoding="latin-1")
38f0c6
         f.writelines(lines)
38f0c6
         f.close()
38f0c6
 
38f0c6
@@ -232,9 +235,11 @@ class Xindy:
38f0c6
 
38f0c6
         # Collect the script output, and errors
38f0c6
         logname = join(dirname(self.target), "xindy.log")
38f0c6
-        logfile = open(logname, "w")
38f0c6
+        logfile = open(logname, "wb")
38f0c6
         p = Popen(cmd, stdout=logfile, stderr=PIPE)
38f0c6
         errdata = p.communicate()[1]
38f0c6
+        if isinstance(errdata, bytes):
38f0c6
+            errdata = errdata.decode(sys.getdefaultencoding())
38f0c6
         rc = p.wait()
38f0c6
         if msg.stdout:
38f0c6
             msg.stdout.write(errdata)
38f0c6
@@ -264,7 +269,7 @@ class Indexentry:
38f0c6
     """
38f0c6
     Index entry wrapper from idxfile. Its role is to detect range anomalies
38f0c6
     """
38f0c6
-    _re_entry = re.compile("\indexentry{(.*)\|([\(\)]?).*}{(\d+)}", re.DOTALL)
38f0c6
+    _re_entry = re.compile(r"\\indexentry{(.*)\|([\(\)]?).*}{(\d+)}", re.DOTALL)
38f0c6
 
38f0c6
     def __init__(self, index_key):
38f0c6
         self.index_key = index_key
38f0c6
@@ -330,7 +335,7 @@ class Makeindex:
38f0c6
         return cmd
38f0c6
 
38f0c6
     def _index_is_unicode(self):
38f0c6
-        f = file(self.target, "r")
38f0c6
+        f = open(self.target, "rb")
38f0c6
         is_unicode = True 
38f0c6
         for line in f:
38f0c6
             try:
38f0c6
@@ -514,7 +519,7 @@ class Module (TexModule):
38f0c6
         index = self.indices[name] = Index(self.doc, idx, ind, ilg)
38f0c6
         for cmd in self.defaults:
38f0c6
             index.command(*cmd)
38f0c6
-        if self.commands.has_key(name):
38f0c6
+        if name in self.commands:
38f0c6
             for cmd in self.commands[name]:
38f0c6
                 index.command(*cmd)
38f0c6
 
38f0c6
@@ -548,9 +553,9 @@ class Module (TexModule):
38f0c6
             self.defaults.append([cmd, args])
38f0c6
             names = indices.keys()
38f0c6
         for index in names:
38f0c6
-            if indices.has_key(index):
38f0c6
+            if index in indices:
38f0c6
                 indices[index].command(cmd, args[1:])
38f0c6
-            elif self.commands.has_key(index):
38f0c6
+            elif index in self.commands:
38f0c6
                 self.commands[index].append([cmd, args])
38f0c6
             else:
38f0c6
                 self.commands[index] = [[cmd, args]]
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/latex.py b/lib/dbtexmf/dblatex/grubber/latex.py
38f0c6
index 1708cd9..8524fd8 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/latex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/latex.py
38f0c6
@@ -10,13 +10,14 @@ import os
38f0c6
 import sys
38f0c6
 import time
38f0c6
 import subprocess
38f0c6
+from io import open
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
-from util import Watcher
38f0c6
-from logparser import LogParser
38f0c6
-from texparser import TexParser
38f0c6
-from plugins import Modules
38f0c6
-from maker import Depend
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.util import Watcher
38f0c6
+from dbtexmf.dblatex.grubber.logparser import LogParser
38f0c6
+from dbtexmf.dblatex.grubber.texparser import TexParser
38f0c6
+from dbtexmf.dblatex.grubber.plugins import Modules
38f0c6
+from dbtexmf.dblatex.grubber.maker import Depend
38f0c6
 
38f0c6
 
38f0c6
 class Latex(Depend):
38f0c6
@@ -122,7 +123,7 @@ class Latex(Depend):
38f0c6
         Prepare the compilation by parsing the source file. The parsing
38f0c6
         loads all the necessary modules required by the packages used, etc.
38f0c6
         """
38f0c6
-        f = open(self.srcfile)
38f0c6
+        f = open(self.srcfile, "rt", encoding="latin-1")
38f0c6
         self.parser.parse(f, exclude_mods=exclude_mods)
38f0c6
         f.close()
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/logparser.py b/lib/dbtexmf/dblatex/grubber/logparser.py
38f0c6
index d7a00b9..e490d9f 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/logparser.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/logparser.py
38f0c6
@@ -8,8 +8,9 @@ This module defines the class that parses the LaTeX log files.
38f0c6
 from __future__ import generators
38f0c6
 
38f0c6
 import re
38f0c6
+from io import open
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
 
38f0c6
 class LogParser:
38f0c6
     """
38f0c6
@@ -51,7 +52,7 @@ class LogParser:
38f0c6
         """
38f0c6
         self.lines = []
38f0c6
         try:
38f0c6
-            file = open(name)
38f0c6
+            file = open(name, "rt")
38f0c6
         except IOError:
38f0c6
             return 2
38f0c6
         line = file.readline()
38f0c6
@@ -188,7 +189,7 @@ class LogParser:
38f0c6
                         m = self.re_ignored.search(error)
38f0c6
                         if m:
38f0c6
                             d["file"] = last_file
38f0c6
-                            if d.has_key("code"):
38f0c6
+                            if "code" in d:
38f0c6
                                 del d["code"]
38f0c6
                             d.update( m.groupdict() )
38f0c6
                         elif pos[-1] is None:
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/makeidx.py b/lib/dbtexmf/dblatex/grubber/makeidx.py
38f0c6
index d4c5f18..1157832 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/makeidx.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/makeidx.py
38f0c6
@@ -24,7 +24,7 @@ The following directives are provided to specify options for makeindex:
38f0c6
 """
38f0c6
 import sys
38f0c6
 
38f0c6
-from index import Index
38f0c6
+from dbtexmf.dblatex.grubber.index import Index
38f0c6
 
38f0c6
 class Module (Index):
38f0c6
     def __init__ (self, doc, dict):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/maker.py b/lib/dbtexmf/dblatex/grubber/maker.py
38f0c6
index 14408f8..75d1dc3 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/maker.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/maker.py
38f0c6
@@ -4,11 +4,12 @@
38f0c6
 This module contains all the classes used to manage the building
38f0c6
 dependencies.
38f0c6
 """
38f0c6
+from __future__ import print_function
38f0c6
 import os
38f0c6
 import time
38f0c6
 import subprocess
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
 
38f0c6
 class Depend (object): #{{{2
38f0c6
     """
38f0c6
@@ -81,7 +82,7 @@ class Depend (object): #{{{2
38f0c6
           on this one have to be remade)
38f0c6
         """
38f0c6
         if self.making:
38f0c6
-            print "FIXME: cyclic make"
38f0c6
+            print("FIXME: cyclic make")
38f0c6
             return 1
38f0c6
         self.making = 1
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/msg.py b/lib/dbtexmf/dblatex/grubber/msg.py
38f0c6
index 4ebb38f..8c2fffc 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/msg.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/msg.py
38f0c6
@@ -4,9 +4,12 @@
38f0c6
 This module defines the messages diplay class, and creates the application-wide
38f0c6
 msg object.
38f0c6
 """
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import os, os.path
38f0c6
 import sys
38f0c6
 import logging
38f0c6
+from io import open
38f0c6
 
38f0c6
 def _(txt): return txt
38f0c6
 
38f0c6
@@ -32,14 +35,14 @@ class Message (object):
38f0c6
         self._log = logging.getLogger("dblatex")
38f0c6
         level = self._log.getEffectiveLevel()
38f0c6
         if level >= logging.WARNING:
38f0c6
-            self.stdout = open(os.devnull, "w")
38f0c6
+            self.stdout = open(os.devnull, "wb")
38f0c6
         else:
38f0c6
             self.stdout = None
38f0c6
 
38f0c6
     def write_stdout(self, text, level=0):
38f0c6
-        print text
38f0c6
+        print(text)
38f0c6
     def write_stderr(self, text, level=0):
38f0c6
-        print >>sys.stderr, text
38f0c6
+        print(text, file=sys.stderr)
38f0c6
 
38f0c6
     def push_pos (self, pos):
38f0c6
         self.pos.append(pos)
38f0c6
@@ -66,7 +69,7 @@ class Message (object):
38f0c6
             if text[0:13] == "LaTeX Error: ":
38f0c6
                 text = text[13:]
38f0c6
             self._log.error(self.format_pos(info, text))
38f0c6
-            if info.has_key("code") and info["code"] and not self.short:
38f0c6
+            if "code" in info and info["code"] and not self.short:
38f0c6
                 self._log.error(self.format_pos(info,
38f0c6
                     _("leading text: ") + info["code"]))
38f0c6
 
38f0c6
@@ -100,24 +103,24 @@ class Message (object):
38f0c6
         the dictionary given as first argument.
38f0c6
         """
38f0c6
         if len(self.pos) > 0:
38f0c6
-            if where is None or not where.has_key("file"):
38f0c6
+            if where is None or "file" not in where:
38f0c6
                 where = self.pos[-1]
38f0c6
         elif where is None or where == {}:
38f0c6
             return text
38f0c6
 
38f0c6
-        if where.has_key("file") and where["file"] is not None:
38f0c6
+        if "file" in where and where["file"] is not None:
38f0c6
             pos = self.simplify(where["file"])
38f0c6
-            if where.has_key("line") and where["line"]:
38f0c6
+            if "line" in where and where["line"]:
38f0c6
                 pos = "%s:%d" % (pos, int(where["line"]))
38f0c6
-                if where.has_key("last"):
38f0c6
+                if "last" in where:
38f0c6
                     if where["last"] != where["line"]:
38f0c6
                         pos = "%s-%d" % (pos, int(where["last"]))
38f0c6
             pos = pos + ": "
38f0c6
         else:
38f0c6
             pos = ""
38f0c6
-        if where.has_key("page"):
38f0c6
+        if "page" in where:
38f0c6
             text = "%s (page %d)" % (text, int(where["page"]))
38f0c6
-        if where.has_key("pkg"):
38f0c6
+        if "pkg" in where:
38f0c6
             text = "[%s] %s" % (where["pkg"], text)
38f0c6
         return pos + text
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/pdftex.py b/lib/dbtexmf/dblatex/grubber/pdftex.py
38f0c6
index b10b2e2..f5f6635 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/pdftex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/pdftex.py
38f0c6
@@ -9,13 +9,14 @@ using pdfTeX.
38f0c6
 The module optimizes the pdflatex calls by setting -draftmode and apply a last
38f0c6
 call to build the final PDF output.
38f0c6
 """
38f0c6
+import sys
38f0c6
 import os
38f0c6
 import re
38f0c6
 import subprocess
38f0c6
 from subprocess import Popen, PIPE
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
-from plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
 
38f0c6
 
38f0c6
 class Module (TexModule):
38f0c6
@@ -73,6 +74,8 @@ class Module (TexModule):
38f0c6
         # Grab the major version number
38f0c6
         p = Popen("pdflatex -version", shell=True, stdout=PIPE)
38f0c6
         data = p.communicate()[0]
38f0c6
+        if isinstance(data, bytes):
38f0c6
+            data = data.decode(sys.getdefaultencoding())
38f0c6
         m = re.search("pdfTeX.*3.14[^-]*-(\d*.\d*)", data, re.M)
38f0c6
         if not(m):
38f0c6
             return ""
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/plugins.py b/lib/dbtexmf/dblatex/grubber/plugins.py
38f0c6
index f72bd13..01264fc 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/plugins.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/plugins.py
38f0c6
@@ -7,7 +7,7 @@ All the modules must be derived from the TexModule class.
38f0c6
 import imp
38f0c6
 
38f0c6
 from os.path import *
38f0c6
-from msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
 
38f0c6
 import sys
38f0c6
 
38f0c6
@@ -106,7 +106,7 @@ class Plugins (object):
38f0c6
         dictionary. Return 0 if no module was found, 1 if a module was found
38f0c6
         and loaded, and 2 if the module was found but already loaded.
38f0c6
         """
38f0c6
-        if self.modules.has_key(name):
38f0c6
+        if name in self.modules:
38f0c6
             return 2
38f0c6
         try:
38f0c6
             file, path, descr = imp.find_module(name, [""])
38f0c6
@@ -151,11 +151,11 @@ class Modules (Plugins):
38f0c6
         """
38f0c6
         return self.objects[name]
38f0c6
 
38f0c6
-    def has_key (self, name):
38f0c6
+    def __contains__ (self, name):
38f0c6
         """
38f0c6
         Check if a given module is loaded.
38f0c6
         """
38f0c6
-        return self.objects.has_key(name)
38f0c6
+        return name in self.objects
38f0c6
 
38f0c6
     def register (self, name, dict={}):
38f0c6
         """
38f0c6
@@ -165,7 +165,7 @@ class Modules (Plugins):
38f0c6
         delayed commands for this module. The dictionary describes the
38f0c6
         command that caused the registration.
38f0c6
         """
38f0c6
-        if self.has_key(name):
38f0c6
+        if name in self:
38f0c6
             msg.debug(_("module %s already registered") % name)
38f0c6
             return 2
38f0c6
 
38f0c6
@@ -191,7 +191,7 @@ class Modules (Plugins):
38f0c6
 
38f0c6
         # Run any delayed commands.
38f0c6
 
38f0c6
-        if self.commands.has_key(name):
38f0c6
+        if name in self.commands:
38f0c6
             for (cmd, args, vars) in self.commands[name]:
38f0c6
                 msg.push_pos(vars)
38f0c6
                 try:
38f0c6
@@ -219,10 +219,10 @@ class Modules (Plugins):
38f0c6
         Send a command to a particular module. If this module is not loaded,
38f0c6
         store the command so that it will be sent when the module is register.
38f0c6
         """
38f0c6
-        if self.objects.has_key(mod):
38f0c6
+        if mod in self.objects:
38f0c6
             self.objects[mod].command(cmd, args)
38f0c6
         else:
38f0c6
-            if not self.commands.has_key(mod):
38f0c6
+            if mod not in self.commands:
38f0c6
                 self.commands[mod] = []
38f0c6
             self.commands[mod].append((cmd, args, self.env.vars.copy()))
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/ps2pdf.py b/lib/dbtexmf/dblatex/grubber/ps2pdf.py
38f0c6
index d7e1f33..02dfa60 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/ps2pdf.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/ps2pdf.py
38f0c6
@@ -7,9 +7,9 @@ PostScript to PDF conversion using GhostScript.
38f0c6
 import sys
38f0c6
 import os
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
-from maker import DependShell
38f0c6
-from plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.maker import DependShell
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
 
38f0c6
 
38f0c6
 class Module (TexModule):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/texbuilder.py b/lib/dbtexmf/dblatex/grubber/texbuilder.py
38f0c6
index bcb02ba..adce529 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/texbuilder.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/texbuilder.py
38f0c6
@@ -9,9 +9,9 @@ of the rubber internals.
38f0c6
 import subprocess
38f0c6
 import os
38f0c6
 import shlex
38f0c6
-from msg import _, msg
38f0c6
-from maker import Maker
38f0c6
-from latex import Latex
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.maker import Maker
38f0c6
+from dbtexmf.dblatex.grubber.latex import Latex
38f0c6
 
38f0c6
 
38f0c6
 class IndexBuilder:
38f0c6
@@ -90,7 +90,7 @@ class LatexBuilder:
38f0c6
         self.tex.prepare()
38f0c6
 
38f0c6
         # Set the index configuration
38f0c6
-        if self.tex.modules.has_key("makeidx"):
38f0c6
+        if "makeidx" in self.tex.modules:
38f0c6
             idx = self.tex.modules["makeidx"]
38f0c6
             if self.index.style: idx.do_style(self.index.style)
38f0c6
             if self.index.tool: idx.do_tool(self.index.tool)
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/util.py b/lib/dbtexmf/dblatex/grubber/util.py
38f0c6
index fa3bda6..289acaf 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/util.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/util.py
38f0c6
@@ -11,7 +11,9 @@ except ImportError:
38f0c6
     # Fallback for python 2.4:
38f0c6
     import md5 as hashlib
38f0c6
 import os
38f0c6
-from msg import _, msg
38f0c6
+from io import open
38f0c6
+
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
 
38f0c6
 
38f0c6
 def md5_file(fname):
38f0c6
@@ -19,7 +21,7 @@ def md5_file(fname):
38f0c6
     Compute the MD5 sum of a given file.
38f0c6
     """
38f0c6
     m = hashlib.md5()
38f0c6
-    file = open(fname)
38f0c6
+    file = open(fname, "rb")
38f0c6
     for line in file.readlines():
38f0c6
         m.update(line)
38f0c6
     file.close()
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/xetex.py b/lib/dbtexmf/dblatex/grubber/xetex.py
38f0c6
index f39a941..63bfe9d 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/xetex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/xetex.py
38f0c6
@@ -2,7 +2,7 @@
38f0c6
 XeTeX support for Rubber.
38f0c6
 """
38f0c6
 
38f0c6
-from plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
 
38f0c6
 class Module (TexModule):
38f0c6
     def __init__ (self, doc, dict):
38f0c6
diff --git a/lib/dbtexmf/dblatex/grubber/xr-hyper.py b/lib/dbtexmf/dblatex/grubber/xr-hyper.py
38f0c6
index d7bee5c..36f4761 100644
38f0c6
--- a/lib/dbtexmf/dblatex/grubber/xr-hyper.py
38f0c6
+++ b/lib/dbtexmf/dblatex/grubber/xr-hyper.py
38f0c6
@@ -9,9 +9,9 @@ file, so this support package registers these files as dependencies.
38f0c6
 """
38f0c6
 import os
38f0c6
 
38f0c6
-from msg import _, msg
38f0c6
-from plugins import TexModule
38f0c6
-from latex import Latex
38f0c6
+from dbtexmf.dblatex.grubber.msg import _, msg
38f0c6
+from dbtexmf.dblatex.grubber.plugins import TexModule
38f0c6
+from dbtexmf.dblatex.grubber.latex import Latex
38f0c6
 
38f0c6
 class Module(TexModule):
38f0c6
     def __init__ (self, doc, dict):
38f0c6
@@ -23,7 +23,7 @@ class Module(TexModule):
38f0c6
         # remember the engine used to build the main latex document
38f0c6
         self.texmodules = []
38f0c6
         for m in ("pdftex", "xetex"):
38f0c6
-            if doc.modules.has_key(m):
38f0c6
+            if m in doc.modules:
38f0c6
                 self.texmodules.append(m)
38f0c6
 
38f0c6
         # want to track each external document whose .aux is required
38f0c6
diff --git a/lib/dbtexmf/dblatex/rawparse.py b/lib/dbtexmf/dblatex/rawparse.py
38f0c6
index a06a61d..9af17fa 100644
38f0c6
--- a/lib/dbtexmf/dblatex/rawparse.py
38f0c6
+++ b/lib/dbtexmf/dblatex/rawparse.py
38f0c6
@@ -1,7 +1,7 @@
38f0c6
 import re
38f0c6
 
38f0c6
-from texcodec import LatexCodec, TexCodec
38f0c6
-from texhyphen import BasicHyphenator, UrlHyphenator
38f0c6
+from dbtexmf.dblatex.texcodec import LatexCodec, TexCodec
38f0c6
+from dbtexmf.dblatex.texhyphen import BasicHyphenator, UrlHyphenator
38f0c6
 
38f0c6
 
38f0c6
 def utf8(u):
38f0c6
@@ -31,7 +31,7 @@ class RawLatexParser:
38f0c6
         self.hypof = re.compile(utf8(u"\u0371h"))
38f0c6
 
38f0c6
     def parse(self, line):
38f0c6
-        lout = ""
38f0c6
+        lout = b""
38f0c6
         while (line):
38f0c6
             self.key_in.pos = line.find(self.key_in.key)
38f0c6
             self.key_out.pos = line.find(self.key_out.key)
38f0c6
@@ -48,14 +48,14 @@ class RawLatexParser:
38f0c6
                 line = line[key.pos + key.len:]
38f0c6
             else:
38f0c6
                 text = line
38f0c6
-                line = ""
38f0c6
+                line = b""
38f0c6
 
38f0c6
             if (text):
38f0c6
                 if self.depth > 0:
38f0c6
                     lout += self.translate(text)
38f0c6
                 else:
38f0c6
-                    text, hon = self.hypon.subn("", text)
38f0c6
-                    text, hof = self.hypof.subn("", text)
38f0c6
+                    text, hon = self.hypon.subn(b"", text)
38f0c6
+                    text, hof = self.hypof.subn(b"", text)
38f0c6
                     self.hyphenate += (hon - hof)
38f0c6
                     lout += text
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/rawtex.py b/lib/dbtexmf/dblatex/rawtex.py
38f0c6
index cc70d25..be3daee 100644
38f0c6
--- a/lib/dbtexmf/dblatex/rawtex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/rawtex.py
38f0c6
@@ -7,10 +7,11 @@
38f0c6
 import sys
38f0c6
 import os
38f0c6
 import re
38f0c6
+from io import open
38f0c6
 
38f0c6
-from rawparse import RawLatexParser, RawUtfParser
38f0c6
-from rawverb import VerbParser
38f0c6
-from xetex.codec import XetexCodec
38f0c6
+from dbtexmf.dblatex.rawparse import RawLatexParser, RawUtfParser
38f0c6
+from dbtexmf.dblatex.rawverb import VerbParser
38f0c6
+from dbtexmf.dblatex.xetex.codec import XetexCodec
38f0c6
 from dbtexmf.core.imagedata import *
38f0c6
 
38f0c6
 
38f0c6
@@ -18,9 +19,9 @@ class RawLatex:
38f0c6
     "Main latex file parser"
38f0c6
     def __init__(self):
38f0c6
         self.figre = \
38f0c6
-            re.compile(r"(\\includegraphics[\[]?|"\
38f0c6
-                       r"\\begin{overpic}|"\
38f0c6
-                       r"\\imgexits)[^{]*{([^}]*)}")
38f0c6
+            re.compile(br"(\\includegraphics[\[]?|"\
38f0c6
+                       br"\\begin{overpic}|"\
38f0c6
+                       br"\\imgexits)[^{]*{([^}]*)}")
38f0c6
         self.image = Imagedata()
38f0c6
         self.parsers = []
38f0c6
         self.format = None
38f0c6
@@ -35,7 +36,7 @@ class RawLatex:
38f0c6
             output_encoding = "utf8"
38f0c6
             codec = XetexCodec()
38f0c6
         elif not(output_encoding):
38f0c6
-            f = file(input)
38f0c6
+            f = open(input, "rt", encoding="latin-1")
38f0c6
             params = {}
38f0c6
             started = 0
38f0c6
             for line in f:
38f0c6
@@ -68,8 +69,8 @@ class RawLatex:
38f0c6
 
38f0c6
     def parse(self, input, output):
38f0c6
         self.set_parsers(input)
38f0c6
-        f = file(input)
38f0c6
-        o = file(output, "w")
38f0c6
+        f = open(input, "rb")
38f0c6
+        o = open(output, "wb")
38f0c6
         for line in f:
38f0c6
             if self.format:
38f0c6
                 line = self.figconvert(line)
38f0c6
@@ -95,7 +96,7 @@ class RawLatex:
38f0c6
 
38f0c6
             # If something done, replace the figure in the tex file
38f0c6
             if newfig != fig:
38f0c6
-                line = re.sub(r"{%s}" % fig, r"{%s}" % newfig, line)
38f0c6
+                line = re.sub(br"{%s}" % fig, br"{%s}" % newfig, line)
38f0c6
 
38f0c6
         return line
38f0c6
             
38f0c6
diff --git a/lib/dbtexmf/dblatex/rawverb.py b/lib/dbtexmf/dblatex/rawverb.py
38f0c6
index 36b30cf..49c0d0a 100644
38f0c6
--- a/lib/dbtexmf/dblatex/rawverb.py
38f0c6
+++ b/lib/dbtexmf/dblatex/rawverb.py
38f0c6
@@ -10,10 +10,11 @@
38f0c6
 #   if necessary.
38f0c6
 #
38f0c6
 import re
38f0c6
+from io import open
38f0c6
 
38f0c6
-from texcodec import TexCodec
38f0c6
-from texcodec import tex_handler_counter
38f0c6
-from rawparse import RawUtfParser
38f0c6
+from dbtexmf.dblatex.texcodec import TexCodec
38f0c6
+from dbtexmf.dblatex.texcodec import tex_handler_counter
38f0c6
+from dbtexmf.dblatex.rawparse import RawUtfParser
38f0c6
 
38f0c6
 
38f0c6
 class VerbCodec(TexCodec):
38f0c6
@@ -49,13 +50,13 @@ class VerbParser:
38f0c6
     def __init__(self, output_encoding="latin-1"):
38f0c6
         # The listing environment can be different from 'lstlisting'
38f0c6
         # but the rule is that it must begin with 'lst'
38f0c6
-        self.start_re = re.compile(r"\\begin{lst[^}]*}")
38f0c6
-        self.stop_re = re.compile(r"\\end{lst[^}]*}")
38f0c6
-        self.esc_re = re.compile(r"escapeinside={([^}]*)}{([^}]*)}")
38f0c6
-        self.block = ""
38f0c6
+        self.start_re = re.compile(br"\\begin{lst[^}]*}")
38f0c6
+        self.stop_re = re.compile(br"\\end{lst[^}]*}")
38f0c6
+        self.esc_re = re.compile(br"escapeinside={([^}]*)}{([^}]*)}")
38f0c6
+        self.block = b""
38f0c6
         self.encoding = output_encoding
38f0c6
-        self.default_esc_start = "<:"
38f0c6
-        self.default_esc_stop = ":>"
38f0c6
+        self.default_esc_start = b"<:"
38f0c6
+        self.default_esc_stop = b":>"
38f0c6
         self.default_codec = VerbCodec(self.default_esc_start,
38f0c6
                                        self.default_esc_stop,
38f0c6
                                        output_encoding=output_encoding)
38f0c6
@@ -79,13 +80,13 @@ class VerbParser:
38f0c6
         self.command = line[m.start():m.end()]
38f0c6
         line = line[m.end():]
38f0c6
         # By default, no escape sequence defined yet
38f0c6
-        self.esc_start = ""
38f0c6
-        self.esc_stop = ""
38f0c6
-        self.options = ""
38f0c6
+        self.esc_start = b""
38f0c6
+        self.esc_stop = b""
38f0c6
+        self.options = b""
38f0c6
 
38f0c6
         # If there are some options, look for escape specs
38f0c6
-        if line[0] == "[":
38f0c6
-            e = line.find("]")+1
38f0c6
+        if line[0] == b"[":
38f0c6
+            e = line.find(b"]")+1
38f0c6
             self.options = line[:e]
38f0c6
             line = line[e:]
38f0c6
             m = self.esc_re.search(self.options)
38f0c6
@@ -109,28 +110,28 @@ class VerbParser:
38f0c6
 
38f0c6
         # Add the escape option if necessary
38f0c6
         if not(self.esc_start) and c.get_errors() != 0:
38f0c6
-            escopt = "escapeinside={%s}{%s}" % (c.pre, c.post)
38f0c6
+            escopt = b"escapeinside={%s}{%s}" % (c.pre, c.post)
38f0c6
             if self.options:
38f0c6
                 if self.options[-2] != ",":
38f0c6
-                    escopt = "," + escopt
38f0c6
+                    escopt = b"," + escopt
38f0c6
                 self.options = self.options[:-1] + escopt + "]"
38f0c6
             else:
38f0c6
-                self.options = "[" + escopt + "]"
38f0c6
+                self.options = b"[" + escopt + b"]"
38f0c6
 
38f0c6
         block = self.command + self.options + text + line[m.start():]
38f0c6
-        self.block = ""
38f0c6
+        self.block = b""
38f0c6
         return block
38f0c6
 
38f0c6
     def block_grow(self, line):
38f0c6
         self.block += line
38f0c6
-        return ""
38f0c6
+        return b""
38f0c6
 
38f0c6
     def get_codec(self):
38f0c6
         # Something already specified
38f0c6
         if (self.esc_start):
38f0c6
             if self.esc_start != self.default_esc_start:
38f0c6
                 return VerbCodec(self.esc_start, self.esc_stop,
38f0c6
-                                 "verbtex" + self.esc_start,
38f0c6
+                                 b"verbtex" + self.esc_start,
38f0c6
                                  output_encoding=self.encoding)
38f0c6
             else:
38f0c6
                 return self.default_codec
38f0c6
@@ -140,7 +141,7 @@ class VerbParser:
38f0c6
         iter = 0
38f0c6
         i = self.block.find(s)
38f0c6
         while (i != -1):
38f0c6
-            s = "<" + str(iter) + ":"
38f0c6
+            s = b"<" + bytes(iter) + b":"
38f0c6
             i = self.block.find(s)
38f0c6
             iter += 1
38f0c6
 
38f0c6
@@ -148,16 +149,17 @@ class VerbParser:
38f0c6
         if (s == self.default_esc_start):
38f0c6
             return self.default_codec
38f0c6
 
38f0c6
-        return VerbCodec(s, self.default_esc_stop, "verbtex" + s,
38f0c6
+        return VerbCodec(s, self.default_esc_stop, b"verbtex" + s,
38f0c6
                          output_encoding=self.encoding)
38f0c6
 
38f0c6
 
38f0c6
 if __name__ == "__main__":
38f0c6
     import sys
38f0c6
     v = VerbParser()
38f0c6
-    f = open(sys.argv[1])
38f0c6
+    buf = getattr(sys.stdout, "buffer", sys.stdout)
38f0c6
+    f = open(sys.argv[1], "rb")
38f0c6
     for line in f:
38f0c6
         text = v.parse(line)
38f0c6
         if text:
38f0c6
-            sys.stdout.write(text)
38f0c6
+            buf.write(text)
38f0c6
 
38f0c6
diff --git a/lib/dbtexmf/dblatex/runtex.py b/lib/dbtexmf/dblatex/runtex.py
38f0c6
index c89e43d..91a88ae 100644
38f0c6
--- a/lib/dbtexmf/dblatex/runtex.py
38f0c6
+++ b/lib/dbtexmf/dblatex/runtex.py
38f0c6
@@ -4,8 +4,9 @@
38f0c6
 import os
38f0c6
 import re
38f0c6
 import shutil
38f0c6
+from io import open
38f0c6
 
38f0c6
-from grubber.texbuilder import LatexBuilder
38f0c6
+from dbtexmf.dblatex.grubber.texbuilder import LatexBuilder
38f0c6
 
38f0c6
 
38f0c6
 class RunLatex:
38f0c6
@@ -86,16 +87,16 @@ class RunLatex:
38f0c6
         texout = root + "." + format
38f0c6
 
38f0c6
         # The temporary file contains the extra paths
38f0c6
-        f = file(tmptex, "w")
38f0c6
+        f = open(tmptex, "wt", encoding="latin-1")
38f0c6
         if self.fig_paths:
38f0c6
             paths = "{" + "//}{".join(self.fig_paths) + "//}"
38f0c6
-            f.write("\\makeatletter\n")
38f0c6
-            f.write("\\def\\input@path{%s}\n" % paths)
38f0c6
-            f.write("\\makeatother\n")
38f0c6
+            f.write(u"\\makeatletter\n")
38f0c6
+            f.write(u"\\def\\input@path{%s}\n" % paths)
38f0c6
+            f.write(u"\\makeatother\n")
38f0c6
 
38f0c6
         # Copy the original file and collect parameters embedded in the tex file
38f0c6
         self._clear_params()
38f0c6
-        input = file(texfile)
38f0c6
+        input = open(texfile, "rt", encoding="latin-1")
38f0c6
         for line in input:
38f0c6
             self._set_params(line)
38f0c6
             f.write(line)
38f0c6
diff --git a/lib/dbtexmf/dblatex/texcodec.py b/lib/dbtexmf/dblatex/texcodec.py
38f0c6
index 3dfab6b..67e28b8 100644
38f0c6
--- a/lib/dbtexmf/dblatex/texcodec.py
38f0c6
+++ b/lib/dbtexmf/dblatex/texcodec.py
38f0c6
@@ -2,9 +2,11 @@
38f0c6
 # The Latex Codec handles the encoding from UFT-8 text to latin1
38f0c6
 # latex compatible text.
38f0c6
 #
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import re
38f0c6
 import codecs
38f0c6
-import unient
38f0c6
+import dbtexmf.dblatex.unient as unient
38f0c6
 
38f0c6
 # Dictionnary of the handlers installed
38f0c6
 tex_handler_installed = {}
38f0c6
@@ -21,7 +23,7 @@ def latex_char_replace(exc, pre, post, name):
38f0c6
         try:
38f0c6
             l.append(unient.unicode_map[ord(c)])
38f0c6
         except KeyError:
38f0c6
-            print "Missing character &#x%x;" % ord(c)
38f0c6
+            print("Missing character &#x%x;" % ord(c))
38f0c6
             l.append(u"\&\#x%x;" % ord(c))
38f0c6
         if post: l.append(post)
38f0c6
         n = n + 1
38f0c6
@@ -32,21 +34,21 @@ def latex_char_replace(exc, pre, post, name):
38f0c6
 class TexCodec:
38f0c6
     # This mapping for characters < 256 seems enough for latin1 output
38f0c6
     charmap = {
38f0c6
-              "\xa0": r"~",
38f0c6
-              # "\xa2": r"\textcent{}",
38f0c6
-              # "\xa4": r"\textcurrency{}",
38f0c6
-              "\xa5": r"$\yen$",
38f0c6
-              # "\xa6": r"\textbrokenbar{}",
38f0c6
-              "\xac": r"\ensuremath{\lnot}",
38f0c6
-              # "\xad": r"", # FIXME: bug around soft hyphen...
38f0c6
-              "\xb0": r"\textdegree{}",
38f0c6
-              "\xb1": r"\ensuremath{\pm}",
38f0c6
-              "\xb2": r"$^2$",
38f0c6
-              "\xb3": r"$^3$",
38f0c6
-              "\xb5": r"$\mathrm{\mu}$",
38f0c6
-              "\xb9": r"$^1$",
38f0c6
-              "\xd7": r"$\times$",
38f0c6
-              "\xf7": r"$\div$"
38f0c6
+              b"\xa0": br"~",
38f0c6
+              # b"\xa2": br"\textcent{}",
38f0c6
+              # b"\xa4": br"\textcurrency{}",
38f0c6
+              b"\xa5": br"$\yen$",
38f0c6
+              # b"\xa6": br"\textbrokenbar{}",
38f0c6
+              b"\xac": br"\ensuremath{\lnot}",
38f0c6
+              # "\xad": br"", # FIXME: bug around soft hyphen...
38f0c6
+              b"\xb0": br"\textdegree{}",
38f0c6
+              b"\xb1": br"\ensuremath{\pm}",
38f0c6
+              b"\xb2": br"$^2$",
38f0c6
+              b"\xb3": br"$^3$",
38f0c6
+              b"\xb5": br"$\mathrm{\mu}$",
38f0c6
+              b"\xb9": br"$^1$",
38f0c6
+              b"\xd7": br"$\times$",
38f0c6
+              b"\xf7": br"$\div$"
38f0c6
               }
38f0c6
 
38f0c6
     def __init__(self, input_encoding="utf8", output_encoding="latin-1",
38f0c6
@@ -60,7 +62,7 @@ class TexCodec:
38f0c6
             self.charmap = {}
38f0c6
             return
38f0c6
 
38f0c6
-        if not(tex_handler_installed.has_key(self._errors)):
38f0c6
+        if not(self._errors in tex_handler_installed):
38f0c6
             f = self.build_error_func(pre, post, errors)
38f0c6
             codecs.register_error(self._errors, f)
38f0c6
             tex_handler_installed[self._errors] = f
38f0c6
@@ -121,19 +123,20 @@ class LatexCodec(TexCodec):
38f0c6
             text = text.replace(c, v)
38f0c6
 
38f0c6
         # Things are done, complete with {}
38f0c6
-        text = text.replace(r"\textbackslash", r"\textbackslash{}")
38f0c6
+        text = text.replace(br"\textbackslash", br"\textbackslash{}")
38f0c6
         return text
38f0c6
 
38f0c6
 
38f0c6
 def main():
38f0c6
     import sys
38f0c6
     c = LatexCodec()
38f0c6
-    f = open(sys.argv[1])
38f0c6
-    text = ""
38f0c6
+    buf = getattr(sys.stdout, "buffer", sys.stdout)
38f0c6
+    f = open(sys.argv[1], "rb")
38f0c6
+    text = "" if buf == sys.stdout else b""
38f0c6
     for line in f:
38f0c6
         text += c.encode(c.decode(line))
38f0c6
         if text:
38f0c6
-            sys.stdout.write(text)
38f0c6
+            buf.write(text)
38f0c6
 
38f0c6
 
38f0c6
 if __name__ == "__main__":
38f0c6
diff --git a/lib/dbtexmf/dblatex/texhyphen.py b/lib/dbtexmf/dblatex/texhyphen.py
38f0c6
index ab3545b..b28e6f8 100644
38f0c6
--- a/lib/dbtexmf/dblatex/texhyphen.py
38f0c6
+++ b/lib/dbtexmf/dblatex/texhyphen.py
38f0c6
@@ -2,6 +2,8 @@
38f0c6
 # dblatex - Hyphenation classes to provide smart hyphenation of path like
38f0c6
 # strings
38f0c6
 #
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import re
38f0c6
 
38f0c6
 class Hyphenator:
38f0c6
@@ -18,14 +20,14 @@ class BasicHyphenator(Hyphenator):
38f0c6
     """
38f0c6
     def __init__(self, codec=None):
38f0c6
         self.codec = codec
38f0c6
-        self.hyphenchar = "\-"
38f0c6
+        self.hyphenchar = b"\-"
38f0c6
 
38f0c6
     def hyphenate(self, text):
38f0c6
         if self.codec: text = self.codec.decode(text)
38f0c6
         ntext = "\1".join(list(text))
38f0c6
         if self.codec: ntext = self.codec.encode(ntext)
38f0c6
-        ntext = re.sub("\1? \1?", " ", ntext)
38f0c6
-        ntext = ntext.replace("\1", self.hyphenchar)
38f0c6
+        ntext = re.sub(b"\1? \1?", b" ", ntext)
38f0c6
+        ntext = ntext.replace(b"\1", self.hyphenchar)
38f0c6
         return ntext
38f0c6
 
38f0c6
 
38f0c6
@@ -49,7 +51,7 @@ class UrlHyphenator(Hyphenator):
38f0c6
     existing latex styles.
38f0c6
     """
38f0c6
     def __init__(self, codec=None,
38f0c6
-                 h_sep="\penalty0 ", h_char="\penalty5000 ",
38f0c6
+                 h_sep=b"\penalty0 ", h_char=b"\penalty5000 ",
38f0c6
                  h_start=3, h_stop=3):
38f0c6
         self.codec = codec
38f0c6
         self.seps = r":/\@=?#;-."
38f0c6
@@ -84,17 +86,17 @@ class UrlHyphenator(Hyphenator):
38f0c6
                     nw += "\1".join(list(hword))
38f0c6
                     nw += w[-self.h_stop:]
38f0c6
                     nw = self._translate(nw)
38f0c6
-                    nw = re.sub("\1? \1?", " ", nw)
38f0c6
-                    nw = nw.replace("\1", self.h_char)
38f0c6
+                    nw = re.sub(b"\1? \1?", b" ", nw)
38f0c6
+                    nw = nw.replace(b"\1", self.h_char)
38f0c6
                     vtext.append(nw)
38f0c6
 
38f0c6
-        ntext = "".join(vtext)
38f0c6
+        ntext = b"".join(vtext)
38f0c6
         return ntext
38f0c6
 
38f0c6
 
38f0c6
 if __name__ == "__main__":
38f0c6
-    url = "http://www.fg/foobar fun#fght/fkkkf.tz?id=123"
38f0c6
+    url = b"http://www.fg/foobar fun#fght/fkkkf.tz?id=123"
38f0c6
     h1 = BasicHyphenator()
38f0c6
     h2 = UrlHyphenator()
38f0c6
-    print h1.hyphenate(url)
38f0c6
-    print h2.hyphenate(url)
38f0c6
+    print(h1.hyphenate(url))
38f0c6
+    print(h2.hyphenate(url))
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/codec.py b/lib/dbtexmf/dblatex/xetex/codec.py
38f0c6
index 9ef35b9..b4aad2b 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/codec.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/codec.py
38f0c6
@@ -3,7 +3,7 @@ import os
38f0c6
 import codecs
38f0c6
 
38f0c6
 from dbtexmf.dblatex.texcodec import LatexCodec
38f0c6
-from fsencoder import FontSpecEncoder
38f0c6
+from dbtexmf.dblatex.xetex.fsencoder import FontSpecEncoder
38f0c6
 
38f0c6
 
38f0c6
 class XetexCodec(LatexCodec):
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/fcfallback.py b/lib/dbtexmf/dblatex/xetex/fcfallback.py
38f0c6
index dea9ea2..29c1a44 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/fcfallback.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/fcfallback.py
38f0c6
@@ -1,5 +1,7 @@
38f0c6
-from fontspec import FontSpec
38f0c6
-from fcmanager import FcManager
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
+from dbtexmf.dblatex.xetex.fontspec import FontSpec
38f0c6
+from dbtexmf.dblatex.xetex.fcmanager import FcManager
38f0c6
 
38f0c6
 
38f0c6
 class DefaultFontSpec(FontSpec):
38f0c6
@@ -54,8 +56,8 @@ class FcFallbackFontSpec(DefaultFontSpec):
38f0c6
         for fontspec in self.fontspecs:
38f0c6
 
38f0c6
             if fontspec in self.fcmissed:
38f0c6
-                print "Specified font '%s' is missing in the system!" % \
38f0c6
-                      (fontspec.mainfont())
38f0c6
+                print("Specified font '%s' is missing in the system!" % \
38f0c6
+                      (fontspec.mainfont()))
38f0c6
                 continue
38f0c6
 
38f0c6
             fcfont = self.fccache.get(fontspec.mainfont()) or \
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/fcmanager.py b/lib/dbtexmf/dblatex/xetex/fcmanager.py
38f0c6
index b972270..91ed6da 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/fcmanager.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/fcmanager.py
38f0c6
@@ -5,12 +5,15 @@
38f0c6
 # An efficient solution should use some python bindings to directly call the
38f0c6
 # C fontconfig library.
38f0c6
 #
38f0c6
+import sys
38f0c6
 import logging
38f0c6
 from subprocess import Popen, PIPE
38f0c6
 
38f0c6
 def execute(cmd):
38f0c6
     p = Popen(cmd, stdout=PIPE)
38f0c6
     data = p.communicate()[0]
38f0c6
+    if isinstance(data, bytes):
38f0c6
+        data = data.decode(sys.getdefaultencoding())
38f0c6
     rc = p.wait()
38f0c6
     if rc != 0:
38f0c6
         raise OSError("'%s' failed (%d)" % (" ".join(cmd), rc))
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/fontspec.py b/lib/dbtexmf/dblatex/xetex/fontspec.py
38f0c6
index cd93cde..767d003 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/fontspec.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/fontspec.py
38f0c6
@@ -49,7 +49,7 @@ class UnicodeInterval:
38f0c6
         if m:
38f0c6
             return int(m.group(1), 16)
38f0c6
         else:
38f0c6
-            raise RuntimeError, 'Not a unicode codepoint: ' + codepoint
38f0c6
+            raise RuntimeError('Not a unicode codepoint: ' + codepoint)
38f0c6
 
38f0c6
     def from_char(self, char):
38f0c6
         """Interval for a single character"""
38f0c6
@@ -167,7 +167,7 @@ class FontSpec:
38f0c6
                     intervals.append(
38f0c6
                         UnicodeInterval().from_codepoint(m.group(1)))
38f0c6
                 else:
38f0c6
-                    raise RuntimeError, 'Unable to parse range: "' + range + '"'
38f0c6
+                    raise RuntimeError('Unable to parse range: "' + range + '"')
38f0c6
         return intervals
38f0c6
 
38f0c6
     def _parse_transitions(self, node, transition_type):
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/fsconfig.py b/lib/dbtexmf/dblatex/xetex/fsconfig.py
38f0c6
index f62e51e..06c9adf 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/fsconfig.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/fsconfig.py
38f0c6
@@ -12,8 +12,8 @@ import re
38f0c6
 import xml.dom.minidom
38f0c6
 import logging
38f0c6
 
38f0c6
-from fcfallback import FcFallbackFontSpec, DefaultFontSpec
38f0c6
-from fontspec import FontSpec, _indent
38f0c6
+from dbtexmf.dblatex.xetex.fcfallback import FcFallbackFontSpec, DefaultFontSpec
38f0c6
+from dbtexmf.dblatex.xetex.fontspec import FontSpec, _indent
38f0c6
 
38f0c6
 
38f0c6
 class FontSpecConfig:
38f0c6
diff --git a/lib/dbtexmf/dblatex/xetex/fsencoder.py b/lib/dbtexmf/dblatex/xetex/fsencoder.py
38f0c6
index 9960bbe..6175adf 100644
38f0c6
--- a/lib/dbtexmf/dblatex/xetex/fsencoder.py
38f0c6
+++ b/lib/dbtexmf/dblatex/xetex/fsencoder.py
38f0c6
@@ -7,12 +7,14 @@ Provide an encoder for a font specification configuration: the encoder is fed
38f0c6
 with Unicode characters one by one and determines the needed font switches
38f0c6
 between the preceding and the current character.
38f0c6
 """
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import sys
38f0c6
 import re
38f0c6
 import xml.dom.minidom
38f0c6
 
38f0c6
-from fontspec import UnicodeInterval
38f0c6
-from fsconfig import FontSpecConfig
38f0c6
+from dbtexmf.dblatex.xetex.fontspec import UnicodeInterval
38f0c6
+from dbtexmf.dblatex.xetex.fsconfig import FontSpecConfig
38f0c6
 
38f0c6
 
38f0c6
 class FontSpecEncoder:
38f0c6
@@ -68,7 +70,7 @@ class FontSpecEncoder:
38f0c6
         """
38f0c6
         fontspec = self._cur_fontspec or self._conf.default_fontspec
38f0c6
 
38f0c6
-        print >>sys.stderr, "Current:", fontspec.id
38f0c6
+        print("Current:", fontspec.id, file=sys.stderr)
38f0c6
         fontspec = fontspec.match(char)
38f0c6
         while not(fontspec):
38f0c6
             leaf = self._ref_stack.pop()
38f0c6
diff --git a/lib/dbtexmf/xslt/4xslt.py b/lib/dbtexmf/xslt/4xslt.py
38f0c6
index 4af729f..3746fce 100644
38f0c6
--- a/lib/dbtexmf/xslt/4xslt.py
38f0c6
+++ b/lib/dbtexmf/xslt/4xslt.py
38f0c6
@@ -3,6 +3,7 @@
38f0c6
 #
38f0c6
 import sys
38f0c6
 import os
38f0c6
+from io import open
38f0c6
 
38f0c6
 from Ft.Xml.Xslt import Processor
38f0c6
 from Ft.Lib.Uri import OsPathToUri
38f0c6
@@ -49,7 +50,7 @@ class FourXslt:
38f0c6
         uri =  OsPathToUri(xslfile)
38f0c6
         xslt = factory.fromUri(uri,  processIncludes=False)
38f0c6
 
38f0c6
-        o = open(outfile, "w")
38f0c6
+        o = open(outfile, "wb")
38f0c6
         proc.appendStylesheet(xslt)
38f0c6
         if params:
38f0c6
             rc = proc.run(xml, outputStream=o, topLevelParams=params)
38f0c6
diff --git a/lib/dbtexmf/xslt/xsltproc.py b/lib/dbtexmf/xslt/xsltproc.py
38f0c6
index 38f1d2b..db72a87 100644
38f0c6
--- a/lib/dbtexmf/xslt/xsltproc.py
38f0c6
+++ b/lib/dbtexmf/xslt/xsltproc.py
38f0c6
@@ -2,6 +2,7 @@
38f0c6
 # Basic wrapper for xsltproc. Maybe we should directly use the lixslt Python
38f0c6
 # API.
38f0c6
 #
38f0c6
+import sys
38f0c6
 import os
38f0c6
 import logging
38f0c6
 import re
38f0c6
@@ -43,6 +44,8 @@ class XsltProc:
38f0c6
         # check that with help output the option is there
38f0c6
         p = Popen(["xsltproc"], stdout=PIPE)
38f0c6
         data = p.communicate()[0]
38f0c6
+        if isinstance(data, bytes):
38f0c6
+            data = data.decode(sys.getdefaultencoding())
38f0c6
         m = re.search("--xincludestyle", data, re.M)
38f0c6
         if not(m):
38f0c6
             return False
38f0c6
diff --git a/setup.py b/setup.py
38f0c6
index 5af4cfb..379323b 100644
38f0c6
--- a/setup.py
38f0c6
+++ b/setup.py
38f0c6
@@ -3,11 +3,14 @@
38f0c6
 #
38f0c6
 # dblatex python setup script - See the COPYRIGHT
38f0c6
 #
38f0c6
+from __future__ import print_function
38f0c6
+
38f0c6
 import os
38f0c6
 import sys
38f0c6
 import re
38f0c6
 import glob
38f0c6
 import subprocess
38f0c6
+from io import open
38f0c6
 
38f0c6
 try:
38f0c6
     from setuptools import setup
38f0c6
@@ -83,7 +86,7 @@ os.environ["SGML_CATALOG_FILES"] = cat
38f0c6
         self._catalogs = install.catalogs
38f0c6
         self._style = install.style
38f0c6
         self._use_py_path = install.use_python_path
38f0c6
-        print self._package_base
38f0c6
+        print(self._package_base)
38f0c6
 
38f0c6
         # Build the command line script
38f0c6
         self.build_script()
38f0c6
@@ -162,8 +165,8 @@ os.environ["SGML_CATALOG_FILES"] = cat
38f0c6
         script = self.SHELL_SCRIPT % script_args
38f0c6
         script_name = os.path.basename(script_name)
38f0c6
         outfile = os.path.join(self.build_dir, script_name)
38f0c6
-        fd = os.open(outfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0755)
38f0c6
-        os.write(fd, script)
38f0c6
+        fd = os.open(outfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0o755)
38f0c6
+        os.write(fd, script.encode('ascii'))
38f0c6
         os.close(fd)
38f0c6
 
38f0c6
 
38f0c6
@@ -225,8 +228,10 @@ def kpsewhich(tex_file):
38f0c6
         close_fds = True
38f0c6
     p = Popen("kpsewhich %s" % tex_file, shell=True,
38f0c6
               stdin=PIPE, stdout=PIPE, close_fds=close_fds)
38f0c6
-    out = "".join(p.stdout.readlines()).strip()
38f0c6
-    return out
38f0c6
+    data = p.communicate()[0]
38f0c6
+    if isinstance(data, bytes):
38f0c6
+        data = data.decode(sys.getdefaultencoding())
38f0c6
+    return data.strip()
38f0c6
 
38f0c6
 
38f0c6
 class Sdist(sdist):
38f0c6
@@ -260,19 +265,19 @@ class Install(install):
38f0c6
         # First, check non critical graphic tools
38f0c6
         found, missed = find_programs(("epstopdf", "convert", "fig2dev"))
38f0c6
         for util in found:
38f0c6
-            print "+checking %s... yes" % util
38f0c6
+            print("+checking %s... yes" % util)
38f0c6
         for util in missed:
38f0c6
-            print "+checking %s... no" % util
38f0c6
+            print("+checking %s... no" % util)
38f0c6
         if missed:
38f0c6
-            print("warning: not found: %s" % ", ".join(missed))
38f0c6
+            print(("warning: not found: %s" % ", ".join(missed)))
38f0c6
 
38f0c6
         # Now, be serious
38f0c6
         found, missed = find_programs(("latex", "makeindex",
38f0c6
                                        "pdflatex", "kpsewhich"))
38f0c6
         for util in found:
38f0c6
-            print "+checking %s... yes" % util
38f0c6
+            print("+checking %s... yes" % util)
38f0c6
         for util in missed:
38f0c6
-            print "+checking %s... no" % util
38f0c6
+            print("+checking %s... no" % util)
38f0c6
         if missed:
38f0c6
             raise OSError("not found: %s" % ", ".join(missed))
38f0c6
 
38f0c6
@@ -292,21 +297,21 @@ class Install(install):
38f0c6
         for (mod, deplist) in deplists:
38f0c6
             if not(deplist):
38f0c6
                 xslt_found.append(mod)
38f0c6
-                print "+checking XSLT %s... yes" % mod
38f0c6
+                print("+checking XSLT %s... yes" % mod)
38f0c6
                 continue
38f0c6
             found, missed = find_programs(deplist)
38f0c6
             if missed:
38f0c6
                 xslt_missed.append(mod)
38f0c6
-                print "+checking XSLT %s... no (missing %s)" % \
38f0c6
-                      (mod, ", ".join(missed))
38f0c6
+                print("+checking XSLT %s... no (missing %s)" % \
38f0c6
+                      (mod, ", ".join(missed)))
38f0c6
             else:
38f0c6
                 xslt_found.append(mod)
38f0c6
-                print "+checking XSLT %s... yes" % mod
38f0c6
+                print("+checking XSLT %s... yes" % mod)
38f0c6
 
38f0c6
         if not(xslt_found):
38f0c6
             raise OSError("XSLT not installed: %s" % ", ".join(xslt_missed))
38f0c6
         elif xslt_missed:
38f0c6
-            print "warning: XSLT not found: %s" % ", ".join(xslt_missed)
38f0c6
+            print("warning: XSLT not found: %s" % ", ".join(xslt_missed))
38f0c6
 
38f0c6
     def check_latex_dependencies(self):
38f0c6
         # Find the Latex files from the package
38f0c6
@@ -322,7 +327,7 @@ class Install(install):
38f0c6
         used_stys = []
38f0c6
         re_sty = re.compile(r"\\usepackage\s*\[?.*\]?{(\w+)}")
38f0c6
         for sty in stys:
38f0c6
-            f = open(sty)
38f0c6
+            f = open(sty, "rt", encoding="latin-1")
38f0c6
             for line in f:
38f0c6
                 line = line.split("%")[0]
38f0c6
                 m = re_sty.search(line)
38f0c6
@@ -353,7 +358,7 @@ class Install(install):
38f0c6
             if sty in own_stys:
38f0c6
                 status += "found in package"
38f0c6
                 found_stys.append(sty)
38f0c6
-                print status
38f0c6
+                print(status)
38f0c6
                 continue
38f0c6
             stypath = kpsewhich("%s.sty" % sty)
38f0c6
             if stypath:
38f0c6
@@ -362,7 +367,7 @@ class Install(install):
38f0c6
             else:
38f0c6
                 status += "no"
38f0c6
                 mis_stys.append(sty)
38f0c6
-            print status
38f0c6
+            print(status)
38f0c6
             
38f0c6
         if mis_stys:
38f0c6
             raise OSError("not found: %s" % ", ".join(mis_stys))
38f0c6
@@ -378,8 +383,8 @@ class Install(install):
38f0c6
                 self.check_xslt_dependencies()
38f0c6
                 self.check_util_dependencies()
38f0c6
                 self.check_latex_dependencies()
38f0c6
-            except Exception, e:
38f0c6
-                print >>sys.stderr, "Error: %s" % e
38f0c6
+            except Exception as e:
38f0c6
+                print("Error: %s" % e, file=sys.stderr)
38f0c6
                 sys.exit(1)
38f0c6
 
38f0c6
         if db: db.adapt_paths()
38f0c6
@@ -450,17 +455,17 @@ class InstallData(install_data):
38f0c6
             return
38f0c6
 
38f0c6
         # Grab the value from package version
38f0c6
-        d = open(hyper_sty).read()
38f0c6
-        m = re.search("\\ProvidesPackage{hyperref}\s+\[(\d+)", d, re.M)
38f0c6
+        d = open(hyper_sty, "rt", encoding="latin-1").read()
38f0c6
+        m = re.search(r"\\ProvidesPackage{hyperref}\s+\[(\d+)", d, re.M)
38f0c6
         if not(m):
38f0c6
             return
38f0c6
         year = m.group(1)
38f0c6
 
38f0c6
         # Patch the parameter with the found value
38f0c6
-        p = open(param_file).read()
38f0c6
+        p = open(param_file, "rt", encoding="latin-1").read()
38f0c6
         p2 = re.sub('name="texlive.version">.*<',
38f0c6
                     'name="texlive.version">%s<' % year, p)
38f0c6
-        f = open(param_file, "w")
38f0c6
+        f = open(param_file, "wt", encoding="latin-1")
38f0c6
         f.write(p2)
38f0c6
         f.close()
38f0c6
 
38f0c6
-- 
38f0c6
2.17.1
38f0c6