示例#1
0
文件: text.py 项目: Cgadal/beampy
    def local_render(self):
        """Function to render only on text of this module.

        It's slower than writing all texts to one latex file and then
        render it to dvi then svg.
        """

        if self.latex_text != '':
            pretex = r"""
            \documentclass[crop=true]{standalone}
            \usepackage[utf8x]{inputenc}
            \usepackage{fix-cm}
            \usepackage[hypertex]{hyperref}
            \usepackage[svgnames]{xcolor}
            \renewcommand{\familydefault}{\sfdefault}
            \usepackage{varwidth}
            \usepackage{amsmath}
            \usepackage{amsfonts}
            \usepackage{amssymb}
            """

            pretex += '\n'.join(self.extra_packages + document._latex_packages)
            pretex += r'\begin{document}'
            pretex += self.latex_text
            pretex += r'\end{document}'

            #latex2svg
            self.svgtext = latex2svg(pretex)

        else:
            self.svgtext = ''
示例#2
0
def render_tikz( tikzcommands, args ):
    """
    Latex -> dvi -> svg for tikz image
    """

    tex_pt_to_px = 96/72.27

    #replace '\slidewidth'
    tiktikzcommands = tikzcommands.replace( r'\slidewidth','%ipt'%0.75*document._width)

    #Include extrac packages for tex
    if 'tex_packages' in args:
        extra_tex_packages = '\n'.join(['\\usepackages{%s}'%pkg for pkg in args['tex_packages']])
    else:
        extra_tex_packages = ''

    #Include extra tikz headers
    if 'tikzheader' in args:
        extra_tex_packages += '\n' + args['tikzheader']

    #Tikzfigure options in []
    if 'tikzfigureoptions' in args:
        tikz_fig_opts = '['+args['tikzfigureoptions']+']'
    else:
        tikz_fig_opts = ''

    #Render to a dvi file
    pretex = """
    \\documentclass[tikz,svgnames]{standalone}
    \\usepackage[utf8x]{inputenc}

    %s

    \\begin{document}
        \\begin{tikzpicture}%s
        %s
        \\end{tikzpicture}
    \\end{document}
    """%(extra_tex_packages,tikz_fig_opts,tikzcommands)

    #latex2svg
    svgout = latex2svg(pretex)

    if svgout != '':

        #Parse the svg
        soup = BeautifulSoup(svgout, 'xml')

        #Change svg id with global ids
        #soup = make_global_svg_defs(soup)

        #Find the width and height
        svgsoup = soup.find('svg')
        g = soup.find('g')

        xinit, yinit, tikz_width, tikz_height = svgsoup.get('viewBox').split()
        tikz_width = float(tikz_width)
        tikz_height = float(tikz_height)

        newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)'%(tex_pt_to_px, -float(xinit), -float(yinit))
        g['transform'] = newmatrix

        output = svgsoup.renderContents()

    else:
        #print(tex_msg)
        output = ''
        tikz_height = 0
        tikz_width = 0

    return output, tikz_width, tikz_height
示例#3
0
文件: text.py 项目: frankier/beampy
def render_text(ct, usetex=True):
    """
        Function to render the text using latex

        latex -> dvi -> dvi2svgm -> svg

        Use the svg output for the text in the frame
    """

    args = ct['args']
    textin = ct['content']

    #Check if their is width in args or if we need to use the default width
    if "width" in args:
        w = float(ct['positionner'].width)
    else:
        w = float(document._width)

    if usetex:

        #Check if a color is defined in args
        if 'color' in args:
            textin = color_text(textin, args['color'])

        if 'center' in args['align']:
            texalign = r'\centering'
        else:
            texalign = ''

        #fontsize{size}{interlinear_size}
        pretex = r"""
        \documentclass[crop=True]{standalone}
        \usepackage[utf8x]{inputenc}
        \usepackage{fix-cm}
        \usepackage[hypertex]{hyperref}
        \usepackage[svgnames]{xcolor}
        \renewcommand{\familydefault}{\sfdefault}
        \usepackage{varwidth}
        \usepackage{amsmath}
        \usepackage{amsfonts}
        \usepackage{amssymb}
        \begin{document}
        \begin{varwidth}{%ipt}
        %s
        \fontsize{%i}{%i}\selectfont %s

        \end{varwidth}
        \end{document}
        """ % (w * (72.27 / 96.), texalign, args['size'],
               (args['size'] + args['size'] * 0.1), textin)
        #96/72.27 pt_to_px for latex

        #latex2svg
        testsvg = latex2svg(pretex)

        if testsvg == '':
            print("Latex Compilation Error")
            print("Beampy Input")
            print(pretex)
            sys.exit(0)

        #Parse the ouput with beautifullsoup
        soup = BeautifulSoup(testsvg, 'xml')
        svgsoup = soup.find('svg')

        #Get id of paths element to make a global counter over the entire document
        if 'path' not in document._global_counter:
            document._global_counter['path'] = 0

        #Create unique_id_ with time
        text_id = ("%0.2f" % time.time()).split('.')[-1]
        for path in soup.find_all('path'):
            pid = path.get('id')
            new_pid = '%s_%i' % (text_id, document._global_counter['path'])
            testsvg = re.sub(pid, new_pid, testsvg)
            #path['id'] = new_pid //Need to change also the id ine each use elements ... replace (above) is simpler
            document._global_counter['path'] += 1

        #Reparse the svg
        soup = BeautifulSoup(testsvg, 'xml')

        #Change id in svg defs to use the global id system
        soup = make_global_svg_defs(soup)

        svgsoup = soup.find('svg')

        xinit, yinit, text_width, text_height = svgsoup.get('viewBox').split()
        text_width = float(text_width)
        text_height = float(text_height)

        #Find all links to apply the style defined in theme['link']
        links = soup.find_all('a')
        style = ' '.join([
            '%s:%s;' % (str(key), str(value))
            for key, value in document._theme['link'].items()
        ])
        for link in links:
            link['style'] = style

        #Use the first <use> in svg to get the y of the first letter
        try:
            uses = soup.find_all('use')
        except:
            print soup

        if len(uses) > 0:
            #TODO: need to make a more fine definition of baseline
            baseline = 0
            for use in uses:
                if use.has_attr('y'):
                    baseline = float(use.get('y'))
                    break

            if baseline == 0:
                print("Baseline one TeX error and is put to 0")
                #print baseline

            #Get the group tag to get the transform matrix to add yoffset
            g = soup.find('g')
            transform_matrix = g.get('transform')

            if 'va' in args and args['va'] == 'baseline':
                yoffset = -float(baseline)
                xoffset = -float(xinit)
                #for the box plot (see boxed below)
                oldyinit = yinit
                yinit = -float(baseline) + float(yinit)
                baseline = -float(oldyinit) + float(baseline)

            else:
                yoffset = -float(yinit)
                xoffset = -float(xinit)
                #For the box plot
                baseline = -float(yinit) + float(baseline)
                yinit = 0

            #print baseline, float(yinit), yoffset
            #newmatrix = 'translate(%s,%0.4f)'%(-float(xoffset),-float(yoffset) )
            tex_pt_to_px = 96 / 72.27
            newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)' % (
                tex_pt_to_px, xoffset, yoffset)
            g['transform'] = newmatrix
            text_width = text_width * tex_pt_to_px
            text_height = text_height * tex_pt_to_px
            baseline = baseline * tex_pt_to_px
            yinit = yinit * tex_pt_to_px
            #g['viewBox'] = svgsoup.get('viewBox')

        output = svgsoup.renderContents()

        #Add red box around the text
        if document._text_box:

            boxed = '''<g transform="translate(%0.1f,%0.1f)">
            <line x1="0" y1="0" x2="%i" y2="0" style="stroke: red"/>
            <line x1="%i" y1="0" x2="%i" y2="%i" style="stroke: red"/>
            <line x1="%i" y1="%i" x2="0" y2="%i" style="stroke: red"/>
            <line x1="0" y1="%i" x2="0" y2="0" style="stroke: red"/>
            <line x1="0" y1="%i" x2="%i" y2="%i" style="stroke: green"/>
            </g>'''
            output += boxed % (0, float(yinit), text_width, text_width,
                               text_width, text_height, text_width,
                               text_height, text_height, text_height, baseline,
                               text_width, baseline)

        #print output
    else:
        #Render as svg text
        #args['x'] = convert_unit(args['x'])
        #args['y'] = convert_unit(args['y'])
        #args = ' '.join( [str(arg)+"='"+str(val)+"'" for arg, val in args.iteritems()] )
        print('[WARNING !!!]: Classic text not yet implemented')
        output = "<text>%s</text>" % (textin.decode('utf-8'))
        #TODO: Need to fix the estimation of te width
        #print("[WARNING!!!] Width of classic svg text can't be estimated")
        text_width = 0
        text_height = 0

    #Update positionner with the correct width and height of the final svg
    ct['positionner'].update_size(text_width, text_height)

    return output
示例#4
0
def render_text( textin, args, usetex=True):
    """
        Function to render the text using latex

        latex -> dvi -> dvi2svgm -> svg

        Use the svg output for the text in the frame
    """

    #Check if their is width in args or if we need to use the default width
    if "width" in args:
        w = float(convert_unit(str(args['width'])))
    else:
        w = float(document._width)

    if usetex:

        #Check if a color is defined in args
        if 'fill' in args:
            if "#" in args['fill']:
                textin = r'{\color[HTML]{%s} %s }'%(args['fill'].replace('#','').upper(), textin)
            else:
                textin =r'{\color{%s} %s }'%(args['fill'], textin)

        if 'center' in args['align']:
            texalign = r'\centering'
        else:
            texalign = ''

        #fontsize{size}{interlinear_size}
        pretex = r"""
        \documentclass[crop=True]{standalone}
        \usepackage[utf8x]{inputenc}
        \usepackage{fix-cm}
        \usepackage{hyperref}
        \usepackage[svgnames]{xcolor}
        \renewcommand{\familydefault}{\sfdefault}
        \usepackage{varwidth}
        \usepackage{amsmath}
        \usepackage{amsfonts}
        \usepackage{amssymb}
        \special{html}
        \begin{document}
        \begin{varwidth}{%ipt}
        %s
        \fontsize{%i}{%i}\selectfont %s

        \end{varwidth}
        \end{document}
        """%(w*(72.27/96.),texalign,args['font-size'],(args['font-size']+args['font-size']*0.1),textin)
        #96/72.27 pt_to_px for latex

        
        #latex2svg
        testsvg = latex2svg( pretex )

        if testsvg == '':
            print("Latex Compilation Error")
            print("Beampy Input")
            print(pretex)
            sys.exit(0)
            
        #Parse the ouput with beautifullsoup
        soup = BeautifulSoup(testsvg, 'xml')
        svgsoup = soup.find('svg')

        #Get id of paths element to make a global counter over the entire document
        if 'path' not in document._global_counter:
            document._global_counter['path'] = 0

        #Create unique_id_ with time
        text_id =  ("%0.2f"%time.time()).split('.')[-1]
        for path in soup.find_all('path'):
            pid = path.get('id')
            new_pid = '%s_%i'%(text_id, document._global_counter['path'])
            testsvg = re.sub(pid,new_pid, testsvg)
            #path['id'] = new_pid //Need to change also the id ine each use elements ... replace (above) is simpler
            document._global_counter['path'] += 1

        #Reparse the svg
        soup = BeautifulSoup(testsvg, 'xml')

        #Change id in svg defs to use the global id system
        soup = make_global_svg_defs(soup)

        svgsoup = soup.find('svg')

        xinit, yinit, text_width, text_height = svgsoup.get('viewBox').split()
        text_width = float(text_width)
        text_height = float(text_height)



        #Use the first <use> in svg to get the y of the first letter
        try:
            uses = soup.find_all('use')
        except:
            print soup

        if len(uses) > 0:
            #TODO: need to make a more fine definition of baseline
            baseline = 0
            for use in uses:
                if use.has_attr('y'):
                    baseline = float(use.get('y'))
                    break

            if baseline == 0:
                print("Baseline one TeX error and is put to 0")
                #print baseline

            #Get the group tag to get the transform matrix to add yoffset
            g = soup.find('g')
            transform_matrix = g.get('transform')


            if 'va' in args and args['va'] == 'baseline':
                yoffset = - float(baseline)
                xoffset = - float(xinit)
                #for the box plot (see boxed below)
                oldyinit = yinit
                yinit = - float(baseline) + float(yinit)
                baseline = -float(oldyinit) + float(baseline)

            else:
                yoffset = -float(yinit)
                xoffset = -float(xinit)
                #For the box plot
                baseline = -float(yinit) + float(baseline)
                yinit = 0



            #print baseline, float(yinit), yoffset
            #newmatrix = 'translate(%s,%0.4f)'%(-float(xoffset),-float(yoffset) )
            tex_pt_to_px = 96/72.27
            newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)'%(tex_pt_to_px, xoffset, yoffset)
            g['transform'] = newmatrix
            text_width = text_width * tex_pt_to_px
            text_height = text_height * tex_pt_to_px
            baseline = baseline * tex_pt_to_px
            yinit = yinit * tex_pt_to_px
            #g['viewBox'] = svgsoup.get('viewBox')

        output = svgsoup.renderContents()

        #Add red box around the text
        if document._text_box:

            boxed = '''<g transform="translate(%0.1f,%0.1f)">
            <line x1="0" y1="0" x2="%i" y2="0" style="stroke: red"/>
            <line x1="%i" y1="0" x2="%i" y2="%i" style="stroke: red"/>
            <line x1="%i" y1="%i" x2="0" y2="%i" style="stroke: red"/>
            <line x1="0" y1="%i" x2="0" y2="0" style="stroke: red"/>
            <line x1="0" y1="%i" x2="%i" y2="%i" style="stroke: green"/>
            </g>'''
            output += boxed%( 0, float(yinit),
                             text_width,
                             text_width,text_width,text_height,
                             text_width,text_height,text_height,
                             text_height,
                             baseline,text_width,baseline)

        #print output
    else:
        #Render as svg text
        args['x'] = convert_unit(args['x'])
        args['y'] = convert_unit(args['y'])
        args = ' '.join( [str(arg)+"='"+str(val)+"'" for arg, val in args.iteritems()] )
        output = "<text %s>%s</text>"%(args, textin.decode('utf-8'))
        #TODO: Need to fix the estimation of te width
        #print("[WARNING!!!] Width of classic svg text can't be estimated")
        text_width = 0
        text_height = 0

    return output, text_width, text_height
示例#5
0
    def render(self):
        """
            Latex -> dvi -> svg for tikz image
        """

        tikzcommands = self.content
        #args = ct['args']

        tex_pt_to_px = 96 / 72.27

        #replace '\slidewidth'

        tiktikzcommands = tikzcommands.replace(
            r'\slidewidth', '%ipt' % (0.75 * document._slides[gcs()].curwidth))

        #Include extrac packages for tex
        if getattr(self, 'tex_packages', False):
            extra_tex_packages = '\n'.join(
                ['\\usepackages{%s}' % pkg for pkg in self.tex_packages])
        else:
            extra_tex_packages = ''

        #Include extra tikz headers
        if getattr(self, 'tikz_header', False):
            extra_tex_packages += '\n%s' % (self.tikz_header)

        #Tikzfigure options in []
        if getattr(self, 'figure_options', False):
            tikz_fig_opts = '[' + self.figure_options + ']'
        else:
            tikz_fig_opts = ''

        # Render to a dvi file
        pretex = """
        \\documentclass[tikz,svgnames]{standalone}
        \\usepackage[utf8x]{inputenc}

        %s

        \\begin{document}
            \\begin{tikzpicture}%s
            %s
            \\end{tikzpicture}
        \\end{document}
        """ % (extra_tex_packages, tikz_fig_opts, tikzcommands)

        #latex2svg
        svgout = latex2svg(pretex)

        if svgout != '':

            #Parse the svg
            soup = BeautifulSoup(svgout, 'xml')

            #Find the width and height
            svgsoup = soup.find('svg')
            g = soup.find('g')

            xinit, yinit, tikz_width, tikz_height = svgsoup.get(
                'viewBox').split()
            tikz_width = float(tikz_width) * tex_pt_to_px
            tikz_height = float(tikz_height) * tex_pt_to_px

            print(tikz_width, tikz_height)

            # Default is args['figure_anchor'] == top_left
            dx = -float(xinit)
            dy = -float(yinit)

            print(self.positionner.x, self.positionner.y)

            if 'bottom' in self.figure_anchor:
                self.positionner.y['anchor'] = 'bottom'

            if 'right' in self.figure_anchor:
                self.positionner.x['anchor'] = 'right'

            newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)' % (tex_pt_to_px,
                                                                 dx, dy)
            g['transform'] = newmatrix

            output = svgsoup.renderContents()

        else:
            output = ''
            tikz_height = 0
            tikz_width = 0

        self.update_size(tikz_width, tikz_height)
        self.svgout = output
        self.rendered = True
示例#6
0
    def render(self):
        """
            Text is rendered using latex if self.usetex = True if not use simple svg
        """

        if self.usetex:

            #Check if a color is defined in args
            if hasattr(self, 'color'):
                textin = color_text(self.content, self.color)
            else:
                textin = self.content

            if 'center' in self.align:
                texalign = r'\centering'
            elif 'right' in self.align:
                texalign = r'\flushright'
            else:
                texalign = ''

            #fontsize{size}{interlinear_size}
            pretex = r"""
            \documentclass[crop=True]{standalone}
            \usepackage[utf8x]{inputenc}
            \usepackage{fix-cm}
            \usepackage[hypertex]{hyperref}
            \usepackage[svgnames]{xcolor}
            \renewcommand{\familydefault}{\sfdefault}
            \usepackage{varwidth}
            \usepackage{amsmath}
            \usepackage{amsfonts}
            \usepackage{amssymb}
            \begin{document}
            \begin{varwidth}{%ipt}
            %s
            \fontsize{%i}{%i}\selectfont %s

            \end{varwidth}
            \end{document}
            """ % (self.width * (72.27 / 96.), texalign, self.size,
                   (self.size + self.size * 0.1), textin)
            #96/72.27 pt_to_px for latex

            #latex2svg
            testsvg = latex2svg(pretex)

            if testsvg == '':
                print("Latex Compilation Error")
                print("Beampy Input")
                print(pretex)
                sys.exit(0)

            #Parse the ouput with beautifullsoup
            soup = BeautifulSoup(testsvg, 'xml')
            svgsoup = soup.find('svg')
            #print(soup)

            #Find the width and height
            xinit, yinit, text_width, text_height = svgsoup.get(
                'viewBox').split()
            text_width = float(text_width)
            text_height = float(text_height)

            #TODO: REPLACE BeautifulSoup by lxml (which is faster)
            #from lxml import etree
            #doc = etree.fromstring(testsvg)
            #dtest = doc.xpath('//path/id')
            #print(dtest)

            #Get id of paths element to make a global counter over the entire document
            if 'path' not in document._global_counter:
                document._global_counter['path'] = 0

            #Create unique_id_ with time
            #text_id =  ("%0.2f"%time.time()).split('.')[-1]
            """
            for path in soup.find_all('path'):
                pid = path.get('id')
                new_pid = '%s_%i'%(text_id, document._global_counter['path'])

                #Check genereta an hash of the glyphs svg path and check if it's
                #already define in the global store
                md5print = hashlib.md5(path.get('d')).hexdigest()

                new_svg_path = "<path d='%s', id='%s'> "%(path.get('d'), new_pid)
                print(new_svg_path)
               
                print(md5print, 'for ', pid, 'nid', new_pid)

                #Old way on the global svg
                testsvg = re.sub(pid, new_pid, testsvg)
                document._global_counter['path'] += 1

            #Reparse the svg
            soup = BeautifulSoup(testsvg, 'xml')
            """

            #New method with a global glyph store
            svgsoup = parse_dvisvgm_svg(svgsoup)

            #Change id in svg defs to use the global id system
            #soup = make_global_svg_defs(soup)

            #svgsoup = soup.find('svg')

            #Find all links to apply the style defined in theme['link']
            links = svgsoup.find_all('a')
            style = ' '.join([
                '%s:%s;' % (str(key), str(value))
                for key, value in document._theme['link'].items()
            ])
            for link in links:
                link['style'] = style

            #Use the first <use> in svg to get the y of the first letter
            try:
                uses = svgsoup.find_all('use')
            except:
                print(soup)

            if len(uses) > 0:
                #TODO: need to make a more fine definition of baseline
                baseline = 0
                for use in uses:
                    if use.has_attr('y'):
                        baseline = float(use.get('y'))
                        break

                if baseline == 0:
                    print("No Baseline found in TeX and is put to 0")
                    #print baseline

                #Get the group tag to get the transform matrix to add yoffset
                g = svgsoup.find('g')
                transform_matrix = g.get('transform')

                if getattr(self, 'va', False) and self.va == 'baseline':
                    yoffset = -float(baseline)
                    xoffset = -float(xinit)
                    #for the box plot (see boxed below)
                    oldyinit = yinit
                    yinit = -float(baseline) + float(yinit)
                    baseline = -float(oldyinit) + float(baseline)

                else:
                    yoffset = -float(yinit)
                    xoffset = -float(xinit)
                    #For the box plot
                    baseline = -float(yinit) + float(baseline)
                    yinit = 0

                #print baseline, float(yinit), yoffset
                #newmatrix = 'translate(%s,%0.4f)'%(-float(xoffset),-float(yoffset) )
                tex_pt_to_px = 96 / 72.27
                newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)' % (
                    tex_pt_to_px, xoffset, yoffset)
                g['transform'] = newmatrix
                text_width = text_width * tex_pt_to_px
                text_height = text_height * tex_pt_to_px
                baseline = baseline * tex_pt_to_px
                yinit = yinit * tex_pt_to_px
                #g['viewBox'] = svgsoup.get('viewBox')

            output = svgsoup.renderContents()

            #Add red box around the text
            if document._text_box:
                boxed = '''<g transform="translate(%0.1f,%0.1f)">
                <line x1="0" y1="0" x2="%i" y2="0" style="stroke: red"/>
                <line x1="%i" y1="0" x2="%i" y2="%i" style="stroke: red"/>
                <line x1="%i" y1="%i" x2="0" y2="%i" style="stroke: red"/>
                <line x1="0" y1="%i" x2="0" y2="0" style="stroke: red"/>
                <line x1="0" y1="%i" x2="%i" y2="%i" style="stroke: green"/>
                </g>'''
                output += boxed % (0, float(yinit), text_width, text_width,
                                   text_width, text_height, text_width,
                                   text_height, text_height, text_height,
                                   baseline, text_width, baseline)

            #print output
        else:
            #Render as svg text
            #print('[WARNING !!!]: Classic text not yet implemented')
            textin = self.content
            style = ''
            if hasattr(self, 'color'):
                style += 'color:%s' % (self.color)

            output = '<text style="%s">%s</text>' % (style,
                                                     textin.decode('utf-8'))
            tmpsvg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" xmlns:xlink="http://www.w3.org/1999/xlink">%s</svg>' % output

            #Need to create a temp file
            tmpfile, tmpnam = tempfile.mkstemp(prefix='beampytmp')
            with open(tmpnam + '.svg', 'w') as f:
                f.write(tmpsvg)

            text_width = getsvgwidth(tmpnam + '.svg')
            text_height = getsvgheight(tmpnam + '.svg')

            os.remove(tmpnam + '.svg')

            print(text_width, text_height)

        #Update positionner with the correct width and height of the final svg
        self.update_size(text_width, text_height)

        #Store the output svg
        self.svgout = output
        #Update the rendered state of the module
        self.rendered = True
示例#7
0
文件: tikz.py 项目: hchauvet/beampy
    def render(self):
        """
            Latex -> dvi -> svg for tikz image
        """

        tikzcommands = self.content
        #args = ct['args']

        tex_pt_to_px = 96/72.27

        #replace '\slidewidth'
        tiktikzcommands = tikzcommands.replace( r'\slidewidth','%ipt'%0.75*document._width)

        #Include extrac packages for tex
        if getattr(self, 'tex_packages', False):
            extra_tex_packages = '\n'.join(['\\usepackages{%s}'%pkg for pkg in self.tex_packages])
        else:
            extra_tex_packages = ''

        #Include extra tikz headers
        if getattr(self, 'tikz_header', False):
            extra_tex_packages += '\n%s'%(self.tikz_header)

        #Tikzfigure options in []
        if getattr(self,'figure_options', False):
            tikz_fig_opts = '['+self.figure_options+']'
        else:
            tikz_fig_opts = ''

        #Render to a dvi file
        pretex = """
        \\documentclass[tikz,svgnames]{standalone}
        \\usepackage[utf8x]{inputenc}

        %s

        \\begin{document}
            \\begin{tikzpicture}%s
            %s
            \\end{tikzpicture}
        \\end{document}
        """%(extra_tex_packages,tikz_fig_opts,tikzcommands)

        #latex2svg
        svgout = latex2svg(pretex)

        if svgout != '':

            #Parse the svg
            soup = BeautifulSoup(svgout, 'xml')

            #Change svg id with global ids
            #soup = make_global_svg_defs(soup)

            #Find the width and height
            svgsoup = soup.find('svg')
            g = soup.find('g')

            xinit, yinit, tikz_width, tikz_height = svgsoup.get('viewBox').split()
            tikz_width = float(tikz_width)
            tikz_height = float(tikz_height)

            #Default is args['figure_anchor'] == top_left
            dx = -float(xinit)
            dy = -float(yinit)

            if 'bottom' in self.figure_anchor:
                dy = -float(yinit) - tikz_height

            if 'right' in self.figure_anchor:
                dx = -float(xinit)-tikz_width

            newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)'%(tex_pt_to_px, dx, dy)
            g['transform'] = newmatrix

            output = svgsoup.renderContents()

        else:
            #print(tex_msg)
            output = ''
            tikz_height = 0
            tikz_width = 0


        self.update_size(tikz_width, tikz_height)
        self.svgout = output
        self.rendered = True
示例#8
0
文件: text.py 项目: hchauvet/beampy
    def render(self):
        """
            Text is rendered using latex if self.usetex = True if not use simple svg
        """

        if self.usetex:

            #Check if a color is defined in args
            if hasattr(self, 'color'):
                textin = color_text( self.content, self.color )
            else:
                textin = self.content

            if 'center' in self.align:
                texalign = r'\centering'
            elif 'right' in self.align:
                texalign = r'\flushright'
            else:
                texalign = ''

            #fontsize{size}{interlinear_size}
            pretex = r"""
            \documentclass[crop=True]{standalone}
            \usepackage[utf8x]{inputenc}
            \usepackage{fix-cm}
            \usepackage[hypertex]{hyperref}
            \usepackage[svgnames]{xcolor}
            \renewcommand{\familydefault}{\sfdefault}
            \usepackage{varwidth}
            \usepackage{amsmath}
            \usepackage{amsfonts}
            \usepackage{amssymb}
            \begin{document}
            \begin{varwidth}{%ipt}
            %s
            \fontsize{%i}{%i}\selectfont %s

            \end{varwidth}
            \end{document}
            """%( self.width*(72.27/96.), texalign,
                self.size, (self.size+self.size*0.1),
                textin )
            #96/72.27 pt_to_px for latex

            #latex2svg
            testsvg = latex2svg( pretex )

            if testsvg == '':
                print("Latex Compilation Error")
                print("Beampy Input")
                print(pretex)
                sys.exit(0)

            #Parse the ouput with beautifullsoup
            soup = BeautifulSoup(testsvg, 'xml')
            svgsoup = soup.find('svg')

            #Get id of paths element to make a global counter over the entire document
            if 'path' not in document._global_counter:
                document._global_counter['path'] = 0

            #Create unique_id_ with time
            text_id =  ("%0.2f"%time.time()).split('.')[-1]
            for path in soup.find_all('path'):
                pid = path.get('id')
                new_pid = '%s_%i'%(text_id, document._global_counter['path'])
                testsvg = re.sub(pid,new_pid, testsvg)
                #path['id'] = new_pid //Need to change also the id ine each use elements ... replace (above) is simpler
                document._global_counter['path'] += 1

            #Reparse the svg
            soup = BeautifulSoup(testsvg, 'xml')

            #Change id in svg defs to use the global id system
            soup = make_global_svg_defs(soup)

            svgsoup = soup.find('svg')

            xinit, yinit, text_width, text_height = svgsoup.get('viewBox').split()
            text_width = float(text_width)
            text_height = float(text_height)

            #Find all links to apply the style defined in theme['link']
            links = soup.find_all('a')
            style = ' '.join(['%s:%s;'%(str(key), str(value)) for key, value in document._theme['link'].items()])
            for link in links:
                link['style'] = style

            #Use the first <use> in svg to get the y of the first letter
            try:
                uses = soup.find_all('use')
            except:
                print soup

            if len(uses) > 0:
                #TODO: need to make a more fine definition of baseline
                baseline = 0
                for use in uses:
                    if use.has_attr('y'):
                        baseline = float(use.get('y'))
                        break

                if baseline == 0:
                    print("No Baseline found in TeX and is put to 0")
                    #print baseline

                #Get the group tag to get the transform matrix to add yoffset
                g = soup.find('g')
                transform_matrix = g.get('transform')


                if getattr(self, 'va', False) and self.va == 'baseline':
                    yoffset = - float(baseline)
                    xoffset = - float(xinit)
                    #for the box plot (see boxed below)
                    oldyinit = yinit
                    yinit = - float(baseline) + float(yinit)
                    baseline = -float(oldyinit) + float(baseline)

                else:
                    yoffset = -float(yinit)
                    xoffset = -float(xinit)
                    #For the box plot
                    baseline = -float(yinit) + float(baseline)
                    yinit = 0



                #print baseline, float(yinit), yoffset
                #newmatrix = 'translate(%s,%0.4f)'%(-float(xoffset),-float(yoffset) )
                tex_pt_to_px = 96/72.27
                newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)'%(tex_pt_to_px, xoffset, yoffset)
                g['transform'] = newmatrix
                text_width = text_width * tex_pt_to_px
                text_height = text_height * tex_pt_to_px
                baseline = baseline * tex_pt_to_px
                yinit = yinit * tex_pt_to_px
                #g['viewBox'] = svgsoup.get('viewBox')

            output = svgsoup.renderContents()

            #Add red box around the text
            if document._text_box:
                boxed = '''<g transform="translate(%0.1f,%0.1f)">
                <line x1="0" y1="0" x2="%i" y2="0" style="stroke: red"/>
                <line x1="%i" y1="0" x2="%i" y2="%i" style="stroke: red"/>
                <line x1="%i" y1="%i" x2="0" y2="%i" style="stroke: red"/>
                <line x1="0" y1="%i" x2="0" y2="0" style="stroke: red"/>
                <line x1="0" y1="%i" x2="%i" y2="%i" style="stroke: green"/>
                </g>'''
                output += boxed%( 0, float(yinit),
                                 text_width,
                                 text_width,text_width,text_height,
                                 text_width,text_height,text_height,
                                 text_height,
                                 baseline,text_width,baseline)

            #print output
        else:
            #Render as svg text
            #print('[WARNING !!!]: Classic text not yet implemented')
            textin = self.content
            style = ''
            if hasattr(self, 'color'):
                style += 'color:%s'%(self.color)

            output = '<text style="%s">%s</text>'%(style, textin.decode('utf-8'))
            tmpsvg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" xmlns:xlink="http://www.w3.org/1999/xlink">%s</svg>'%output

            #Need to create a temp file
            tmpfile, tmpnam = tempfile.mkstemp(prefix='beampytmp')
            with open( tmpnam + '.svg', 'w' ) as f:
                f.write( tmpsvg )

            text_width =  getsvgwidth(tmpnam + '.svg')
            text_height = getsvgheight(tmpnam + '.svg')

            os.remove(tmpnam + '.svg')

            print(text_width, text_height)

        #Update positionner with the correct width and height of the final svg
        self.update_size(text_width, text_height)

        #Store the output svg
        self.svgout = output
        #Update the rendered state of the module
        self.rendered = True
示例#9
0
文件: tikz.py 项目: frankier/beampy
def render_tikz( ct ):
    """
    Latex -> dvi -> svg for tikz image
    """

    tikzcommands = ct['content']
    args = ct['args']

    tex_pt_to_px = 96/72.27

    #replace '\slidewidth'
    tiktikzcommands = tikzcommands.replace( r'\slidewidth','%ipt'%0.75*document._width)

    #Include extrac packages for tex
    if args['tex_packages']:
        extra_tex_packages = '\n'.join(['\\usepackages{%s}'%pkg for pkg in args['tex_packages']])
    else:
        extra_tex_packages = ''

    #Include extra tikz headers
    if args['tikz_header']:
        extra_tex_packages += '\n' + args['tikz_header']

    #Tikzfigure options in []
    if args['figure_options']:
        tikz_fig_opts = '['+args['figure_options']+']'
    else:
        tikz_fig_opts = ''

    #Render to a dvi file
    pretex = """
    \\documentclass[tikz,svgnames]{standalone}
    \\usepackage[utf8x]{inputenc}

    %s

    \\begin{document}
        \\begin{tikzpicture}%s
        %s
        \\end{tikzpicture}
    \\end{document}
    """%(extra_tex_packages,tikz_fig_opts,tikzcommands)

    #latex2svg
    svgout = latex2svg(pretex)

    if svgout != '':

        #Parse the svg
        soup = BeautifulSoup(svgout, 'xml')

        #Change svg id with global ids
        #soup = make_global_svg_defs(soup)

        #Find the width and height
        svgsoup = soup.find('svg')
        g = soup.find('g')

        xinit, yinit, tikz_width, tikz_height = svgsoup.get('viewBox').split()
        tikz_width = float(tikz_width)
        tikz_height = float(tikz_height)

        #Default is args['figure_anchor'] == top_left
        dx = -float(xinit)
        dy = -float(yinit)

        if 'bottom' in args['figure_anchor']:
            dy = -float(yinit) - tikz_height

        if 'right' in args['figure_anchor']:
            dx = -float(xinit)-tikz_width

        newmatrix = 'scale(%0.3f) translate(%0.1f,%0.1f)'%(tex_pt_to_px, dx, dy)
        g['transform'] = newmatrix

        output = svgsoup.renderContents()

    else:
        #print(tex_msg)
        output = ''
        tikz_height = 0
        tikz_width = 0

    ct['positionner'].update_size(tikz_width, tikz_height)
    return output