#
# FILE            $Id: MMLFormatter.py,v 1.4 1998/02/04 19:16:51 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: MMLFormatter.py,v $
# Revision 1.4  1998/02/04 19:16:51  dlarsson
# Fixed list rendering.
#
# Revision 1.3  1996/09/06 10:11:02  omfadmin
# Changed some names.
#
# Revision 1.2  1996/07/08  05:31:54  omfadmin
# Added dummy render_navigation.
#
# Revision 1.1  1996/06/24  10:07:57  omfadmin
# Initial revision
#
#

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

		
import regsub

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


MML_HEADER = """<MML %s>
<Comment Generated by gendoc.py>
<Comment Created by: %s at %s>

<Include "%s/tags.mml">
"""
MML_MARKER  = """
    <Marker
        <MType %d>
	<MText `%s'>
    >"""
MML_INDEX   = MML_MARKER % (2, "%s")

# Paragraphs used
MML_HEADING_T = '<%sHeading>'
MML_HEADING = MML_HEADING_T % 2


class MML:
    """Manual formatter generating MML (Maker Markup Language).

    MML is a markup language for generating Frame documents.
    This formatter is added primarily as a replacement for the
    MIF formatter, which is a bit hairy.
    """

    file_ext = '.mml'

    # 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	= ['Step', 'Step']
    SECTION_TAGS= []

    def _add_(self, txt):
	# Add text to the document
	self._text_ = self._text_ + txt

    # -----   THESE ARE THE REQUIRED METHODS  -----
    def __init__(self):
	# String to collect document text
	self._text_ = ''

    def render_title(self, manpage, title, marker):
	"""Render document title."""
	import time, pwd, os
	tim = time.ctime(time.time())
	try:
	    user = pwd.getpwuid(os.getuid())[4]
	except:
	    user = 'Unknown'

	if marker:
	    marker_text = marker[0]
	    for i in marker[1:]:
		marker_text = marker_text+';'+i+':'+marker[0]
	    title = MML_INDEX % marker_text + title

	import gendoc.formatters

	text = MML_HEADER % (manpage.name(), user, tim, gendoc.formatters.__path__[0])
	text = text + '\n' + MML_HEADING + title + '\n\n'
	self._add_(text)

    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):
	"""Render a section heading."""

	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_text
		section = MML_INDEX % marker_text + section

	paragraph_type = MML_HEADING_T % (lvl+2) # Start at level 3

	self._add_(paragraph_type+section+'\n')

    def render_paragraph(self, manpage, para):
	"""Render a paragraph

	~para~ is the paragraph text.
	"""
	lvl = manpage.cur_level()
	if len(self.PARA_TAGS) > lvl:
	    tag = self.PARA_TAGS[lvl]
	else:
	    tag = 'Body%d' % lvl
	self._add_('<' + tag + '>\n')

	# Replace the character '\' so MML won't interpret
	# it as an escape character
	para = _gsub('\\\\', '<Character \\x5C >', para)

	self._add_(para+'\n\n')

    def render_code(self, manpage, code):
	"""Render code snippet.
	
	~code~ is the code snippet.
	"""
	lvl = manpage.cur_level()
	if len(self.CODE_TAGS) > lvl:
	    tag = self.CODE_TAGS[lvl]
	else:
	    tag = 'ProgramCode%d' % lvl
	self._add_('<' + tag + '>\n')

	# Replace the character '\' so MML won't interpret
	# it as an escape character
	code = _gsub('\\\\', '<Character \\x5C >', code)

	# Replace two consecutive spaces with two hard spaces
	code = _gsub('  ', '<HardSpace><HardSpace>', code)

	# Replace newlines with hard newlines, else FrameMaker
	# will fill the paragraph automatically
	code = _gsub('\n', '<HardReturn>\n', code)
	self._add_('<HardReturn>'+code+'\n\n')

    def render_ordered_list(self, manpage, list):
	"""Render an ordered list

	~list~ is a list of items.
	"""
	lvl = manpage.cur_level()
	if len(self.BULLET_TAGS) > lvl:
	    tag = self.BULLET_TAGS[lvl]
	else:
	    tag = 'Bullet%d' % lvl
	code = tag
	for i in range(len(list)):
	    code = code + list[i] + '\n'

	# Replace the character '\' so MML won't interpret
	# it as an escape character
	code = _gsub('\\\\', '<Character \\x5C >', code)

	self._add_(code+'\n')

    def render_list(self, manpage, list):
	"""Render an unordered list (bullet list)

	~list~ is a list of items.
	"""
	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

	    code = tag
	    for i in list:
	        if type(i) == type(''):
	            code = code + '%s\n' % i
	        else:
                    code = code + recursive(self, i, lvl+1, recursive)
	    return code + '\n'

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

	# Replace the character '\' so MML won't interpret
	# it as an escape character
	code = _gsub('\\\\', '<Character \\x5C >', code)

	self._add_(code+'\n')

    def render_strong(self, text):
	return '<Bold>' + text + '<Plain>'

    def render_emphasis(self, text):
	# Preserve markup. We fix this later.
	return '<Italic>' + text + '<Plain>'

    def render_underline(self, text):
	# Preserve markup. We fix this later.
	return '<Underline>' + text + '<Plain>'

    def end(self):
	"""Return the rendered document.

	IMPORTANT: The same formatter object is very likely
	to be used for more than one ManualPage, so we must
	remove the text also (alternatively, we might initialise
	self._text_ in 'render_title', since it is always called
	first).
	"""
	text = self._text_+'\n'
	self._text_ = ''
	return text

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

if __name__ == '__main__':
    test()


