#
# FILE            $Id: MIFFormatter.py,v 1.4 1998/02/04 19:16:38 dlarsson Exp $
#
# DESCRIPTION     Formatters for MIF and HTML manual formats.
#
# AUTHOR          SEISY/LKSB Daniel Larsson
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of ABB Industrial Systems
# not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior permission.
#
# ABB INDUSTRIAL SYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS, IN NO EVENT SHALL ABB INDUSTRIAL SYSTEMS BE LIABLE
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Copyright (C) ABB Industrial Systems AB, 1996
# Unpublished work.  All Rights Reserved.
#
# HISTORY:
#
# $Log: MIFFormatter.py,v $
# Revision 1.4  1998/02/04 19:16:38  dlarsson
# Fixed list rendering.
#
# Revision 1.3  1996/09/06 10:10:24  omfadmin
# Removed use of setext.
#
# Revision 1.2  1996/07/08  05:31:44  omfadmin
# Added dummy render_navigation.
#
# Revision 1.1  1996/06/24  10:07:57  omfadmin
# Initial revision
#
# Revision 1.3  1996/06/21  00:14:37  omfadmin
# MML formatter changes:
# - Figured out how to make hard returns!
# - Changed numbering on used paragraph formats for headings
# - Replaced '\' characters '<Character \\x5C >', which is
#   the ASCII code for '\'.
#
# Revision 1.2  1996/06/13  17:56:19  omfadmin
# Various changes of the interface.
# Added a MML formatter. Still sketchy though.
#
# Revision 1.1  1995/04/15  13:36:07  dlarsson
# Initial revision
#
#

__author__ = "Daniel Larsson"
__version__ = "$Revision: 1.4 $"

import string
import regsub
from gendoc import docregex

# Rename imported objects.
# The underscore is to hide the names
_gsub		= regsub.gsub


_MIF_STRING	   = "\n\t<String `%s'>"
##_MIF_CODE	   = "\n\t<ParaLine\n\t<String `%s'>\n\t<Char HardReturn>>"
_MIF_CODE	   = "\n\t<ParaLine\n\t<String `%s'>\n\t>"
_MIF_PARAHEAD	   = "\n<Para <PgfTag `%s'>\n\t%s\n>"
_MIF_PARALINE	   = "<ParaLine\n\t%s\n\t>"
_MIF_PARAHEAD_WLINE= _MIF_PARAHEAD % ('%s', _MIF_PARALINE)
_MIF_SECTION	   = _MIF_PARAHEAD_WLINE % ('%s', _MIF_STRING)

_MIF_MARKER	   = "\n\t<Marker\n\t\t<MType %d>\n\t\t<MText `%s'>\n\t>"
_MIF_INDEX	   = _MIF_MARKER % (2, "%s")
_MIF_FONT	   = "\n\t<Font <FTag `%s'>>"
_MIF_EMPHASIS	   = _MIF_FONT % 'Emphasis'
_MIF_STRONG	   = _MIF_FONT % 'Bold'
_MIF_UNDERLINE	   = _MIF_FONT % 'Underline'
_MIF_DEFAULT	   = _MIF_FONT % ''

_MIF_HEADER = """<MIFFile 5.00> # Generated by MifFormatter
<Verbose Yes>
<Para <PgfTag `Heading'>
	%s
\n>""" % _MIF_PARALINE


def _repl(str):
    str = _gsub("'", "\\'", str)
    str = _gsub("\t", "\\t", str)
    str = _gsub("\\\\n", "\\\\\\\\n", str)
    str = _gsub("<", "\\<", str)
    return _gsub(">", "\\>", str)+' '

class MIF:
    """Manual formatter generating MIF files."""

    file_ext = '.mif'

    # Tags used for different types of manual items.
    # The list indices represents the nesting depth
    # (level) at which the item occurs.
    PARA_TAGS	= ['Body', 'Body', 'BodyIndent', 'BodyIndent2']
    CODE_TAGS	= ['ProgramCode', 'ProgramCode']
    BULLET_TAGS	= ['Bullet', 'Bullet', 'Bullet2']
    NL_TAGS	= ['Numbered', 'Numbered']
    NL1_TAGS	= ['NumberedFirst', 'NumberedFirst']
    SECTION_TAGS	= []

    def __init__(self):
	"""Initialize object."""
	self._text_ = ''

    def _add_(self, txt):
	self._text_ = self._text_ + txt

    def render_title(self, manpage, title, marker):
	"Write document title"
	if marker:
	    marker_text = marker[0]
	    for i in marker[1:]:
		marker_text = marker_text+';'+i+':'+marker[0]
	    title = _MIF_INDEX % marker_text + _MIF_STRING % title
	else:
	    title = _MIF_STRING % title
	self._add_(_MIF_HEADER % title)

    def render_navigation(self, top, prev, next):
	"""Render navigation buttons.

	~top~, ~prev~ and ~next~ are ManualPage instances."""
	pass

    def render_section(self, manpage, lvl, section, marker):
	"Print the section 'section'"
	section = _repl(section)
	if marker:
	    marker_text = marker[0]
	    if len(marker) > 1:
		marker_text = marker_text+':in '+marker[1]
	    for i in marker[1:]:
		marker_text = marker_text+';'+i+':'+marker[0]
		section = _MIF_INDEX % marker_text + _MIF_STRING % section
	else:
	    section = _MIF_STRING % section
	if len(self.SECTION_TAGS) > lvl:
	    tag = self.SECTION_TAGS[lvl]
	else:
	    tag = 'Heading%d' % lvl
	self._add_(_MIF_PARAHEAD_WLINE % (tag, section))

    def render_paragraph(self, manpage, para):
	"Print a paragraph"
	lines = string.splitfields(para, '\n')
	if lines[-1] == '':
	    lines = lines[:-1]
	no_lines = len(lines)
	lvl = manpage.cur_level() - 1
	if len(self.PARA_TAGS) > lvl:
	    tag = self.PARA_TAGS[lvl]
	else:
	    tag = 'Body%d' % lvl

	lines = map(lambda line, f=self._fix_txt_: f(_repl(line)), lines)
	text = _MIF_PARAHEAD_WLINE % (tag, (_MIF_STRING*no_lines) % tuple(lines))
	self._add_(text)

    def render_code(self, manpage, code):
	"Print code"
	lines = string.splitfields(code, '\n')
	if lines[-1] == '':
	    lines = lines[:-1]
	no_lines = len(lines)
	lvl = manpage.cur_level() - 1
	if len(self.CODE_TAGS) > lvl:
	    tag = self.CODE_TAGS[lvl]
	else:
	    tag = 'ProgramCode%d' % lvl
	text = ''
	for ready in lines:
	    text = text + _MIF_PARAHEAD % (tag, (_MIF_CODE) % ready)
	self._add_(text)

    def render_list(self, manpage, list):
	"Print an unordered list. 'list' is a list of strings."

	def emit_list(self, (listtype, list), lvl, recursive):
	    from gendoc.ManualPage import UN_LIST, OR_LIST
	    if listtype == UN_LIST:
		if len(self.BULLET_TAGS) > lvl:
		    tag = self.BULLET_TAGS[lvl]
		else:
		    tag = 'Bullet%d' % lvl
	    else:
		if len(self.NL_TAGS) > lvl:
		    tag = self.NL_TAGS[lvl]
		else:
		    tag = 'Step%d' % lvl

	    for i in list:
	        if type(i) == type(''):
	            self._add_(_MIF_PARAHEAD_WLINE % (tag, _MIF_STRING % i))
	        else:
                    recursive(self, i, lvl+1, recursive)

	code = emit_list(self, list, manpage.cur_level(), emit_list)

    def render_strong(self, text):
	# Preserve markup. We fix this later.
	return '**' + text + '**'

    def render_emphasis(self, text):
	# Preserve markup. We fix this later.
	return '~' + text + '~'

    def render_underline(self, text):
	# Preserve markup. We fix this later.
	return '_' + text + '_'

    def end(self):
	"""Document is ready.
	
	Returns the resulting document as a string."""
	text = self._text_+'\n'
	self._text_ = ''
	return text

    def _fix_txt_(self, txt):
	# Fix hyperlinks (i.e. remove them)
	REPLACE    = "'>%s"+_MIF_STRING % '\\1'+_MIF_DEFAULT+'\n\t<String `'
	EMP_REPL   = REPLACE % _MIF_EMPHASIS
	STRONG_REPL = REPLACE % _MIF_STRONG
#	UNDERL_REPL = REPLACE % _MIF_UNDERLINE
	txt = _gsub(docregex.emph_regex, EMP_REPL, txt)
	return _gsub(docregex.strong_regex, STRONG_REPL, txt)


def test():
    # ... (TO BE ADDED)
    pass

if __name__ == '__main__':
    test()


