Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
5d3f14c3
Commit
5d3f14c3
authored
Jan 04, 2001
by
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merged StructuredText-Dev
parent
1a7fdfd5
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
3917 additions
and
27 deletions
+3917
-27
lib/python/StructuredText/ClassicDocumentClass.py
lib/python/StructuredText/ClassicDocumentClass.py
+689
-0
lib/python/StructuredText/DocBookClass.py
lib/python/StructuredText/DocBookClass.py
+325
-0
lib/python/StructuredText/DocumentClass.py
lib/python/StructuredText/DocumentClass.py
+777
-0
lib/python/StructuredText/DocumentWithImages.py
lib/python/StructuredText/DocumentWithImages.py
+134
-0
lib/python/StructuredText/HTMLClass.py
lib/python/StructuredText/HTMLClass.py
+308
-0
lib/python/StructuredText/HTMLWithImages.py
lib/python/StructuredText/HTMLWithImages.py
+133
-0
lib/python/StructuredText/ST.py
lib/python/StructuredText/ST.py
+278
-0
lib/python/StructuredText/STDOM.py
lib/python/StructuredText/STDOM.py
+736
-0
lib/python/StructuredText/STNG.txt
lib/python/StructuredText/STNG.txt
+116
-0
lib/python/StructuredText/StructuredText.py
lib/python/StructuredText/StructuredText.py
+4
-1
lib/python/StructuredText/Zwiki.py
lib/python/StructuredText/Zwiki.py
+158
-0
lib/python/StructuredText/__init__.py
lib/python/StructuredText/__init__.py
+27
-0
lib/python/StructuredText/regressions/examples.stx
lib/python/StructuredText/regressions/examples.stx
+17
-0
lib/python/StructuredText/regressions/regress
lib/python/StructuredText/regressions/regress
+0
-26
lib/python/StructuredText/ts_regex.py
lib/python/StructuredText/ts_regex.py
+215
-0
No files found.
lib/python/StructuredText/ClassicDocumentClass.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
import
re
,
ST
,
STDOM
from
string
import
split
,
join
,
replace
,
expandtabs
,
strip
,
find
StringType
=
type
(
''
)
ListType
=
type
([])
class
StructuredTextExample
(
ST
.
StructuredTextParagraph
):
"""Represents a section of document with literal text, as for examples"""
def
__init__
(
self
,
subs
,
**
kw
):
t
=
[];
a
=
t
.
append
for
s
in
subs
:
a
(
s
.
getNodeValue
())
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
join
(
t
,
'
\
n
\
n
'
),
()),
kw
)
def
getColorizableTexts
(
self
):
return
()
def
setColorizableTexts
(
self
,
src
):
pass
# never color examples
class
StructuredTextBullet
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextNumbered
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescriptionTitle
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescriptionBody
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescription
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
def
__init__
(
self
,
title
,
src
,
subs
,
**
kw
):
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
src
,
subs
),
kw
)
self
.
_title
=
title
def
getColorizableTexts
(
self
):
return
self
.
_title
,
self
.
_src
def
setColorizableTexts
(
self
,
src
):
self
.
_title
,
self
.
_src
=
src
def
getChildren
(
self
):
return
(
StructuredTextDescriptionTitle
(
self
.
_title
),
StructuredTextDescriptionBody
(
self
.
_src
,
self
.
_subs
))
class
StructuredTextSectionTitle
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextSection
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
def
__init__
(
self
,
src
,
subs
=
None
,
**
kw
):
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
StructuredTextSectionTitle
(
src
),
subs
),
kw
)
# a StructuredTextTable holds StructuredTextRows
class
StructuredTextTable
(
ST
.
StructuredTextDocument
):
"""
rows is a list of lists containing tuples, which
represent the columns/cells in each rows.
EX
rows = [[('row 1:column1',1)],[('row2:column1',1)]]
"""
def
__init__
(
self
,
rows
,
src
,
subs
,
**
kw
):
apply
(
ST
.
StructuredTextDocument
.
__init__
,(
self
,
subs
),
kw
)
self
.
_rows
=
[]
for
row
in
rows
:
if
row
:
self
.
_rows
.
append
(
StructuredTextRow
(
row
,
kw
))
def
getRows
(
self
):
return
[
self
.
_rows
]
def
_getRows
(
self
):
return
self
.
getRows
()
def
getColorizableTexts
(
self
):
"""
return a tuple where each item is a column/cell's
contents. The tuple, result, will be of this format.
("r1 col1", "r1=col2", "r2 col1", "r2 col2")
"""
#result = ()
result
=
[]
for
row
in
self
.
_rows
:
for
column
in
row
.
getColumns
()[
0
]:
#result = result[:] + (column.getColorizableTexts(),)
result
.
append
(
column
.
getColorizableTexts
()[
0
])
return
result
def
setColorizableTexts
(
self
,
texts
):
"""
texts is going to a tuple where each item is the
result of being mapped to the colortext function.
Need to insert the results appropriately into the
individual columns/cells
"""
for
row_index
in
range
(
len
(
self
.
_rows
)):
for
column_index
in
range
(
len
(
self
.
_rows
[
row_index
].
_columns
)):
self
.
_rows
[
row_index
].
_columns
[
column_index
].
setColorizableTexts
((
texts
[
0
],))
texts
=
texts
[
1
:]
def
_getColorizableTexts
(
self
):
return
self
.
getColorizableTexts
()
def
_setColorizableTexts
(
self
):
return
self
.
setColorizableTexts
()
# StructuredTextRow holds StructuredTextColumns
class
StructuredTextRow
(
ST
.
StructuredTextDocument
):
def
__init__
(
self
,
row
,
kw
):
"""
row is a list of tuples, where each tuple is
the raw text for a cell/column and the span
of that cell/column".
EX
[('this is column one',1), ('this is column two',1)]
"""
apply
(
ST
.
StructuredTextDocument
.
__init__
,(
self
,[]),
kw
)
self
.
_columns
=
[]
for
column
in
row
:
self
.
_columns
.
append
(
StructuredTextColumn
(
column
[
0
],
column
[
1
],
kw
))
def
getColumns
(
self
):
return
[
self
.
_columns
]
def
_getColumns
(
self
):
return
[
self
.
_columns
]
# this holds the raw text of a table cell
class
StructuredTextColumn
(
ST
.
StructuredTextParagraph
):
"""
StructuredTextColumn is a cell/column in a table.
This contains the actual text of a column and is
thus a StructuredTextParagraph. A StructuredTextColumn
also holds the span of its column
"""
def
__init__
(
self
,
text
,
span
,
kw
):
apply
(
ST
.
StructuredTextParagraph
.
__init__
,(
self
,
text
,[]),
kw
)
self
.
_span
=
span
def
getSpan
(
self
):
return
self
.
_span
def
_getSpan
(
self
):
return
self
.
_span
class
StructuredTextMarkup
(
STDOM
.
Element
):
def
__init__
(
self
,
v
,
**
kw
):
self
.
_value
=
v
self
.
_attributes
=
kw
.
keys
()
for
k
,
v
in
kw
.
items
():
setattr
(
self
,
k
,
v
)
def
getChildren
(
self
,
type
=
type
,
lt
=
type
([])):
v
=
self
.
_value
if
type
(
v
)
is
not
lt
:
v
=
[
v
]
return
v
def
getColorizableTexts
(
self
):
return
self
.
_value
,
def
setColorizableTexts
(
self
,
v
):
self
.
_value
=
v
[
0
]
def
__repr__
(
self
):
return
'%s(%s)'
%
(
self
.
__class__
.
__name__
,
`self._value`
)
class
StructuredTextLiteral
(
StructuredTextMarkup
):
def
getColorizableTexts
(
self
):
return
()
def
setColorizableTexts
(
self
,
v
):
pass
class
StructuredTextEmphasis
(
StructuredTextMarkup
):
pass
class
StructuredTextStrong
(
StructuredTextMarkup
):
pass
class
StructuredTextInnerLink
(
StructuredTextMarkup
):
pass
class
StructuredTextNamedLink
(
StructuredTextMarkup
):
pass
class
StructuredTextUnderline
(
StructuredTextMarkup
):
pass
class
StructuredTextLink
(
StructuredTextMarkup
):
"A simple hyperlink"
class
DocumentClass
:
"""
Class instance calls [ex.=> x()] require a structured text
structure. Doc will then parse each paragraph in the structure
and will find the special structures within each paragraph.
Each special structure will be stored as an instance. Special
structures within another special structure are stored within
the 'top' structure
EX : '-underline this-' => would be turned into an underline
instance. '-underline **this**' would be stored as an underline
instance with a strong instance stored in its string
"""
paragraph_types
=
[
'doc_bullet'
,
'doc_numbered'
,
'doc_description'
,
'doc_header'
,
'doc_table'
,
]
text_types
=
[
'doc_href'
,
'doc_strong'
,
'doc_emphasize'
,
'doc_literal'
,
'doc_inner_link'
,
'doc_named_link'
,
'doc_underline'
,
]
def
__call__
(
self
,
doc
):
if
type
(
doc
)
is
type
(
''
):
doc
=
ST
.
StructuredText
(
doc
)
doc
.
setSubparagraphs
(
self
.
color_paragraphs
(
doc
.
getSubparagraphs
()))
else
:
doc
=
ST
.
StructuredTextDocument
(
self
.
color_paragraphs
(
doc
.
getSubparagraphs
()))
return
doc
def
parse
(
self
,
raw_string
,
text_type
,
type
=
type
,
st
=
type
(
''
),
lt
=
type
([])):
"""
Parse accepts a raw_string, an expr to test the raw_string,
and the raw_string's subparagraphs.
Parse will continue to search through raw_string until
all instances of expr in raw_string are found.
If no instances of expr are found, raw_string is returned.
Otherwise a list of substrings and instances is returned
"""
tmp
=
[]
# the list to be returned if raw_string is split
append
=
tmp
.
append
if
type
(
text_type
)
is
st
:
text_type
=
getattr
(
self
,
text_type
)
while
1
:
t
=
text_type
(
raw_string
)
if
not
t
:
break
#an instance of expr was found
t
,
start
,
end
=
t
if
start
:
append
(
raw_string
[
0
:
start
])
tt
=
type
(
t
)
if
tt
is
st
:
# if we get a string back, add it to text to be parsed
raw_string
=
t
+
raw_string
[
end
:
len
(
raw_string
)]
else
:
if
tt
is
lt
:
# is we get a list, append it's elements
tmp
[
len
(
tmp
):]
=
t
else
:
# normal case, an object
append
(
t
)
raw_string
=
raw_string
[
end
:
len
(
raw_string
)]
if
not
tmp
:
return
raw_string
# nothing found
if
raw_string
:
append
(
raw_string
)
elif
len
(
tmp
)
==
1
:
return
tmp
[
0
]
return
tmp
def
color_text
(
self
,
str
,
types
=
None
):
"""Search the paragraph for each special structure
"""
if
types
is
None
:
types
=
self
.
text_types
for
text_type
in
types
:
if
type
(
str
)
is
StringType
:
str
=
self
.
parse
(
str
,
text_type
)
elif
type
(
str
)
is
ListType
:
r
=
[];
a
=
r
.
append
for
s
in
str
:
if
type
(
s
)
is
StringType
:
s
=
self
.
parse
(
s
,
text_type
)
if
type
(
s
)
is
ListType
:
r
[
len
(
r
):]
=
s
else
:
a
(
s
)
else
:
s
.
setColorizableTexts
(
map
(
self
.
color_text
,
s
.
getColorizableTexts
()
))
a
(
s
)
str
=
r
else
:
r
=
[];
a
=
r
.
append
;
color
=
self
.
color_text
for
s
in
str
.
getColorizableTexts
():
color
(
s
,
(
text_type
,))
a
(
s
)
str
.
setColorizableTexts
(
r
)
return
str
def
color_paragraphs
(
self
,
raw_paragraphs
,
type
=
type
,
sequence_types
=
(
type
([]),
type
(())),
st
=
type
(
''
)):
result
=
[]
for
paragraph
in
raw_paragraphs
:
if
paragraph
.
getNodeName
()
!=
'StructuredTextParagraph'
:
result
.
append
(
paragraph
)
continue
for
pt
in
self
.
paragraph_types
:
if
type
(
pt
)
is
st
:
# grab the corresponding function
pt
=
getattr
(
self
,
pt
)
# evaluate the paragraph
r
=
pt
(
paragraph
)
if
r
:
if
type
(
r
)
not
in
sequence_types
:
r
=
r
,
new_paragraphs
=
r
for
paragraph
in
new_paragraphs
:
paragraph
.
setSubparagraphs
(
self
.
color_paragraphs
(
paragraph
.
getSubparagraphs
()))
break
else
:
new_paragraphs
=
ST
.
StructuredTextParagraph
(
paragraph
.
getColorizableTexts
()[
0
],
self
.
color_paragraphs
(
paragraph
.
getSubparagraphs
()),
indent
=
paragraph
.
indent
),
# color the inline StructuredText types
# for each StructuredTextParagraph
for
paragraph
in
new_paragraphs
:
paragraph
.
setColorizableTexts
(
map
(
self
.
color_text
,
paragraph
.
getColorizableTexts
()
))
result
.
append
(
paragraph
)
return
result
def
doc_table
(
self
,
paragraph
,
expr
=
re
.
compile
(
'(
\
s*)([||]+)
'
).match):
text = paragraph.getColorizableTexts()[0]
m = expr(text)
if not (m):
return None
rows = []
# initial split
for row in split(text,"
\
n
"):
rows.append(row)
# clean up the rows
for index in range(len(rows)):
tmp = []
rows[index] = strip(rows[index])
l = len(rows[index])-2
result = split(rows[index][:l],"||")
for text in result:
if text:
tmp.append(text)
tmp.append('')
else:
tmp.append(text)
rows[index] = tmp
# remove trailing '''s
for index in range(len(rows)):
l = len(rows[index])-1
rows[index] = rows[index][:l]
result = []
for row in rows:
cspan = 0
tmp = []
for item in row:
if item:
tmp.append(item,cspan)
cspan = 0
else:
cspan = cspan + 1
result.append(tmp)
subs = paragraph.getSubparagraphs()
indent=paragraph.indent
return StructuredTextTable(result,text,subs,indent=paragraph.indent)
def doc_bullet(self, paragraph, expr = re.compile('
\
s
*
[
-*
o
]
\
s
+
').match):
top=paragraph.getColorizableTexts()[0]
m=expr(top)
if not m:
return None
subs=paragraph.getSubparagraphs()
if top[-2:]=='
::
':
subs=[StructuredTextExample(subs)]
top=top[:-1]
return StructuredTextBullet(top[m.span()[1]:], subs,
indent=paragraph.indent,
bullet=top[:m.span()[1]]
)
def doc_numbered(
self, paragraph,
expr = re.compile('
(
\
s
*
[
a
-
zA
-
Z
]
+
\
.)
|
(
\
s
*
[
0
-
9
]
+
\
.)
|
(
\
s
*
[
0
-
9
]
+
\
s
+
)
').match):
# This is the old expression. It had a nasty habit
# of grabbing paragraphs that began with a single
# letter word even if there was no following period.
#expr = re.compile('
\
s
*
'
# '
(([
a
-
zA
-
Z
]
|
[
0
-
9
]
+|
[
ivxlcdmIVXLCDM
]
+
)
\
.)
*
'
# '
([
a
-
zA
-
Z
]
|
[
0
-
9
]
+|
[
ivxlcdmIVXLCDM
]
+
)
\
.
?
'
# '
\
s
+
').match):
top=paragraph.getColorizableTexts()[0]
m=expr(top)
if not m: return None
subs=paragraph.getSubparagraphs()
if top[-2:]=='
::
':
subs=[StructuredTextExample(subs)]
top=top[:-1]
return StructuredTextNumbered(top[m.span()[1]:], subs,
indent=paragraph.indent,
number=top[:m.span()[1]])
def doc_description(
self, paragraph,
delim = re.compile('
\
s
+--
\
s
+
').search,
nb=re.compile(r'
[
^
\
0
-
]
').search,
):
top=paragraph.getColorizableTexts()[0]
d=delim(top)
if not d: return None
start, end = d.span()
title=top[:start]
if find(title, '
\
n
') >= 0: return None
if not nb(title): return None
d=top[start:end]
top=top[end:]
subs=paragraph.getSubparagraphs()
if top[-2:]=='
::
':
subs=[StructuredTextExample(subs)]
top=top[:-1]
return StructuredTextDescription(
title, top, subs,
indent=paragraph.indent,
delim=d)
def doc_header(self, paragraph,
expr = re.compile('
[
a
-
zA
-
Z0
-
9.
:
/
,
-
_
*<>
\
?
\
'
\
"
]+'
).
match
):
subs
=
paragraph
.
getSubparagraphs
()
if
not
subs
:
return
None
top
=
paragraph
.
getColorizableTexts
()[
0
]
if
not
strip
(
top
):
return
None
if
top
[
-
2
:]
==
'::'
:
subs
=
StructuredTextExample
(
subs
)
if
strip
(
top
)
==
'::'
:
return
subs
return
ST
.
StructuredTextParagraph
(
top
[:
-
1
],
[
subs
],
indent
=
paragraph
.
indent
,
level
=
paragraph
.
level
)
if
find
(
top
,
'
\
n
'
)
>=
0
:
return
None
return
StructuredTextSection
(
top
,
subs
,
indent
=
paragraph
.
indent
,
level
=
paragraph
.
level
)
def
doc_literal
(
self
,
s
,
expr
=
re
.
compile
(
"(?:
\
s|^)
'
"
# open
"([^
\
t
\
n
\
r
\
f
\
v
']|[^
\
t
\
n
\
r
\
f
\
v
'][^
\
n
']*[^
\
t
\
n
\
r
\
f
\
v
'])"
# contents
"'(?:
\
s|[,.;:!?]|$)
"
# close
).search):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextLiteral(s[start:end]), start-1, end+1)
else:
return None
def doc_emphasize(
self, s,
expr = re.compile('
\
s*
\
*([
\
n
a-zA-Z0-9.:/;,
\
'
\
"
\
?]+)
\
*(?!
\
*|-)
'
).search
):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextEmphasis(s[start:end]), start-1, end+1)
else:
return None
def doc_inner_link(self,
s,
expr1 = re.compile("
\
.
\
.
\
s
*
").search,
expr2 = re.compile("
\
[[
a
-
zA
-
Z0
-
9
]
+
\
]
").search):
# make sure we dont grab a named link
if expr2(s) and expr1(s):
start1,end1 = expr1(s).span()
start2,end2 = expr2(s).span()
if end1 == start2:
# uh-oh, looks like a named link
return None
else:
# the .. is somewhere else, ignore it
return (StructuredTextInnerLink(s[start2+1,end2-1],start2,end2))
return None
elif expr2(s) and not expr1(s):
start,end = expr2(s).span()
return (StructuredTextInnerLink(s[start+1:end-1]),start,end)
return None
def doc_named_link(self,
s,
expr=re.compile("
(
\
.
\
.
\
s
)(
\
[[
a
-
zA
-
Z0
-
9
]
+
\
])
").search):
result = expr(s)
if result:
start,end = result.span(2)
a,b = result.span(1)
str = strip(s[a:b]) + s[start:end]
str = s[start+1:end-1]
st,en = result.span()
return (StructuredTextNamedLink(str),st,en)
#return (StructuredTextNamedLink(s[st:en]),st,en)
return None
def doc_underline(self,
s,
expr=re.compile("
\
_
([
a
-
zA
-
Z0
-
9
\
s
\
.,
\
?
\
/
]
+
)
\
_
").search):
result = expr(s)
if result:
start,end = result.span(1)
st,e = result.span()
return (StructuredTextUnderline(s[start:end]),st,e)
else:
return None
def doc_strong(self,
s,
expr = re.compile('
\
s*
\
*
\
*([
\
na-zA-Z0-9.:/;
\
-,!
\
?
\
'
\
"
]+)
\
*
\
*').search
):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextStrong(s[start:end]), start-2, end+2)
else:
return None
def doc_href(
self, s,
expr1 = re.compile("
(
\
"[ a-zA-Z0-9
\
n
\
-
\
.
\
,
\
;
\
(
\
)
\
/
\
:
\
/]+
\
"
)(:)([
a
-
zA
-
Z0
-
9
\
:
\
/
\
.
\
~
\
-
]
+
)([,]
*
\
s
*
)
").search,
expr2 = re.compile('(
\
"
[ a-zA-Z0-9
\
n
\
-
\
.
\
:
\
;
\
(
\
)
\
/]+
\
"
)([,]
+
\
s
+
)([
a
-
zA
-
Z0
-
9
\
@
\
.
\
,
\
?
\
!
\
/
\
:
\
;
\
-
\
#]+)(\s*)').search):
#expr1=re.compile('\"([ a-zA-Z0-9.:/;,\n\~\(\)\-]+)\"'
# ':'
# '([a-zA-Z0-9.:/;,\n\~]+)(?=(\s+|\.|\!|\?))'
# ).search,
#expr2=re.compile('\"([ a-zA-Z0-9./:]+)\"'
# ',\s+'
# '([ a-zA-Z0-9@.:/;]+)(?=(\s+|\.|\!|\?))'
# ).search,
punctuation
=
re
.
compile
(
"[
\
,
\
.
\
?
\
!
\
;]+
"
).match
r=expr1(s) or expr2(s)
if r:
# need to grab the href part and the
# beginning part
start,e = r.span(1)
name = s[start:e]
name = replace(name,'"','',2)
#start = start + 1
st,end = r.span(3)
if punctuation(s[end-1:end]):
end = end -1
link = s[st:end]
#end = end - 1
# name is the href title, link is the target
# of the href
return (StructuredTextLink(name, href=link),
start, end)
#return (StructuredTextLink(s[start:end], href=s[start:end]),
# start, end)
else:
return None
lib/python/StructuredText/DocBookClass.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
import
string
from
string
import
join
,
split
,
find
,
lstrip
class
DocBookClass
:
element_types
=
{
'#text'
:
'_text'
,
'StructuredTextDocument'
:
'document'
,
'StructuredTextParagraph'
:
'paragraph'
,
'StructuredTextExample'
:
'example'
,
'StructuredTextBullet'
:
'bullet'
,
'StructuredTextNumbered'
:
'numbered'
,
'StructuredTextDescription'
:
'description'
,
'StructuredTextDescriptionTitle'
:
'descriptionTitle'
,
'StructuredTextDescriptionBody'
:
'descriptionBody'
,
'StructuredTextSection'
:
'section'
,
'StructuredTextSectionTitle'
:
'sectionTitle'
,
'StructuredTextLiteral'
:
'literal'
,
'StructuredTextEmphasis'
:
'emphasis'
,
'StructuredTextStrong'
:
'strong'
,
'StructuredTextLink'
:
'link'
,
'StructuredTextXref'
:
'xref'
,
}
def
dispatch
(
self
,
doc
,
level
,
output
):
getattr
(
self
,
self
.
element_types
[
doc
.
getNodeName
()])(
doc
,
level
,
output
)
def
__call__
(
self
,
doc
,
level
=
1
):
r
=
[]
self
.
dispatch
(
doc
,
level
-
1
,
r
.
append
)
return
join
(
r
,
''
)
def
_text
(
self
,
doc
,
level
,
output
):
if
doc
.
getNodeName
()
==
'StructuredTextLiteral'
:
output
(
doc
.
getNodeValue
())
else
:
output
(
lstrip
(
doc
.
getNodeValue
()))
def
document
(
self
,
doc
,
level
,
output
):
output
(
'<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
\
n
'
)
output
(
'<book>
\
n
'
)
children
=
doc
.
getChildNodes
()
if
(
children
and
children
[
0
].
getNodeName
()
==
'StructuredTextSection'
):
output
(
'<title>%s</title>'
%
children
[
0
].
getChildNodes
()[
0
].
getNodeValue
())
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</book>
\
n
'
)
def
section
(
self
,
doc
,
level
,
output
):
output
(
'
\
n
<sect%s>
\
n
'
%
(
level
+
1
))
children
=
doc
.
getChildNodes
()
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
+
1
,
output
)
output
(
'
\
n
</sect%s>
\
n
'
%
(
level
+
1
))
def
sectionTitle
(
self
,
doc
,
level
,
output
):
output
(
'<title>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</title>
\
n
'
)
def
description
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<variablelist>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</variablelist>
\
n
'
)
def
descriptionTitle
(
self
,
doc
,
level
,
output
):
output
(
'<varlistentry><term>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</term>
\
n
'
)
def
descriptionBody
(
self
,
doc
,
level
,
output
):
output
(
'<listitem><para>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</para></listitem>
\
n
'
)
output
(
'</varlistentry>
\
n
'
)
def
bullet
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<itemizedlist>
\
n
'
)
output
(
'<listitem><para>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
output
(
'</para></listitem>
\
n
'
)
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</itemizedlist>
\
n
'
)
def
numbered
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<orderedlist>
\
n
'
)
output
(
'<listitem><para>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
output
(
'</para></listitem>
\
n
'
)
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</orderedlist>
\
n
'
)
def
example
(
self
,
doc
,
level
,
output
):
i
=
0
for
c
in
doc
.
getChildNodes
():
if
i
==
0
:
output
(
'<programlisting>
\
n
<![CDATA[
\
n
'
)
##
## eek. A ']]>' in your body will break this...
##
output
(
prestrip
(
c
.
getNodeValue
()))
output
(
'
\
n
]]></programlisting>
\
n
'
)
else
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
def
paragraph
(
self
,
doc
,
level
,
output
):
output
(
'<para>
\
n
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</para>
\
n
\
n
'
)
def
link
(
self
,
doc
,
level
,
output
):
# output('<link linkend="%s">' % doc.href)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
# output('</link>')
def
emphasis
(
self
,
doc
,
level
,
output
):
output
(
'<emphasis>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</emphasis> '
)
def
literal
(
self
,
doc
,
level
,
output
):
output
(
'<literal>'
)
for
c
in
doc
.
getChildNodes
():
output
(
c
.
getNodeValue
())
output
(
'</literal>'
)
def
strong
(
self
,
doc
,
level
,
output
):
output
(
'<emphasis>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</emphasis>'
)
def
xref
(
self
,
doc
,
level
,
output
):
output
(
'<xref linkend="%s">'
%
doc
.
getNodeValue
())
def
prestrip
(
v
):
v
=
string
.
replace
(
v
,
'
\
r
\
n
'
,
'
\
n
'
)
v
=
string
.
replace
(
v
,
'
\
r
'
,
'
\
n
'
)
v
=
string
.
replace
(
v
,
'
\
t
'
,
' '
)
lines
=
string
.
split
(
v
,
'
\
n
'
)
indent
=
len
(
lines
[
0
])
for
line
in
lines
:
if
not
len
(
line
):
continue
i
=
len
(
line
)
-
len
(
string
.
lstrip
(
line
))
if
i
<
indent
:
indent
=
i
nlines
=
[]
for
line
in
lines
:
nlines
.
append
(
line
[
indent
:])
return
string
.
join
(
nlines
,
'
\
r
\
n
'
)
class
DocBookChapter
(
DocBookClass
):
def
document
(
self
,
doc
,
level
,
output
):
output
(
'<chapter>
\
n
'
)
children
=
doc
.
getChildNodes
()
if
(
children
and
children
[
0
].
getNodeName
()
==
'StructuredTextSection'
):
output
(
'<title>%s</title>'
%
children
[
0
].
getChildNodes
()[
0
].
getNodeValue
())
for
c
in
children
[
0
].
getChildNodes
()[
1
:]:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</chapter>
\
n
'
)
ets
=
DocBookClass
.
element_types
ets
.
update
({
'StructuredTextImage'
:
'image'
})
class
DocBookChapterWithFigures
(
DocBookChapter
):
element_types
=
ets
def
image
(
self
,
doc
,
level
,
output
):
if
hasattr
(
doc
,
'key'
):
output
(
'<figure id="%s"><title>%s</title>
\
n
'
%
(
doc
.
key
,
doc
.
getNodeValue
())
)
else
:
output
(
'<figure><title>%s</title>
\
n
'
%
doc
.
getNodeValue
())
## for c in doc.getChildNodes():
## getattr(self, self.element_types[c.getNodeName()])(c, level, output)
output
(
'<graphic fileref="%s"></graphic>
\
n
</figure>
\
n
'
%
doc
.
href
)
class
DocBookArticle
(
DocBookClass
):
def
document
(
self
,
doc
,
level
,
output
):
output
(
'<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
\
n
'
)
output
(
'<article>
\
n
'
)
children
=
doc
.
getChildNodes
()
if
(
children
and
children
[
0
].
getNodeName
()
==
'StructuredTextSection'
):
output
(
'<artheader>
\
n
<title>%s</title>
\
n
</artheader>
\
n
'
%
children
[
0
].
getChildNodes
()[
0
].
getNodeValue
())
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</article>
\
n
'
)
class
DocBookBook
:
def
__init__
(
self
,
title
=
''
):
self
.
title
=
title
self
.
chapters
=
[]
def
addChapter
(
self
,
chapter
):
self
.
chapters
.
append
(
chapter
)
def
read
(
self
):
out
=
'<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
\
n
<book>
\
n
'
out
=
out
+
'<title>%s</title>
\
n
'
%
self
.
title
for
chapter
in
self
.
chapters
:
out
=
out
+
chapter
+
'
\
n
</book>
\
n
'
return
out
def
__str__
(
self
):
return
self
.
read
()
lib/python/StructuredText/DocumentClass.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
import
re
,
ST
,
STDOM
from
string
import
split
,
join
,
replace
,
expandtabs
,
strip
,
find
,
rstrip
StringType
=
type
(
''
)
ListType
=
type
([])
class
StructuredTextExample
(
ST
.
StructuredTextParagraph
):
"""Represents a section of document with literal text, as for examples"""
def
__init__
(
self
,
subs
,
**
kw
):
t
=
[];
a
=
t
.
append
for
s
in
subs
:
a
(
s
.
getNodeValue
())
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
join
(
t
,
'
\
n
\
n
'
),
()),
kw
)
def
getColorizableTexts
(
self
):
return
()
def
setColorizableTexts
(
self
,
src
):
pass
# never color examples
class
StructuredTextBullet
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextNumbered
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescriptionTitle
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescriptionBody
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextDescription
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
def
__init__
(
self
,
title
,
src
,
subs
,
**
kw
):
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
src
,
subs
),
kw
)
self
.
_title
=
title
def
getColorizableTexts
(
self
):
return
self
.
_title
,
self
.
_src
def
setColorizableTexts
(
self
,
src
):
self
.
_title
,
self
.
_src
=
src
def
getChildren
(
self
):
return
(
StructuredTextDescriptionTitle
(
self
.
_title
),
StructuredTextDescriptionBody
(
self
.
_src
,
self
.
_subs
))
class
StructuredTextSectionTitle
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
class
StructuredTextSection
(
ST
.
StructuredTextParagraph
):
"""Represents a section of a document with a title and a body"""
def
__init__
(
self
,
src
,
subs
=
None
,
**
kw
):
apply
(
ST
.
StructuredTextParagraph
.
__init__
,
(
self
,
StructuredTextSectionTitle
(
src
),
subs
),
kw
)
# a StructuredTextTable holds StructuredTextRows
class
StructuredTextTable
(
ST
.
StructuredTextDocument
):
"""
rows is a list of lists containing tuples, which
represent the columns/cells in each rows.
EX
rows = [[('row 1:column1',1)],[('row2:column1',1)]]
"""
def
__init__
(
self
,
rows
,
src
,
subs
,
**
kw
):
apply
(
ST
.
StructuredTextDocument
.
__init__
,(
self
,
subs
),
kw
)
self
.
_rows
=
[]
for
row
in
rows
:
if
row
:
self
.
_rows
.
append
(
StructuredTextRow
(
row
,
kw
))
def
getRows
(
self
):
return
[
self
.
_rows
]
def
_getRows
(
self
):
return
self
.
getRows
()
def
getColumns
(
self
):
result
=
[]
for
row
in
self
.
_rows
:
result
.
append
(
row
.
getColumns
())
return
result
def
_getColumns
(
self
):
return
self
.
getColumns
()
def
setColumns
(
self
,
columns
):
for
index
in
range
(
len
(
self
.
_rows
)):
self
.
_rows
[
index
].
setColumns
(
columns
[
index
])
def
_setColumns
(
self
,
columns
):
return
self
.
setColumns
(
columns
)
def
getColorizableTexts
(
self
):
"""
return a tuple where each item is a column/cell's
contents. The tuple, result, will be of this format.
("r1 col1", "r1=col2", "r2 col1", "r2 col2")
"""
result
=
[]
for
row
in
self
.
_rows
:
for
column
in
row
.
getColumns
()[
0
]:
result
.
append
(
column
.
getColorizableTexts
()[
0
])
return
result
def
setColorizableTexts
(
self
,
texts
):
"""
texts is going to a tuple where each item is the
result of being mapped to the colortext function.
Need to insert the results appropriately into the
individual columns/cells
"""
for
row_index
in
range
(
len
(
self
.
_rows
)):
for
column_index
in
range
(
len
(
self
.
_rows
[
row_index
].
_columns
)):
self
.
_rows
[
row_index
].
_columns
[
column_index
].
setColorizableTexts
((
texts
[
0
],))
texts
=
texts
[
1
:]
def
_getColorizableTexts
(
self
):
return
self
.
getColorizableTexts
()
def
_setColorizableTexts
(
self
):
return
self
.
setColorizableTexts
()
# StructuredTextRow holds StructuredTextColumns
class
StructuredTextRow
(
ST
.
StructuredTextDocument
):
def
__init__
(
self
,
row
,
kw
):
"""
row is a list of tuples, where each tuple is
the raw text for a cell/column and the span
of that cell/column".
EX
[('this is column one',1), ('this is column two',1)]
"""
apply
(
ST
.
StructuredTextDocument
.
__init__
,(
self
,[]),
kw
)
self
.
_columns
=
[]
for
column
in
row
:
self
.
_columns
.
append
(
StructuredTextColumn
(
column
[
0
],
column
[
1
],
kw
))
def
getColumns
(
self
):
return
[
self
.
_columns
]
def
_getColumns
(
self
):
return
[
self
.
_columns
]
def
setColumns
(
self
,
columns
):
self
.
_columns
=
columns
def
_setColumns
(
self
,
columns
):
return
self
.
setColumns
(
columns
)
# this holds the text of a table cell
class
StructuredTextColumn
(
ST
.
StructuredTextParagraph
):
"""
StructuredTextColumn is a cell/column in a table.
A cell can hold multiple paragraphs. The cell
is either classified as a StructuredTextTableHeader
or StructuredTextTableData.
"""
def
__init__
(
self
,
text
,
span
,
kw
):
# print "StructuredTextColumn", text, span
apply
(
ST
.
StructuredTextParagraph
.
__init__
,(
self
,
text
,[]),
kw
)
self
.
_span
=
span
def
getSpan
(
self
):
return
self
.
_span
def
_getSpan
(
self
):
return
self
.
_span
class
StructuredTextTableHeader
(
ST
.
StructuredTextDocument
):
pass
class
StructuredTextTableData
(
ST
.
StructuredTextDocument
):
pass
class
StructuredTextMarkup
(
STDOM
.
Element
):
def
__init__
(
self
,
v
,
**
kw
):
self
.
_value
=
v
self
.
_attributes
=
kw
.
keys
()
for
k
,
v
in
kw
.
items
():
setattr
(
self
,
k
,
v
)
def
getChildren
(
self
,
type
=
type
,
lt
=
type
([])):
v
=
self
.
_value
if
type
(
v
)
is
not
lt
:
v
=
[
v
]
return
v
def
getColorizableTexts
(
self
):
return
self
.
_value
,
def
setColorizableTexts
(
self
,
v
):
self
.
_value
=
v
[
0
]
def
__repr__
(
self
):
return
'%s(%s)'
%
(
self
.
__class__
.
__name__
,
`self._value`
)
class
StructuredTextLiteral
(
StructuredTextMarkup
):
def
getColorizableTexts
(
self
):
return
()
def
setColorizableTexts
(
self
,
v
):
pass
class
StructuredTextEmphasis
(
StructuredTextMarkup
):
pass
class
StructuredTextStrong
(
StructuredTextMarkup
):
pass
class
StructuredTextInnerLink
(
StructuredTextMarkup
):
pass
class
StructuredTextNamedLink
(
StructuredTextMarkup
):
pass
class
StructuredTextUnderline
(
StructuredTextMarkup
):
pass
class
StructuredTextSGML
(
StructuredTextMarkup
):
pass
class
StructuredTextLink
(
StructuredTextMarkup
):
pass
class
DocumentClass
:
"""
Class instance calls [ex.=> x()] require a structured text
structure. Doc will then parse each paragraph in the structure
and will find the special structures within each paragraph.
Each special structure will be stored as an instance. Special
structures within another special structure are stored within
the 'top' structure
EX : '-underline this-' => would be turned into an underline
instance. '-underline **this**' would be stored as an underline
instance with a strong instance stored in its string
"""
#'doc_table',
paragraph_types
=
[
'doc_bullet'
,
'doc_numbered'
,
'doc_description'
,
'doc_header'
,
'doc_table'
,
]
#'doc_inner_link',
#'doc_named_link',
#'doc_underline',
text_types
=
[
'doc_href'
,
'doc_strong'
,
'doc_emphasize'
,
'doc_literal'
,
'doc_sgml'
]
def
__call__
(
self
,
doc
):
if
type
(
doc
)
is
type
(
''
):
doc
=
ST
.
StructuredText
(
doc
)
doc
.
setSubparagraphs
(
self
.
color_paragraphs
(
doc
.
getSubparagraphs
()))
else
:
doc
=
ST
.
StructuredTextDocument
(
self
.
color_paragraphs
(
doc
.
getSubparagraphs
()))
return
doc
def
parse
(
self
,
raw_string
,
text_type
,
type
=
type
,
st
=
type
(
''
),
lt
=
type
([])):
"""
Parse accepts a raw_string, an expr to test the raw_string,
and the raw_string's subparagraphs.
Parse will continue to search through raw_string until
all instances of expr in raw_string are found.
If no instances of expr are found, raw_string is returned.
Otherwise a list of substrings and instances is returned
"""
tmp
=
[]
# the list to be returned if raw_string is split
append
=
tmp
.
append
if
type
(
text_type
)
is
st
:
text_type
=
getattr
(
self
,
text_type
)
while
1
:
t
=
text_type
(
raw_string
)
if
not
t
:
break
#an instance of expr was found
t
,
start
,
end
=
t
if
start
:
append
(
raw_string
[
0
:
start
])
tt
=
type
(
t
)
if
tt
is
st
:
# if we get a string back, add it to text to be parsed
raw_string
=
t
+
raw_string
[
end
:
len
(
raw_string
)]
else
:
if
tt
is
lt
:
# is we get a list, append it's elements
tmp
[
len
(
tmp
):]
=
t
else
:
# normal case, an object
append
(
t
)
raw_string
=
raw_string
[
end
:
len
(
raw_string
)]
if
not
tmp
:
return
raw_string
# nothing found
if
raw_string
:
append
(
raw_string
)
elif
len
(
tmp
)
==
1
:
return
tmp
[
0
]
return
tmp
def
color_text
(
self
,
str
,
types
=
None
):
"""Search the paragraph for each special structure
"""
if
types
is
None
:
types
=
self
.
text_types
for
text_type
in
types
:
if
type
(
str
)
is
StringType
:
str
=
self
.
parse
(
str
,
text_type
)
elif
type
(
str
)
is
ListType
:
r
=
[];
a
=
r
.
append
for
s
in
str
:
if
type
(
s
)
is
StringType
:
s
=
self
.
parse
(
s
,
text_type
)
if
type
(
s
)
is
ListType
:
r
[
len
(
r
):]
=
s
else
:
a
(
s
)
else
:
s
.
setColorizableTexts
(
map
(
self
.
color_text
,
s
.
getColorizableTexts
()
))
a
(
s
)
str
=
r
else
:
r
=
[];
a
=
r
.
append
;
color
=
self
.
color_text
for
s
in
str
.
getColorizableTexts
():
color
(
s
,
(
text_type
,))
a
(
s
)
str
.
setColorizableTexts
(
r
)
return
str
def
color_paragraphs
(
self
,
raw_paragraphs
,
type
=
type
,
sequence_types
=
(
type
([]),
type
(())),
st
=
type
(
''
)):
result
=
[]
for
paragraph
in
raw_paragraphs
:
#print type(paragraph)
if
paragraph
.
getNodeName
()
!=
'StructuredTextParagraph'
:
result
.
append
(
paragraph
)
continue
for
pt
in
self
.
paragraph_types
:
if
type
(
pt
)
is
st
:
# grab the corresponding function
pt
=
getattr
(
self
,
pt
)
# evaluate the paragraph
r
=
pt
(
paragraph
)
if
r
:
if
type
(
r
)
not
in
sequence_types
:
r
=
r
,
new_paragraphs
=
r
for
paragraph
in
new_paragraphs
:
paragraph
.
setSubparagraphs
(
self
.
color_paragraphs
(
paragraph
.
getSubparagraphs
()))
break
else
:
new_paragraphs
=
ST
.
StructuredTextParagraph
(
paragraph
.
getColorizableTexts
()[
0
],
self
.
color_paragraphs
(
paragraph
.
getSubparagraphs
()),
indent
=
paragraph
.
indent
),
# color the inline StructuredText types
# for each StructuredTextParagraph
for
paragraph
in
new_paragraphs
:
if
paragraph
.
getNodeName
()
is
"StructuredTextTable"
:
#print "we have a table"
cells
=
paragraph
.
getColumns
()
text
=
paragraph
.
getColorizableTexts
()
text
=
map
(
ST
.
StructuredText
,
text
)
text
=
map
(
self
.
__call__
,
text
)
#for index in range(len(text)):
# text[index].setColorizableTexts(map(self.color_text,text[index].getColorizableTexts()))
paragraph
.
setColorizableTexts
(
text
)
paragraph
.
setColorizableTexts
(
map
(
self
.
color_text
,
paragraph
.
getColorizableTexts
()
))
result
.
append
(
paragraph
)
return
result
def
doc_table
(
self
,
paragraph
,
expr
=
re
.
compile
(
'
\
s*
\
|[-]+
\
|
'
).match):
text = paragraph.getColorizableTexts()[0]
m = expr(text)
subs = paragraph.getSubparagraphs()
if not (m):
return None
rows = []
rows = split(text,'
\
n
')
spans = []
ROWS = []
COLS = []
TDdivider = re.compile("[
\
-]+
"
).match
THdivider = re.compile("[
\
=]+
"
).match
# find where the column markers are located
col = re.compile('
\
|
').search
text = strip(text)
rows = split(text,'
\
n
')
for row in range(len(rows)):
rows[row] = strip(rows[row])
for row in rows:
tmp = strip(row)
tmp = row[1:len(tmp)-1] # remove leading and trailing |
offset = 0
if col(tmp):
while col(tmp):
start,end = col(tmp).span()
if not start+offset in spans:
spans.append(start + offset)
COLS.append((tmp[0:start],start+offset))
tmp = " " + tmp[end:]
offset = offset + (start)
if not offset+len(tmp) in spans:
spans.append(offset+len(tmp))
COLS.append((tmp,offset+len(tmp)))
ROWS.append(COLS)
COLS = []
spans.sort()
ROWS = ROWS[1:len(ROWS)]
# find each column span
cols = []
tmp = []
for row in ROWS:
for c in row:
tmp.append(c[1])
cols.append(tmp)
tmp = []
cur = 1 # the current column span
tmp = []
C = [] # holds the span of each cell
for col in cols:
for span in spans:
if not span in col:
cur = cur + 1
else:
tmp.append(cur)
cur = 1
C.append(tmp)
tmp = []
# make rows contain the cell'
s
text
and
the
span
# of that cell
for
index
in
range
(
len
(
C
)):
for
i
in
range
(
len
(
C
[
index
])):
ROWS
[
index
][
i
]
=
(
ROWS
[
index
][
i
][
0
],
C
[
index
][
i
])
rows
=
ROWS
# now munge the table cells together
ROWS
=
[]
COLS
=
[]
for
row
in
rows
:
for
index
in
range
(
len
(
row
)):
if
not
COLS
:
COLS
=
range
(
len
(
row
))
for
i
in
range
(
len
(
COLS
)):
COLS
[
i
]
=
[
""
,
1
]
if
TDdivider
(
row
[
index
][
0
])
or
THdivider
(
row
[
index
][
0
]):
ROWS
.
append
(
COLS
)
COLS
=
[]
else
:
COLS
[
index
][
0
]
=
COLS
[
index
][
0
]
+
rstrip
(
row
[
index
][
0
])
+
"
\
n
"
COLS
[
index
][
1
]
=
row
[
index
][
1
]
return
StructuredTextTable
(
ROWS
,
text
,
subs
,
indent
=
paragraph
.
indent
)
def
doc_bullet
(
self
,
paragraph
,
expr
=
re
.
compile
(
'
\
s*[-*o]
\
s+'
).
match
):
top
=
paragraph
.
getColorizableTexts
()[
0
]
m
=
expr
(
top
)
if
not
m
:
return
None
subs
=
paragraph
.
getSubparagraphs
()
if
top
[
-
2
:]
==
'::'
:
subs
=
[
StructuredTextExample
(
subs
)]
top
=
top
[:
-
1
]
return
StructuredTextBullet
(
top
[
m
.
span
()[
1
]:],
subs
,
indent
=
paragraph
.
indent
,
bullet
=
top
[:
m
.
span
()[
1
]]
)
def
doc_numbered
(
self
,
paragraph
,
expr
=
re
.
compile
(
'(
\
s*[
a
-zA-Z]+
\
.)|(
\
s*[0-9]+
\
.)|(
\
s*[0-9]+
\
s+)
'
).match):
# This is the old expression. It had a nasty habit
# of grabbing paragraphs that began with a single
# letter word even if there was no following period.
#expr = re.compile('
\
s
*
'
# '
(([
a
-
zA
-
Z
]
|
[
0
-
9
]
+|
[
ivxlcdmIVXLCDM
]
+
)
\
.)
*
'
# '
([
a
-
zA
-
Z
]
|
[
0
-
9
]
+|
[
ivxlcdmIVXLCDM
]
+
)
\
.
?
'
# '
\
s
+
').match):
top=paragraph.getColorizableTexts()[0]
m=expr(top)
if not m: return None
subs=paragraph.getSubparagraphs()
if top[-2:]=='
::
':
subs=[StructuredTextExample(subs)]
top=top[:-1]
return StructuredTextNumbered(top[m.span()[1]:], subs,
indent=paragraph.indent,
number=top[:m.span()[1]])
def doc_description(
self, paragraph,
delim = re.compile('
\
s
+--
\
s
+
').search,
nb=re.compile(r'
[
^
\
0
-
]
').search,
):
top=paragraph.getColorizableTexts()[0]
d=delim(top)
if not d: return None
start, end = d.span()
title=top[:start]
if find(title, '
\
n
') >= 0: return None
if not nb(title): return None
d=top[start:end]
top=top[end:]
subs=paragraph.getSubparagraphs()
if top[-2:]=='
::
':
subs=[StructuredTextExample(subs)]
top=top[:-1]
return StructuredTextDescription(
title, top, subs,
indent=paragraph.indent,
delim=d)
def doc_header(self, paragraph,
expr = re.compile('
[
a
-
zA
-
Z0
-
9.
:
/
,
-
_
*<>
\
?
\
'
\
"
]+'
).
match
):
subs
=
paragraph
.
getSubparagraphs
()
if
not
subs
:
return
None
top
=
paragraph
.
getColorizableTexts
()[
0
]
if
not
strip
(
top
):
return
None
if
top
[
-
2
:]
==
'::'
:
subs
=
StructuredTextExample
(
subs
)
if
strip
(
top
)
==
'::'
:
return
subs
return
ST
.
StructuredTextParagraph
(
top
[:
-
1
],
[
subs
],
indent
=
paragraph
.
indent
)
if
find
(
top
,
'
\
n
'
)
>=
0
:
return
None
return
StructuredTextSection
(
top
,
subs
,
indent
=
paragraph
.
indent
)
def
doc_literal
(
self
,
s
,
expr
=
re
.
compile
(
"(?:
\
s|^)
'
"
# open
"([^
\
t
\
n
\
r
\
f
\
v
']|[^
\
t
\
n
\
r
\
f
\
v
'][^
\
n
']*[^
\
t
\
n
\
r
\
f
\
v
'])"
# contents
"'(?:
\
s|[,.;:!?]|$)
"
# close
).search):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextLiteral(s[start:end]), start-1, end+1)
else:
return None
def doc_emphasize(
self, s,
expr = re.compile('
\
s*
\
*([
\
n
a-zA-Z0-9.:/;,
\
'
\
"
\
?]+)
\
*(?!
\
*|-)
'
).search
):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextEmphasis(s[start:end]), start-1, end+1)
else:
return None
def doc_inner_link(self,
s,
expr1 = re.compile("
\
.
\
.
\
s
*
").search,
expr2 = re.compile("
\
[[
a
-
zA
-
Z0
-
9
]
+
\
]
").search):
# make sure we dont grab a named link
if expr2(s) and expr1(s):
start1,end1 = expr1(s).span()
start2,end2 = expr2(s).span()
if end1 == start2:
# uh-oh, looks like a named link
return None
else:
# the .. is somewhere else, ignore it
return (StructuredTextInnerLink(s[start2+1,end2-1],start2,end2))
return None
elif expr2(s) and not expr1(s):
start,end = expr2(s).span()
return (StructuredTextInnerLink(s[start+1:end-1]),start,end)
return None
def doc_named_link(self,
s,
expr=re.compile("
(
\
.
\
.
\
s
)(
\
[[
a
-
zA
-
Z0
-
9
]
+
\
])
").search):
result = expr(s)
if result:
start,end = result.span(2)
a,b = result.span(1)
str = strip(s[a:b]) + s[start:end]
st,en = result.span()
return (StructuredTextNamedLink(str),st,en)
#return (StructuredTextNamedLink(s[st:en]),st,en)
return None
def doc_underline(self,
s,
expr=re.compile("
\
_
([
a
-
zA
-
Z0
-
9
\
s
\
.,
\
?
]
+
)
\
_
").search):
result = expr(s)
if result:
start,end = result.span(1)
st,e = result.span()
return (StructuredTextUnderline(s[start:end]),st,e)
else:
return None
def doc_strong(self,
s,
expr = re.compile('
\
s*
\
*
\
*([
\
na-zA-Z0-9.:/;
\
-,!
\
?
\
'
\
"
]+)
\
*
\
*').search
):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextStrong(s[start:end]), start-2, end+2)
else:
return None
def doc_href(
self, s,
expr1 = re.compile("
(
\
"[ a-zA-Z0-9
\
n
\
-
\
.
\
,
\
;
\
(
\
)
\
/
\
:
\
/]+
\
"
)(:)([
a
-
zA
-
Z0
-
9
\
:
\
/
\
.
\
~
\
-
]
+
)([,]
*
\
s
*
)
").search,
expr2 = re.compile('(
\
"
[ a-zA-Z0-9
\
n
\
-
\
.
\
:
\
;
\
(
\
)
\
/]+
\
"
)([,]
+
\
s
+
)([
a
-
zA
-
Z0
-
9
\
@
\
.
\
,
\
?
\
!
\
/
\
:
\
;
\
-
\
#]+)(\s*)').search):
punctuation
=
re
.
compile
(
"[
\
,
\
.
\
?
\
!
\
;]+
"
).match
r=expr1(s) or expr2(s)
if r:
# need to grab the href part and the
# beginning part
start,e = r.span(1)
name = s[start:e]
name = replace(name,'"','',2)
#start = start + 1
st,end = r.span(3)
if punctuation(s[end-1:end]):
end = end -1
link = s[st:end]
#end = end - 1
# name is the href title, link is the target
# of the href
return (StructuredTextLink(name, href=link),
start, end)
#return (StructuredTextLink(s[start:end], href=s[start:end]),
# start, end)
else:
return None
def doc_sgml(self,s,expr=re.compile("
\
<[
a
-zA-Z0-9
\
.
\
=
\
'
\
"
\
:
\
/
\
-
\
#
\
+
\
s]+
\
>
"
).search):
"""
SGML text is ignored and outputed as-is
"""
r = expr(s)
if r:
start,end = r.span()
text = s[start:end]
return (StructuredTextSGML(text),start,end)
lib/python/StructuredText/DocumentWithImages.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
import
re
,
ST
,
STDOM
from
string
import
split
,
join
,
replace
,
expandtabs
,
strip
,
find
from
DocumentClass
import
*
class
StructuredTextImage
(
StructuredTextMarkup
):
"A simple embedded image"
class
DocumentWithImages
(
DocumentClass
):
"""
"""
text_types
=
[
'doc_img'
,
]
+
DocumentClass
.
text_types
def
doc_img
(
self
,
s
,
expr1
=
re
.
compile
(
'
\
"
([ _a-zA-Z0-9*.:/;,
\
-
\
n
\
~]+)
\
":img:([a-zA-Z0-9
\
-.:/;,
\
n
\
~]+)
'
).search,
expr2=re.compile('
\
"([ _a-zA-Z0-9*.:/;,
\
-
\
n
\
~]+)
\
"
:
img
:([
a
-
zA
-
Z0
-
9
\
-
.:
/
;,
\
n
\
~
]
+
):([
a
-
zA
-
Z0
-
9
\
-
.:
/
;,
\
n
\
~
]
+
)
').search
):
r = expr2(s)
if r:
startt, endt = r.span(1)
startk, endk = r.span(2)
starth, endh = r.span(3)
start, end = r.span()
return (StructuredTextImage(s[startt:endt], href=s[starth:endh], key=s[startk:endk]),
start, end)
else:
r=expr1(s)
if r:
startt, endt = r.span(1)
starth, endh = r.span(2)
start, end = r.span()
return (StructuredTextImage(s[startt:endt], href=s[starth:endh]),
start, end)
return None
lib/python/StructuredText/HTMLClass.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
from
string
import
join
,
split
,
find
import
re
,
sys
,
ST
class
HTMLClass
:
element_types
=
{
'#text'
:
'_text'
,
'StructuredTextDocument'
:
'document'
,
'StructuredTextParagraph'
:
'paragraph'
,
'StructuredTextExample'
:
'example'
,
'StructuredTextBullet'
:
'bullet'
,
'StructuredTextNumbered'
:
'numbered'
,
'StructuredTextDescription'
:
'description'
,
'StructuredTextDescriptionTitle'
:
'descriptionTitle'
,
'StructuredTextDescriptionBody'
:
'descriptionBody'
,
'StructuredTextSection'
:
'section'
,
'StructuredTextSectionTitle'
:
'sectionTitle'
,
'StructuredTextLiteral'
:
'literal'
,
'StructuredTextEmphasis'
:
'emphasis'
,
'StructuredTextStrong'
:
'strong'
,
'StructuredTextLink'
:
'link'
,
'StructuredTextXref'
:
'xref'
,
'StructuredTextInnerLink'
:
'innerLink'
,
'StructuredTextNamedLink'
:
'namedLink'
,
'StructuredTextUnderline'
:
'underline'
,
'StructuredTextTable'
:
'table'
,
'StructuredTextSGML'
:
'sgml'
,
}
def
dispatch
(
self
,
doc
,
level
,
output
):
getattr
(
self
,
self
.
element_types
[
doc
.
getNodeName
()])(
doc
,
level
,
output
)
def
__call__
(
self
,
doc
,
level
=
1
):
r
=
[]
self
.
dispatch
(
doc
,
level
-
1
,
r
.
append
)
return
join
(
r
,
''
)
def
_text
(
self
,
doc
,
level
,
output
):
output
(
doc
.
getNodeValue
())
def
document
(
self
,
doc
,
level
,
output
):
output
(
'<html>
\
n
'
)
children
=
doc
.
getChildNodes
()
if
(
children
and
children
[
0
].
getNodeName
()
==
'StructuredTextSection'
):
output
(
'<head>
\
n
<title>%s</title>
\
n
</head>
\
n
'
%
children
[
0
].
getChildNodes
()[
0
].
getNodeValue
())
output
(
'<body>
\
n
'
)
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</body>
\
n
'
)
output
(
'</html>
\
n
'
)
def
section
(
self
,
doc
,
level
,
output
):
children
=
doc
.
getChildNodes
()
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
+
1
,
output
)
def
sectionTitle
(
self
,
doc
,
level
,
output
):
output
(
'<h%d>'
%
(
level
))
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</h%d>
\
n
'
%
(
level
))
def
description
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<dl>
\
n
'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</dl>
\
n
'
)
def
descriptionTitle
(
self
,
doc
,
level
,
output
):
output
(
'<dt>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</dt>
\
n
'
)
def
descriptionBody
(
self
,
doc
,
level
,
output
):
output
(
'<dd>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</dd>
\
n
'
)
def
bullet
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<ul>
\
n
'
)
output
(
'<li>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
output
(
'</li>
\
n
'
)
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</ul>
\
n
'
)
def
numbered
(
self
,
doc
,
level
,
output
):
p
=
doc
.
getPreviousSibling
()
if
p
is
None
or
p
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'<ol>
\
n
'
)
output
(
'<li>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
n
=
doc
.
getNextSibling
()
output
(
'</li>
\
n
'
)
if
n
is
None
or
n
.
getNodeName
()
is
not
doc
.
getNodeName
():
output
(
'</ol>
\
n
'
)
def
example
(
self
,
doc
,
level
,
output
):
i
=
0
for
c
in
doc
.
getChildNodes
():
if
i
==
0
:
output
(
'<pre>'
)
output
(
html_quote
(
c
.
getNodeValue
()))
output
(
'</pre>
\
n
'
)
else
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
def
paragraph
(
self
,
doc
,
level
,
output
):
i
=
0
output
(
'<p>'
)
for
c
in
doc
.
getChildNodes
():
if
c
.
getNodeName
()
in
[
'StructuredTextParagraph'
]:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
else
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</p>'
)
def
link
(
self
,
doc
,
level
,
output
):
output
(
'<a href="%s">'
%
doc
.
href
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</a>'
)
def
emphasis
(
self
,
doc
,
level
,
output
):
output
(
'<em>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</em>'
)
def
literal
(
self
,
doc
,
level
,
output
):
output
(
'<code>'
)
for
c
in
doc
.
getChildNodes
():
output
(
html_quote
(
c
.
getNodeValue
()))
output
(
'</code>'
)
def
strong
(
self
,
doc
,
level
,
output
):
output
(
'<strong>'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</strong>'
)
def
underline
(
self
,
doc
,
level
,
output
):
output
(
"<u>"
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
"</u>"
)
def
innerLink
(
self
,
doc
,
level
,
output
):
output
(
'<a href="#'
);
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'">['
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
']</a>'
)
def
namedLink
(
self
,
doc
,
level
,
output
):
output
(
'<a name="'
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'">['
)
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
']</a>'
)
def
sgml
(
self
,
doc
,
level
,
output
):
for
c
in
doc
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
def
table
(
self
,
doc
,
level
,
output
):
"""
A StructuredTextTable holds StructuredTextRow(s) which
holds StructuredTextColumn(s). A StructuredTextColumn
is a type of StructuredTextParagraph and thus holds
the actual data.
"""
output
(
"<table border=1 cellpadding=2>
\
n
"
)
for
row
in
doc
.
getRows
()[
0
]:
output
(
"<tr>
\
n
"
)
for
column
in
row
.
getColumns
()[
0
]:
str
=
"<td colspan=%s>"
%
column
.
getSpan
()
output
(
str
)
#for c in doc.getChildNodes():
# getattr(self, self.element_types[c.getNodeName()])(c, level, output)
for
c
in
column
.
getChildNodes
():
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
"</td>
\
n
"
)
output
(
"</tr>
\
n
"
)
output
(
"</table>
\
n
"
)
def
html_quote
(
v
,
name
=
'(Unknown name)'
,
md
=
{},
character_entities
=
(
((
'&'
),
'&'
),
((
'<'
),
'<'
),
((
'>'
),
'>'
),
((
'
\
213
'
),
'<'
),
((
'
\
233
'
),
'>'
),
((
'"'
),
'"'
))):
#"
text
=
str
(
v
)
for
re
,
name
in
character_entities
:
if
find
(
text
,
re
)
>=
0
:
text
=
join
(
split
(
text
,
re
),
name
)
return
text
lib/python/StructuredText/HTMLWithImages.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
from
string
import
join
,
split
,
find
import
re
,
sys
,
ST
import
time
from
HTMLClass
import
HTMLClass
ets
=
HTMLClass
.
element_types
ets
.
update
({
'StructuredTextImage'
:
'image'
})
class
HTMLWithImages
(
HTMLClass
):
element_types
=
ets
def
document
(
self
,
doc
,
level
,
output
):
output
(
'<html>
\
n
'
)
children
=
doc
.
getChildNodes
()
if
(
children
and
children
[
0
].
getNodeName
()
==
'StructuredTextSection'
):
output
(
'<head>
\
n
<title>%s</title>
\
n
</head>
\
n
'
%
children
[
0
].
getChildNodes
()[
0
].
getNodeValue
())
output
(
'<body bgcolor="#FFFFFF">
\
n
'
)
for
c
in
children
:
getattr
(
self
,
self
.
element_types
[
c
.
getNodeName
()])(
c
,
level
,
output
)
output
(
'</body>
\
n
'
)
output
(
'</html>
\
n
'
)
def
image
(
self
,
doc
,
level
,
output
):
output
(
'<img src="%s" alt="%s">'
%
(
doc
.
href
,
doc
.
getNodeValue
()))
def
image
(
self
,
doc
,
level
,
output
):
if
hasattr
(
doc
,
'key'
):
output
(
'<a name="%s"></a>
\
n
<img src="%s" alt="%s">'
%
(
doc
.
key
,
doc
.
href
,
doc
.
getNodeValue
()))
else
:
output
(
'<img src="%s" alt="%s">'
%
(
doc
.
href
,
doc
.
getNodeValue
()))
def
xref
(
self
,
doc
,
level
,
output
):
val
=
doc
.
getNodeValue
()
output
(
'<a href="#%s">%s</a>'
%
(
val
,
val
)
)
lib/python/StructuredText/ST.py
0 → 100644
View file @
5d3f14c3
import
re
,
STDOM
from
string
import
split
,
join
,
replace
,
expandtabs
,
strip
,
find
#####################################################################
# Updated functions #
#####################################################################
def
indention
(
str
,
front
=
re
.
compile
(
"^
\
s+
"
).match):
"""
Convert all tabs to the appropriate number of spaces.
Find the number of leading spaces. If none, return 0
"""
if front(str):
start,end = front(str).span()
return end-start-1
else:
return 0 # no leading spaces
def insert(struct, top, level):
"""
find what will be the parant paragraph of
a sentence and return that paragraph's
sub-paragraphs. The new paragraph will be
appended to those sub-paragraphs
"""
#print "
struct
", struct, top-1
if not top-1 in range(len(struct)):
return None
run = struct[top-1]
i = 0
while i+1 < level:
run = run.getSubparagraphs()[len(run.getSubparagraphs())-1]
i = i + 1
#print "
parent
for
level
", level, "
was
=>
", run.getColorizableTexts()
return run.getSubparagraphs()
def display(struct):
"""
runs through the structure and prints out
the paragraphs. If the insertion works
correctly, display's results should mimic
the orignal paragraphs.
"""
if struct.getColorizableTexts():
print join(struct.getColorizableTexts()),"
\
n
"
if struct.getSubparagraphs():
for x in struct.getSubparagraphs():
display(x)
def display2(struct):
"""
runs through the structure and prints out
the paragraphs. If the insertion works
correctly, display's results should mimic
the orignal paragraphs.
"""
if struct.getNodeValue():
print struct.getNodeValue(),"
\
n
"
if struct.getSubparagraphs():
for x in struct.getSubparagraphs():
display(x)
def findlevel(levels,indent):
"""
remove all level information of levels
with a greater level of indentation.
Then return which level should insert this
paragraph
"""
keys = levels.keys()
for key in keys:
if levels[key] > indent:
del(levels[key])
keys = levels.keys()
if not(keys):
return 0
else:
for key in keys:
if levels[key] == indent:
return key
highest = 0
for key in keys:
if key > highest:
highest = key
return highest-1
#####################################################################
# Golly, the capitalization of this function always makes me think it's a class
def StructuredText(paragraphs, paragraph_delimiter=re.compile('
\
n
\
s*
\
n')):
"""
StructuredText accepts paragraphs, which is a list of
lines to be parsed. StructuredText creates a structure
which mimics the structure of the paragraphs.
Structure => [paragraph,[sub-paragraphs]]
"""
currentlevel = 0
currentindent = 0
levels = {0:0}
level = 0 # which header are we under
struct = [] # the structure to be returned
run = struct
paragraphs = filter(
strip,
paragraph_delimiter.split(expandtabs('
\
n
\
n
'+paragraphs+'
\
n
\
n
'))
)
if not paragraphs: return []
ind = [] # structure based on indention levels
for paragraph in paragraphs:
ind.append([indention(paragraph), paragraph])
currentindent = indention(paragraphs[0])
levels[0] = currentindent
#############################################################
# updated #
#############################################################
for indent,paragraph in ind :
if indent == 0:
level = level + 1
currentlevel = 0
currentindent = 0
levels = {0:0}
struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
elif indent > currentindent:
currentlevel = currentlevel + 1
currentindent = indent
levels[currentlevel] = indent
run = insert(struct,level,currentlevel)
run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
elif indent < currentindent:
result = findlevel(levels,indent)
if result > 0:
currentlevel = result
currentindent = indent
run = insert(struct,level,currentlevel)
run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
else:
if insert(struct,level,currentlevel):
run = insert(struct,level,currentlevel)
else:
run = struct
currentindet = indent
run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
return StructuredTextDocument(struct)
Basic = StructuredText
class StructuredTextParagraph(STDOM.Element):
indent=0
def __init__(self, src, subs=None, **kw):
if subs is None: subs=[]
self._src=src
self._subs=list(subs)
self._attributes=kw.keys()
for k, v in kw.items(): setattr(self, k, v)
def getChildren(self, type=type, lt=type([])):
src=self._src
if type(src) is not lt: src=[src]
return src+self._subs
def getAttribute(self, name):
return getattr(self, name, None)
def getAttributeNode(self, name):
if hasattr(self, name):
return STDOM.Attr(name, getattr(self, name))
def getAttributes(self):
d={}
for a in self._attributes:
d[a]=getattr(self, a, '')
return STDOM.NamedNodeMap(d)
def getSubparagraphs(self):
return self._subs
def setSubparagraphs(self, subs):
self._subs=subs
def getColorizableTexts(self):
return (self._src,)
def setColorizableTexts(self, src):
self._src=src[0]
def __repr__(self):
r=[]; a=r.append
a((' '*(self.indent or 0))+
('%s(' % self.__class__.__name__)
+str(self._src)+', ['
)
for p in self._subs: a(`p`)
a((' '*(self.indent or 0))+'])')
return join(r,'
\
n
')
"""
create aliases for all above functions in the pythony way.
"""
def _get_Children(self, type=type, lt=type([])):
return self.getChildren(type,lt)
def _get_Attribute(self, name):
return self.getAttribute(name)
def _get_AttributeNode(self, name):
return self.getAttributeNode(name)
def _get_Attributes(self):
return self.getAttributes()
def _get_Subparagraphs(self):
return self.getSubparagraphs()
def _set_Subparagraphs(self, subs):
return self.setSubparagraphs(subs)
def _get_ColorizableTexts(self):
return self.getColorizableTexts()
def _set_ColorizableTexts(self, src):
return self.setColorizableTexts(src)
class StructuredTextDocument(StructuredTextParagraph):
"""
A StructuredTextDocument holds StructuredTextParagraphs
as its subparagraphs.
"""
_attributes=()
def __init__(self, subs=None, **kw):
apply(StructuredTextParagraph.__init__,
(self, '', subs),
kw)
def getChildren(self):
return self._subs
def getColorizableTexts(self):
return ()
def setColorizableTexts(self, src):
pass
def __repr__(self):
r=[]; a=r.append
a('%s([' % self.__class__.__name__)
for p in self._subs: a(`p`+',')
a('])')
return join(r,'
\
n
')
"""
create aliases for all above functions in the pythony way.
"""
def _get_Children(self):
return self.getChildren()
def _get_ColorizableTexts(self):
return self.getColorizableTexts()
def _set_ColorizableTexts(self, src):
return self.setColorizableTexts(src)
lib/python/StructuredText/STDOM.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
DOM implementation in StructuredText : Read-Only methods
All standard Zope objects support DOM to a limited extent.
"""
import
string
# Node type codes
# ---------------
ELEMENT_NODE
=
1
ATTRIBUTE_NODE
=
2
TEXT_NODE
=
3
CDATA_SECTION_NODE
=
4
ENTITY_REFERENCE_NODE
=
5
ENTITY_NODE
=
6
PROCESSING_INSTRUCTION_NODE
=
7
COMMENT_NODE
=
8
DOCUMENT_NODE
=
9
DOCUMENT_TYPE_NODE
=
10
DOCUMENT_FRAGMENT_NODE
=
11
NOTATION_NODE
=
12
# Exception codes
# ---------------
INDEX_SIZE_ERR
=
1
DOMSTRING_SIZE_ERR
=
2
HIERARCHY_REQUEST_ERR
=
3
WRONG_DOCUMENT_ERR
=
4
INVALID_CHARACTER_ERR
=
5
NO_DATA_ALLOWED_ERR
=
6
NO_MODIFICATION_ALLOWED_ERR
=
7
NOT_FOUND_ERR
=
8
NOT_SUPPORTED_ERR
=
9
INUSE_ATTRIBUTE_ERR
=
10
# Exceptions
# ----------
class
DOMException
(
Exception
):
pass
class
IndexSizeException
(
DOMException
):
code
=
INDEX_SIZE_ERR
class
DOMStringSizeException
(
DOMException
):
code
=
DOMSTRING_SIZE_ERR
class
HierarchyRequestException
(
DOMException
):
code
=
HIERARCHY_REQUEST_ERR
class
WrongDocumentException
(
DOMException
):
code
=
WRONG_DOCUMENT_ERR
class
InvalidCharacterException
(
DOMException
):
code
=
INVALID_CHARACTER_ERR
class
NoDataAllowedException
(
DOMException
):
code
=
NO_DATA_ALLOWED_ERR
class
NoModificationAllowedException
(
DOMException
):
code
=
NO_MODIFICATION_ALLOWED_ERR
class
NotFoundException
(
DOMException
):
code
=
NOT_FOUND_ERR
class
NotSupportedException
(
DOMException
):
code
=
NOT_SUPPORTED_ERR
class
InUseAttributeException
(
DOMException
):
code
=
INUSE_ATTRIBUTE_ERR
# Node classes
# ------------
class
ParentNode
:
"""
A node that can have children, or, more precisely, that implements
the child access methods of the DOM.
"""
def
getChildNodes
(
self
,
type
=
type
,
st
=
type
(
''
)):
"""
Returns a NodeList that contains all children of this node.
If there are no children, this is a empty NodeList
"""
r
=
[]
for
n
in
self
.
getChildren
():
if
type
(
n
)
is
st
:
n
=
TextNode
(
n
)
r
.
append
(
n
.
__of__
(
self
))
return
NodeList
(
r
)
def
getFirstChild
(
self
,
type
=
type
,
st
=
type
(
''
)):
"""
The first child of this node. If there is no such node
this returns None
"""
children
=
self
.
getChildren
()
if
not
children
:
return
None
n
=
chidren
[
0
]
if
type
(
n
)
is
st
:
n
=
TextNode
(
n
)
return
n
.
__of__
(
self
)
def
getLastChild
(
self
,
type
=
type
,
st
=
type
(
''
)):
"""
The last child of this node. If there is no such node
this returns None.
"""
children
=
self
.
getChildren
()
if
not
children
:
return
None
n
=
chidren
[
-
1
]
if
type
(
n
)
is
st
:
n
=
TextNode
(
n
)
return
n
.
__of__
(
self
)
"""
create aliases for all above functions in the pythony way.
"""
def
_get_ChildNodes
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
getChildNodes
(
type
,
st
)
def
_get_FirstChild
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
getFirstChild
(
type
,
st
)
def
_get_LastChild
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
getLastChild
(
type
,
st
)
class
NodeWrapper
(
ParentNode
):
"""
This is an acquisition-like wrapper that provides parent access for
DOM sans circular references!
"""
def
__init__
(
self
,
aq_self
,
aq_parent
):
self
.
aq_self
=
aq_self
self
.
aq_parent
=
aq_parent
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
aq_self
,
name
)
def
getParentNode
(
self
):
"""
The parent of this node. All nodes except Document
DocumentFragment and Attr may have a parent
"""
return
self
.
aq_parent
def
_getDOMIndex
(
self
,
children
,
getattr
=
getattr
):
i
=
0
self
=
self
.
aq_self
for
child
in
children
:
if
getattr
(
child
,
'aq_self'
,
child
)
is
self
:
self
.
_DOMIndex
=
i
return
i
i
=
i
+
1
return
None
def
getPreviousSibling
(
self
,
type
=
type
,
st
=
type
(
''
),
getattr
=
getattr
,
None
=
None
):
"""
The node immediately preceding this node. If
there is no such node, this returns None.
"""
children
=
self
.
aq_parent
.
getChildren
()
if
not
children
:
return
None
index
=
getattr
(
self
,
'_DOMIndex'
,
None
)
if
index
is
None
:
index
=
self
.
_getDOMIndex
(
children
)
if
index
is
None
:
return
None
index
=
index
-
1
if
index
<
0
:
return
None
try
:
n
=
children
[
index
]
except
IndexError
:
return
None
else
:
if
type
(
n
)
is
st
:
n
=
TextNode
(
n
)
n
.
_DOMIndex
=
index
return
n
.
__of__
(
self
)
def
getNextSibling
(
self
,
type
=
type
,
st
=
type
(
''
)):
"""
The node immediately preceding this node. If
there is no such node, this returns None.
"""
children
=
self
.
aq_parent
.
getChildren
()
if
not
children
:
return
None
index
=
getattr
(
self
,
'_DOMIndex'
,
None
)
if
index
is
None
:
index
=
self
.
_getDOMIndex
(
children
)
if
index
is
None
:
return
None
index
=
index
+
1
try
:
n
=
children
[
index
]
except
IndexError
:
return
None
else
:
if
type
(
n
)
is
st
:
n
=
TextNode
(
n
)
n
.
_DOMIndex
=
index
return
n
.
__of__
(
self
)
def
getOwnerDocument
(
self
):
"""
The Document object associated with this node, if any.
"""
return
self
.
aq_parent
.
getOwnerDocument
()
"""
create aliases for all above functions in the pythony way.
"""
def
_get_ParentNode
(
self
):
return
self
.
getParentNode
()
def
_get_DOMIndex
(
self
,
children
,
getattr
=
getattr
):
return
self
.
_getDOMIndex
(
children
,
getattr
)
def
_get_PreviousSibling
(
self
,
type
=
type
,
st
=
type
(
''
),
getattr
=
getattr
,
None
=
None
):
return
self
.
getPreviousSibling
(
type
,
st
,
getattr
,
None
)
def
_get_NextSibling
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
getNextSibling
(
type
,
st
)
def
_get_OwnerDocument
(
self
):
return
self
.
getOwnerDocument
()
class
Node
(
ParentNode
):
"""
Node Interface
"""
# Get a DOM wrapper with a parent link
def
__of__
(
self
,
parent
):
return
NodeWrapper
(
self
,
parent
)
# DOM attributes
# --------------
def
getNodeName
(
self
):
"""
The name of this node, depending on its type
"""
def
getNodeValue
(
self
):
"""
The value of this node, depending on its type
"""
return
None
def
getParentNode
(
self
):
"""
The parent of this node. All nodes except Document
DocumentFragment and Attr may have a parent
"""
def
getChildren
(
self
):
"""
Get a Python sequence of children
"""
return
()
def
getPreviousSibling
(
self
,
type
=
type
,
st
=
type
(
''
),
getattr
=
getattr
,
None
=
None
):
"""
The node immediately preceding this node. If
there is no such node, this returns None.
"""
def
getNextSibling
(
self
,
type
=
type
,
st
=
type
(
''
)):
"""
The node immediately preceding this node. If
there is no such node, this returns None.
"""
def
getAttributes
(
self
):
"""
Returns a NamedNodeMap containing the attributes
of this node (if it is an element) or None otherwise.
"""
return
None
def
getOwnerDocument
(
self
):
"""
The Document object associated with this node, if any.
"""
# DOM Methods
# -----------
def
hasChildNodes
(
self
):
"""
Returns true if the node has any children, false
if it doesn't.
"""
return
len
(
self
.
getChildren
())
"""
create aliases for all above functions in the pythony way.
"""
def
_get_NodeName
(
self
):
return
self
.
getNodeName
()
def
_get_NodeValue
(
self
):
return
self
.
getNodeValue
()
def
_get_ParentNode
(
self
):
return
self
.
getParentNode
()
def
_get_Children
(
self
):
return
self
.
getChildren
()
def
_get_PreviousSibling
(
self
,
type
=
type
,
st
=
type
(
''
),
getattr
=
getattr
,
None
=
None
):
return
self
.
getPreviousSibling
(
type
,
st
,
getattr
,
None
)
def
_get_NextSibling
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
getNextSibling
()
def
_get_Attributes
(
self
):
return
self
.
getAttributes
()
def
_get_OwnerDocument
(
self
):
return
self
.
getOwnerDocument
()
def
_has_ChildNodes
(
self
):
return
self
.
hasChildNodes
()
class
TextNode
(
Node
):
def
__init__
(
self
,
str
):
self
.
_value
=
str
def
getNodeType
(
self
):
return
TEXT_NODE
def
getNodeName
(
self
):
return
'#text'
def
getNodeValue
(
self
):
return
self
.
_value
"""
create aliases for all above functions in the pythony way.
"""
def
_get_NodeType
(
self
):
return
self
.
getNodeType
()
def
_get_NodeName
(
self
):
return
self
.
getNodeName
()
def
_get_NodeValue
(
self
):
return
self
.
getNodeValue
()
class
Element
(
Node
):
"""
Element interface
"""
# Element Attributes
# ------------------
def
getTagName
(
self
):
"""The name of the element"""
return
self
.
__class__
.
__name__
def
getNodeName
(
self
):
"""The name of this node, depending on its type"""
return
self
.
__class__
.
__name__
def
getNodeType
(
self
):
"""A code representing the type of the node."""
return
ELEMENT_NODE
def
getNodeValue
(
self
,
type
=
type
,
st
=
type
(
''
)):
r
=
[]
for
c
in
self
.
getChildren
():
if
type
(
c
)
is
not
st
:
c
=
c
.
getNodeValue
()
r
.
append
(
c
)
return
string
.
join
(
r
,
''
)
def
getParentNode
(
self
):
"""
The parent of this node. All nodes except Document
DocumentFragment and Attr may have a parent
"""
# Element Methods
# ---------------
_attributes
=
()
def
getAttribute
(
self
,
name
):
return
getattr
(
self
,
name
,
None
)
def
getAttributeNode
(
self
,
name
):
if
hasattr
(
self
,
name
):
return
Attr
(
name
,
getattr
(
self
,
name
))
def
getAttributes
(
self
):
d
=
{}
for
a
in
self
.
_attributes
:
d
[
a
]
=
getattr
(
self
,
a
,
''
)
return
NamedNodeMap
(
d
)
def
getAttribute
(
self
,
name
):
"""Retrieves an attribute value by name."""
return
None
def
getAttributeNode
(
self
,
name
):
""" Retrieves an Attr node by name or None if
there is no such attribute. """
return
None
def
getElementsByTagName
(
self
,
tagname
):
"""
Returns a NodeList of all the Elements with a given tag
name in the order in which they would be encountered in a
preorder traversal of the Document tree. Parameter: tagname
The name of the tag to match (* = all tags). Return Value: A new
NodeList object containing all the matched Elements.
"""
nodeList
=
[]
for
child
in
self
.
getChildren
():
if
(
child
.
getNodeType
()
==
ELEMENT_NODE
and
\
child
.
getTagName
()
==
tagname
or
tagname
==
'*'
):
nodeList
.
append
(
child
)
if
hasattr
(
child
,
'getElementsByTagName'
):
n1
=
child
.
getElementsByTagName
(
tagname
)
nodeList
=
nodeList
+
n1
.
_data
return
NodeList
(
nodeList
)
"""
create aliases for all above functions in the pythony way.
"""
def
_get_TagName
(
self
):
return
self
.
getTagName
()
def
_get_NodeName
(
self
):
return
self
.
getNodeName
()
def
_get_NodeType
(
self
):
return
self
.
getNodeType
()
def
_get_NodeValue
(
self
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
GetNodeValue
(
type
,
st
)
def
_get_ParentNode
(
self
):
return
self
.
getParentNode
()
def
_get_Attribute
(
self
,
name
):
return
self
.
getAttribute
(
name
)
def
_get_AttributeNode
(
self
,
name
):
return
self
.
getAttributeNode
(
name
)
def
_get_Attributes
(
self
):
return
self
.
getAttributes
()
def
_get_Attribute
(
self
,
name
):
return
self
.
getAttribute
(
name
)
def
_get_AttributeNode
(
self
,
name
):
return
self
.
getAttributeNode
(
name
)
def
_get_ElementsByTagName
(
self
,
tagname
):
return
self
.
getElementsByTagName
(
tagname
)
class
NodeList
:
"""
NodeList interface - Provides the abstraction of an ordered
collection of nodes.
Python extensions: can use sequence-style 'len', 'getitem', and
'for..in' constructs.
"""
def
__init__
(
self
,
list
=
None
):
self
.
_data
=
list
or
[]
def
__getitem__
(
self
,
index
,
type
=
type
,
st
=
type
(
''
)):
return
self
.
_data
[
index
]
def
__getslice__
(
self
,
i
,
j
):
return
self
.
_data
[
i
:
j
]
def
item
(
self
,
index
):
"""
Returns the index-th item in the collection
"""
try
:
return
self
.
_data
[
index
]
except
IndexError
:
return
None
def
getLength
(
self
):
"""
The length of the NodeList
"""
return
len
(
self
.
_data
)
__len__
=
getLength
"""
create aliases for all above functions in the pythony way.
"""
def
_get_Length
(
self
):
return
self
.
getLength
()
class
NamedNodeMap
:
"""
NamedNodeMap interface - Is used to represent collections
of nodes that can be accessed by name. NamedNodeMaps are not
maintained in any particular order.
Python extensions: can use sequence-style 'len', 'getitem', and
'for..in' constructs, and mapping-style 'getitem'.
"""
def
__init__
(
self
,
data
=
None
):
if
data
is
None
:
data
=
{}
self
.
_data
=
data
def
item
(
self
,
index
):
"""
Returns the index-th item in the map
"""
try
:
return
self
.
_data
.
values
()[
index
]
except
IndexError
:
return
None
def
__getitem__
(
self
,
key
):
if
type
(
key
)
==
type
(
1
):
return
self
.
_data
.
values
()[
key
]
else
:
return
self
.
_data
[
key
]
def
getLength
(
self
):
"""
The length of the NodeList
"""
return
len
(
self
.
_data
)
__len__
=
getLength
def
getNamedItem
(
self
,
name
):
"""
Retrieves a node specified by name. Parameters:
name Name of a node to retrieve. Return Value A Node (of any
type) with the specified name, or None if the specified name
did not identify any node in the map.
"""
if
self
.
_data
.
has_key
(
name
):
return
self
.
_data
[
name
]
return
None
"""
create aliases for all above functions in the pythony way.
"""
def
_get_Length
(
self
):
return
self
.
getLength
()
def
_get_NamedItem
(
self
,
name
):
return
self
.
getNamedItem
(
name
)
class
Attr
(
Node
):
"""
Attr interface - The Attr interface represents an attriubte in an
Element object. Attr objects inherit the Node Interface
"""
def
__init__
(
self
,
name
,
value
,
specified
=
1
):
self
.
name
=
name
self
.
value
=
value
self
.
specified
=
specified
def
getNodeName
(
self
):
"""
The name of this node, depending on its type
"""
return
self
.
name
def
getName
(
self
):
"""
Returns the name of this attribute.
"""
return
self
.
name
def
getNodeValue
(
self
):
"""
The value of this node, depending on its type
"""
return
self
.
value
def
getNodeType
(
self
):
"""
A code representing the type of the node.
"""
return
ATTRIBUTE_NODE
def
getSpecified
(
self
):
"""
If this attribute was explicitly given a value in the
original document, this is true; otherwise, it is false.
"""
return
self
.
specified
"""
create aliases for all above functions in the pythony way.
"""
def
_get_NodeName
(
self
):
return
self
.
getNodeName
()
def
_get_Name
(
self
):
return
self
.
getName
()
def
_get_NodeValue
(
self
):
return
self
.
getNodeValue
()
def
_get_NodeType
(
self
):
return
self
.
getNodeType
()
def
_get_Specified
(
self
):
return
self
.
getSpecified
()
lib/python/StructuredText/STNG.txt
0 → 100644
View file @
5d3f14c3
Using Structured Text
The goal of StructuredText is to make it possible to express
structured text using a relatively simple plain text format. Simple
structures, like bullets or headings are indicated through
conventions that are natural, for some definition of
"natural". Hierarchical structures are indicated through
indentation. The use of indentation to express hierarchical
structure is inspired by the Python programming language.
Use of StructuredText consists of one to three logical steps. In the
first step, a text string is converted to a network of objects using
the 'StructuredText.Basic' facility, as in the following
example::
raw=open("mydocument.txt").read()
import StructuredText
st=StructuredText.Basic(raw)
The output of 'StructuredText.Basic' is simply a
StructuredTextDocumemt object containing StructuredTextParagraph
objects arranged in a hierarchy. Paragraphs are delimited by strings
of two or more whitespace characters beginning and ending with
newline characters. Hierarchy is indicated by indentation. The
indentation of a paragraph is the minimum number of leading spaces
in a line containing non-white-space characters after converting tab
characters to spaces (assuming a tab stop every eight characters).
StructuredTextNode objects support the read-only subset of the
Document Object Model (DOM) API. It should be possible to process
'StructuredTextNode' hierarchies using XML tools such as XSLT.
The second step in using StructuredText is to apply additional
structuring rules based on text content. A variety of differentText
rules can be used. Typically, these are used to implement a
structured text language for producing documents, but any sort of
structured text language could be implemented in the second
step. For example, it is possible to use StructuredText to implement
structured text formats for representing structured data. The second
step, which could consist of multiple processing steps, is
performed by processing, or "coloring", the hierarchy of generic
StructuredTextParagraph objects into a network of more specialized
objects. Typically, the objects produced should also implement the DOM
API to allow processing with XML tools.
A document processor is provided to convert a StructuredTextDocument
object containing only StructuredStructuredTextParagraph objects
into a StructuredTextDocument object containing a richer collection
of objects such as bullets, headings, emphasis, and so on using
hints in the text. Hints are selected based on conventions of the
sort typically seen in electronic mail or news-group postings. It
should be noted, however, that these conventions are somewhat
culturally dependent, fortunately, the document processor is easily
customized to implement alternative rules. Here's an example of
using the DOC processor to convert the output of the previous example::
doc=StructuredText.Document(st)
The final step is to process the colored networks produced from the
second step to produce additional outputs. The final step could be
performed by Python programs, or by XML tools. A Python outputter is
provided for the document processor output that produces Hypertext Markup
Language (HTML) text::
html=StructuredText.HTML(doc)
Customizing the document processor
The document processor is driven by two tables. The first table,
named 'paragraph_types', is a sequence of callable objects or method
names for coloring paragraphs. If a table entry is a string, then it
is the name of a method of the document processor to be used. For
each input paragraph, the objects in the table are called until one
returns a value (not 'None'). The value returned replaces the
original input paragraph in the output. If none of the objects in
the paragraph types table return a value, then a copy of the
original paragraph is used. The new object returned by calling a
paragraph type should implement the ReadOnlyDOM,
StructuredTextColorizable, and StructuredTextSubparagraphContainer
interfaces. See the 'Document.py' source file for examples.
A paragraph type may return a list or tuple of replacement
paragraphs, this allowing a paragraph to be split into multiple
paragraphs.
The second table, 'text_types', is a sequence of callable objects or
method names for coloring text. The callable objects in this table
are used in sequence to transform the input text into new text or
objects. The callable objects are passed a string and return
nothing ('None') or a three-element tuple consisting of:
- a replacement object,
- a starting position, and
- an ending position
The text from the starting position is (logically) replaced with the
replacement object. The replacement object is typically an object
that implements that implements the ReadOnlyDOM, and
StructuredTextColorizable interfaces. The replacement object can
also be a string or a list of strings or objects. Replacement is
done from beginning to end and text after the replacement ending
position will be passed to the character type objects for processing.
Example: adding wiki links
We want to add support for Wiki links. A Wiki link is a string of
text containing mixed-case letters, such that at least two of the
letters are upper case and such that the first letter is upper case.
lib/python/StructuredText/StructuredText.py
View file @
5d3f14c3
...
...
@@ -204,7 +204,7 @@ Special symbology is used to indicate special constructs:
</TABLE>
$Id: StructuredText.py,v 1.
29 2000/11/10 16:55:56
brian Exp $'''
$Id: StructuredText.py,v 1.
30 2001/01/04 15:01:59
brian Exp $'''
# Copyright
#
# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
...
...
@@ -256,6 +256,9 @@ $Id: StructuredText.py,v 1.29 2000/11/10 16:55:56 brian Exp $'''
# (540) 371-6909
#
# $Log: StructuredText.py,v $
# Revision 1.30 2001/01/04 15:01:59 brian
# Merged StructuredText-Dev
#
# Revision 1.29 2000/11/10 16:55:56 brian
# Fixed stx to allow ampersands in urls.
#
...
...
lib/python/StructuredText/Zwiki.py
0 → 100644
View file @
5d3f14c3
#!/usr/bin/python
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
from
Html
import
HTML
from
string
import
split
from
ST
import
DOC
import
re
"""
This is the new structured text type.
"""
class
Zwiki_Title
:
def
__init__
(
self
,
str
=
''
):
self
.
expr1
=
re
.
compile
(
'([A-Z]+[A-Z]+[a-zA-Z]*)'
).
search
self
.
expr2
=
re
.
compile
(
'([A-Z]+[a-z]+[A-Z]+[a-zA-Z]*)'
).
search
self
.
str
=
[
str
]
self
.
typ
=
"Zwiki_Title"
def
type
(
self
):
return
'%s'
%
self
.
typ
def
string
(
self
):
return
self
.
str
def
__getitem__
(
self
,
index
):
return
self
.
str
[
index
]
def
__call__
(
self
,
raw_string
,
subs
):
"""
The raw_string is checked to see if it matches the rules
for this structured text expression. If the raw_string does,
it is parsed for the sub-string which matches and a doc_inner_link
instance is returned whose string is the matching substring.
If raw_string does not match, nothing is returned.
"""
if
self
.
expr1
(
raw_string
):
start
,
end
=
self
.
expr1
(
raw_string
).
span
()
result
=
Zwiki_Title
(
raw_string
[
start
:
end
])
result
.
start
,
result
.
end
=
self
.
expr1
(
raw_string
).
span
()
return
result
elif
self
.
expr2
(
raw_string
):
start
,
end
=
self
.
expr2
(
raw_string
).
span
()
result
=
Zwiki_Title
(
raw_string
[
start
:
end
])
result
.
start
,
result
.
end
=
self
.
expr2
(
raw_string
).
span
()
return
result
else
:
return
None
def
span
(
self
):
return
self
.
start
,
self
.
end
class
Zwiki_doc
(
DOC
):
def
__init__
(
self
):
DOC
.
__init__
(
self
)
"""
Add the new type to self.types
"""
self
.
types
.
append
(
Zwiki_Title
())
class
Zwiki_parser
(
HTML
):
def
__init__
(
self
):
HTML
.
__init__
(
self
)
self
.
types
[
"Zwiki_Title"
]
=
self
.
zwiki_title
def
zwiki_title
(
self
,
object
):
result
=
""
for
x
in
object
.
string
():
result
=
result
+
x
result
=
"<a href=%s>%s</a>"
%
(
result
,
result
)
#result = "<dtml-wikiname %s>" % result
self
.
string
=
self
.
string
+
result
lib/python/StructuredText/__init__.py
View file @
5d3f14c3
...
...
@@ -82,4 +82,31 @@
# attributions are listed in the accompanying credits file.
#
##############################################################################
import
HTMLClass
,
DocumentClass
import
ClassicDocumentClass
from
StructuredText
import
html_with_references
,
HTML
from
ST
import
Basic
import
DocBookClass
import
HTMLWithImages
import
DocumentWithImages
ClassicHTML
=
HTML
HTMLNG
=
HTMLClass
.
HTMLClass
()
def
HTML
(
src
,
level
=
0
,
type
=
type
,
StringType
=
type
(
''
)):
if
type
(
src
)
is
StringType
:
return
ClassicHTML
(
src
,
level
)
return
HTMLNG
(
src
,
level
)
Classic
=
ClassicDocumentClass
.
DocumentClass
()
Document
=
DocumentClass
.
DocumentClass
()
DocumentWithImages
=
DocumentWithImages
.
DocumentWithImages
()
HTMLWithImages
=
HTMLWithImages
.
HTMLWithImages
()
DocBookBook
=
DocBookClass
.
DocBookBook
DocBookChapter
=
DocBookClass
.
DocBookChapter
()
DocBookChapterWithFigures
=
DocBookClass
.
DocBookChapterWithFigures
()
DocBookArticle
=
DocBookClass
.
DocBookArticle
()
lib/python/StructuredText/regressions/examples.stx
View file @
5d3f14c3
...
...
@@ -10,6 +10,23 @@ Small Trials for Structured Text Formatting
- A word: _underlined_.
- A word **strong**.
- An inline example: '1+2'.
- Another example with a different format:
``x='spam''' or ``y='spam''' or ``<dtml-var spam>''.'
We can use expressions in the DTML var tag as
in ``<dtml-var "x+'.txt'">''
- A mult-line example::
blah
*foo bar*
<dtml-var yeha>
.. [1] (The referring text should be a paragraph, not a header, and
should contain a reference to this footnote, footnote "[1]".)
...
...
lib/python/StructuredText/regressions/regress
deleted
100755 → 0
View file @
1a7fdfd5
#!/bin/sh
# Compare current StructuredText.py processing against prior versions.
# You should see no output if there are no discrepancies.
regressdir
=
`
dirname
$0
`
PYTHONPATH
=
`
cd
$regressdir
/../..
;
pwd
`
:
$PYTHONPATH
export
PYTHONPATH
differences
=
""
for
i
in
*
.stx
;
do
stx
=
$i
base
=
`
basename
$i
.stx
`
ref
=
$base
.ref
new
=
$base
.new
python ../StructuredText.py
$stx
>
$new
if
cmp
$ref
$new
;
then
:
else
differences
=
"
$differences
$stx
"
fi
done
if
[
-n
"
$differences
"
]
;
then
echo
"Differences encountered processing
$differences
."
fi
lib/python/StructuredText/ts_regex.py
0 → 100644
View file @
5d3f14c3
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""Provide a thread-safe interface to regex
"""
import
regex
,
regsub
#, Sync
from
regex
import
*
from
regsub
import
split
,
sub
,
gsub
,
splitx
,
capwords
try
:
import
thread
except
:
class
allocate_lock
:
def
acquire
(
*
args
):
pass
def
release
(
*
args
):
pass
else
:
class
SafeFunction
:
_l
=
thread
.
allocate_lock
()
_a
=
_l
.
acquire
_r
=
_l
.
release
def
__init__
(
self
,
f
):
self
.
_f
=
f
def
__call__
(
self
,
*
args
,
**
kw
):
self
.
_a
()
try
:
return
apply
(
self
.
_f
,
args
,
kw
)
finally
:
self
.
_r
()
split
=
SafeFunction
(
split
)
sub
=
SafeFunction
(
sub
)
gsub
=
SafeFunction
(
gsub
)
splitx
=
SafeFunction
(
splitx
)
capwords
=
SafeFunction
(
capwords
)
allocate_lock
=
thread
.
allocate_lock
class
compile
:
_r
=
None
groupindex
=
None
def
__init__
(
self
,
*
args
):
self
.
_r
=
r
=
apply
(
regex
.
compile
,
args
)
self
.
_init
(
r
)
def
_init
(
self
,
r
):
lock
=
allocate_lock
()
self
.
__a
=
lock
.
acquire
self
.
__r
=
lock
.
release
self
.
translate
=
r
.
translate
self
.
givenpat
=
r
.
givenpat
self
.
realpat
=
r
.
realpat
def
match
(
self
,
string
,
pos
=
0
):
self
.
__a
()
try
:
return
self
.
_r
.
match
(
string
,
pos
)
finally
:
self
.
__r
()
def
search
(
self
,
string
,
pos
=
0
):
self
.
__a
()
try
:
return
self
.
_r
.
search
(
string
,
pos
)
finally
:
self
.
__r
()
def
search_group
(
self
,
str
,
group
,
pos
=
0
):
"""Search a string for a pattern.
If the pattern was not found, then None is returned,
otherwise, the location where the pattern was found,
as well as any specified group are returned.
"""
self
.
__a
()
try
:
r
=
self
.
_r
l
=
r
.
search
(
str
,
pos
)
if
l
<
0
:
return
None
return
l
,
apply
(
r
.
group
,
group
)
finally
:
self
.
__r
()
def
match_group
(
self
,
str
,
group
,
pos
=
0
):
"""Match a pattern against a string
If the string does not match the pattern, then None is
returned, otherwise, the length of the match, as well
as any specified group are returned.
"""
self
.
__a
()
try
:
r
=
self
.
_r
l
=
r
.
match
(
str
,
pos
)
if
l
<
0
:
return
None
return
l
,
apply
(
r
.
group
,
group
)
finally
:
self
.
__r
()
def
search_regs
(
self
,
str
,
pos
=
0
):
"""Search a string for a pattern.
If the pattern was not found, then None is returned,
otherwise, the 'regs' attribute of the expression is
returned.
"""
self
.
__a
()
try
:
r
=
self
.
_r
r
.
search
(
str
,
pos
)
return
r
.
regs
finally
:
self
.
__r
()
def
match_regs
(
self
,
str
,
pos
=
0
):
"""Match a pattern against a string
If the string does not match the pattern, then None is
returned, otherwise, the 'regs' attribute of the expression is
returned.
"""
self
.
__a
()
try
:
r
=
self
.
_r
r
.
match
(
str
,
pos
)
return
r
.
regs
finally
:
self
.
__r
()
class
symcomp
(
compile
):
def
__init__
(
self
,
*
args
):
self
.
_r
=
r
=
apply
(
regex
.
symcomp
,
args
)
self
.
_init
(
r
)
self
.
groupindex
=
r
.
groupindex
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment