Skip to content

Instantly share code, notes, and snippets.

@alxf
Created January 21, 2012 00:10
Show Gist options
  • Save alxf/1650373 to your computer and use it in GitHub Desktop.
Save alxf/1650373 to your computer and use it in GitHub Desktop.
Render restructured text as html in pygtk webkit view
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" Render restructured text as html in a pygtk webkit view.
"""
import gobject
import gtk
import gtksourceview2 as gtksourceview
import io
import os.path
import pango
import webkit
import sys
import publishrst
class GtkApplication(object):
""" Application class.
"""
def __init__(self, rst_file):
#build main gtk window
self.rst_file = rst_file
self.win = gtk.Window()
self.win.set_default_size(800, 600)
self.win.connect("destroy", lambda w: gtk.main_quit())
self.lm = gtksourceview.language_manager_get_default()
self.lm.set_search_path(self.lm.get_search_path() + [os.getcwd()])
self.lang = self.lm.get_language('restructuredtext')
#build notebook
notebook = gtk.Notebook()
#build webkit widget
tab1 = gtk.ScrolledWindow()
browser = webkit.WebView()
with io.open(self.rst_file, 'rb') as fp:
data = publishrst.html_parts(unicode(fp.read()))['whole']
browser.load_html_string(data, 'file:///')
#build source view
tab2 = gtk.ScrolledWindow()
buf = gtksourceview.Buffer()
buf.set_language(self.lang)
buf.set_highlight_syntax(True)
with io.open(self.rst_file, 'rb') as fp:
buf.set_text(fp.read())
buf.set_data('filename', self.rst_file)
buf.set_modified(True)
buf.place_cursor(buf.get_start_iter())
sview = gtksourceview.View(buf)
sview.set_editable(False)
font_desc = pango.FontDescription('monospace')
if font_desc:
sview.modify_font(font_desc)
#add widgets and show window
tab1.add_with_viewport(browser)
tab2.add_with_viewport(sview)
notebook.append_page(tab1, gtk.Label("Html view"))
notebook.append_page(tab2, gtk.Label("Source view"))
self.win.add(notebook)
self.win.show_all()
def open_file(self, buf, filename):
return buf
def run(self):
gtk.main()
if __name__ == '__main__':
if len(sys.argv) > 1:
gobject.threads_init()
app = GtkApplication(sys.argv[1])
app.run()
else:
print("usage: %s <rst file>" % os.path.basename(sys.argv[0]))
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This module contains practical examples of Docutils client code.
Importing this module from client code is not recommended; its contents are
subject to change in future Docutils releases. Instead, it is recommended
that you copy and paste the parts you need into your own code, modifying as
necessary.
"""
from docutils import core, io
def html_parts(input_string, source_path=None, destination_path=None,
input_encoding='unicode', doctitle=True,
initial_header_level=1):
"""
Given an input string, returns a dictionary of HTML document parts.
Dictionary keys are the names of parts, and values are Unicode strings;
encoding is up to the client.
Parameters:
- `input_string`: A multi-line text string; required.
- `source_path`: Path to the source file or object. Optional, but useful
for diagnostic output (system messages).
- `destination_path`: Path to the file or object which will receive the
output; optional. Used for determining relative paths (stylesheets,
source links, etc.).
- `input_encoding`: The encoding of `input_string`. If it is an encoded
8-bit string, provide the correct encoding. If it is a Unicode string,
use "unicode", the default.
- `doctitle`: Disable the promotion of a lone top-level section title to
document title (and subsequent section title to document subtitle
promotion); enabled by default.
- `initial_header_level`: The initial level for header elements (e.g. 1
for "<h1>").
"""
overrides = {'input_encoding': input_encoding,
'doctitle_xform': doctitle,
'initial_header_level': initial_header_level}
parts = core.publish_parts(
source=input_string, source_path=source_path,
destination_path=destination_path,
writer_name='html', settings_overrides=overrides)
return parts
def html_body(input_string, source_path=None, destination_path=None,
input_encoding='unicode', output_encoding='unicode',
doctitle=True, initial_header_level=1):
"""
Given an input string, returns an HTML fragment as a string.
The return value is the contents of the <body> element.
Parameters (see `html_parts()` for the remainder):
- `output_encoding`: The desired encoding of the output. If a Unicode
string is desired, use the default value of "unicode" .
"""
parts = html_parts(
input_string=input_string, source_path=source_path,
destination_path=destination_path,
input_encoding=input_encoding, doctitle=doctitle,
initial_header_level=initial_header_level)
fragment = parts['html_body']
if output_encoding != 'unicode':
fragment = fragment.encode(output_encoding)
return fragment
def internals(input_string, source_path=None, destination_path=None,
input_encoding='unicode', settings_overrides=None):
"""
Return the document tree and publisher, for exploring Docutils internals.
Parameters: see `html_parts()`.
"""
if settings_overrides:
overrides = settings_overrides.copy()
else:
overrides = {}
overrides['input_encoding'] = input_encoding
output, pub = core.publish_programmatically(
source_class=io.StringInput, source=input_string,
source_path=source_path,
destination_class=io.NullOutput, destination=None,
destination_path=destination_path,
reader=None, reader_name='standalone',
parser=None, parser_name='restructuredtext',
writer=None, writer_name='null',
settings=None, settings_spec=None, settings_overrides=overrides,
config_section=None, enable_exit_status=None)
return pub.writer.document, pub
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language _name="reStructuredText" version="1.0" _section="Markup" mimetypes="text/restructured">
<pattern-item _name="Emphasis" style="Preprocessor">
<regex>(\*[^\*\n]*[^\*]\*)</regex>
</pattern-item>
<pattern-item _name="Strong Emphasis" style="Data Type">
<regex>(\*\*[^\*\n]*\*\*)</regex>
</pattern-item>
<pattern-item _name="Link" style="String">
<regex>`[^`]*`_</regex>
</pattern-item>
<pattern-item _name="WikiLink" style="Link">
<regex>\[\[[^\n]+\]\]</regex>
</pattern-item>
<pattern-item _name="List item" style="Keyword">
<regex>(^ *\*[ \t]+)|(^ *[0-9]+\.[ \t]+)</regex>
</pattern-item>
<pattern-item _name="Line" style="Data Type">
<regex>^[ \t]*[-='`"~`]+[ \t]*$</regex>
</pattern-item>
<pattern-item _name="Automatic link" style="String" end-at-line-end="TRUE">
<regex>(&lt;[A-Za-z._0-9]+@[A-Za-z0-9]+.[A-Za-z]+&gt;)|(&lt;[a-z]+://[^ \n]+&gt;)</regex>
</pattern-item>
<block-comment _name = "Code block" style= "Comment">
<start-regex>^::</start-regex>
<end-regex>^$</end-regex>
</block-comment>
<pattern-item _name="Inline Code" style="Comment">
<regex>``[^``]*``</regex>
</pattern-item>
<string _name="Directive" style="Comment">
<start-regex>^\.\. </start-regex>
<end-regex>$</end-regex>
</string>
</language>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment