Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 740f9368fc
Fetching contributors…

Cannot retrieve contributors at this time

254 lines (223 sloc) 9.924 kB
#!/usr/bin/env python
# -*- Mode: Python -*-
# GObject-Introspection - a framework for introspecting GObject libraries
# Copyright (C) 2010 Zach Goldberg
# Copyright (C) 2011 Johan Dahlin
# Copyright (C) 2011 Shaun McCance
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
import os
import re
import tempfile
from xml.sax import saxutils
from mako.template import Template
from mako.runtime import supports_caller
from . import ast
from .utils import to_underscores
def _space(num):
return " " * num
class MallardFormatter(object):
def __init__(self, transformer):
self._transformer = transformer
def escape(self, text):
return saxutils.escape(text.encode('utf-8')).decode('utf-8')
def format(self, doc):
if doc is None:
return ''
result = ''
for para in doc.split('\n\n'):
result += '<p>'
result += self.format_inline(para)
result += '</p>'
return result
def format_inline(self, para):
result = ''
poss = []
poss.append((para.find('#'), '#'))
poss = [pos for pos in poss if pos[0] >= 0]
poss.sort(cmp=lambda x, y: cmp(x[0], y[0]))
if len(poss) == 0:
result += self.escape(para)
elif poss[0][1] == '#':
pos = poss[0][0]
result += self.escape(para[:pos])
rest = para[pos + 1:]
link = re.split('[^a-zA-Z_:-]', rest, maxsplit=1)[0]
if link.endswith(':'):
link = link[:-1]
namespace = self._transformer.namespace
if '::' in link:
type_name, signal_name = link.split('::')
if type_name in namespace.ctypes:
type_ = namespace.get_by_ctype(type_name)
xref = '%s.%s-%s' % (namespace.name, type_.name, signal_name)
xref_name = '%s.%s::%s' % (namespace.name, type_.name, signal_name)
else:
xref = link
xref_name = link
elif ':' in link:
type_name, property_name = link.split(':')
if type_name in namespace.ctypes:
type_ = namespace.get_by_ctype(type_name)
xref = '%s.%s-%s' % (namespace.name, type_.name, property_name)
xref_name = '%s.%s:%s' % (namespace.name, type_.name, property_name)
else:
xref = link
xref_name = link
elif link in namespace.ctypes:
type_ = namespace.get_by_ctype(link)
xref = '%s.%s' % (namespace.name, type_.name)
xref_name = xref
else:
xref = link
xref_name = link
result += '<link xref="%s">%s</link>' % (xref, xref_name)
if len(link) < len(rest):
result += self.format_inline(rest[len(link):])
return result
def format_type(self, type_):
raise NotImplementedError
def format_property_flags(self, property_):
flags = []
if property_.readable:
flags.append("Read")
if property_.writable:
flags.append("Write")
if property_.construct:
flags.append("Construct")
if property_.construct_only:
flags.append("Construct Only")
return " / ".join(flags)
def to_underscores(self, string):
return to_underscores(string)
def get_class_hierarchy(self, node):
parent_chain = [node]
while node.parent:
node = self._transformer.lookup_giname(str(node.parent))
parent_chain.append(node)
parent_chain.reverse()
return parent_chain
class MallardFormatterC(MallardFormatter):
def format_type(self, type_):
if isinstance(type_, ast.Array):
try:
return self.format_type(type_.element_type) + '*'
except:
return type_.target_fundamental
elif type_.ctype is not None:
return type_.ctype
else:
return type_.target_fundamental
class MallardFormatterPython(MallardFormatter):
def format_type(self, type_):
if isinstance(type_, ast.Array):
return '[' + self.format_type(type_.element_type) + ']'
elif isinstance(type_, ast.Map):
return '{%s: %s}' % (self.format_type(type_.key_type),
self.format_type(type_.value_type))
elif type_.target_giname is not None:
return type_.target_giname
else:
return type_.target_fundamental
def format(self, doc):
doc = MallardFormatter.format(self, doc)
doc = doc.replace('%NULL', 'None')
doc = doc.replace('%TRUE', 'True')
doc = doc.replace('%FALSE', 'False')
return doc
class MallardWriter(object):
def __init__(self, transformer, language):
self._transformer = transformer
self._language = language
if self._language == 'C':
self._formatter = MallardFormatterC(self._transformer)
elif self._language == 'Python':
self._formatter = MallardFormatterPython(self._transformer)
else:
raise SystemExit("Unsupported language: %s" % language)
def write(self, output):
nodes = [self._transformer.namespace]
for node in self._transformer.namespace.itervalues():
if isinstance(node, ast.Function) and node.moved_to is not None:
continue
if getattr(node, 'disguised', False):
continue
if isinstance(node, ast.Record) and \
self._language == 'Python' and \
node.is_gtype_struct_for is not None:
continue
nodes.append(node)
if isinstance(node, (ast.Class, ast.Interface, ast.Record)):
nodes += getattr(node, 'methods', [])
nodes += getattr(node, 'static_methods', [])
nodes += getattr(node, 'virtual_methods', [])
nodes += getattr(node, 'properties', [])
nodes += getattr(node, 'signals', [])
if self._language == 'C':
nodes += getattr(node, 'constructors', [])
for node in nodes:
self._render_node(node, output)
def _render_node(self, node, output):
namespace = self._transformer.namespace
if isinstance(node, ast.Namespace):
template_name = 'mallard-%s-namespace.tmpl' % self._language
page_id = 'index'
elif isinstance(node, (ast.Class, ast.Interface)):
template_name = 'mallard-%s-class.tmpl' % self._language
page_id = '%s.%s' % (namespace.name, node.name)
elif isinstance(node, ast.Record):
template_name = 'mallard-%s-record.tmpl' % self._language
page_id = '%s.%s' % (namespace.name, node.name)
elif isinstance(node, ast.Function):
template_name = 'mallard-%s-function.tmpl' % self._language
if node.parent is not None:
page_id = '%s.%s.%s' % (namespace.name, node.parent.name, node.name)
else:
page_id = '%s.%s' % (namespace.name, node.name)
elif isinstance(node, ast.Enum):
template_name = 'mallard-%s-enum.tmpl' % self._language
page_id = '%s.%s' % (namespace.name, node.name)
elif isinstance(node, ast.Property) and node.parent is not None:
template_name = 'mallard-%s-property.tmpl' % self._language
page_id = '%s.%s-%s' % (namespace.name, node.parent.name, node.name)
elif isinstance(node, ast.Signal) and node.parent is not None:
template_name = 'mallard-%s-signal.tmpl' % self._language
page_id = '%s.%s-%s' % (namespace.name, node.parent.name, node.name)
elif isinstance(node, ast.VFunction) and node.parent is not None:
template_name = 'mallard-%s-vfunc.tmpl' % self._language
page_id = '%s.%s-%s' % (namespace.name, node.parent.name, node.name)
else:
template_name = 'mallard-%s-default.tmpl' % self._language
page_id = '%s.%s' % (namespace.name, node.name)
if 'UNINSTALLED_INTROSPECTION_SRCDIR' in os.environ:
top_srcdir = os.environ['UNINSTALLED_INTROSPECTION_SRCDIR']
template_dir = os.path.join(top_srcdir, 'giscanner')
else:
template_dir = os.path.dirname(__file__)
file_name = os.path.join(template_dir, template_name)
file_name = os.path.abspath(file_name)
template = Template(filename=file_name, output_encoding='utf-8',
module_directory=tempfile.gettempdir())
result = template.render(namespace=namespace,
node=node,
page_id=page_id,
formatter=self._formatter)
output_file_name = os.path.join(os.path.abspath(output),
page_id + '.page')
fp = open(output_file_name, 'w')
fp.write(result)
fp.close()
Jump to Line
Something went wrong with that request. Please try again.