#! /usr/bin/python # -*- coding: UTF-8 -*- import sys import re import string import commands import warnings errors = 0 def warn(msg, error=None): global errors errors += 1 if error is None: warnings.warn("-- "+str(errors)+" --\n "+msg, RuntimeWarning, 2) else: warnings.warn("-- "+str(errors)+" --\n "+msg+ "\n error was "+str(error), RuntimeWarning, 2) #fu # beware, stupid python interprets backslashes in repl only partially! def s(string, pattern, repl, count=0): return re.sub(pattern, repl, string, count) def m(string, pattern): return re.match(pattern, string) def sorted_keys(dict): keys = dict.keys() keys.sort() return keys # we make up a few formatter routines to help in the processing: def html2docbook(text): """ the C comment may contain html markup - simulate with docbook tags """ return ( s(s(s(s(s(s(s(s(s(s(s(text, r"",""), r"(",r"\1emphasis>"), r"",""), r"",""), r"",""), r"",""), r"(?s)\s*",""), # r"",""), # r"
  • ",""), # r"
  • ","
    \n"), r"",""), r"
  • ",""), r"
  • ","")) def paramdef2html(text): return s(s(s(s(s(text, r"\s+", r"\n"), r"",r""), r"",r""), r"",r"\n "), r"",r"\n") def section2html(text): mapping = { "" : "
    ", "" : "
    ", "" : "

    ", "" : "

    " , "" : "", "" : "" } for str in mapping: text = string.replace(text, str, mapping[str]) return text def html(text): return section2html(paramdef2html(text)) def cdata1(text): return string.replace(text, "&", "&") def cdata31(text): return string.replace(string.replace(text, "<","<"), ">",">") def cdata3(text): return cdata31(cdata1(text)) def cdata43(text): return string.replace(text,"\"", """) def cdata41(text): return cdata43(cdata31(text)) def cdata4(text): return cdata43(cdata3(text)) def markup_as_screen41 (text): """ used for non-star lines in comment blocks """ return " " + s(cdata41(text), r"(?m)^", r" ") +" " def file_comment2section(text): """ convert a C comment into a series of and parts """ return ("\n"+ s(s(s(s(s(s(s(text, r"(?s){<([\w\.\-]+\@[\w\.\-]+\w\w)>", r"<\1>"), r"(?mx) ^\s?\s?\s? ([^\*\s]+ .*) $", lambda x : markup_as_screen41 (x.group(1))), r"(?mx) ^\s*[*]\s* $", r" \n\n"), r"(?mx) ^\s?\s?\s?\* (.*) $", r" \1 "), r"(?sx) (\s*) ", r"\1"), r"(?sx) <([^<>\;]+\@[^<>\;]+)> ", r"\1"), r"(?sx) \<\;([^<>\&\;]+\@[^<>\&\;]+)\>\; ", r"\1") + "\n") def func_comment2section(text): """ convert a C comment into a series of and parts and sanitize a few markups already present in the comment text """ return ("\n"+ s(s(s(s(s(s(s(s(s(s(s(text, r"",r""), r"", r""), r"(?mx) ^\s?\s?\s? ([^\*\s]+.*)", lambda x: markup_as_screen41 (x.group(1))), r"(?mx) ^\s?\s?\s?\* (.*) $", r"
    \1"), r"(?mx) ^\s*\s* $", r"\n
    \n"), r"<<",r"<"), r">>",r">"), r"(?sx) (\s*)",r"\1"), r"(?sx) (\s*)",r"\1"), r"(?sx) (\s*)",r"\1"), r"(?sx) <\/screen>(\s*)",r"\1") + "\n") def markup_link_syntax(text): """ markup the link-syntax ` => somewhere ` in the text block """ return ( s(s(s(s(text, r"(?mx) (^|\s)\=\>\"([^\"]*)\"", r"\1\2"), r"(?mx) (^|\s)\=\>\'([^\"]*)\'", r"\1\2"), r"(?mx) (^|\s)\=\>\s(\w[\w.]*\w)\b", r"\1\2"), r"(?mx) (^|\s)\=\>\s([^\s\,\.\!\?\:\;\<\>\&\'\=\-]+)", r"\1\2")) def this_function_link(text, name): return s(text, r"(?sx) (T|t)his \s (function|procedure) ", lambda x : ""+x.group(1)+"he "+name+" "+x.group(2)+"") # ----------------------------------------------------------------------- class Options: var = {} def __getattr__(self, name): if not self.var.has_key(name): return None return self.var[name] def __setattr__(self, name, value): self.var[name] = value #end o = Options() o.verbose = 0 o.version = s( commands.getoutput( """ grep -i "^version *:" *.spec 2>/dev/null | sed -e "s/[Vv]ersion *: *//" """), r"\s*",r"") o.package = s(commands.getoutput( """ grep -i "^name *:" *.spec 2>/dev/null | sed -e "s/[Nn]ame *: *//" """), r"\s*",r"") if not len(o.version): o.version = commands.getoutput(""" date +%Y.%m.%d """) if not len(o.package): o.package = "_project" o.suffix = "-doc3" o.mainheader = o.package+".h" class File: def __init__(self, filename): self.name = filename self.mainheader = o.mainheader self.authors = "" self.copyright = "" def __getattr__(self, name): """ defend against program to break on uninited members """ if self.__dict__.has_key(name): return self.__dict__[name] warn("no such member: "+name); return None def set_author(self, text): if self.authors: self.authors += "\n" self.authors += text return text def set_copyright(self, text): self.copyright = text return text class InputFiles: """ for each set of input files we can create an object it does correspond with a single html-output page and a single docbook master page to be output """ def __init__(self): # the id will tell us in which order # we did meet each function definition self.id = 1000 self.files = [] # file_list self.funcs = [] # func_list: of hidden class FuncDeclaration self.file = None # current file def new_File(self, name): self.file = File(name) self.files.append(self.file) return self.file def next_id(self): id = self.id ; self.id += 1 return id def add_function_declaration(self, comment, prototype): class FuncDeclaration: # note that both decl.comment and pass # decl.prototype are in cdata1 format func = FuncDeclaration() func.file = self.file func.comment = s(comment, # need to take out email-style markups r"<([\w\.\-]+\@[\w\.\-]+\w\w)>", r"<\1>") func.prototype = prototype func.id = all.next_id() self.funcs.append(func) # print id return prototype def scan_options (options, list): def encode(text): return s(s(text, r"¬", r"&#AC;"), r"\*/",r"¬") def decode(text): return s(text, r"¬", r"*/") for name in options: found = m(name, r"^(\w+)=(.*)") if found: o.var[found.group(1)] = found.group(2) continue #else try: input = open(name, "r") except IOError, error: warn(#...... (scan_options) ............... "can not open input file: "+name, error) continue text = input.read() ; input.close() text = encode (cdata1 (text)) file = list.new_File(name) # cut per-function comment block text = s(text, r"(?x) [/][*][*](?=\s) ([^¬]+) ¬ ([^\{\}\;\#]+) [\{\;]", lambda x : list.add_function_declaration( decode(x.group(1)), decode(x.group(2)))) # cut per-file comment block found = m(text, r"(?sx) [/][*]+(?=\s) ([^¬]+) ¬ " r"(?:\s*\#define\s*\S+)*" r"(\s*\#include\s*<[^<>]*>(?:\s*//[^\n]*)?)") if found: file.comment = decode(found.group(1)) file.include = cdata31(found.group(2)) else: file.comment = None file.include = None found = m(text, r"(?sx) ^ [/][*]+(?=\s) ([^¬]+) ¬ ") if found: file.comment = decode(found.group(1)) #fi # throw away the rest - further processing on memorized strings only return None all = InputFiles() scan_options (sys.argv[1:], all) if not o.docbookfile: o.docbookfile = o.package+o.suffix+".docbook" if not o.libhtmlfile: o.libhtmlfile = o.package+o.suffix+".html" if not o.dumpdocfile: o.dumpdocfile = o.package+o.suffix+".dxml" # ........................................................................... # check out information in the file.comment section def all_files_comment2section(list): for file in list: if file.comment is None: continue file.section = file_comment2section(file.comment) file.section = s( file.section, r"(?sx) \b[Aa]uthor\s*:(.*) ", lambda x : "" + file.set_author(x.group(1)) + "") file.section = s( file.section, r"(?sx) \b[Cc]opyright\s*:([^<>]*)
    ",lambda x : "" + file.set_copyright(x.group(1)) + "") # if "file" in file.name: print >> sys.stderr, file.comment # 2.3 #od all_files_comment2section(all.files) # ----------------------------------------------------------------------- class Function: " void* hello (int) const " def __init__(self): self.prespec = "" self.namespec = "" self.callspec = "" self.name = "" # def set(self, **defines): # name = defines.keys()[0] # self.__dict__[name] = defines[name] # return defines[name] # def cut(self, **defines): # name = defines.keys()[0] # self.__dict__[name] += defines[name] # return "" def __getattr__(self, name): """ defend against program exit on members being not inited """ if self.__dict__.has_key(name): return self.__dict__[name] warn("no such member: "+name); return None def dict(self): return self.__dict__ def dict_sorted_keys(self): keys = self.__dict__.keys() keys.sort() return keys def parse(self, prototype): found = m(prototype, r"(?sx) ^(.*[^.]) \b(\w[\w.]*\w)\b (\s*\(.*) $ ") if found: self.prespec = found.group(1).lstrip() self.namespec = found.group(2) self.callspec = found.group(3).lstrip() self.name = self.namespec.strip() return self.name return None # pass 1 of per-func strings ............................................... # (a) cut prototype into prespec/namespec/callspec # (b) cut out first line of comment as headline information # (c) sanitize rest of comment block into proper docbook formatted .body # # do this while copying strings from all.funcs to function_list # and remember the original order in name_list def markup_callspec(text): return ( s(s(s(s(s(text, r"(?sx) ^([^\(\)]*)\(", r"\1(",1), r"(?sx) \)([^\(\)]*)$", r")\1",1), r"(?sx) , ", r","), r"(?sx) (\s+) ", r"\1"), r"(?sx) (\s+)", r"\1")) def parse_all_functions(func_list): # list of FunctionDeclarations """ parse all FunctionDeclarations and create a list of Functions """ list = [] for func in all.funcs: function = Function() if not function.parse (func.prototype): continue list.append(function) function.body = markup_link_syntax(func.comment) if "\n" not in function.body: # single-line comment is the head function.head = function.body function.body = "" else: # cut comment in first-line and only keep the rest as descr body function.head = s(function.body, r"(?sx) ^([^\n]*\n).*",r"\1",1) function.body = s(function.body, r"(?sx) ^[^\n]*\n", r"", 1) #fi if m(function.head, r"(?sx) ^\s*$ "): # empty head line, autofill here function.head = s("("+func.file.name+")", r"[.][.][/]", r"") function.body = func_comment2section(function.body) function.src = func # keep a back reference # add extra docbook markups to callspec in $fn-hash function.callspec = markup_callspec (function.callspec) #od return list function_list = parse_all_functions(all.funcs) def examine_head_anchors(func_list): """ .into tells later steps which func-name is the leader of a man page and that this func should add its descriptions over there. """ for function in func_list: function.into = None function.seealso = None found = m(function.head, r"(?sx) ^ \s* (\w[\w.]*\w)<\/link>") # if found and found.group(1) in func_list.names: if found and found.group(1): function.into = found.group(1) def set_seealso(f, value): f.seealso = value return value function.head = s(function.head, r"(.*)also:(.*)", lambda x : set_seealso(function, x.group(2)) and x.group(1)) if function.seealso and None: print "function[",function.name,"].seealso=",function.seealso examine_head_anchors(function_list) # =============================================================== HTML ===== def find_by_name(func_list, name): for func in func_list: if func.name == name: return func #od return None #fu class HtmlFunction: def __init__(self, func): self.src = func.src self.into = func.into self.name = func.name self.toc_line = paramdef2html( " "+func.prespec+"\n"+ "   \n"+ " \n"+ " "+func.namespec+""+ " \n"+ "   \n"+ " "+func.callspec+"\n") self.synopsis = paramdef2html( " "+func.prespec+"\n"+ "
    "+func.namespec+"\n"+ "   "+func.callspec+"\n") self.anchor = "" self.section = "  "+func.head+"\n"+ \ "\n"+section2html(func.body) #class class HtmlFunctionFamily(HtmlFunction): def __init__(page, func): HtmlFunction.__init__(page, func) page.toc_line_list = [ page.toc_line ] # page.html_txt = page.synopsis page.synopsis_list = [ page.synopsis ] page.anchor_list = [ page.anchor ] page.section_list = [ this_function_link(page.section, func.name) ] def ensure_name(text, name): adds = ""+name+" -" match = r"(?sx) .*>[^<>]*\b" + name + r"\b[^<>]*<.*" found = m(text, match) if found: return text found = m(text, r".*.*") if found: return s(text, r"()", r"\1"+adds, 1) return adds+text def combined_html_pages(func_list): """ and now add descriptions of non-leader entries (html-mode) """ combined = {} for func in func_list: # assemble leader pages if func.into is not None: continue combined[func.name] = HtmlFunctionFamily(func) for func in func_list: if func.into is None: continue if func.into not in combined : warn(#......... (combine_html_pages) .............. "function '"+func.name+"'s into => '"+func.into+ "\n: no such target function: "+func.into) combined[func.name] = HtmlFunctionFamily(func) continue #fi page = HtmlFunction(func) into = combined[func.into] into.toc_line_list.append( page.toc_line ) into.anchor_list.append( page.anchor ) into.synopsis_list.append( page.synopsis ) into.section_list.append( s(ensure_name(this_function_link(section2html( func.body ), func.name), func.name), r"(?sx) (\s*) ", r"\1")) return combined.values() html_pages = combined_html_pages(function_list) def html_resolve_links_on_page(text, list): """ link ref-names of a page with its endpoint on the same html page""" def html_link (name , extra): """ make s to of correct target or make it """ if find_by_name(list, name) is None: return ""+name+extra+"" else: return ""+name+extra+"" #fu html_link return s(s(text, r"(?sx) (\w+)([^<>]*)<\/link> ", lambda x : html_link(x.group(1),x.group(2))), r"(?sx) \-\> ", r"->") # just sanitize.. #fu html_resolve_links class HtmlPage: def __init__(self): self.toc = "" self.txt = "" self.package = o.package self.version = o.version def page_text(self): """ render .toc and .txt parts into proper page """ T = "" T += "" T += ""+self.package+"autodoc documentation " T += "\n\n" T += "\n

    "+self.package+" - "+self.version T += "

    " T += "\n" T += self.toc T += "\n
    " T += "\n

    Documentation

    \n\n
    " T += html_resolve_links_on_page(self.txt, function_list) T += "\n
    \n\n" return T def add_page_map(self, list): """ generate the index-block at the start of the onepage-html file """ keys = list.keys() keys.sort() for name in keys: self.toc += "\n"+ \ "\n\n".join( list[name].toc_line_list)+"\n" self.txt += "\n
    "+" ".join(list[name].anchor_list) self.txt += "\n"+"\n
    ".join(list[name].synopsis_list)+"
    " self.txt += "\n
    \n"+"\n".join(list[name].section_list) self.txt += ("\n

    "+ "("+list[name].src.file.name+")"+ "

    ") def add_page_list(self, functions): """ generate the index-block at the start of the onepage-html file """ mapp = {} for func in functions: mapp[func.name] = func #od self.add_page_map(mapp) #end html = HtmlPage() # html.add_function_dict(Fn) # html.add_function_list(Fn.sort.values()) html.add_page_list(html_pages) # and finally print the html-formatted output try: F = open(o.libhtmlfile, "w") except IOError, error: warn(# ............. open(o.libhtmlfile, "w") .............. "can not open html output file: "+o.libhtmlfile, error) else: print >> F, html.page_text() F.close() #fi # ========================================================== DOCBOOK ===== # let's go for the pure docbook, a reference type master for all man pages class RefPage: def __init__(self, func): """ initialize the fields needed for a man page entry - the fields are named after the docbook-markup that encloses (!!) the text we store the entries like X.refhint = "hello" will be printed therefore as hello. Names with underscores are only used as temporaries but they are memorized, perhaps for later usage. """ self.refhint = "\n\n" self.refentry = None self.refentry_date = o.version.strip() # //refentryinfo/date self.refentry_productname = o.package.strip() # //refentryinfo/prod* self.refentry_title = None # //refentryinfo/title self.refentryinfo = None # override self.manvolnum = "3" # //refmeta/manvolnum self.refentrytitle = None # //refmeta/refentrytitle self.refmeta = None # override self.refpurpose = None # //refnamediv/refpurpose self.refname = None # //refnamediv/refname self.refname_list = [] self.refnamediv = None # override self.mainheader = func.src.file.mainheader self.includes = func.src.file.include self.funcsynopsisinfo = "" # //funcsynopsisdiv/funcsynopsisinfo self.funcsynopsis = None # //funcsynopsisdiv/funcsynopsis self.funcsynopsis_list = [] self.description = None self.description_list = [] # optional sections self.authors_list = [] # //sect1[authors]/listitem self.authors = None # override self.copyright = None self.copyright_list = [] self.seealso = None self.seealso_list = [] if func.seealso: self.seealso_list.append(func.seealso) # func.func references self.func = func self.file_authors = None if func.src.file.authors: self.file_authors = func.src.file.authors self.file_copyright = None if func.src.file.copyright: self.file_copyright = func.src.file.copyright #fu def refentryinfo_text(page): """ the manvol formatter wants to render a footer line and header line on each manpage and such info is set in """ if page.refentryinfo: return page.refentryinfo if page.refentry_date and \ page.refentry_productname and \ page.refentry_title: return ( "\n "+page.refentry_date+""+ "\n "+page.refentry_productname+""+ "\n "+page.refentry_title+"") if page.refentry_date and \ page.refentry_productname: return ( "\n "+page.refentry_date+""+ "\n "+page.refentry_productname+"") return "" def refmeta_text(page): """ the manvol formatter needs to know the filename of the manpage to be made up and these parts are set in actually """ if page.refmeta: return page.refmeta if page.manvolnum and page.refentrytitle: return ( "\n "+page.refentrytitle+""+ "\n "+page.manvolnum+"") if page.manvolnum and page.func.name: return ( "\n "+page.func.name+""+ "\n "+page.manvolnum+"") return "" def refnamediv_text(page): """ the manvol formatter prints a header line with a line and 'd functions that are described later. For each of the s listed here, a mangpage is generated, and for each of the != then a symlink is created """ if page.refnamediv: return page.refnamediv if page.refpurpose and page.refname: return ("\n "+page.refname+''+ "\n "+page.refpurpose+" ") if page.refpurpose and page.refname_list: T = "" for refname in page.refname_list: T += "\n "+refname+'' T += "\n "+page.refpurpose+" " return T return "" def funcsynopsisdiv_text(page): """ refsynopsisdiv shall be between the manvol mangemaent information and the reference page description blocks """ T="" if page.funcsynopsis: T += "\n" if page.funcsynopsisinfo: T += "\n"+ page.funcsynopsisinfo + \ "\n\n" T += page.funcsynopsis + \ "\n\n" if page.funcsynopsis_list: T += "\n" if page.funcsynopsisinfo: T += "\n"+ page.funcsynopsisinfo + \ "\n\n" for funcsynopsis in page.funcsynopsis_list: T += funcsynopsis T += "\n\n" #fi return T def description_text(page): """ the description section on a manpage is the main part. Here it is generated from the per-function comment area. """ if page.description: return page.description if page.description_list: T = "" for description in page.description_list: if not description: continue T += description if T: return T return "" def authors_text(page): """ part of the footer sections on a manpage and a description of original authors. We prever an itimizedlist to let the manvol show a nice vertical aligment of authors of this ref item """ if page.authors: return page.authors if page.authors_list: T = "" previous="" for authors in page.authors_list: if not authors: continue if previous == authors: continue T += "\n "+authors+"" previous = authors T += "" return T if page.authors: return page.authors return "" def copyright_text(page): """ the copyright section is almost last on a manpage and purely optional. We list the part of the per-file copyright info """ if page.copyright: return page.copyright """ we only return the first valid instead of merging them """ if page.copyright_list: T = "" for copyright in page.copyright_list: if not copyright: continue return copyright # !!! return "" def seealso_text(page): """ the last section on a manpage is called 'SEE ALSO' usally and contains a comma-separated list of references. Some manpage viewers can parse these and convert them into hyperlinks """ if page.seealso: return page.seealso if page.seealso_list: T = "" for seealso in page.seealso_list: if not seealso: continue if T: T += ", " T += seealso if T: return T return "" def refentry_text(page, id=None): """ combine fields into a proper docbook refentry """ if id is None: id = page.refentry if id: T = '' else: T = '' # this is an error if page.refentryinfo_text(): T += "\n"+ page.refentryinfo_text()+ \ "\n\n" if page.refmeta_text(): T += "\n"+ page.refmeta_text() + \ "\n\n" if page.refnamediv_text(): T += "\n"+ page.refnamediv_text() + \ "\n\n" if page.funcsynopsisdiv_text(): T += "\n\n"+ page.funcsynopsisdiv_text()+ \ "\n\n" if page.description_text(): T += "\nDescription " + \ page.description_text() + "\n" if page.authors_text(): T += "\nAuthor " + \ page.authors_text() + "\n" if page.copyright_text(): T += "\nCopyright " + \ page.copyright_text() + "\n\n" if page.seealso_text(): T += "\nSee Also " + \ page.seealso_text() + "\n\n" T += "\n\n" return T #fu #end # ----------------------------------------------------------------------- class FunctionRefPage(RefPage): def reinit(page): """ here we parse the input function for its values """ if page.func.into: page.refhint = "\n \n" #fi page.refentry = page.func.name # //refentry@id page.refentry_title = page.func.name.strip() # //refentryinfo/title page.refentrytitle = page.func.name # //refmeta/refentrytitle if page.includes: page.funcsynopsisinfo += "\n"+page.includes if not page.funcsynopsisinfo: page.funcsynopsisinfo="\n"+' #include <'+page.mainheader+'>' page.refpurpose = page.func.head page.refname = page.func.name def funcsynopsis_of(func): return ( "\n \n "+func.prespec+ " "+func.name+""+ "\n"+s(s(s(func.callspec, r"\s*\(",r" "), r"\)\s*",r" "), r"
    \s*,\s*",r"\n ")+ " ") page.funcsynopsis = funcsynopsis_of(page.func) page.description = ( html2docbook(this_function_link(page.func.body, page.func.name))) if page.file_authors: def add_authors(page, ename, email): page.authors_list.append( ename+' '+email ) return ename+email s(page.file_authors, r"(?sx) \s* ([^<>]*) ([^<>]*) ", lambda x : add_authors(page, x.group(1), x.group(2))) #fi if page.file_copyright: page.copyright = "\n"+page.file_copyright+"\n" #fi return page def __init__(page,func): RefPage.__init__(page, func) FunctionRefPage.reinit(page) def refpage_list_from_function_list(funclist): list = [] mapp = {} for func in funclist: mapp[func.name] = func #od for func in funclist: page = FunctionRefPage(func) if func.into and func.into not in mapp: warn (# ............ (refpage_list_from_function_list) ....... "page '"+page.func.name+"' has no target => "+ "'"+page.func.into+"'" "\n: going to reset .into of Function '"+page.func.name+"'") func.into = None #fi list.append(FunctionRefPage(func)) return list #fu # ordered list of pages refpage_list = refpage_list_from_function_list(function_list) class FunctionFamilyRefPage(RefPage): def __init__(self, page): RefPage.__init__(self, page.func) self.seealso_list = [] # reset self.refhint_list = [] def refhint_list_text(page): T = "" for hint in page.refhint_list: T += hint return T def refentry_text(page): return page.refhint_list_text() + "\n" + \ RefPage.refentry_text(page) pass def docbook_pages_recombine(pagelist): """ take a list of RefPages and create a new list where sections are recombined in a way that their description is listed on the same page and the manvol formatter creates symlinks to the combined function description page - use the attribute 'into' to guide the processing here as each of these will be removed from the output list. If no into-pages are there then the returned list should render to the very same output text like the input list would do """ list = [] combined = {} for orig in pagelist: if orig.func.into: continue page = FunctionFamilyRefPage(orig) combined[orig.func.name] = page ; list.append(page) page.refentry = orig.refentry # //refentry@id page.refentry_title = orig.refentrytitle # //refentryinfo/title page.refentrytitle = orig.refentrytitle # //refmeta/refentrytitle page.includes = orig.includes page.funcsynopsisinfo = orig.funcsynopsisinfo page.refpurpose = orig.refpurpose if orig.refhint: page.refhint_list.append( orig.refhint ) if orig.refname: page.refname_list.append( orig.refname ) elif orig.refname_list: page.refname_list.extend( orig.refname_list ) if orig.funcsynopsis: page.funcsynopsis_list.append( orig.funcsynopsis ) elif orig.refname_list: page.funcsynopsis_list.extend( orig.funcsynopsis_list ) if orig.description: page.description_list.append( orig.description ) elif orig.refname_list: page.description_list.extend( orig.description_list ) if orig.seealso: page.seealso_list.append( orig.seealso ) elif orig.seealso_list: page.seealso_list.extend( orig.seealso_list ) if orig.authors: page.authors_list.append( orig.authors ) elif orig.authors_list: page.authors_list.extend( orig.authors_list ) if orig.copyright: page.copyright_list.append( orig.copyright ) elif orig.refname_list: page.copyright_list.extend( orig.copyright_list ) #od for orig in pagelist: if not orig.func.into: continue if orig.func.into not in combined: warn("page for '"+orig.func.name+ "' has no target => '"+orig.func.into+"'") page = FunctionFamilyRefPage(orig) else: page = combined[orig.func.into] if orig.refname: page.refname_list.append( orig.refname ) elif orig.refname_list: page.refname_list.extend( orig.refname_list ) if orig.funcsynopsis: page.funcsynopsis_list.append( orig.funcsynopsis ) elif orig.refname_list: page.funcsynopsis_list.extend( orig.funcsynopsis_list ) if orig.description: page.description_list.append( orig.description ) elif orig.refname_list: page.description_list.extend( orig.description_list ) if orig.seealso: page.seealso_list.append( orig.seealso ) elif orig.seealso_list: page.seealso_list.extend( orig.seealso_list ) if orig.authors: page.authors_list.append( orig.authors ) elif orig.authors_list: page.authors_list.extend( orig.authors_list ) if orig.copyright: page.copyright_list.append( orig.copyright ) elif orig.refname_list: page.copyright_list.extend( orig.copyright_list ) #od return list #fu combined_pages = docbook_pages_recombine(pagelist = refpage_list) # ----------------------------------------------------------------------- class HeaderRefPage(RefPage): pass def docbook_refpages_perheader(page_list): # headerlist " creating the per-header manpage - a combination of function man pages " header = {} for page in page_list: assert not page.func.into file = page.func.src.file.mainheader # short for the mainheader index if file not in header: header[file] = HeaderRefPage(page.func) header[file].id = s(file, r"[^\w\.]","-") header[file].refentry = header[file].id header[file].refentryinfo = None header[file].refentry_date = page.refentry_date header[file].refentry_productname = ( "the library "+page.refentry_productname) header[file].manvolnum = page.manvolnum header[file].refentrytitle = file header[file].funcsynopsis = "" if 1: # or += or if not header[file].refnamediv: header[file].refpurpose = " library " header[file].refname = header[file].id if not header[file].funcsynopsisinfo and page.funcsynopsisinfo: header[file].funcsynopsisinfo = page.funcsynopsisinfo if page.funcsynopsis: header[file].funcsynopsis += "\n"+page.funcsynopsis if not header[file].copyright and page.copyright: header[file].copyright = page.copyright if not header[file].authors and page.authors: header[file].authors = page.authors if not header[file].authors and page.authors_list: header[file].authors_list = page.authors_list if not header[file].description: found = m(commands.getoutput("cat "+o.package+".spec"), r"(?s)\%description\b([^\%]*)\%") if found: header[file].description = found.group(1) elif not header[file].description: header[file].description = "" + ( page.refentry_productname + " library") + ""; #fi #fi #od return header#list #fu def leaders(pagelist): list = [] for page in pagelist: if page.func.into : continue list.append(page) return list header_refpages = docbook_refpages_perheader(leaders(refpage_list)) # ----------------------------------------------------------------------- # printing the docbook file is a two-phase process - we spit out the # leader pages first - later we add more pages with _refstart pointing # to the leader page, so that xmlto will add the functions there. Only the # leader page contains some extra info needed for troff page processing. doctype = ''+"\n" try: F = open(o.docbookfile,"w") except IOError, error: warn("can not open docbook output file: "+o.docbookfile, error) else: print >> F, doctype, 'Manual Pages' for page in combined_pages: print >> F, page.refentry_text() #od for page in header_refpages.values(): if not page.refentry: continue print >> F, "\n", print >> F, page.refentry_text() #od print >> F, "\n",'',"\n" F.close() #fi # _____________________________________________________________________ try: F = open( o.dumpdocfile, "w") except IOError, error: warn ("can not open"+o.dumpdocfile,error) else: for func in function_list: name = func.name print >> F, ""+"\n" for H in sorted_keys(func.dict()): print >> F, "<"+H+" name=\""+name+"\">", print >> F, str(func.dict()[H]), print >> F, "" #od print >> F, "\n\n"; #od F.close(); #fi if errors: sys.exit(errors)