""" implement aafigure directive """ import os, sys, tempfile, popen2 #~ import cStringIO import aafigure import svg try: import pil except ImportError: #no support for bitmaps pil = None from docutils import nodes from docutils.parsers.rst.directives import register_directive, flag DEFAULT_FORMAT = 'svg' #~ DEFAULT_FORMAT = 'png' aafigure_counter = 0 def decode_color(color_string): if color_string[0] == '#': #HTML like color syntax if len(color_string) == 4: # #rgb format r,g,b = [int(c+c, 16) for c in color_string[1:]] elif len(color_string) == 7: # #rrggbb format r,g,b = [int(color_string[n:n+2], 16) for n in range(1, len(color_string), 2)] else: raise ValueError('not a valid color: %r' % color_string) #XXX add a list of named colors return r,g,b def AAFigureDrective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): text = '\n'.join(content) global aafigure_counter #ensure that options are present and initialized with defaults if not given if not options.has_key('background'): options['background'] = '#ffffff' if not options.has_key('foreground'): options['foreground'] = '#000000' if not options.has_key('fill'): options['fill'] = options['foreground'] #fill = fore by default if not options.has_key('scale'): options['scale'] = 1 if not options.has_key('line_width'): options['line_width'] = 2 if not options.has_key('format'): options['format'] = DEFAULT_FORMAT if not options.has_key('aspect'): options['aspect'] = 1 if not options.has_key('name'): options['name'] = 'aafigure-%i' % aafigure_counter aafigure_counter += 1 aaimg = aafigure.AsciiArtImage( text, aspect_ratio = options['aspect'], textual = options.has_key('textual') ) aaimg.recognize() if options['format'] == 'svg': output_name = options['name'] + '.svg' #~ io = cStringIO.StringIO() svgout = svg.SVGOutputVisitor( file(output_name, 'w'), #~ io, scale = options['scale']*6, line_width = options['line_width'], foreground = decode_color(options['foreground']), background = decode_color(options['background']), fillcolor = decode_color(options['fill']) ) svgout.visit_image(aaimg) #~ svgout.visit(aaimg, xml_header = False) #insert data into html using a raw node attributes = {'format': 'html'} #~ # result = [nodes.raw('', '' % ( result = [nodes.raw('', '' % ( output_name, svgout.get_size_attrs() ), **attributes)] #~ result = [nodes.raw('', io.getvalue(), **attributes)] elif pil is not None: output_name = '%s.%s' % (options['name'], options['format']) pilout = pil.PILOutputVisitor( file(output_name, 'wb'), scale = options['scale']*7, line_width = options['line_width'], debug = True, file_type = options['format'], foreground = decode_color(options['foreground']), background = decode_color(options['background']), fillcolor = decode_color(options['fill']), ) try: pilout.visit_image(aaimg) except KeyError: result = [state_machine.reporter.error( 'No support for image format %r' % (options['format']), nodes.literal_block(block_text, block_text), line=lineno )] else: # Return an image directive. image_options = {} image_options['uri'] = os.path.basename(output_name) result = [nodes.image(output_name, **image_options)] else: result = [state_machine.reporter.error( 'No support for image format %r (PIL not installed)' % (options['format']), nodes.literal_block(block_text, block_text), line=lineno )] return result AAFigureDrective.content = True #~ AAFigureDrective.arguments = (1, 1, 1) AAFigureDrective.options = { 'scale': float, 'line_width': float, 'format': str, 'name': str, 'background': str, 'foreground': str, 'fill': str, 'aspect': float, 'textual': flag, } def register(): register_directive('aafigure', AAFigureDrective)