docutils - s5html - Eine kleine Erweiterung

Code-Stücke können hier veröffentlicht werden.
Antworten
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Sonntag 5. März 2006, 18:23

Hier mal ein kleiner Wrapper um den s5html-Writer von den docutils.

Hintergrund:
Mit s5html kann man aus restructuredtext klasse Präsentationen erstellen die via Javascript im Browser laufen und damit vergleichsweise leicht auf relativ vielen Kisten darzustellen sind und schönen sourcecode haben.
Anpassen lässt sich das Aussehen auch noch schön mit CSS.

Der (aus meiner Sicht) Nachteil beim normalen s5-writer ist, dass jede level-1-Sektion zu nem einzelnen slide (also einer Seite) wird.
Untersektionen werden dann auf den Slide mit drauf gerendert.

Das macht es bei größeren Präsentationen schwer, soetwas wie eine Struktur zu behalten, erst recht, wenn man vielleicht aus dem selbern source auch mal ein schönes pdf zaubern will.

Hier soll mein writer abhilfe schaffen, er bedient sich der s5html- und html4css-writer und macht Level-2-Sektionen zu Slides und hängt dabei den Titel der "väterlichen" Level-1-Sektion in kleiner Schrift an den Titel des Slides. (Mit richtigem css-code auch darunter was sehr fesch aussehen kann).

Vielleicht hat noch jemand anderes als ich Verwendung dafür oder will das Ding sogar ein bisschen ausbauen.

Code: Alles auswählen

import sys
import os
import re
import docutils
from docutils import frontend, nodes, utils
#from docutils.writers import html4css1
from docutils.parsers.rst import directives
from docutils.writers import s5_html


themes_dir_path = utils.relative_path(
    os.path.join(os.getcwd(), 'dummy'),
    os.path.join(os.path.dirname(__file__), 'themes'))

def find_theme(name):
  # Where else to look for a theme?
  # Check working dir?  Destination dir?  Config dir?  Plugins dir?
  path = os.path.join(themes_dir_path, name)
  if not os.path.isdir(path):
    raise docutils.ApplicationError(
      'Theme directory not found: %r (path: %r)' % (name, path))
  return path


class Writer(s5_html.Writer):

  config_section = 's5_html writer'
  config_section_dependencies = ('writers', 's5_html writer')

  def __init__(self):
    s5_html.Writer.__init__(self)
    self.translator_class = S5HTMLSectTranslator


class S5HTMLSectTranslator(s5_html.S5HTMLTranslator):

  def __init__(self, *args):
    s5_html.S5HTMLTranslator.__init__(self, *args)
    self._foretitle = ""

  def visit_section(self, node):
    if not self.section_count:
      self.body.append('\n</div>\n')
    self.section_count += 1
    self.section_level += 1

    if self.section_level > 2:
      # dummy for matching div's
      self.body.append(self.starttag(node, 'div', CLASS='section'))
    else:
      self.body.append(self.starttag(node, 'div', CLASS='slide'))

  def visit_Text(self, node):
    if isinstance(node.parent, nodes.title) and self.section_level == 1:
      self._foretitle = node.astext()
    elif isinstance(node.parent, nodes.title) and self.section_level == 2:
      pass
    s5_html.S5HTMLTranslator.visit_Text(self, node)

  def visit_subtitle(self, node):
    if isinstance(node.parent, nodes.section):
      level = self.section_level + self.initial_header_level - 1
          
      if level == 1:
        level = 2
      tag = 'h%s' % level
      self.body.append(self.starttag(node, tag, ''))
      self.context.append('</%s>\n' % tag)
    else:
      s5_html.S5HTMLTranslator.visit_subtitle(self, node)

  def visit_title(self, node, move_ids=0):
    if self.section_level == 2:
      self.body.append(self.starttag(node, "h1", CLASS=''))
      self.context.append('</h1><span class="tiny layout"><i>%s</i></span>\n' % self._foretitle)
    else:
      s5_html.S5HTMLTranslator.visit_title(self, node, move_ids=move_ids)
PS:
Bevor man mich dafür steinigt, nehm ichs gleich vorweg: Das meiste ist copy&paste vom s5html-writer, da ich aber von dem "erbe" kann man einiges auch noch weglassen, war bloß zu faul die überflüssigen Funktionen noch rauszusortieren.

Vielleicht hat ja jemand Lust und Zeit das ein wenig zu säubern etc...

edit:
Das "layout" in der span-class soll übrigens dafür sorgen, dass der Titel der Vater-Sektion in der Druckversion nicht mit angehängt wird. (S5 hat da so einen schönen Handout-Modus)
Antworten