]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/stxview/StructuredText/ClassicDocumentClass.py
   1 ############################################################################## 
   3 # Zope Public License (ZPL) Version 1.0 
   4 # ------------------------------------- 
   6 # Copyright (c) Digital Creations.  All rights reserved. 
   8 # This license has been certified as Open Source(tm). 
  10 # Redistribution and use in source and binary forms, with or without 
  11 # modification, are permitted provided that the following conditions are 
  14 # 1. Redistributions in source code must retain the above copyright 
  15 #    notice, this list of conditions, and the following disclaimer. 
  17 # 2. Redistributions in binary form must reproduce the above copyright 
  18 #    notice, this list of conditions, and the following disclaimer in 
  19 #    the documentation and/or other materials provided with the 
  22 # 3. Digital Creations requests that attribution be given to Zope 
  23 #    in any manner possible. Zope includes a "Powered by Zope" 
  24 #    button that is installed by default. While it is not a license 
  25 #    violation to remove this button, it is requested that the 
  26 #    attribution remain. A significant investment has been put 
  27 #    into Zope, and this effort will continue if the Zope community 
  28 #    continues to grow. This is one way to assure that growth. 
  30 # 4. All advertising materials and documentation mentioning 
  31 #    features derived from or use of this software must display 
  32 #    the following acknowledgement: 
  34 #       "This product includes software developed by Digital Creations 
  35 #       for use in the Z Object Publishing Environment 
  36 #       (http://www.zope.org/)." 
  38 #    In the event that the product being advertised includes an 
  39 #    intact Zope distribution (with copyright and license included) 
  40 #    then this clause is waived. 
  42 # 5. Names associated with Zope or Digital Creations must not be used to 
  43 #    endorse or promote products derived from this software without 
  44 #    prior written permission from Digital Creations. 
  46 # 6. Modified redistributions of any form whatsoever must retain 
  47 #    the following acknowledgment: 
  49 #       "This product includes software developed by Digital Creations 
  50 #       for use in the Z Object Publishing Environment 
  51 #       (http://www.zope.org/)." 
  53 #    Intact (re-)distributions of any official Zope release do not 
  54 #    require an external acknowledgement. 
  56 # 7. Modifications are encouraged but must be packaged separately as 
  57 #    patches to official Zope releases.  Distributions that do not 
  58 #    clearly separate the patches from the original work must be clearly 
  59 #    labeled as unofficial distributions.  Modifications which do not 
  60 #    carry the name Zope may be packaged in any form, as long as they 
  61 #    conform to all of the clauses above. 
  66 #    THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY 
  67 #    EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  68 #    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  69 #    PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS 
  70 #    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  71 #    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  72 #    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
  73 #    USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
  74 #    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
  75 #    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
  76 #    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  80 # This software consists of contributions made by Digital Creations and 
  81 # many individuals on behalf of Digital Creations.  Specific 
  82 # attributions are listed in the accompanying credits file. 
  84 ############################################################################## 
  87 from string 
import split
, join
, replace
, expandtabs
, strip
, find
 
  88 from STletters 
import letters
,lettpunc
,punctuations
 
  93 class StructuredTextExample(ST
.StructuredTextParagraph
): 
  94     """Represents a section of document with literal text, as for examples""" 
  96     def __init__(self
, subs
, **kw
): 
  98        for s 
in subs
: a(s
.getNodeValue()) 
  99        apply(ST
.StructuredTextParagraph
.__init
__, 
 100              (self
, join(t
,'\n\n'), ()), 
 103     def getColorizableTexts(self
): return () 
 104     def setColorizableTexts(self
, src
): pass # never color examples 
 106 class StructuredTextBullet(ST
.StructuredTextParagraph
): 
 107     """Represents a section of a document with a title and a body""" 
 109 class StructuredTextNumbered(ST
.StructuredTextParagraph
): 
 110     """Represents a section of a document with a title and a body""" 
 112 class StructuredTextDescriptionTitle(ST
.StructuredTextParagraph
): 
 113     """Represents a section of a document with a title and a body""" 
 115 class StructuredTextDescriptionBody(ST
.StructuredTextParagraph
): 
 116     """Represents a section of a document with a title and a body""" 
 118 class StructuredTextDescription(ST
.StructuredTextParagraph
): 
 119     """Represents a section of a document with a title and a body""" 
 121     def __init__(self
, title
, src
, subs
, **kw
): 
 122        apply(ST
.StructuredTextParagraph
.__init
__, (self
, src
, subs
), kw
) 
 125     def getColorizableTexts(self
): return self
._title
, self
._src
 
 126     def setColorizableTexts(self
, src
): self
._title
, self
._src 
= src
 
 128     def getChildren(self
): 
 129        return (StructuredTextDescriptionTitle(self
._title
), 
 130                StructuredTextDescriptionBody(self
._src
, self
._subs
)) 
 132 class StructuredTextSectionTitle(ST
.StructuredTextParagraph
): 
 133     """Represents a section of a document with a title and a body""" 
 135 class StructuredTextSection(ST
.StructuredTextParagraph
): 
 136     """Represents a section of a document with a title and a body""" 
 137     def __init__(self
, src
, subs
=None, **kw
): 
 138        apply(ST
.StructuredTextParagraph
.__init
__, 
 139              (self
, StructuredTextSectionTitle(src
), subs
), 
 142     def getColorizableTexts(self
): 
 143         return self
._src
.getColorizableTexts() 
 145     def setColorizableTexts(self
,src
): 
 146         self
._src
.setColorizableTexts(src
) 
 148 # a StructuredTextTable holds StructuredTextRows 
 149 class StructuredTextTable(ST
.StructuredTextDocument
): 
 151     rows is a list of lists containing tuples, which 
 152     represent the columns/cells in each rows. 
 154     rows = [[('row 1:column1',1)],[('row2:column1',1)]] 
 157     def __init__(self
, rows
, src
, subs
, **kw
): 
 158         apply(ST
.StructuredTextDocument
.__init
__,(self
,subs
),kw
) 
 162                 self
._rows
.append(StructuredTextRow(row
,kw
)) 
 168         return self
.getRows() 
 170     def getColorizableTexts(self
): 
 172         return a tuple where each item is a column/cell's 
 173         contents. The tuple, result, will be of this format. 
 174         ("r1 col1", "r1=col2", "r2 col1", "r2 col2") 
 179         for row 
in self
._rows
: 
 180             for column 
in row
.getColumns()[0]: 
 181                 #result = result[:] + (column.getColorizableTexts(),) 
 182                 result
.append(column
.getColorizableTexts()[0]) 
 185     def setColorizableTexts(self
,texts
): 
 187         texts is going to a tuple where each item is the 
 188         result of being mapped to the colortext function. 
 189         Need to insert the results appropriately into the 
 190         individual columns/cells 
 192         for row_index 
in range(len(self
._rows
)): 
 193             for column_index 
in range(len(self
._rows
[row_index
]._columns
)): 
 194                 self
._rows
[row_index
]._columns
[column_index
].setColorizableTexts((texts
[0],)) 
 197     def _getColorizableTexts(self
): 
 198         return self
.getColorizableTexts() 
 200     def _setColorizableTexts(self
): 
 201         return self
.setColorizableTexts() 
 203 # StructuredTextRow holds StructuredTextColumns 
 204 class StructuredTextRow(ST
.StructuredTextDocument
): 
 206     def __init__(self
,row
,kw
): 
 208         row is a list of tuples, where each tuple is 
 209         the raw text for a cell/column and the span 
 210         of that cell/column". 
 212         [('this is column one',1), ('this is column two',1)] 
 215         apply(ST
.StructuredTextDocument
.__init
__,(self
,[]),kw
) 
 218             self
._columns
.append(StructuredTextColumn(column
[0],column
[1],kw
)) 
 219     def getColumns(self
): 
 220         return [self
._columns
] 
 222     def _getColumns(self
): 
 223         return [self
._columns
] 
 225 # this holds the raw text of a table cell 
 226 class StructuredTextColumn(ST
.StructuredTextParagraph
): 
 228     StructuredTextColumn is a cell/column in a table. 
 229     This contains the actual text of a column and is 
 230     thus a StructuredTextParagraph. A StructuredTextColumn 
 231     also holds the span of its column 
 234     def __init__(self
,text
,span
,kw
): 
 235         apply(ST
.StructuredTextParagraph
.__init
__,(self
,text
,[]),kw
) 
 244 class StructuredTextMarkup(STDOM
.Element
): 
 246     def __init__(self
, v
, **kw
): 
 248        self
._attributes
=kw
.keys() 
 249        for k
, v 
in kw
.items(): setattr(self
, k
, v
) 
 251     def getChildren(self
, type=type, lt
=type([])): 
 253        if type(v
) is not lt
: v
=[v
] 
 256     def getColorizableTexts(self
): return self
._value
, 
 257     def setColorizableTexts(self
, v
): self
._value
=v
[0] 
 260        return '%s(%s)' % (self
.__class
__.__name
__, `self
._value`
) 
 262 class StructuredTextLiteral(StructuredTextMarkup
): 
 263     def getColorizableTexts(self
): return () 
 264     def setColorizableTexts(self
, v
): pass 
 266 class StructuredTextEmphasis(StructuredTextMarkup
): pass 
 268 class StructuredTextStrong(StructuredTextMarkup
): pass 
 270 class StructuredTextInnerLink(StructuredTextMarkup
): pass 
 272 class StructuredTextNamedLink(StructuredTextMarkup
): pass 
 274 class StructuredTextUnderline(StructuredTextMarkup
): pass 
 276 class StructuredTextLink(StructuredTextMarkup
): 
 281     Class instance calls [ex.=> x()] require a structured text 
 282     structure. Doc will then parse each paragraph in the structure 
 283     and will find the special structures within each paragraph. 
 284     Each special structure will be stored as an instance. Special 
 285     structures within another special structure are stored within 
 287     EX : '-underline this-' => would be turned into an underline 
 288     instance. '-underline **this**' would be stored as an underline 
 289     instance with a strong instance stored in its string 
 310     def __call__(self
, doc
): 
 311         if type(doc
) is type(''): 
 312            doc
=ST
.StructuredText(doc
) 
 313            doc
.setSubparagraphs(self
.color_paragraphs( 
 314               doc
.getSubparagraphs())) 
 316            doc
=ST
.StructuredTextDocument(self
.color_paragraphs( 
 317               doc
.getSubparagraphs())) 
 320     def parse(self
, raw_string
, text_type
, 
 321               type=type, st
=type(''), lt
=type([])): 
 324        Parse accepts a raw_string, an expr to test the raw_string, 
 325        and the raw_string's subparagraphs. 
 327        Parse will continue to search through raw_string until 
 328        all instances of expr in raw_string are found. 
 330        If no instances of expr are found, raw_string is returned. 
 331        Otherwise a list of substrings and instances is returned 
 334        tmp 
= []    # the list to be returned if raw_string is split 
 337        if type(text_type
) is st
: text_type
=getattr(self
, text_type
) 
 340           t 
= text_type(raw_string
) 
 342           #an instance of expr was found 
 345           if start
: append(raw_string
[0:start
]) 
 349              # if we get a string back, add it to text to be parsed 
 350              raw_string 
= t
+raw_string
[end
:len(raw_string
)] 
 353                 # is we get a list, append it's elements 
 356                 # normal case, an object 
 358              raw_string 
= raw_string
[end
:len(raw_string
)] 
 360        if not tmp
: return raw_string 
# nothing found 
 362        if raw_string
: append(raw_string
) 
 363        elif len(tmp
)==1: return tmp
[0] 
 368     def color_text(self
, str, types
=None): 
 369        """Search the paragraph for each special structure 
 371        if types 
is None: types
=self
.text_types
 
 373        for text_type 
in types
: 
 375           if type(str) is StringType
: 
 376              str = self
.parse(str, text_type
) 
 377           elif type(str) is ListType
: 
 380                 if type(s
) is StringType
: 
 381                     s
=self
.parse(s
, text_type
) 
 382                     if type(s
) is ListType
: r
[len(r
):]=s
 
 385                     s
.setColorizableTexts( 
 387                            s
.getColorizableTexts() 
 392              r
=[]; a
=r
.append
; color
=self
.color_text
 
 393              for s 
in str.getColorizableTexts(): 
 394                 color(s
, (text_type
,)) 
 397              str.setColorizableTexts(r
) 
 401     def color_paragraphs(self
, raw_paragraphs
, 
 402                            type=type, sequence_types
=(type([]), type(())), 
 405        for paragraph 
in raw_paragraphs
: 
 407           if paragraph
.getNodeName() != 'StructuredTextParagraph': 
 408              result
.append(paragraph
) 
 411           for pt 
in self
.paragraph_types
: 
 413                 # grab the corresponding function 
 415              # evaluate the paragraph 
 418                 if type(r
) not in sequence_types
: 
 421                 for paragraph 
in new_paragraphs
: 
 422                     paragraph
.setSubparagraphs(self
.color_paragraphs(paragraph
.getSubparagraphs())) 
 425              new_paragraphs
=ST
.StructuredTextParagraph(paragraph
.getColorizableTexts()[0], 
 426                                                           self
.color_paragraphs(paragraph
.getSubparagraphs()), 
 427                                                           indent
=paragraph
.indent
), 
 428           # color the inline StructuredText types 
 429           # for each StructuredTextParagraph 
 430           for paragraph 
in new_paragraphs
: 
 431              paragraph
.setColorizableTexts( 
 433                     paragraph
.getColorizableTexts() 
 435              result
.append(paragraph
) 
 439     def doc_table(self
,paragraph
, expr 
= re
.compile('(\s*)([||]+)').match
): 
 440         #print "paragraph=>", type(paragraph), paragraph, paragraph._src 
 441         text    
= paragraph
.getColorizableTexts()[0] 
 449         for row 
in split(text
,"\n"): 
 453         for index 
in range(len(rows
)): 
 455             rows
[index
] = strip(rows
[index
]) 
 456             l 
= len(rows
[index
])-2 
 457             result 
= split(rows
[index
][:l
],"||") 
 465         # remove trailing '''s 
 466         for index 
in range(len(rows
)): 
 467             l 
= len(rows
[index
])-1 
 468             rows
[index
] = rows
[index
][:l
] 
 476                     tmp
.append((item
,cspan
)) 
 482         subs 
= paragraph
.getSubparagraphs() 
 483         indent
=paragraph
.indent
 
 484         return StructuredTextTable(result
,text
,subs
,indent
=paragraph
.indent
) 
 486     def doc_bullet(self
, paragraph
, expr 
= re
.compile('\s*[-*o]\s+').match
): 
 487         top
=paragraph
.getColorizableTexts()[0] 
 493         subs
=paragraph
.getSubparagraphs() 
 495            subs
=[StructuredTextExample(subs
)] 
 497         return StructuredTextBullet(top
[m
.span()[1]:], subs
, 
 498                                      indent
=paragraph
.indent
, 
 499                                      bullet
=top
[:m
.span()[1]] 
 504         expr 
= re
.compile('(\s*[%s]+\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)' % letters
).match
): 
 506         # This is the old expression. It had a nasty habit 
 507         # of grabbing paragraphs that began with a single 
 508         # letter word even if there was no following period. 
 510         #expr = re.compile('\s*' 
 511         #                   '(([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.)*' 
 512         #                   '([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.?' 
 515         top
=paragraph
.getColorizableTexts()[0] 
 517         if not m
: return None 
 518         subs
=paragraph
.getSubparagraphs() 
 520            subs
=[StructuredTextExample(subs
)] 
 522         return StructuredTextNumbered(top
[m
.span()[1]:], subs
, 
 523                                         indent
=paragraph
.indent
, 
 524                                         number
=top
[:m
.span()[1]]) 
 528         delim 
= re
.compile('\s+--\s+').search
, 
 529         nb
=re
.compile(r
'[^\000- ]').search
, 
 532         top
=paragraph
.getColorizableTexts()[0] 
 534         if not d
: return None 
 535         start
, end 
= d
.span() 
 537         if find(title
, '\n') >= 0: return None 
 538         if not nb(title
): return None 
 542         subs
=paragraph
.getSubparagraphs() 
 544            subs
=[StructuredTextExample(subs
)] 
 547         return StructuredTextDescription( 
 549            indent
=paragraph
.indent
, 
 552     def doc_header(self
, paragraph
, 
 553                     expr    
= re
.compile('[ %s0-9.:/,-_*<>\?\'\"]+' % letters
).match
 
 555         subs
=paragraph
.getSubparagraphs() 
 556         if not subs
: return None 
 557         top
=paragraph
.getColorizableTexts()[0] 
 558         if not strip(top
): return None 
 560            subs
=StructuredTextExample(subs
) 
 561            if strip(top
)=='::': return subs
 
 562            return ST
.StructuredTextParagraph(top
[:-1], 
 564                                              indent
=paragraph
.indent
, 
 565                                              level
=paragraph
.level
) 
 567         if find(top
,'\n') >= 0: return None 
 568         return StructuredTextSection(top
, subs
, indent
=paragraph
.indent
, level
=paragraph
.level
) 
 574           "([^ \t\n\r\f\v']|[^ \t\n\r\f\v'][^\n']*[^ \t\n\r\f\v'])" # contents 
 575           "'(?:\s|[,.;:!?]|$)"                                      # close 
 580            start
, end 
= r
.span(1) 
 581            return (StructuredTextLiteral(s
[start
:end
]), start
-1, end
+1) 
 587         expr 
= re
.compile('\s*\*([ \n%s0-9]+)\*(?!\*|-)' % lettpunc
).search
 
 592            start
, end 
= r
.span(1) 
 593            return (StructuredTextEmphasis(s
[start
:end
]), start
-1, end
+1) 
 597     def doc_inner_link(self
, 
 599                        expr1 
= re
.compile("\.\.\s*").search
, 
 600                        expr2 
= re
.compile("\[[%s0-9]+\]" % letters
).search
): 
 602         # make sure we dont grab a named link 
 603         if expr2(s
) and expr1(s
): 
 604             start1
,end1 
= expr1(s
).span() 
 605             start2
,end2 
= expr2(s
).span() 
 607                 # uh-oh, looks like a named link 
 610                 # the .. is somewhere else, ignore it 
 611                 return (StructuredTextInnerLink(s
[start2
+1:end2
-1]),start2
,end2
) 
 613         elif expr2(s
) and not expr1(s
): 
 614             start
,end 
= expr2(s
).span() 
 615             return (StructuredTextInnerLink(s
[start
+1:end
-1]),start
,end
) 
 618     def doc_named_link(self
, 
 620                        expr
=re
.compile("(\.\.\s)(\[[%s0-9]+\])" % letters
).search
): 
 624             start
,end   
= result
.span(2) 
 626             str         = strip(s
[a
:b
]) + s
[start
:end
] 
 627             str         = s
[start
+1:end
-1] 
 628             st
,en       
= result
.span() 
 629             return (StructuredTextNamedLink(str),st
,en
) 
 630             #return (StructuredTextNamedLink(s[st:en]),st,en) 
 633     def doc_underline(self
, 
 635                       expr
=re
.compile("\s+\_([0-9%s ]+)\_" % lettpunc
).search
): 
 639             start
,end 
= result
.span(1) 
 641             return (StructuredTextUnderline(s
[start
:end
]),st
,e
) 
 647         expr 
= re
.compile('\s*\*\*([ \n%s0-9]+)\*\*' % lettpunc
).search
 
 652            start
, end 
= r
.span(1) 
 653            return (StructuredTextStrong(s
[start
:end
]), start
-2, end
+2) 
 660         expr1 
= re
.compile("(\"[ %s0-9\n\-\.\,\;\(\)\/\:\/\*\']+\")(:)([a-zA-Z0-9\@\.\,\?\!\/\:\;\-\#\~]+)([,]*\s*)" % letters
).search
, 
 661         expr2 
= re
.compile('(\"[ %s0-9\n\-\.\:\;\(\)\/\*\']+\")([,]+\s+)([a-zA-Z0-9\@\.\,\?\!\/\:\;\-\#\~]+)(\s*)' % letters
).search
): 
 663         r
=expr1(s
) or expr2(s
) 
 666             # need to grab the href part and the 
 671             name    
= replace(name
,'"','',2) 
 674             if s
[end
-1:end
] in punctuations
: end
-=1 
 677             # name is the href title, link is the target 
 679             return (StructuredTextLink(name
, href
=link
),