1    """
                htmlmax.py
                
            html macros for use from pymacro by lpy app
            
            """
    
       7    __Id__ = "$Id: htmlmax.py.html,v 1.1 2005/01/26 01:13:52 u37519820 Exp $"

Table of Contents


Introduction

html macros for lpy

This stuff is getting a little hectic, primarily with the Netscape v Explorer issues becoming apparent. Several different HTML strategies have been tried, and there remains lots of cruft in here from mucking about.

The Netscape jaggy-gray-background issue is really pretty tragic.


Imports


simple macros

    pre

    @pre{Preformatted} ->
    Preformatted
        42    # using single-parameter %s strings works just as well for f{s}
        43    
        44    pre = "<pre>%s</pre>"

    h2

    @h2{heading 2} ->

    heading 2

        49    h2 = '<h2>%s</h2>'

    h3

    @h3{heading 3} ->

    heading 3

        54    def h3(s):
        55        return '<h3>%s</h3>' % s

    b

    b is for bold
        60    def b(s):
        61        return '<b>%s</b>' % s
    i is for italic
        65    def i(s):
        66        return '<i>%s</i>' % s
    bi is bold italic
        70    def bi(s):
        71        return '<b><i>%s</i></b>' % s
    tt for teletype
        75    def tt(s):
        76        return '<tt>%s</tt>' % s

    xlink


        @xlink('Danbala Software', 'http://www.danbala.com') ->     Danbala Software
        84    def xlink(s,x=None):
        85        if x is None:
        86            x = s      
        87        return '<a href="%s">%s</a>' % (x, s)
        88    
        89    def nested(s):
        90        """ keep on expanding """
        91        while string.find(s, '@') >= 0:
        92            s = pymacro.pymax_process(s)
        93        return s
        94        
        95    def html(s):
        96        """ put it back """
        97        return string.replace(string.replace(s, '&lt;','<'),'&amp;','&')
        98    
        99    def image(name, w=0, h=0):
       100        if w and h:
       101            return '<img src="%s" width=%d height=%d, border=0>' % (name,w,h)
       102        else:
       103            return '<img src="%s" border=0>' % name
       104    
       105    startlink = '<a href="%s">'
       106    endlink = '</a>'
       107    invert = '<div width=100% style="color:white; background:black;">'
       108    endinvert = '</div>'

handy random symbols Let's put a

Paragraph in, followed by a
line break and then a line


@indent
    @bullet
  • @outdent
     127    indent = "<ul>"
     128    outdent = "</ul>"
     129    bullet = "<li>"
     130    
     131    # this need to be tested - perhaps a different tag?
     132    
     133    ff = '<div style="page-break-after:always"></div>'

UL: unordered list

@UL{unordered list
a
b
c} 
    unordered list
  • a
  • b
  • c
     151    def UL(s):
     152        return '<ul>' + string.join(string.split(s, '\n'), '<li>\n') + '</ul>'

OL: ordered list

@OL{ordered list
one
two
three}

    ordered list
  1. one
  2. two
  3. three
     170    def OL(s):
     171        return '<ol>' + string.join(string.split(s, '\n'), '<li>\n') + '</ol>'

TABLE

@TABLE{
    this; is; the; way
    it's; supposed; to; work
    more; or; less; ok?}
->

this is the way
it's supposed to work
more or less ok?

this is the way
it's supposed to work
more or less ay?

     199    def TABLE(s, c=';', border=None):
     200        lines = string.split(s, '\n')
     201        if border:
     202            r = '<table border=%d>' % border
     203        else:
     204            r = '<table>'
     205        for line in lines:
     206            r = r + '\n<tr>'
     207            cols = string.split(line, c)
     208            for col in cols:
     209                r = r + '<td>' + col
     210        r = r + '</table>'
     211        return r
python module link: @pylink{pymacro} -> pymacro
     215    def pylink(module, dir=""):
     216        " generate a link to an external .py.html (import) "
     217        if dir:
     218            dir = dir + '/'
     219        return '<a href="%s%s.py.html">%s</a>' % (dir, module, module)
python standard library module link: @stdlink{sys} -> sys
     223    def stdlink(*args):
     224        s = ''
     225        for module in args:
     226            if s:
     227                s = s + ', '
     228            s = (
     229    '%s<a href="http://www.python.org/doc/current/lib/module-%s.html">%s</a>'
     230                % (s, module, module))
     231        return s
hidden stuff:
     234    def rem(s):
     235        """ remark out some stuff so it doesn't appear """
     236        return ""
Command Line options use attributes to make sure we complain if you mis-spell a flag
     241    class Generic:
     242        pass
     243        
     244    gFlags = Generic()
     245    gFlags.printing = 0
     246    gFlags.nosplits = 0
     247    gFlags.noindex  = 0
     248    gFlags.autoformat = 0
     249    gFlags.autosplit  = 0
     250    
     251    def SetFlag(s):
     252        global gFlags
     253        if not hasattr(gFlags, s):
     254            raise 'unrecognized option', s
     255        setattr(gFlags, s, 1)
     256    
     257    def TestFlag(s):
     258        global gFlags
     259        return getattr(gFlags, s)
     260    
     261    def danbala_logo():
     262        return TABLE(image('d88.jpg',88,88)+';'+
     263        TABLE('for more information,\ncontact:\n' + 
     264            xlink('Danbala Software', 'http://www.danbala.com')))

lpy configuration

Here's the lpy specific bits
 this is getting a bit brutal...
 Navigator v Explorer v Layout options etc. etc.
 Maybe external style sheets would be better, though harder to distribute
    lpy-netscape.css
    lpy-explorer.css
    lpy-p-netscape.css
    lpy-p-explorer.css

The table mode layout was an interesting option; maybe there is a simple wayt to make it a live option...

     282    STANDARDSCRIPT ='''
            <script language="javascript">
            var isNetscape = (navigator.appName.indexOf("Netscape") != -1);
            var isExplorer = (navigator.appName.indexOf("Microsoft") != -1);
            </script>
            '''
    
     288    
     289    def escape_quote(s):
     290        return string.replace(s, "'", "\\'")
     291        
     292    def NetscapeOrExplorer(netscape, explorer):
     293        return '''
            <script language="javascript">
            if (isNetscape) {
                document.writeln(%s);
            } else {
                document.writeln(%s);
            }
            </script>
            '''
     % (escape_quote(netscape), escape_quote(explorer))
Escaping in and out of HTML mode
     304    # still worried about our extra blank line gas...
     305    
     306    #
     307    
     308    # terminology is bassackwards - leading/trailing wrap the special comment
     309    
     310    # trailing opens a new code segment
     311    html_trailing = '''<ul><div class="code"><pre>'''
     312    
     313    # leading actually ends the open code segment
     314    
     315    html_leading = '''</pre></div></ul>'''
     316    
     317    # for split mode, alternative wrappers
     318    
     319    split_starting = html_leading + '</td></tr></table><table><tr><td class="splitdoc">'
     320    split_ending   = html_leading + '</td></tr></table><table><tr><td class="doc">'
     321    split_leading  = html_leading + '</td></tr><tr><td class="splitdoc">'
     322    split_trailing = '</td><td>'  + html_trailing
html_prefix is what goes out at the top
     327    # be careful of % signs in strings - use multiple strings instead of % format
     328    
     329    html_start = '''<html><head><title>'''
     330    
     331    # then title, plus:
     332    
     333    stdprefix = '''</title>
            <!-- html produced by lpy.py, http://www.danbala.com -->
            <!-- this is the standard header -->
            <style>
            <!--
            a:link { color:blue; text-decoration:none }
            a:visited { color:purple; text-decoration:none }
            a:active { color:red; text-decoration:none }
            a:hover { color:red; text-decoration:none }
            -->
            </style>
            <style>
            <--
            H3 {    /* need this for navigator */
               font: bold 14pt "Verdana", "Arial", "Helvetica" 
            }
            div.code { 
                background: #e0e0e0;
                font: 10pt "Courier New", "Courier", "Monaco" 
            }
            div.doc { 
                font: 10pt "Courier New", "Courier", "Monaco" 
            }
            td.doc { 
                width:600; 
                font: 9pt "Verdana", "Arial", "Helvetica" 
            }
            td.xref { 
                font: 9pt "Courier New", "Courier", "Monaco" 
            }
            table.xref { 
                font: 9pt "Courier New", "Courier", "Monaco" 
            }
            td.splitdoc { 
                width:50%; 
                font: 9pt "Verdana", "Arial", "Helvetica" 
             }
            td.splitcode { 
                width:50%; 
                font: 9pt "Verdana", "Arial", "Helvetica" 
            }
            -->
            </style>
            </head>
            <body><table><tr><td class="doc">'''
     + html_trailing
     378    
     379    stdsuffix = html_leading + '</td></tr></table></body></html>'
     380    
     381    printprefix = '''</title>
            <!-- html produced by lpy.py, http://www.danbala.com -->
            <!-- this is the -printing header -->
            <style>
            <!--
            H3 {        /* need this for navigator */ 
                font: bold 10pt "Verdana", "Arial", "Helvetica" 
            }
            div.code { 
                font: 7pt "Courier New", "Courier", "Monaco" 
            }
            pre.code { 
                font: 7pt "Courier New", "Courier", "Monaco" 
            }
            td.doc { 
                width:600; font: 6pt "Verdana", "Arial", "Helvetica" 
            }
            td.xref { 
                font: 6pt "Courier New", "Courier", "Monaco" 
            }
            table.xref { 
                font: 6pt "Courier New", "Courier", "Monaco" 
            }
            td.splitdoc { 
                width:50%; font: 6pt "Verdana", "Arial", "Helvetica" 
            }
            td.splitcode { 
                width:50%; 
                font: 9pt "Verdana", "Arial", "Helvetica" 
            }
            -->
            </style>
            </head>
            <body><table><tr><td class="doc">'''
     + html_trailing
     415    
     416    def html_prefix(title):
     417        global gFlags
     418        if gFlags.printing:
     419            return html_start + title +printprefix
     420        return html_start + title + stdprefix
html_suffix for End of file/cleanup:
     424    def html_suffix():
     425        return stdsuffix

side by side

     429    # lot's of guffing about for split mode
     430    
     431    kSplitStart = 1
     432    kSplitting = 2
     433    kSplitEnd = 3
     434    
     435    gSplitMode = 0
     436        
     437    def startsplit():
     438        global gFlags, gSplitMode
     439        # do two positives make a negative? yeah, right
     440        if not gFlags.nosplits and not gSplitMode:
     441            gSplitMode = kSplitStart
     442        
     443    def endsplit():
     444        global gSplitMode
     445        if gSplitMode:
     446            gSplitMode = kSplitEnd
     447    
     448    def html_wrap(leading, trailing, s):
     449        global gSplitMode
     450        uselead = html_leading
     451        usetrail = html_trailing
     452        if gSplitMode:
     453            if gSplitMode == kSplitting:
     454                uselead = split_leading
     455                usetrail = split_trailing
     456            else:
     457                if gSplitMode == kSplitStart:
     458                    uselead = split_starting
     459                    usetrail = split_trailing
     460                    gSplitMode = kSplitting
     461                elif gSplitMode == kSplitEnd:
     462                    uselead = split_ending
     463                    usetrail = html_trailing
     464                    gSplitMode = 0
     465                if not leading:
     466                    uselead = html_trailing + uselead
     467                    leading = 1
     468                
     469        if leading:
     470            s = uselead + s
     471        if trailing:
     472            s = s + usetrail
     473        return s

Specific classes of tokens need special handling...
     478    # those tokens come from module @imp{pytokens}
     479    from pytokens import COMMENT, STRING, RESERVED
     480    
     481    gPreAndPost = { 
     482        COMMENT   : ["<i><font color=green>","</font></i>"],
     483        STRING    : ["<font color=darkcyan>","</font>"],
     484        RESERVED  : ["<b>","</b>"]}
     485    
     486    gWraps = { 
     487        COMMENT   : "<i><font color=green>%s</font></i>",
     488        STRING    : "<font color=darkcyan>%s</font>",
     489        RESERVED  : "<b>%s</b>"}

contents generator

For manually constructing a table of contents
     496    _contents = {}
     497    
     498    def reset_contents():
     499        global _contents
     500        _contents = {}
     501    
     502    def reset_contents1(which="default"):
     503        global _contents
     504        _contents[which] = []
     505                              
     506    def display_contents(which="default"):
     507        """ potential runaway recursion, be careful """
     508        global _contents
     509        content = _contents.get(which, None)
     510        if content:
     511            s = "<ul>"
     512            for item in content:
     513                s = '%s\n<li><a href="#%s">%s' % (s, item, item)
     514                if _contents.has_key(item):
     515                    s = s + display_contents(item)
     516            s = s + "\n</ul>"
     517            return s
     518        return ""
     519        
     520    def contents_item(c, which="default"):
     521        global _contents
     522        content = _contents.get(which,None)
     523        if content is None:
     524            content = []
     525            _contents[which] = content
     526        content.append(c)
     527        return '<a name="%s"><h3>%s</h3></a>' % (c, c)