# # This file is part of Documancer (http://documancer.sf.net) # # Copyright (C) 2002-2005 Vaclav Slavik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: provider.py,v 1.10 2005/01/30 22:29:08 vaclavslavik Exp $ # # Manual pages documentation provider (Unix) # import sys if sys.platform == 'win32': raise ImportError('Man provider is for Unix only') from gettext import gettext as _ import providers, book import os.path, commands, string, urllib, re # known manual sections: MAN_SECTIONS = [ ('1', _('User Commands')), ('2', _('System Calls')), ('3', _('Library Functions')), ('4', _('Special Files')), ('5', _('File Formats')), ('6', _('Games')), ('7', _('Miscellaneous')), ('8', _('System Administration and Privileged Commands')), ('9', _('Kernel')), ('n', _('New')) ] # where to find manpages: manPaths = None # cached indexes: manpagesLists = {} def getSectionName(section): for num, name in MAN_SECTIONS: if num == section: return name return section def getManpagesList(section, filter): global manPaths, manpagesLists if section in manpagesLists: manlist = manpagesLists[section] else: if manPaths == None: paths = commands.getoutput('man -w').split(':') # eliminate duplicates here (can happen e.g. thanks to symlinks): manPaths = [] for p in paths: if os.path.islink(p): p = os.readlink(p) if p not in manPaths: manPaths.append(p) manlist = [] for path in manPaths: searchPath = '%s/man%s' % (path, section) if not os.path.isdir(searchPath): continue for file in os.listdir(searchPath): _file = '%s/%s' % (searchPath, file) if os.path.islink(_file): filename = os.path.basename(os.readlink(_file)) else: filename = file manfile = urllib.quote(filename[:filename.find('.')]) manname = file[:file.find('.')] manlist.append((manname.lower(),manfile,manname)) manlist.sort() manpagesLists[section] = manlist if filter == '': return manlist else: filterRegex = re.compile(filter) return [x for x in manlist if filterRegex.match(x[2])] def generateIndex(section, filter): manlist = getManpagesList(section, filter) out_abc = '' out_list = '' letter = '?' for manid,manfile,manname in manlist: if len(manname) == 0: continue if manid[0] != letter: letter = manid[0] l = string.upper(letter) out_abc += ' %s ' % (l,l) out_list += '

%s

' % (l,l) out_list += '%s
\n' % (manfile,manname) output_template = """ %s

%s

%%s

%%s """ % (_('Section %s'), _('Manual Pages Section %s')) output = output_template % (section,section, out_abc, out_list) return output class ManContentsNode(book.ContentsNode): def __init__(self, parent, section, filter): self.section = section self.filter = filter name = '%s. %s' % (section, getSectionName(section)) book.ContentsNode.__init__(self, parent, name, '%s/' % section) def _expand(self): nodes = [] manlist = getManpagesList(self.section, self.filter) for manid,manfile,manname in manlist: url = '%s/%s.html' % (self.section, manfile) n = book.ContentsNode(self, manname, url) nodes.append(n) return nodes def _hasChildren(self): return 1 class ManProvider(providers.DocumentationProvider): def getID(self): return 'man' def getName(self): return _('Man pages') def getDescription(self): return _("""Unix manual pages.
This plugin is based on man2html by Richard Verhoeven and others.""") def serve(self, book, url): # Stylesheet: if url[-12:] == 'man2html.css': f = open('%s/helpers/man2html/man2html.css' % os.getenv('DOCUMANCER_HOME'), 'rt') data = f.read() f.close() return (data, 'text/css') if url[-5:] == ".html": url = url[:-5] if url == '': url = 'index' urls = url.split("/") # Global index: if url == 'index': data = """ %s

%s

%s

' return (data, 'text/html') # Section indexes: elif len(urls) == 2 and urls[1] == '': return (generateIndex(urls[0], book.getAttr('regex')), 'text/html') # Man pages: elif len(urls) == 2: section=urls[0] page=urls[1] interim=commands.getoutput("helpers/man2html/man2html.cgi %s %s" % (section,page)) # NB: man2html has annoying misfeature of adding \007 (bell) # characters around section name, kill them: return (interim.replace('\007',''), 'text/html') else: return None def getHomeURL(self, book): s = book.getAttr('section') if s == '': return 'index.html' else: return '%s/' % s def getContents(self, book): s = book.getAttr('section') filter = book.getAttr('regex') if s == '': from book import ContentsNode root = ContentsNode(None, _('Manual pages'), 'index.html') root.children = [] for sec, secname in MAN_SECTIONS: root.children.append(ManContentsNode(root, sec, filter)) return root else: return ManContentsNode(None, s, filter) def getURLForIndexing(self, book): return self.getHomeURL(book) def getConfigurationDialog(self, parent): from confgui import ManSettingsPanel return ManSettingsPanel(parent, -1) providers.register(ManProvider())