]>
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
92 class StructuredTextExample(ST
.StructuredTextParagraph
):
93 """Represents a section of document with literal text, as for examples"""
95 def __init__(self
, subs
, **kw
):
97 for s
in subs
: a(s
.getNodeValue())
98 apply(ST
.StructuredTextParagraph
.__init
__,
99 (self
, join(t
,'\n\n'), ()),
102 def getColorizableTexts(self
): return ()
103 def setColorizableTexts(self
, src
): pass # never color examples
105 class StructuredTextBullet(ST
.StructuredTextParagraph
):
106 """Represents a section of a document with a title and a body"""
108 class StructuredTextNumbered(ST
.StructuredTextParagraph
):
109 """Represents a section of a document with a title and a body"""
111 class StructuredTextDescriptionTitle(ST
.StructuredTextParagraph
):
112 """Represents a section of a document with a title and a body"""
114 class StructuredTextDescriptionBody(ST
.StructuredTextParagraph
):
115 """Represents a section of a document with a title and a body"""
117 class StructuredTextDescription(ST
.StructuredTextParagraph
):
118 """Represents a section of a document with a title and a body"""
120 def __init__(self
, title
, src
, subs
, **kw
):
121 apply(ST
.StructuredTextParagraph
.__init
__, (self
, src
, subs
), kw
)
124 def getColorizableTexts(self
): return self
._title
, self
._src
125 def setColorizableTexts(self
, src
): self
._title
, self
._src
= src
127 def getChildren(self
):
128 return (StructuredTextDescriptionTitle(self
._title
),
129 StructuredTextDescriptionBody(self
._src
, self
._subs
))
131 class StructuredTextSectionTitle(ST
.StructuredTextParagraph
):
132 """Represents a section of a document with a title and a body"""
134 class StructuredTextSection(ST
.StructuredTextParagraph
):
135 """Represents a section of a document with a title and a body"""
136 def __init__(self
, src
, subs
=None, **kw
):
137 apply(ST
.StructuredTextParagraph
.__init
__,
138 (self
, StructuredTextSectionTitle(src
), subs
),
141 # a StructuredTextTable holds StructuredTextRows
142 class StructuredTextTable(ST
.StructuredTextDocument
):
144 rows is a list of lists containing tuples, which
145 represent the columns/cells in each rows.
147 rows = [[('row 1:column1',1)],[('row2:column1',1)]]
150 def __init__(self
, rows
, src
, subs
, **kw
):
151 apply(ST
.StructuredTextDocument
.__init
__,(self
,subs
),kw
)
155 self
._rows
.append(StructuredTextRow(row
,kw
))
161 return self
.getRows()
163 def getColorizableTexts(self
):
165 return a tuple where each item is a column/cell's
166 contents. The tuple, result, will be of this format.
167 ("r1 col1", "r1=col2", "r2 col1", "r2 col2")
172 for row
in self
._rows
:
173 for column
in row
.getColumns()[0]:
174 #result = result[:] + (column.getColorizableTexts(),)
175 result
.append(column
.getColorizableTexts()[0])
178 def setColorizableTexts(self
,texts
):
180 texts is going to a tuple where each item is the
181 result of being mapped to the colortext function.
182 Need to insert the results appropriately into the
183 individual columns/cells
185 for row_index
in range(len(self
._rows
)):
186 for column_index
in range(len(self
._rows
[row_index
]._columns
)):
187 self
._rows
[row_index
]._columns
[column_index
].setColorizableTexts((texts
[0],))
190 def _getColorizableTexts(self
):
191 return self
.getColorizableTexts()
193 def _setColorizableTexts(self
):
194 return self
.setColorizableTexts()
196 # StructuredTextRow holds StructuredTextColumns
197 class StructuredTextRow(ST
.StructuredTextDocument
):
199 def __init__(self
,row
,kw
):
201 row is a list of tuples, where each tuple is
202 the raw text for a cell/column and the span
203 of that cell/column".
205 [('this is column one',1), ('this is column two',1)]
208 apply(ST
.StructuredTextDocument
.__init
__,(self
,[]),kw
)
211 self
._columns
.append(StructuredTextColumn(column
[0],column
[1],kw
))
212 def getColumns(self
):
213 return [self
._columns
]
215 def _getColumns(self
):
216 return [self
._columns
]
218 # this holds the raw text of a table cell
219 class StructuredTextColumn(ST
.StructuredTextParagraph
):
221 StructuredTextColumn is a cell/column in a table.
222 This contains the actual text of a column and is
223 thus a StructuredTextParagraph. A StructuredTextColumn
224 also holds the span of its column
227 def __init__(self
,text
,span
,kw
):
228 apply(ST
.StructuredTextParagraph
.__init
__,(self
,text
,[]),kw
)
237 class StructuredTextMarkup(STDOM
.Element
):
239 def __init__(self
, v
, **kw
):
241 self
._attributes
=kw
.keys()
242 for k
, v
in kw
.items(): setattr(self
, k
, v
)
244 def getChildren(self
, type=type, lt
=type([])):
246 if type(v
) is not lt
: v
=[v
]
249 def getColorizableTexts(self
): return self
._value
,
250 def setColorizableTexts(self
, v
): self
._value
=v
[0]
253 return '%s(%s)' % (self
.__class
__.__name
__, `self
._value`
)
255 class StructuredTextLiteral(StructuredTextMarkup
):
256 def getColorizableTexts(self
): return ()
257 def setColorizableTexts(self
, v
): pass
259 class StructuredTextEmphasis(StructuredTextMarkup
): pass
261 class StructuredTextStrong(StructuredTextMarkup
): pass
263 class StructuredTextInnerLink(StructuredTextMarkup
): pass
265 class StructuredTextNamedLink(StructuredTextMarkup
): pass
267 class StructuredTextUnderline(StructuredTextMarkup
): pass
269 class StructuredTextLink(StructuredTextMarkup
):
274 Class instance calls [ex.=> x()] require a structured text
275 structure. Doc will then parse each paragraph in the structure
276 and will find the special structures within each paragraph.
277 Each special structure will be stored as an instance. Special
278 structures within another special structure are stored within
280 EX : '-underline this-' => would be turned into an underline
281 instance. '-underline **this**' would be stored as an underline
282 instance with a strong instance stored in its string
303 def __call__(self
, doc
):
304 if type(doc
) is type(''):
305 doc
=ST
.StructuredText(doc
)
306 doc
.setSubparagraphs(self
.color_paragraphs(
307 doc
.getSubparagraphs()))
309 doc
=ST
.StructuredTextDocument(self
.color_paragraphs(
310 doc
.getSubparagraphs()))
313 def parse(self
, raw_string
, text_type
,
314 type=type, st
=type(''), lt
=type([])):
317 Parse accepts a raw_string, an expr to test the raw_string,
318 and the raw_string's subparagraphs.
320 Parse will continue to search through raw_string until
321 all instances of expr in raw_string are found.
323 If no instances of expr are found, raw_string is returned.
324 Otherwise a list of substrings and instances is returned
327 tmp
= [] # the list to be returned if raw_string is split
330 if type(text_type
) is st
: text_type
=getattr(self
, text_type
)
333 t
= text_type(raw_string
)
335 #an instance of expr was found
338 if start
: append(raw_string
[0:start
])
342 # if we get a string back, add it to text to be parsed
343 raw_string
= t
+raw_string
[end
:len(raw_string
)]
346 # is we get a list, append it's elements
349 # normal case, an object
351 raw_string
= raw_string
[end
:len(raw_string
)]
353 if not tmp
: return raw_string
# nothing found
355 if raw_string
: append(raw_string
)
356 elif len(tmp
)==1: return tmp
[0]
361 def color_text(self
, str, types
=None):
362 """Search the paragraph for each special structure
364 if types
is None: types
=self
.text_types
366 for text_type
in types
:
368 if type(str) is StringType
:
369 str = self
.parse(str, text_type
)
370 elif type(str) is ListType
:
373 if type(s
) is StringType
:
374 s
=self
.parse(s
, text_type
)
375 if type(s
) is ListType
: r
[len(r
):]=s
378 s
.setColorizableTexts(
380 s
.getColorizableTexts()
385 r
=[]; a
=r
.append
; color
=self
.color_text
386 for s
in str.getColorizableTexts():
387 color(s
, (text_type
,))
390 str.setColorizableTexts(r
)
394 def color_paragraphs(self
, raw_paragraphs
,
395 type=type, sequence_types
=(type([]), type(())),
398 for paragraph
in raw_paragraphs
:
400 if paragraph
.getNodeName() != 'StructuredTextParagraph':
401 result
.append(paragraph
)
404 for pt
in self
.paragraph_types
:
406 # grab the corresponding function
408 # evaluate the paragraph
411 if type(r
) not in sequence_types
:
414 for paragraph
in new_paragraphs
:
415 paragraph
.setSubparagraphs(self
.color_paragraphs(paragraph
.getSubparagraphs()))
418 new_paragraphs
=ST
.StructuredTextParagraph(paragraph
.getColorizableTexts()[0],
419 self
.color_paragraphs(paragraph
.getSubparagraphs()),
420 indent
=paragraph
.indent
),
421 # color the inline StructuredText types
422 # for each StructuredTextParagraph
423 for paragraph
in new_paragraphs
:
424 paragraph
.setColorizableTexts(
426 paragraph
.getColorizableTexts()
428 result
.append(paragraph
)
432 def doc_table(self
,paragraph
, expr
= re
.compile('(\s*)([||]+)').match
):
433 text
= paragraph
.getColorizableTexts()[0]
441 for row
in split(text
,"\n"):
445 for index
in range(len(rows
)):
447 rows
[index
] = strip(rows
[index
])
448 l
= len(rows
[index
])-2
449 result
= split(rows
[index
][:l
],"||")
457 # remove trailing '''s
458 for index
in range(len(rows
)):
459 l
= len(rows
[index
])-1
460 rows
[index
] = rows
[index
][:l
]
468 tmp
.append(item
,cspan
)
474 subs
= paragraph
.getSubparagraphs()
475 indent
=paragraph
.indent
476 return StructuredTextTable(result
,text
,subs
,indent
=paragraph
.indent
)
478 def doc_bullet(self
, paragraph
, expr
= re
.compile('\s*[-*o]\s+').match
):
479 top
=paragraph
.getColorizableTexts()[0]
485 subs
=paragraph
.getSubparagraphs()
487 subs
=[StructuredTextExample(subs
)]
489 return StructuredTextBullet(top
[m
.span()[1]:], subs
,
490 indent
=paragraph
.indent
,
491 bullet
=top
[:m
.span()[1]]
496 expr
= re
.compile('(\s*[a-zA-Z]+\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)').match
):
498 # This is the old expression. It had a nasty habit
499 # of grabbing paragraphs that began with a single
500 # letter word even if there was no following period.
502 #expr = re.compile('\s*'
503 # '(([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.)*'
504 # '([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.?'
507 top
=paragraph
.getColorizableTexts()[0]
509 if not m
: return None
510 subs
=paragraph
.getSubparagraphs()
512 subs
=[StructuredTextExample(subs
)]
514 return StructuredTextNumbered(top
[m
.span()[1]:], subs
,
515 indent
=paragraph
.indent
,
516 number
=top
[:m
.span()[1]])
520 delim
= re
.compile('\s+--\s+').search
,
521 nb
=re
.compile(r
'[^\0- ]').search
,
524 top
=paragraph
.getColorizableTexts()[0]
526 if not d
: return None
527 start
, end
= d
.span()
529 if find(title
, '\n') >= 0: return None
530 if not nb(title
): return None
534 subs
=paragraph
.getSubparagraphs()
536 subs
=[StructuredTextExample(subs
)]
539 return StructuredTextDescription(
541 indent
=paragraph
.indent
,
544 def doc_header(self
, paragraph
,
545 expr
= re
.compile('[ a-zA-Z0-9.:/,-_*<>\?\'\"]+').match
547 subs
=paragraph
.getSubparagraphs()
548 if not subs
: return None
549 top
=paragraph
.getColorizableTexts()[0]
550 if not strip(top
): return None
552 subs
=StructuredTextExample(subs
)
553 if strip(top
)=='::': return subs
554 return ST
.StructuredTextParagraph(top
[:-1],
556 indent
=paragraph
.indent
,
557 level
=paragraph
.level
)
559 if find(top
,'\n') >= 0: return None
560 return StructuredTextSection(top
, subs
, indent
=paragraph
.indent
, level
=paragraph
.level
)
566 "([^ \t\n\r\f\v']|[^ \t\n\r\f\v'][^\n']*[^ \t\n\r\f\v'])" # contents
567 "'(?:\s|[,.;:!?]|$)" # close
572 start
, end
= r
.span(1)
573 return (StructuredTextLiteral(s
[start
:end
]), start
-1, end
+1)
579 expr
= re
.compile('\s*\*([ \na-zA-Z0-9.:/;,\'\"\?]+)\*(?!\*|-)').search
584 start
, end
= r
.span(1)
585 return (StructuredTextEmphasis(s
[start
:end
]), start
-1, end
+1)
589 def doc_inner_link(self
,
591 expr1
= re
.compile("\.\.\s*").search
,
592 expr2
= re
.compile("\[[a-zA-Z0-9]+\]").search
):
594 # make sure we dont grab a named link
595 if expr2(s
) and expr1(s
):
596 start1
,end1
= expr1(s
).span()
597 start2
,end2
= expr2(s
).span()
599 # uh-oh, looks like a named link
602 # the .. is somewhere else, ignore it
603 return (StructuredTextInnerLink(s
[start2
+1,end2
-1],start2
,end2
))
605 elif expr2(s
) and not expr1(s
):
606 start
,end
= expr2(s
).span()
607 return (StructuredTextInnerLink(s
[start
+1:end
-1]),start
,end
)
610 def doc_named_link(self
,
612 expr
=re
.compile("(\.\.\s)(\[[a-zA-Z0-9]+\])").search
):
616 start
,end
= result
.span(2)
618 str = strip(s
[a
:b
]) + s
[start
:end
]
619 str = s
[start
+1:end
-1]
620 st
,en
= result
.span()
621 return (StructuredTextNamedLink(str),st
,en
)
622 #return (StructuredTextNamedLink(s[st:en]),st,en)
625 def doc_underline(self
,
627 expr
=re
.compile("\_([a-zA-Z0-9\s\.,\?\/]+)\_").search
):
631 start
,end
= result
.span(1)
633 return (StructuredTextUnderline(s
[start
:end
]),st
,e
)
639 expr
= re
.compile('\s*\*\*([ \na-zA-Z0-9.:/;\-,!\?\'\"]+)\*\*').search
644 start
, end
= r
.span(1)
645 return (StructuredTextStrong(s
[start
:end
]), start
-2, end
+2)
652 expr1
= re
.compile("(\"[ a-zA-Z0-9\n\-\.\,\;\(\)\/\:\/]+\")(:)([a-zA-Z0-9\:\/\.\~\-]+)([,]*\s*)").search
,
653 expr2
= re
.compile('(\"[ a-zA-Z0-9\n\-\.\:\;\(\)\/]+\")([,]+\s+)([a-zA-Z0-9\@\.\,\?\!\/\:\;\-\#]+)(\s*)').search
):
655 #expr1=re.compile('\"([ a-zA-Z0-9.:/;,\n\~\(\)\-]+)\"'
657 # '([a-zA-Z0-9.:/;,\n\~]+)(?=(\s+|\.|\!|\?))'
659 #expr2=re.compile('\"([ a-zA-Z0-9./:]+)\"'
661 # '([ a-zA-Z0-9@.:/;]+)(?=(\s+|\.|\!|\?))'
664 punctuation
= re
.compile("[\,\.\?\!\;]+").match
665 r
=expr1(s
) or expr2(s
)
668 # need to grab the href part and the
673 name
= replace(name
,'"','',2)
676 if punctuation(s
[end
-1:end
]):
681 # name is the href title, link is the target
683 return (StructuredTextLink(name
, href
=link
),
686 #return (StructuredTextLink(s[start:end], href=s[start:end]),