The previous version had one issue, please use this one instead. El 30/03/11 11:47, Pablo Angulo Ardoy escribió: Hello: I just wrote a plugin to build an outline of a ReStructuredText (rst) document, based upon pythonoutline by Dieter Verfaillie. I'm attaching the relevant files, hope you get them. I'd love to have some feedback. Regards_______________________________________________ gedit-list mailing list gedit-list gnome org http://mail.gnome.org/mailman/listinfo/gedit-list |
#!/usr/bin/env python # -*- coding: utf-8 -*- # # This file is part of the ReST Outline Plugin for Gedit # based upon Python Outline Plugin for Gedit # Copyright (C) 2007 Dieter Verfaillie <dieterv optionexplicit be> # Copyright (C) 2011 Pablo Angulo <pangard cancamusa net> # # 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 St, Fifth Floor, Boston, MA 02110-1301 USA import gtk import gedit import gc import time class ReSTParser (object): '''Updates a treemodel, adding entries for each header section ''' header_chars = ['=', '-', '`', ':', "'", '"', '~', '^', '_', '*', '+', '#', '<', '>'] def __init__(self, treemodel): self.treemodel = treemodel def parse(self, text): last = None parents = [] levels = [] for j,line in enumerate(text.splitlines()): first = line[0] if line else '' if last and first in self.header_chars and all(c==first for c in line): if first not in levels: levels.append(first) i = levels.index(first) while i>len(parents): parents.append(self.treemodel.append(parents[-1] if parents else None, ('?', 'empty node', str(j-1)) )) if i<len(parents): parents = parents[:i] parents.append(self.treemodel.append(parents[-1] if parents else None, (first, last, str(j-1)) )) last = line class OutlineBox(gtk.VBox): def __init__(self): gtk.VBox.__init__(self) scrolledwindow = gtk.ScrolledWindow() scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrolledwindow.show() self.pack_start(scrolledwindow, True, True, 0) self.treeview = gtk.TreeView() self.treeview.set_rules_hint(True) self.treeview.set_headers_visible(False) self.treeview.set_enable_search(True) self.treeview.set_reorderable(False) self.treeselection = self.treeview.get_selection() self.treeselection.connect('changed', self.on_selection_changed) scrolledwindow.add(self.treeview) col = gtk.TreeViewColumn() col.set_title('name') col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) col.set_expand(True) render_text = gtk.CellRendererText() # render_text.set_property('cell-background', '#CCCCCC') render_text.set_property('xpad', 5) render_text.set_property('xalign', 0) render_text.set_property('yalign', 0.5) col.pack_start(render_text, expand=False) col.add_attribute(render_text, 'text', 0) render_text = gtk.CellRendererText() render_text.set_property('xalign', 0) render_text.set_property('yalign', 0.5) col.pack_start(render_text, expand=True) col.add_attribute(render_text, 'text', 1) self.treeview.append_column(col) self.treeview.set_search_column(1) self.label = gtk.Label() self.pack_end(self.label, False) self.expand_classes = False self.expand_functions = False self.show_all() def on_row_has_child_toggled(self, treemodel, path, iter): self.treeview.expand_row(path, False) def on_selection_changed(self, selection): model, iter = selection.get_selected() if iter: lineno = model.get_value(iter, 2) if not lineno: return lineno = int(lineno) name = model.get_value(iter, 1) linestartiter = self.buffer.get_iter_at_line(lineno) lineenditer = self.buffer.get_iter_at_line(lineno) lineenditer.forward_line() lineenditer.backward_char() line = self.buffer.get_text(linestartiter, lineenditer) self.buffer.select_range(linestartiter, lineenditer) self.view.scroll_to_cursor() def create_treemodel(self): #Header char, header, lineno treemodel = gtk.TreeStore(str, str, str) handler = treemodel.connect('row-has-child-toggled', self.on_row_has_child_toggled) return treemodel, handler def parse(self, view, buffer): self.view = view self.buffer = buffer startTime = time.time() treemodel, handler = self.create_treemodel() self.treeview.set_model(treemodel) self.treeview.freeze_child_notify() bounds = self.buffer.get_bounds() text = self.buffer.get_text(bounds[0], bounds[1]).replace('\r', '\n') + '\n' rstparser = ReSTParser(treemodel) rstparser.parse(text) gc.collect() treemodel.disconnect(handler) self.treeview.thaw_child_notify() stopTime = time.time() self.label.set_text('Outline created in ' + str(float(stopTime - startTime)) + ' s') return treemodel class ReSTOutlinePluginInstance(object): def __init__(self, plugin, window): self._window = window self._plugin = plugin self._insert_panel() self._models = {} def deactivate(self): self._remove_panel self._window = None self._plugin = None def update_ui(self): document = self._window.get_active_document() if document: uri = str(document.get_uri()) if document.get_mime_type() == 'text/restructured' or uri.endswith('.rst'): self.outlinebox.parse(self._window.get_active_view(), document) else: treemodel, handler = self.outlinebox.create_treemodel() self.outlinebox.treeview.set_model(treemodel) def _insert_panel(self): self.panel = self._window.get_side_panel() self.outlinebox = OutlineBox() self.panel.add_item(self.outlinebox, "ReST Outline", gtk.STOCK_INDEX) def _remove_panel(self): self.panel.destroy() class ReSTOutlinePlugin(gedit.Plugin): def __init__(self): gedit.Plugin.__init__(self) self._instances = {} def activate(self, window): self._instances[window] = ReSTOutlinePluginInstance(self, window) def deactivate(self, window): self._instances[window].deactivate() del self._instances[window] def update_ui(self, window): self._instances[window].update_ui()