Logo Search packages:      
Sourcecode: yodl version File versions  Download package

yodl2texinfo-post.py

#!@PYTHON@

# yodl2texinfo-post.py
# 
# (c) 1998,1999 Jan Nieuwenhuizen

program_name = 'yodl2texinfo-post'
version = '@TOPLEVEL_VERSION@'
simple_nodes = 0
backup = 0

## urg::
## this hack (File: texinfo,  Node: Pointer Validation)
##
##      @set nodename Node 1
##      @node @value{nodename}, Node 2, Top, Top
## 
## together with --commands-in-node-names, still doesn't work:
##
##    out/topinfo.texinfo:906: Node `@value{nodename}' previously defined at line 48.
##
urg_value = 1
not_in_node_set = '[,:\.?!\\\'`{}]'
not_in_node = '.*[,:\.?!\\\'`{}].*'

import os
import sys

import getopt
from string import *
import regex
import regsub
import time

def program_id ():
      return program_name + ' version ' + version;

def identify ():
      sys.stdout.write (program_id () + '\n')

def help ():
      sys.stdout.write ("Usage: %s [OPTION]... [FILE]...\n"
            "Resolve yodl tags, autogenerate nodes and menus.\n\n"
            + "Options:\n"
            + "  -h, --help            print this help\n"
            + "  -k, --keep              keep backup of Yodl output\n"
            + "  -s, --simple-nodes    don't put next,prev,up references in nodes\n"
            % (program_name)
            )
      sys.exit (0)


identify ()
(options, files) = getopt.getopt (
      sys.argv[1:], 'hks', ['help','keep','simple-nodes'])
for opt in options:
      o = opt[0]
      a = opt[1]
      if o == '--help' or o == '-h':
            help ()
      elif o == '--keep' or o == '-k':
            backup = 1
      elif o == '--simple-nodes' or o == '-s':
            simple_nodes = 1
      else:
            print o
            raise getopt.error


def gulp_file (f):
      try:
            i = open (f)
            i.seek (0, 2)
            n = i.tell ()
            i.seek (0,0)
      except:
            sys.stderr.write ('can\'t open file %s\n ' % f)
            return ''
      s = i.read (n)
      if len (s) <= 0:
            sys.stderr.write ('gulped empty file: %s\n'% f)
      return s


class Node:
      def __init__ (this, pos, name):
            this.pos = pos
            this.name = name
            this.description = ''
            this.prev = ''
            this.next = ''
            this.top = ''

class Menu (Node):
      def __init__ (this, pos, name):
            Node.__init__ (this, pos, name)
            this.node_list = []

TAB_POS = 34

class Pre_texinfo_file (Menu):
      def __init__ (this, filename):
            Menu.__init__ (this, 0, 'Top')
            this.filename = filename
            this.node_list = []
            this.s = ''
            this.offset = 0
            this.last = Node (0, '')
            this.prefix = ''
            this.default = Node (0,'')
            this.default.top = '(dir)'
            this.node_dict = {}
            this.xref_list = []

      def gulp (this):
            this.s = gulp_file (this.filename)

      def new_menu (this, pos, name):
            m = Menu (pos, name)
            if this.default.name:
                  m.name = this.default.name
            if this.default.description:
                  m.description = this.default.description
            m.name = this.prefix + m.name
            return m

      def new_node (this, pos, name):
            n = Node (pos, name)
            if this.default.name:
                  n.name = this.default.name
            if this.default.description:
                  n.description = this.default.description
            n.name = this.prefix + n.name
            while this.node_dict.has_key (n.name):
                  n.name = n.name + 'i'
            this.node_dict[n.name] = 0
            n.top = this.default.top
            n.prev = this.last.name
            this.last.next = n.name
            this.last = n
            return n

      def eat_tag (this):
            i = regex.search ('@TAGSTART@', this.s)
            j = 0
            if i < 0:
                  return 0
            j = regex.search ('@TAGEND@', this.s[i:])
            if j < 0:
                  raise 'huh?'
            j = i + j + len ('@TAGEND@')
            tag = this.s[i + len ('@TAGSTART@'):j - len ('@TAGEND@')]
            k = regex.search (' ', tag[1:]) + 1
            tag_name = tag[1:k]
            tag_string = tag[k:len (tag) - 1]
            while tag_string[:1] == ' ':
                  tag_string = tag_string[1:]
            #
            # urg, commas in titles...
            # but even more urg, makeinfo (3.12) chokes on 
            # various other characters in node names too
            # 
            if urg_value:
                  tag_string = regsub.gsub (not_in_node_set, '-', tag_string)
                  tag_string = regsub.gsub ('--', '-', tag_string)
                  # brr
                  tag_string = regsub.gsub ('--', '-', tag_string)
                  tag_string = regsub.gsub ('@code', '', tag_string)
                  tag_string = regsub.gsub ('@emph', '', tag_string)
                  tag_string = regsub.gsub ('@strong', '', tag_string)
            if tag_name == 'menu':
                  this.default.top = 'Top'
                  n = this.new_node (i, tag_string)
                  m = this.new_menu (i, tag_string)
                  this.default.top = tag_string
                  this.default.name = ''
                  this.default.description = ''
                  m.node_list.append (n)
                  this.node_list.append (m)
            elif tag_name == 'node':
                  n = this.new_node (i, tag_string)
                  this.default.name = ''
                  this.default.description = ''
                  if not len (this.node_list):
                        # m = Menu (i, 'Toplevel')
                        m = this.new_menu (i, 'Toplevel')
                        this.node_list.append (m)
                  this.node_list[len (this.node_list)-1].node_list.append (n)
            elif tag_name == 'node_description':
                  this.default.description = tag_string
            elif tag_name == 'node_name':
                  this.default.name = tag_string
            elif tag_name == 'node_prefix':
                  this.prefix = tag_string
            elif tag_name == 'ref':
                  ## urg, prefix is broken
                  ref = '@ref{' + this.prefix + tag_string + '}'
                  this.s = this.s[:i] + ref + this.s[j:]
                  this.xref_list.append (this.prefix + tag_string)
                  ## urg
                  return 1
            else:
                  sys.stderr.write ("unknown tag: `" + tag + "', skipping\n")
            this.s = this.s[:i] + this.s[j:]
            return 1

      def plug (this):
            if backup:
                  os.rename (this.filename, this.filename + '~')
            fd = open (this.filename, 'w')
            fd.write (this.s)
            fd.close ()

      def create_node (this, n):
            node = '@node '
            set = ''
            if not urg_value and  regex.match (not_in_node, n.name) != -1:
                  set = set + "@set nodename " + n.name + "\n"
                  node = node + "@value{nodename}"
            else:
                  node = node + n.name
            if not simple_nodes:
                  if  not urg_value and regex.match (not_in_node, n.next) != -1:
                        set = set + "@set nextname " + n.next + "\n"
                        node = node + ", @value{nextname}"
                  else:
                        node = node + ", " + n.next
                  if  not urg_value and regex.match (not_in_node, n.prev) != -1:
                        set = set + "@set prevname " + n.prev + "\n"
                        node = node + ", @value{prevname}"
                  else:
                        node = node + ", " + n.prev
                  if  not urg_value and regex.match (not_in_node, n.top) != -1:
                        set = set + "@set topname " + n.top + "\n"
                        node = node + ", @value{topname}"
                  else:
                        node = node + ", " + n.top
            node = set + node + "\n"
            if n.name == 'Top':
                  node = node + "@top\n"
            this.s = this.s[:n.pos + this.offset] + node + this.s[n.pos + this.offset:]
            this.offset = this.offset + len (node)
            
      def create_menu (this, m):
            if len (m.node_list) < 2:
                  return
            menu = "@menu\n"
            for n in m.node_list[1:]:
                  d = n.description
                  if not d:
                        d = n.name
                  if not urg_value and regex.match (not_in_node, n.name) != -1:
                        menu = menu + "@set nodename " + n.name + "\n"
                        menu = menu + "* @value{nodename}::"
                        menu = menu + ' ' * (TAB_POS - len (n.name)) + d + "\n"
                  else:
                        menu = menu + ljust ('* ' + n.name + '::', TAB_POS) + d + "\n"
            menu = menu + "@end menu\n"
            this.s = this.s[:m.pos + this.offset] + menu + this.s[m.pos + this.offset:]
            m.node_list[0].pos = m.node_list[0].pos - len (menu)
            this.offset = this.offset + len (menu)

      def create_nodes (this, m):
            for n in m.node_list:
                  this.create_node (n)
            
      def parse (this):
            i = 1
            while i:
                  i = this.eat_tag ()

      def nodes_and_menus (this):
            this.default.top = '(dir)'
            n = this.new_node (0, 'Top')
            m = Menu (0, 'Top')
            m.node_list.append (n)
            this.node_list.insert (0, m)
            n.pos = this.offset
            this.create_menu (this)
            n.pos = - this.offset
            this.create_nodes (m)
            for m in this.node_list[1:]:
                  this.create_menu (m)
                  this.create_nodes (m)

      def xrefs (this):
            this.prefix = ''
            this.default.top = 'Top'
            m = Menu (len (this.s), 'Missing nodes')
            this.default.top = 'Missing nodes'
            first_b = 1
            for i in this.xref_list:
                  if not this.node_dict.has_key (i):
                        if first_b:
                              this.default.top = 'Top'
                              n = this.new_node (len (this.s), 'Missing nodes')
                              m.node_list.append (n)
                              this.default.top = 'Missing nodes'
                              first_b = 0
                        sys.stderr.write (this.filename + ": warning: xref to nonexistent node: `" + i + "'\n")
                        n = this.new_node (len (this.s), i)
                        m.node_list.append (n)
            if len (m.node_list) > 1:
                  this.node_list.append (m)
            this.default.top = 'Top'

      def post (this):
            this.gulp ()
            this.parse ()
            this.xrefs ()
            this.nodes_and_menus ()
            this.s = regsub.gsub ('^\n\n', '\n', this.s)
            this.s = '\n' + this.s 
            infotitle = ''
            basename = os.path.basename (os.path.splitext (this.filename)[0])
            infoname = basename + ".info"
            if len (this.node_list) > 1:
                  infotitle = this.node_list[1].name
            else:
                  infotitle = basename
#           this.s = '@settitle %s\n' % this.node_list[1].name + this.s 
#           this.s = '@setfilename %s\n' % infoname + this.s 
#           this.s = '\\input texinfo @c -*-texinfo-*-\n' + this.s 
            this.s = r"""\input texinfo @c -*-texinfo-*-
@setfilename %s
@settitle %s
""" % (infoname, infotitle) + this.s 
            this.s = this.s + "\n@bye"
            this.plug ()


for f in files:
      t = Pre_texinfo_file (f)
      t.post ()


Generated by  Doxygen 1.6.0   Back to index