Example #1
0
    def __imgSrc(self, node):
        # location of image
        src = node.attrib.get("src", "")

        if not src:
            msg = "Emtpy or missing 'src' attribute in 'img' tag "
            msg += "on line '%d'." % node.sourceline
            raise ECMDSPluginError(msg, "picture")
        #end if

        # if src is a relative path, prepend doc's location
        if src and not os.path.isabs(src):
            # get the root node
            tree = node.getroottree()

            baseURL = os.path.dirname(os.path.normpath(tree.docinfo.URL))
            src = os.path.join(baseURL, os.path.normpath(src))
        #end if

        if not os.path.isfile(src):
            msg = "Could not find bitmap file at location '%s' " % (src, )
            msg += "as specified in 'img' tag on line '%d'." % node.sourceline
            raise ECMDSPluginError(msg, "picture")
        #end if

        return src
Example #2
0
    def __identifyWidth(self, src):
        cmd = [self.identify_bin, src]
        with subprocess.Popen(cmd,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT) as proc:
            result = proc.stdout.read().decode("utf-8")

        # this is a bit of an interesting way to determine an error condition...
        if result.startswith("identify:"):
            msg = "Could not determine bitmap's dimensions:\n  '%s'." % (
                result, )
            raise ECMDSPluginError(msg, "picture")
        #end if

        result = result.split()
        rexpr = re.compile("[0-9]+x[0-9]+")
        width = None

        for value in result:
            if rexpr.match(value):
                width = value.split('x')[0]
                break
            #end if
        #end for

        if not width:
            msg = "Could not determine bitmap's dimensions:\n  '%s'." % (src, )
            raise ECMDSPluginError(msg, "picture")
        #end if

        return width
Example #3
0
    def __highlight(self, string, options):
        """Call syntax highlighter."""

        # output line numbers?
        try:
            self.__startline = int(options["startline"])
            self.__haveLineNumbers = True
        except ValueError:
            msg = "Invalid start line '%s'." % (options["startline"], )
            raise ECMDSPluginError(msg, "highlight")
        except KeyError:
            self.__haveLineNumbers = False
            self.__startline = 1
        #end try

        # increment to add to each line
        try:
            self.__lineStepping = int(options["linestep"])
        except ValueError:
            msg = "Invalid line stepping '%s'." % (options["linestep"], )
            raise ECMDSPluginError(msg, "highlight")
        except KeyError:
            self.__lineStepping = 1
        #end try

        # style to use
        try:
            self.__style = get_style_by_name(
                options.get('colorscheme', self.__colorscheme))
        except PygmentsClassNotFound:
            msg = "No style by name '%s'" % options["colorscheme"]
            raise ECMDSPluginError(msg, "highlight")
        except KeyError:
            self.__style = get_style_by_name("default")
        #end try

        # get a lexer for given syntax
        try:
            lexer = get_lexer_by_name(options["syntax"])
        except PygmentsClassNotFound:
            msg = "No lexer class found for '%s'." % options["syntax"]
            raise ECMDSPluginError(msg, "highlight")
        #end try

        # do the actual highlighting
        formatter = ECMLPygmentsFormatter(
            emit_line_numbers=self.__haveLineNumbers,
            startline=self.__startline,
            line_step=self.__lineStepping,
            style=self.__style,
            output_format=options["output_format"])

        return highlight(string, lexer, formatter)
Example #4
0
    def __init__(self, config):
        try:
            self.data_dir = config['data_dir']
        except KeyError:
            msg = "Path to data directory not specified."
            raise ECMDSPluginError(msg, "data")
        #end try

        # check if directory exists
        if not os.path.isdir(self.data_dir):
            msg = "Data directory '%s' does not exist." % self.data_dir
            raise ECMDSPluginError(msg, "data")
        #end if

        self.__filelist = []
Example #5
0
    def __convertImg(self, src, dst, width=None):
        # build command line
        if width:
            cmd = [
                self.convert_bin, "-antialias", "-density", self.convert_dpi,
                "-scale", width + "x"
            ]
        else:
            cmd = [
                self.convert_bin, "-antialias", "-density", self.convert_dpi
            ]
        #end if

        # remove alpha channel if not supported
        if not dst[-4:] in [".png", ".pdf", ".svg", ".eps"]:
            cmd += ["-alpha", "remove"]

        # add source and destination filenames
        cmd += [src, dst]

        with open(os.devnull, "wb") as devnull:
            proc = subprocess.Popen(cmd, stdout=devnull, stderr=devnull)
            rval = proc.wait()

        # test exit status
        if rval != 0:
            msg = "Could not convert graphics file '%s'." % src
            raise ECMDSPluginError(msg, "picture")
Example #6
0
    def __init__(self, config):
        # init counter
        self.counter = 1
        self.nodelist = []

        # look for latex executable
        try:
            self.latex_bin = config['latex_bin']
        except KeyError:
            msg = "Location of the 'latex' executable unspecified."
            raise ECMDSPluginError(msg, "math")
        #end try

        if not os.path.isfile(self.latex_bin):
            msg = "Could not find latex executable '%s'." % (self.latex_bin, )
            raise ECMDSPluginError(msg, "math")
        #end if

        # look for conversion tool
        try:
            self.dvipng_bin = ""
            self.dvipng_bin = config['dvipng_bin']
        except KeyError:
            msg = "Location of the 'dvipng' executable unspecified."
            raise ECMDSPluginError(msg, "math")
        #end try

        if not os.path.isfile(self.dvipng_bin):
            msg = "Could not find 'dvipng' executable '%s'." % (
                self.dvipng_bin, )
            raise ECMDSPluginError(msg, "math")
        #end if

        # temporary directory
        self.tmp_dir = config['tmp_dir']

        # conversion dpi
        try:
            self.dvipng_dpi = config['dvipng_dpi']
        except KeyError:
            self.dvipng_dpi = "100"
        #end try

        # output document
        self.out = io.StringIO()
Example #7
0
    def __init__(self, config):
        # set counter
        self.counter = 1
        self.imgmap = {}
        self.imgwidth = {}

        # look for conversion tool
        try:
            self.convert_bin = ""
            self.convert_bin = config['convert_bin']
        except KeyError:
            msg = "Location of the 'convert' executable not specified."
            raise ECMDSPluginError(msg, "picture")
        #end try
        if not os.path.isfile(self.convert_bin):
            msg = "Could not find 'convert' executable '%s'." % (
                self.convert_bin, )
            raise ECMDSPluginError(msg, "picture")
        #end if

        # look for identify tool
        try:
            self.identify_bin = ""
            self.identify_bin = config['identify_bin']
        except KeyError:
            msg = "Location of the 'identify' executable not specified."
            raise ECMDSPluginError(msg, "picture")
        #end try
        if not os.path.isfile(self.identify_bin):
            msg = "Could not find 'identify' executable '%s'." % (
                self.identify_bin, )
            raise ECMDSPluginError(msg, "picture")
        #end if

        # temporary directory
        self.tmp_dir = config['tmp_dir']

        # conversion dpi
        try:
            self.convert_dpi = config['convert_dpi']
        except KeyError:
            self.convert_dpi = "100"
Example #8
0
    def __eps2pdf(self, src, dst):
        # determine extension
        ext = '.' + src.strip().split('.')[-1]

        # look for bounding box
        rexpr = re.compile(
            r"(^%%BoundingBox:)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)")

        infile = None
        outfile = None

        try:
            # open source file and temporary output
            infile = open(src, "r", encoding="utf-8")
            tmpfd, tmpname = tempfile.mkstemp(suffix=".eps", dir=self.tmp_dir)
            outfile = os.fdopen(tmpfd, "w", encoding="utf-8")

            # Look for bounding box and adjust
            done = False
            for line in infile:
                m = rexpr.match(line)

                if not done and m:
                    llx = int(m.group(2))
                    lly = int(m.group(3))
                    urx = int(m.group(4))
                    ury = int(m.group(5))
                    width, height = (urx - llx, ury - lly)
                    xoff, yoff = (-llx, -lly)
                    outfile.write("%%%%BoundingBox: 0 0 %d %d\n" %
                                  (width, height))
                    outfile.write("<< /PageSize [%d %d] >> setpagedevice\n" %
                                  (width, height))
                    outfile.write("gsave %d %d translate\n" % (xoff, yoff))
                    done = True
                else:
                    outfile.write(line)
                #end if
            #end for

            self.__convertImg(tmpname, dst)
        except IOError:
            msg = "Could not convert EPS file '%s'" % src
            raise ECMDSPluginError(msg, "picture")
        finally:
            try:
                infile.close()
            except:
                pass
            try:
                outfile.close()
            except:
                pass
Example #9
0
    def flush(self):
        """Copy static assets, such as the icons, to output directory."""

        for fname in self.__filelist:
            src = None
            dst = None
            try:
                try:
                    src = open(os.path.join(self.data_dir, fname), "rb")
                    dst = open(fname, "wb+")
                    shutil.copyfileobj(src, dst)
                finally:
                    if src: src.close()
                    if dst: dst.close()
                #end try
            except Exception:
                msg = "Error while copying file '%s' to output directory." % fname
                raise ECMDSPluginError(msg, "data")
            #end try
        #end for

        self.__filelist = []
Example #10
0
    def process(self, node, format):
        """Prepare @node for target @format."""

        # look for 'colgroup' element
        colgroup = node.find("./colgroup")
        if colgroup is None:
            msg = "Missing 'colgroup' element in table starting at line '%d'."\
                    % node.sourceline
            raise ECMDSPluginError(msg, "table")
        #end if

        # build list of all 'col' elements
        columns = []
        for child in colgroup.iterchildren():
            if child.tag == "col":
                columns.append(child)
        #end for

        # number of columns
        num_cols = len(columns)

        # look for 'colsep' in table's 'frame' attribute
        table_frame = node.attrib.get("frame", None)

        if table_frame and "colsep" in table_frame:
            table_frame = 1
        else:
            table_frame = 0
        #end if

        # goto first row
        row = colgroup.getnext()

        # loop through table rows
        while row is not None:
            # look for 'colsep' in row's 'frame' attribute
            row_frame = row.attrib.get("frame", None)

            if row_frame and "colsep" in row_frame:
                row_frame = 1
            else:
                row_frame = 0
            #end if

            # goto first table cell
            cur_col = 0
            entry = row[0] if len(row) else None

            # loop over table cells
            while entry is not None:
                colspan = entry.attrib.get("colspan", None)

                if colspan:
                    try:
                        colspan = int(colspan)
                    except ValueError:
                        msg = "Invalid number in 'colspan' attribute on line %d."\
                                % entry.sourceline
                        raise ECMDSPluginError(msg, "table")
                    #end try
                else:
                    colspan = 1
                #end if

                cur_col = cur_col + colspan - 1

                # only for n-1 cols
                if cur_col < (num_cols - 1):
                    # let's see, if we have to update the corresponding 'col'
                    entry_frame = entry.attrib.get("frame", None)

                    if row_frame or table_frame:
                        columns[cur_col].attrib["frame"] = "colsep"
                    elif entry.tag == "subtable" and entry_frame and "right" in entry_frame:
                        columns[cur_col].attrib["frame"] = "colsep"
                    elif entry.tag != "subtable" and entry_frame and "colsep" in entry_frame:
                        columns[cur_col].attrib["frame"] = "colsep"
                    #end if
                #end if

                cur_col += 1
                entry = entry.getnext()
            #end while

            # count how many columns have colsep set
            num_cols_set = 0
            for col in columns:
                if col.attrib.get("frame") and "colsep" in col.attrib["frame"]:
                    num_cols_set += 1
            #end for

            # if every 'col' has been set, we can spare ourselves the rest
            if num_cols_set == (num_cols - 1):
                break

            # else continue in next row
            row = row.getnext()
        #end while

        return node
Example #11
0
    def __LaTeX2Dvi2Gif(self):
        """Write formulae to LaTeX file, compile and extract images."""

        # open a temporary file for TeX output
        tmpfp, tmpname = tempfile.mkstemp(suffix=".tex", dir=self.tmp_dir)

        try:
            with os.fdopen(tmpfp, "w", encoding="utf-8") as texfile:
                texfile.write(self.out.getvalue())
        except IOError:
            msg = "Error while writing temporary TeX file."
            raise ECMDSPluginError(msg, "math")
        #end try

        # compile LaTeX file
        with open(os.devnull, "wb") as devnull:
            cmd = [self.latex_bin, "-interaction", "nonstopmode", tmpname]

            # run LaTeX twice
            for i in range(2):
                proc = subprocess.Popen(cmd,
                                        stdout=devnull,
                                        stderr=devnull,
                                        cwd=self.tmp_dir)
                rval = proc.wait()

                # test exit code
                if rval != 0:
                    msg = "Could not compile temporary TeX file."
                    raise ECMDSPluginError(msg, "math")
                #end if
            #end if
        #end with

        # determine dvi file name
        dvifile = self.tmp_dir + os.sep + \
            ''.join(tmpname.split(os.sep)[-1].split('.')[:-1]) + ".dvi"

        # we need to log the output
        logfp, logname = tempfile.mkstemp(suffix=".log", dir=self.tmp_dir)

        # convert dvi file to GIF image
        with os.fdopen(logfp, "w", encoding="utf-8") as dvilog:
            cmd = [
                self.dvipng_bin, "-D", self.dvipng_dpi, "--depth", "-gif",
                "-T", "tight", "-o", "m%06d.gif", dvifile
            ]

            proc = subprocess.Popen(cmd, stdout=dvilog, stderr=dvilog)
            rval = proc.wait()

            # test exit code
            if rval != 0:
                msg = "Could not convert dvi file to GIF images."
                raise ECMDSPluginError(msg, "math")
            #end if
        #end with

        # read dvipng's log output
        try:
            with open(logname, "r", encoding="utf-8") as logfp:
                string = logfp.read()
        except IOError:
            msg = "Could not read dvipng's log output from '%s'" % logname
            raise ECMDSPluginError(msg, "math")
        #end try

        # look for [??? depth=???px]
        rexpr = re.compile("\\[[0-9]* depth=[0-9]*\\]")

        # add style property to node
        i = 0
        for match in rexpr.finditer(string):
            align = match.group().split("=")[1].strip(" []")
            node = self.nodelist[i]
            node.attrib["style"] = "vertical-align: -" + align + "px;"
            i += 1