]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/stxview/StructuredText/DocumentClass.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
, rstrip
88 from STletters
import *
94 def flatten(obj
, append
):
95 if obj
.getNodeType()==STDOM
.TEXT_NODE
:
96 append(obj
.getNodeValue())
98 for child
in obj
.getChildNodes():
99 flatten(child
, append
)
102 class StructuredTextExample(ST
.StructuredTextParagraph
):
103 """Represents a section of document with literal text, as for examples"""
105 def __init__(self
, subs
, **kw
):
110 apply(ST
.StructuredTextParagraph
.__init
__,
111 (self
, join(t
,'\n\n'), ()),
114 def getColorizableTexts(self
): return ()
115 def setColorizableTexts(self
, src
): pass # never color examples
117 class StructuredTextBullet(ST
.StructuredTextParagraph
):
118 """Represents a section of a document with a title and a body"""
120 class StructuredTextNumbered(ST
.StructuredTextParagraph
):
121 """Represents a section of a document with a title and a body"""
123 class StructuredTextDescriptionTitle(ST
.StructuredTextParagraph
):
124 """Represents a section of a document with a title and a body"""
126 class StructuredTextDescriptionBody(ST
.StructuredTextParagraph
):
127 """Represents a section of a document with a title and a body"""
129 class StructuredTextDescription(ST
.StructuredTextParagraph
):
130 """Represents a section of a document with a title and a body"""
132 def __init__(self
, title
, src
, subs
, **kw
):
133 apply(ST
.StructuredTextParagraph
.__init
__, (self
, src
, subs
), kw
)
136 def getColorizableTexts(self
): return self
._title
, self
._src
137 def setColorizableTexts(self
, src
): self
._title
, self
._src
= src
139 def getChildren(self
):
140 return (StructuredTextDescriptionTitle(self
._title
),
141 StructuredTextDescriptionBody(self
._src
, self
._subs
))
143 class StructuredTextSectionTitle(ST
.StructuredTextParagraph
):
144 """Represents a section of a document with a title and a body"""
146 class StructuredTextSection(ST
.StructuredTextParagraph
):
147 """Represents a section of a document with a title and a body"""
148 def __init__(self
, src
, subs
=None, **kw
):
149 apply(ST
.StructuredTextParagraph
.__init
__,
150 (self
, StructuredTextSectionTitle(src
), subs
),
153 def getColorizableTexts(self
):
154 return self
._src
.getColorizableTexts()
156 def setColorizableTexts(self
,src
):
157 self
._src
.setColorizableTexts(src
)
159 # a StructuredTextTable holds StructuredTextRows
160 class StructuredTextTable(ST
.StructuredTextParagraph
):
162 rows is a list of lists containing tuples, which
163 represent the columns/cells in each rows.
165 rows = [[('row 1:column1',1)],[('row2:column1',1)]]
168 def __init__(self
, rows
, src
, subs
, **kw
):
169 apply(ST
.StructuredTextParagraph
.__init
__,(self
,subs
),kw
)
173 self
._rows
.append(StructuredTextRow(row
,kw
))
179 return self
.getRows()
181 def getColumns(self
):
183 for row
in self
._rows
:
184 result
.append(row
.getColumns())
187 def _getColumns(self
):
188 return self
.getColumns()
190 def setColumns(self
,columns
):
191 for index
in range(len(self
._rows
)):
192 self
._rows
[index
].setColumns(columns
[index
])
194 def _setColumns(self
,columns
):
195 return self
.setColumns(columns
)
197 def getColorizableTexts(self
):
199 return a tuple where each item is a column/cell's
200 contents. The tuple, result, will be of this format.
201 ("r1 col1", "r1=col2", "r2 col1", "r2 col2")
205 for row
in self
._rows
:
206 for column
in row
.getColumns()[0]:
207 result
.append(column
.getColorizableTexts()[0])
210 def setColorizableTexts(self
,texts
):
212 texts is going to a tuple where each item is the
213 result of being mapped to the colortext function.
214 Need to insert the results appropriately into the
215 individual columns/cells
217 for row_index
in range(len(self
._rows
)):
218 for column_index
in range(len(self
._rows
[row_index
]._columns
)):
219 self
._rows
[row_index
]._columns
[column_index
].setColorizableTexts((texts
[0],))
222 def _getColorizableTexts(self
):
223 return self
.getColorizableTexts()
225 def _setColorizableTexts(self
):
226 return self
.setColorizableTexts()
228 # StructuredTextRow holds StructuredTextColumns
229 class StructuredTextRow(ST
.StructuredTextParagraph
):
231 def __init__(self
,row
,kw
):
233 row is a list of tuples, where each tuple is
234 the raw text for a cell/column and the span
237 [('this is column one',1), ('this is column two',1)]
240 apply(ST
.StructuredTextParagraph
.__init
__,(self
,[]),kw
)
244 self
._columns
.append(StructuredTextColumn(column
[0],
251 def getColumns(self
):
252 return [self
._columns
]
254 def _getColumns(self
):
255 return [self
._columns
]
257 def setColumns(self
,columns
):
258 self
._columns
= columns
260 def _setColumns(self
,columns
):
261 return self
.setColumns(columns
)
263 # this holds the text of a table cell
264 class StructuredTextColumn(ST
.StructuredTextParagraph
):
266 StructuredTextColumn is a cell/column in a table.
267 A cell can hold multiple paragraphs. The cell
268 is either classified as a StructuredTextTableHeader
269 or StructuredTextTableData.
272 def __init__(self
,text
,span
,align
,valign
,typ
,kw
):
273 apply(ST
.StructuredTextParagraph
.__init
__,(self
,text
,[]),kw
)
276 self
._valign
= valign
289 return self
.getAlign()
294 def _getValign(self
):
295 return self
.getValign()
301 return self
.getType()
303 class StructuredTextTableHeader(ST
.StructuredTextParagraph
): pass
305 class StructuredTextTableData(ST
.StructuredTextParagraph
): pass
307 class StructuredTextMarkup(STDOM
.Element
):
309 def __init__(self
, v
, **kw
):
311 self
._attributes
=kw
.keys()
312 for k
, v
in kw
.items(): setattr(self
, k
, v
)
314 def getChildren(self
, type=type, lt
=type([])):
316 if type(v
) is not lt
: v
=[v
]
319 def getColorizableTexts(self
): return self
._value
,
320 def setColorizableTexts(self
, v
): self
._value
=v
[0]
323 return '%s(%s)' % (self
.__class
__.__name
__, `self
._value`
)
325 class StructuredTextLiteral(StructuredTextMarkup
):
326 def getColorizableTexts(self
): return ()
327 def setColorizableTexts(self
, v
): pass
329 class StructuredTextEmphasis(StructuredTextMarkup
): pass
331 class StructuredTextStrong(StructuredTextMarkup
): pass
333 class StructuredTextInnerLink(StructuredTextMarkup
): pass
335 class StructuredTextNamedLink(StructuredTextMarkup
): pass
337 class StructuredTextUnderline(StructuredTextMarkup
): pass
339 class StructuredTextSGML(StructuredTextMarkup
): pass
341 class StructuredTextLink(StructuredTextMarkup
): pass
343 class StructuredTextXref(StructuredTextMarkup
): pass
347 Class instance calls [ex.=> x()] require a structured text
348 structure. Doc will then parse each paragraph in the structure
349 and will find the special structures within each paragraph.
350 Each special structure will be stored as an instance. Special
351 structures within another special structure are stored within
353 EX : '-underline this-' => would be turned into an underline
354 instance. '-underline **this**' would be stored as an underline
355 instance with a strong instance stored in its string
379 def __call__(self
, doc
):
380 if type(doc
) is type(''):
381 doc
=ST
.StructuredText(doc
)
382 doc
.setSubparagraphs(self
.color_paragraphs(
383 doc
.getSubparagraphs()))
385 doc
=ST
.StructuredTextDocument(self
.color_paragraphs(
386 doc
.getSubparagraphs()))
389 def parse(self
, raw_string
, text_type
,
390 type=type, st
=type(''), lt
=type([])):
393 Parse accepts a raw_string, an expr to test the raw_string,
394 and the raw_string's subparagraphs.
396 Parse will continue to search through raw_string until
397 all instances of expr in raw_string are found.
399 If no instances of expr are found, raw_string is returned.
400 Otherwise a list of substrings and instances is returned
403 tmp
= [] # the list to be returned if raw_string is split
406 if type(text_type
) is st
: text_type
=getattr(self
, text_type
)
409 t
= text_type(raw_string
)
411 #an instance of expr was found
414 if start
: append(raw_string
[0:start
])
418 # if we get a string back, add it to text to be parsed
419 raw_string
= t
+raw_string
[end
:len(raw_string
)]
422 # is we get a list, append it's elements
425 # normal case, an object
427 raw_string
= raw_string
[end
:len(raw_string
)]
429 if not tmp
: return raw_string
# nothing found
431 if raw_string
: append(raw_string
)
432 elif len(tmp
)==1: return tmp
[0]
437 def color_text(self
, str, types
=None):
438 """Search the paragraph for each special structure
440 if types
is None: types
=self
.text_types
442 for text_type
in types
:
444 if type(str) is StringType
:
445 str = self
.parse(str, text_type
)
446 elif type(str) is ListType
:
449 if type(s
) is StringType
:
450 s
=self
.parse(s
, text_type
)
451 if type(s
) is ListType
: r
[len(r
):]=s
454 s
.setColorizableTexts(
456 s
.getColorizableTexts()
461 r
=[]; a
=r
.append
; color
=self
.color_text
462 for s
in str.getColorizableTexts():
463 color(s
, (text_type
,))
466 str.setColorizableTexts(r
)
470 def color_paragraphs(self
, raw_paragraphs
,
471 type=type, sequence_types
=(type([]), type(())),
474 for paragraph
in raw_paragraphs
:
475 if paragraph
.getNodeName() != 'StructuredTextParagraph':
476 result
.append(paragraph
)
479 for pt
in self
.paragraph_types
:
481 # grab the corresponding function
483 # evaluate the paragraph
486 if type(r
) not in sequence_types
:
489 for paragraph
in new_paragraphs
:
490 paragraph
.setSubparagraphs(self
.color_paragraphs(paragraph
.getSubparagraphs()))
493 new_paragraphs
=ST
.StructuredTextParagraph(paragraph
.getColorizableTexts()[0],
494 self
.color_paragraphs(paragraph
.getSubparagraphs()),
495 indent
=paragraph
.indent
),
497 # color the inline StructuredText types
498 # for each StructuredTextParagraph
499 for paragraph
in new_paragraphs
:
501 if paragraph
.getNodeName() is "StructuredTextTable":
502 cells
= paragraph
.getColumns()
503 text
= paragraph
.getColorizableTexts()
504 text
= map(ST
.StructuredText
,text
)
505 text
= map(self
.__call
__,text
)
506 for t
in range(len(text
)):
507 text
[t
] = text
[t
].getSubparagraphs()
508 paragraph
.setColorizableTexts(text
)
510 paragraph
.setColorizableTexts(
512 paragraph
.getColorizableTexts()
514 result
.append(paragraph
)
518 def doc_table(self
, paragraph
, expr
= re
.compile(r
'\s*\|[-]+\|').match
):
519 text
= paragraph
.getColorizableTexts()[0]
522 subs
= paragraph
.getSubparagraphs()
534 TDdivider
= re
.compile("[\-]+").match
535 THdivider
= re
.compile("[\=]+").match
536 col
= re
.compile('\|').search
537 innertable
= re
.compile('\|([-]+|[=]+)\|').search
540 rows
= split(text
,'\n')
543 for row
in range(len(rows
)):
544 rows
[row
] = strip(rows
[row
])
546 # have indexes store if a row is a divider
548 for index
in range(len(rows
)):
549 tmpstr
= rows
[index
][1:len(rows
[index
])-1]
550 if TDdivider(tmpstr
):
551 indexes
.append("TDdivider")
552 elif THdivider(tmpstr
):
553 indexes
.append("THdivider")
555 indexes
.append("cell")
557 for index
in range(len(indexes
)):
558 if indexes
[index
] is "TDdivider" or indexes
[index
] is THdivider
:
559 ignore
= [] # reset ignore
560 #continue # skip dividers
562 tmp
= strip(rows
[index
]) # clean the row up
563 tmp
= tmp
[1:len(tmp
)-1] # remove leading + trailing |
566 # find the start and end of inner
567 # tables. ignore everything between
570 while innertable(tmpstr
):
571 start
,end
= innertable(tmpstr
).span()
572 if not (start
,end
-1) in ignore
:
573 ignore
.append(start
,end
-1)
574 tmpstr
= " " + tmpstr
[end
:]
576 # find the location of column dividers
577 # NOTE: |'s in inner tables do not count
581 bar
= 1 # true if start is not in ignore
582 start
,end
= col(tmp
).span()
584 if not start
+offset
in spans
:
586 if start
+offset
>= s
or start
+offset
<= e
:
589 if bar
: # start is clean
590 spans
.append(start
+offset
)
592 foo
= foo
+ tmp
[:end
]
594 offset
= offset
+ end
596 COLS
.append((foo
+ tmp
[0:start
],start
+offset
))
598 tmp
= " " + tmp
[end
:]
599 offset
= offset
+ start
600 if not offset
+len(tmp
) in spans
:
601 spans
.append(offset
+len(tmp
))
602 COLS
.append((foo
+ tmp
,offset
+len(tmp
)))
608 ROWS
= ROWS
[1:len(ROWS
)]
610 # find each column span
633 for index
in range(len(C
)):
634 for i
in range(len(C
[index
])):
635 ROWS
[index
][i
] = (ROWS
[index
][i
][0],C
[index
][i
])
638 # label things as either TableData or
643 for index
in range(len(indexes
)):
644 if indexes
[index
] is "TDdivider":
647 if indexes
[index
] is "THdivider":
654 #print "all => ", all, "\n"
658 index
= all
.index(div
)
659 for rowindex
in range(all
[index
-1],all
[index
]):
660 for i
in range(len(rows
[rowindex
])):
661 rows
[rowindex
][i
] = (rows
[rowindex
][i
][0],
662 rows
[rowindex
][i
][1],
665 index
= all
.index(div
)
666 for rowindex
in range(all
[index
-1],all
[index
]):
667 for i
in range(len(rows
[rowindex
])):
668 rows
[rowindex
][i
] = (rows
[rowindex
][i
][0],
669 rows
[rowindex
][i
][1],
672 # now munge the multi-line cells together
677 for index
in range(len(row
)):
679 COLS
= range(len(row
))
680 for i
in range(len(COLS
)):
682 if TDdivider(row
[index
][0]) or THdivider(row
[index
][0]):
686 COLS
[index
][0] = COLS
[index
][0] + (row
[index
][0]) + "\n"
687 COLS
[index
][1] = row
[index
][1]
688 COLS
[index
][2] = row
[index
][2]
690 # now that each cell has been munged together,
691 # determine the cell's alignment.
692 # Default is to center. Also determine the cell's
693 # vertical alignment, top, middle, bottom. Default is
698 for index
in range(len(row
)):
706 text
= split(text
,'\n')
707 text
= text
[:len(text
)-1]
713 topindent
= topindent
+ 1
720 bottomindent
= bottomindent
+ 1
724 tmp
= join(text
[topindent
:len(text
)-bottomindent
],"\n")
725 pars
= re
.compile("\n\s*\n").split(tmp
)
729 par
= split(par
, ' ')
732 leftindent
= leftindent
+1
735 left
.append(leftindent
)
740 rightindent
= rightindent
+ 1
743 right
.append(rightindent
)
748 if topindent
== bottomindent
:
752 elif bottomindent
< 1:
761 elif left
[0] > 1 and right
[0] > 1:
766 cols
.append(row
[index
][0],row
[index
][1],align
,valign
,row
[index
][2])
769 return StructuredTextTable(rows
,text
,subs
,indent
=paragraph
.indent
)
771 def doc_bullet(self
, paragraph
, expr
= re
.compile(r
'\s*[-*o]\s+').match
):
772 top
=paragraph
.getColorizableTexts()[0]
778 subs
=paragraph
.getSubparagraphs()
780 subs
=[StructuredTextExample(subs
)]
782 return StructuredTextBullet(top
[m
.span()[1]:], subs
,
783 indent
=paragraph
.indent
,
784 bullet
=top
[:m
.span()[1]]
789 expr
= re
.compile(r
'(\s*[%s]+\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)' % letters
).match
):
791 # This is the old expression. It had a nasty habit
792 # of grabbing paragraphs that began with a single
793 # letter word even if there was no following period.
795 #expr = re.compile('\s*'
796 # '(([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.)*'
797 # '([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.?'
800 top
=paragraph
.getColorizableTexts()[0]
802 if not m
: return None
803 subs
=paragraph
.getSubparagraphs()
805 subs
=[StructuredTextExample(subs
)]
807 return StructuredTextNumbered(top
[m
.span()[1]:], subs
,
808 indent
=paragraph
.indent
,
809 number
=top
[:m
.span()[1]])
813 delim
= re
.compile(r
'\s+--\s+').search
,
814 nb
=re
.compile(r
'[^\000- ]').search
,
817 top
=paragraph
.getColorizableTexts()[0]
819 if not d
: return None
820 start
, end
= d
.span()
822 if find(title
, '\n') >= 0: return None
823 if not nb(title
): return None
827 subs
=paragraph
.getSubparagraphs()
829 subs
=[StructuredTextExample(subs
)]
832 return StructuredTextDescription(
834 indent
=paragraph
.indent
,
837 def doc_header(self
, paragraph
,
838 expr
= re
.compile(r
'[ %s0-9.:/,-_*<>\?\'\"]+' % letters).match
840 subs=paragraph.getSubparagraphs()
841 if not subs: return None
842 top=paragraph.getColorizableTexts()[0]
843 if not strip(top): return None
845 subs=StructuredTextExample(subs)
846 if strip(top)=='::': return subs
847 return ST.StructuredTextParagraph(
848 top[:-1], [subs], indent=paragraph.indent)
850 if find(top,'\n') >= 0: return None
851 return StructuredTextSection(top, subs, indent=paragraph.indent)
857 r"([^
\t\n\r\f\v']|[^ \t\n\r\f\v'][^
\n']*[^ \t\n\r\f\v'])" # contents
858 r"'(?:\s|[,.;:!?]|$)" # close
863 start, end = r.span(1)
864 return (StructuredTextLiteral(s[start:end]), start-1, end+1)
870 expr = re.compile(r'\s
*\
*([ \n%s0-9]+)\
*(?
!\
*|
-)' % lettpunc).search
875 start, end = r.span(1)
876 return (StructuredTextEmphasis(s[start:end]), start-1, end+1)
880 def doc_inner_link(self,
882 expr1 = re.compile(r"\.\.\s*").search,
883 expr2 = re.compile(r"\[[%s0-9]+\]" % letters ).search):
885 # make sure we dont grab a named link
886 if expr2(s) and expr1(s):
887 start1,end1 = expr1(s).span()
888 start2,end2 = expr2(s).span()
890 # uh-oh, looks like a named link
893 # the .. is somewhere else, ignore it
894 return (StructuredTextInnerLink(s[start2+1,end2-1],start2,end2))
896 elif expr2(s) and not expr1(s):
897 start,end = expr2(s).span()
898 return (StructuredTextInnerLink(s[start+1:end-1]),start,end)
901 def doc_named_link(self,
903 expr=re.compile(r"(\.\.\s)(\[[%s0-9]+\])" % letters).search):
907 start,end = result.span(2)
909 str = strip(s[a:b]) + s[start:end]
910 st,en = result.span()
911 return (StructuredTextNamedLink(str),st,en)
912 #return (StructuredTextNamedLink(s[st:en]),st,en)
915 def doc_underline(self,
917 expr=re.compile(r"\s+\_([%s0-9\s]+)\_" % lettpunc).search):
921 start,end = result.span(1)
923 return (StructuredTextUnderline(s[start:end]),st,e)
929 expr = re.compile(r'\s
*\
*\
*([ \n%s0-9]+)\
*\
*' % lettpunc).search
934 start, end = r.span(1)
935 return (StructuredTextStrong(s[start:end]), start-2, end+2)
939 ## Some constants to make the doc_href() regex easier to read.
940 _DQUOTEDTEXT = r'("[%s0-9\n\-\.\,\;\(\)\/\:\/\*\']+")' % letters ## double quoted text
941 _URL_AND_PUNC = r'([%s0-9\
@\
.\
,\?\
!\
/\
:\
;\
-\
#\~]+)' % letters
944 def doc_href(self
, s
,
945 expr1
= re
.compile(_DQUOTEDTEXT
+ "(:)" + _URL_AND_PUNC
+ _SPACES
).search
,
946 expr2
= re
.compile(_DQUOTEDTEXT
+ r
'(\,\s+)' + _URL_AND_PUNC
+ _SPACES
).search
):
948 punctuation
= re
.compile(r
"[\,\.\?\!\;]+").match
949 r
=expr1(s
) or expr2(s
)
952 # need to grab the href part and the
957 name
= replace(name
,'"','',2)
960 if punctuation(s
[end
-1:end
]):
965 # name is the href title, link is the target
967 return (StructuredTextLink(name
, href
=link
),
970 #return (StructuredTextLink(s[start:end], href=s[start:end]),
975 def doc_sgml(self
,s
,expr
=re
.compile(r
"\<[%s0-9\.\=\'\"\
:\
/\
-\
#\+\s\*]+\>" % letters).search):
977 SGML text is ignored and outputed as-is
983 return (StructuredTextSGML(text
),start
,end
)
986 def doc_xref(self
, s
,
987 expr
= re
.compile('\[([%s0-9\-.:/;,\n\~]+)\]' % letters
).search
991 start
, end
= r
.span(1)
992 return (StructuredTextXref(s
[start
:end
]), start
-1, end
+1)