Sanely deprecate StructuredText by making it a facade of zope.structuredtext.

parent a91bbc42
......@@ -11,8 +11,10 @@
#
##############################################################################
import re, ST, STDOM
from STletters import letters
import re
from zope.structuredtext import stng as ST
from zope.structuredtext import stdom as STDOM
from zope.structuredtext.stletters import letters
from types import StringType, UnicodeType, ListType
StringTypes = (StringType, UnicodeType)
......
......@@ -133,6 +133,12 @@ Special symbology is used to indicate special constructs:
'''
import warnings
warnings.warn('The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext instead.',
DeprecationWarning, stacklevel=2)
import ts_regex
import string, re
......
......@@ -11,246 +11,28 @@
#
##############################################################################
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',
'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):
if doc.getNodeName() == 'StructuredTextLiteral':
output(doc.getNodeValue())
else:
output(doc.getNodeValue().lstrip())
def document(self, doc, level, output):
output('<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.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<section>\n')
children=doc.getChildNodes()
for c in children:
getattr(self, self.element_types[c.getNodeName()])(c, level+1, output)
output('\n</section>\n')
def sectionTitle(self, doc, level, output):
output('<title>')
for c in doc.getChildNodes():
try:
getattr(self, self.element_types[c.getNodeName()])(c, level, output)
except:
print "failed", c.getNodeName(), c
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('<ulink url="%s">' % doc.href)
for c in doc.getChildNodes():
getattr(self, self.element_types[c.getNodeName()])(c, level, output)
output('</ulink>')
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 sgml(self, doc, level, output):
output(doc.getNodeValue())
def prestrip(v):
v=v.replace( '\r\n', '\n')
v=v.replace( '\r', '\n')
v=v.replace( '\t', ' ')
lines=v.split('\n')
indent=len(lines[0])
for line in lines:
if not len(line): continue
i=len(line)-len(line.lstrip())
if i < indent:
indent=i
nlines=[]
for line in lines:
nlines.append(line[indent:])
return '\n'.join(nlines, '\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 V4.1//EN">\n')
output('<article>\n')
children=doc.getChildNodes()
if (children and
children[0].getNodeName() == 'StructuredTextSection'):
output('<articleinfo>\n<title>%s</title>\n</articleinfo>\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 V4.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()
from zope.structuredtext.docbook import DocBook as DocBookClass
from zope.structuredtext.docbook import \
DocBookChapter, DocBookChapterWithFigures, DocBookArticle, DocBookBook
from zope.deprecation import deprecated
deprecated("DocBookClass",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.docbook.DocBook '
'instead.')
deprecated("DocBookChapter",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.docbook.DocBookChapter '
'instead.')
deprecated("DocBookChapterWithFigures",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.docbook.DocBookChapterWithFigures '
'instead.')
deprecated("DocBookArticle",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.docbook.DocBookArticle '
'instead.')
deprecated("DocBookBook",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.docbook.DocBookBook '
'instead.')
......@@ -11,936 +11,21 @@
#
##############################################################################
import re, ST, STDOM
from STletters import letters, digits, literal_punc, under_punc,\
strongem_punc, phrase_delimiters,dbl_quoted_punc
from types import StringType, UnicodeType, ListType
StringTypes = (StringType, UnicodeType)
def flatten(obj, append):
if obj.getNodeType()==STDOM.TEXT_NODE:
append(obj.getNodeValue())
else:
for child in obj.getChildNodes():
flatten(child, append)
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:
flatten(s, a)
ST.StructuredTextParagraph.__init__(self, '\n\n'.join(t), (), **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):
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):
ST.StructuredTextParagraph.__init__(
self, StructuredTextSectionTitle(src), subs, **kw)
def getColorizableTexts(self):
return self._src.getColorizableTexts()
def setColorizableTexts(self,src):
self._src.setColorizableTexts(src)
# a StructuredTextTable holds StructuredTextRows
class StructuredTextTable(ST.StructuredTextParagraph):
"""
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):
ST.StructuredTextParagraph.__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, texts):
return self.setColorizableTexts(texts)
# StructuredTextRow holds StructuredTextColumns
class StructuredTextRow(ST.StructuredTextParagraph):
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)]
"""
ST.StructuredTextParagraph.__init__(self, [], **kw)
self._columns = []
for column in row:
self._columns.append(StructuredTextColumn(column[0],
column[1],
column[2],
column[3],
column[4],
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,align,valign,typ,kw):
ST.StructuredTextParagraph.__init__(self, text, [], **kw)
self._span = span
self._align = align
self._valign = valign
self._type = typ
def getSpan(self):
return self._span
def _getSpan(self):
return self._span
def getAlign(self):
return self._align
def _getAlign(self):
return self.getAlign()
def getValign(self):
return self._valign
def _getValign(self):
return self.getValign()
def getType(self):
return self._type
def _getType(self):
return self.getType()
class StructuredTextTableHeader(ST.StructuredTextParagraph): pass
class StructuredTextTableData(ST.StructuredTextParagraph): 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):
v=self._value
if not isinstance(v, ListType): 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 StructuredTextXref(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
"""
paragraph_types = [
'doc_bullet',
'doc_numbered',
'doc_description',
'doc_header',
'doc_table',
]
#'doc_inner_link',
#'doc_named_link',
#'doc_underline'
text_types = [
'doc_literal',
'doc_sgml',
'doc_inner_link',
'doc_named_link',
'doc_href1',
'doc_href2',
'doc_strong',
'doc_emphasize',
'doc_underline',
'doc_sgml',
'doc_xref',
]
def __call__(self, doc):
if type(doc) in StringTypes:
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, sts=StringTypes, 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) in sts: 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 in sts:
# 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) in StringTypes:
str = self.parse(str, text_type)
elif type(str) is ListType:
r=[]; a=r.append
for s in str:
if type(s) in StringTypes:
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(())),
sts=StringTypes):
result=[]
for paragraph in raw_paragraphs:
if paragraph.getNodeName() != 'StructuredTextParagraph':
result.append(paragraph)
continue
for pt in self.paragraph_types:
if type(pt) in sts:
# 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:
subs = self.color_paragraphs(paragraph.getSubparagraphs())
paragraph.setSubparagraphs(subs)
break
else:
# copy, retain attributes
kw = {}
atts = getattr(paragraph, '_attributes', [])
for att in atts: kw[att] = getattr(paragraph, att)
subs = self.color_paragraphs(paragraph.getSubparagraphs())
new_paragraphs=ST.StructuredTextParagraph(
paragraph. getColorizableTexts()[0], subs, **kw),
# color the inline StructuredText types
# for each StructuredTextParagraph
for paragraph in new_paragraphs:
if paragraph.getNodeName() is "StructuredTextTable":
# cells = paragraph.getColumns()
text = paragraph.getColorizableTexts()
text = map(ST.StructuredText,text)
text = map(self.__call__,text)
for t in range(len(text)):
text[t] = text[t].getSubparagraphs()
paragraph.setColorizableTexts(text)
paragraph.setColorizableTexts(
map(self.color_text,
paragraph.getColorizableTexts()
))
result.append(paragraph)
return result
def doc_table(self, paragraph, expr = re.compile(r'\s*\|[-]+\|').match):
text = paragraph.getColorizableTexts()[0]
m = expr(text)
subs = paragraph.getSubparagraphs()
if not (m):
return None
rows = []
spans = []
ROWS = []
COLS = []
indexes = []
ignore = []
TDdivider = re.compile("[\-]+").match
THdivider = re.compile("[\=]+").match
col = re.compile('\|').search
innertable = re.compile('\|([-]+|[=]+)\|').search
text = text.strip()
rows = text.split('\n')
foo = ""
for row in range(len(rows)):
rows[row] = rows[row].strip()
# have indexes store if a row is a divider
# or a cell part
for index in range(len(rows)):
tmpstr = rows[index][1:len(rows[index])-1]
if TDdivider(tmpstr):
indexes.append("TDdivider")
elif THdivider(tmpstr):
indexes.append("THdivider")
else:
indexes.append("cell")
for index in range(len(indexes)):
if indexes[index] is "TDdivider" or indexes[index] is "THdivider":
ignore = [] # reset ignore
#continue # skip dividers
tmp = rows[index].strip() # clean the row up
tmp = tmp[1:len(tmp)-1] # remove leading + trailing |
offset = 0
# find the start and end of inner
# tables. ignore everything between
if innertable(tmp):
tmpstr = tmp.strip()
while innertable(tmpstr):
start,end = innertable(tmpstr).span()
if not (start,end-1) in ignore:
ignore.append((start,end-1))
tmpstr = " " + tmpstr[end:]
# find the location of column dividers
# NOTE: |'s in inner tables do not count
# as column dividers
if col(tmp):
while col(tmp):
bar = 1 # true if start is not in ignore
start,end = col(tmp).span()
if not start+offset in spans:
for s,e in ignore:
if start+offset >= s or start+offset <= e:
bar = None
break
if bar: # start is clean
spans.append(start+offset)
if not bar:
foo = foo + tmp[:end]
tmp = tmp[end:]
offset = offset + end
else:
COLS.append((foo + tmp[0:start],start+offset))
foo = ""
tmp = " " + tmp[end:]
offset = offset + start
if not offset+len(tmp) in spans:
spans.append(offset+len(tmp))
COLS.append((foo + tmp,offset+len(tmp)))
foo = ""
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
tmp = []
C = []
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 = []
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
# label things as either TableData or
# Table header
TD = []
TH = []
all = []
for index in range(len(indexes)):
if indexes[index] is "TDdivider":
TD.append(index)
all.append(index)
if indexes[index] is "THdivider":
TH.append(index)
all.append(index)
TD = TD[1:]
dividers = all[1:]
#print "TD => ", TD
#print "TH => ", TH
#print "all => ", all, "\n"
for div in dividers:
if div in TD:
index = all.index(div)
for rowindex in range(all[index-1],all[index]):
for i in range(len(rows[rowindex])):
rows[rowindex][i] = (rows[rowindex][i][0],
rows[rowindex][i][1],
"td")
else:
index = all.index(div)
for rowindex in range(all[index-1],all[index]):
for i in range(len(rows[rowindex])):
rows[rowindex][i] = (rows[rowindex][i][0],
rows[rowindex][i][1],
"th")
# now munge the multi-line cells together
# as paragraphs
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] + (row[index][0]) + "\n"
COLS[index][1] = row[index][1]
COLS[index][2] = row[index][2]
# now that each cell has been munged together,
# determine the cell's alignment.
# Default is to center. Also determine the cell's
# vertical alignment, top, middle, bottom. Default is
# to middle
rows = []
cols = []
for row in ROWS:
for index in range(len(row)):
topindent = 0
bottomindent = 0
leftindent = 0
rightindent = 0
left = []
right = []
text = row[index][0]
text = text.split('\n')
text = text[:len(text)-1]
align = ""
valign = ""
for t in text:
t = t.strip()
if not t:
topindent = topindent + 1
else:
break
text.reverse()
for t in text:
t = t.strip()
if not t:
bottomindent = bottomindent + 1
else:
break
text.reverse()
tmp = '\n'.join(text[topindent:len(text)-bottomindent])
pars = re.compile("\n\s*\n").split(tmp)
for par in pars:
if index > 0:
par = par[1:]
par = par.split(' ')
for p in par:
if not p:
leftindent = leftindent+1
else:
break
left.append(leftindent)
leftindent = 0
par.reverse()
for p in par:
if not p:
rightindent = rightindent + 1
else:
break
right.append(rightindent)
rightindent = 0
left.sort()
right.sort()
if topindent == bottomindent:
valign="middle"
elif topindent < 1:
valign="top"
elif bottomindent < 1:
valign="bottom"
else:
valign="middle"
if left[0] < 1:
align = "left"
elif right[0] < 1:
align = "right"
elif left[0] > 1 and right[0] > 1:
align="center"
else:
align="left"
cols.append((row[index][0],row[index][1],align,valign,row[index][2]))
rows.append(cols)
cols = []
return StructuredTextTable(rows,text,subs,indent=paragraph.indent)
def doc_bullet(self, paragraph, expr = re.compile(r'\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(r'(\s*[%s]\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)' % letters).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(r'\s+--\s+').search,
nb=re.compile(r'[^\000- ]').search,
):
top=paragraph.getColorizableTexts()[0]
d=delim(top)
if not d: return None
start, end = d.span()
title=top[:start]
if title.find('\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):
subs=paragraph.getSubparagraphs()
if not subs: return None
top=paragraph.getColorizableTexts()[0]
if not top.strip(): return None
if top[-2:]=='::':
subs=StructuredTextExample(subs)
if top.strip()=='::': return subs
# copy attrs when returning a paragraph
kw = {}
atts = getattr(paragraph, '_attributes', [])
for att in atts: kw[att] = getattr(paragraph, att)
return ST.StructuredTextParagraph(top[:-1], [subs], **kw)
if top.find('\n') >= 0: return None
return StructuredTextSection(top, subs, indent=paragraph.indent)
def doc_literal(
self, s,
expr = re.compile(r"(\W+|^)'([%s%s%s\s]+)'([%s]+|$)" % (letters, digits, literal_punc, phrase_delimiters)).search,):
# old expr... failed to cross newlines.
# expr=re.compile(
# r"(?:\s|^)'" # open
# r"([^ \t\n\r\f\v']|[^ \t\n\r\f\v'][^\n\r']*[^ \t\n\r\f\v'])" # contents
# r"'(?:\s|[,.;:!?]|$)" # close
# ).search):
r=expr(s) #or expr2(s)
if r:
start, end = r.span(2)
return (StructuredTextLiteral(s[start:end]), start-1, end+1)
else:
return None
def doc_emphasize(
self, s,
expr = re.compile(r'\*([%s%s%s\s]+?)\*' % (letters, digits, strongem_punc)).search
#expr = re.compile(r'\s*\*([ \n\r%s0-9.:/;,\'\"\?\-\_\/\=\-\>\<\(\)]+)\*(?!\*|-)' % letters).search # old expr, inconsistent punctuation
):
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(r"\.\.\s*").search,
expr2 = re.compile(r"\[[%s%s]+\]" % (letters, digits) ).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(r"(\.\.\s)(\[[%s0-9]+\])" % letters).search):
result = expr(s)
if result:
start,end = result.span(2)
str = s[start+1:end-1]
st,en = result.span()
return (StructuredTextNamedLink(str),st,en)
return None
def doc_underline(self,
s,
expr=re.compile(r'_([%s%s%s\s]+)_([\s%s]|$)' % (letters, digits, under_punc,phrase_delimiters)).search):
result = expr(s)
if result:
if result.group(1)[:1] == '_':
return None # no double unders
start,end = result.span(1)
st,e = result.span()
return (StructuredTextUnderline(s[start:end]),st,e-len(result.group(2)))
else:
return None
def doc_strong(self,
s,
expr = re.compile(r'\*\*([%s%s%s\s]+?)\*\*' % (letters, digits, strongem_punc)).search
#expr = re.compile(r'\s*\*\*([ \n\r%s0-9.:/;,\'\"\?\-\_\/\=\-\>\<\(\)]+)\*\*(?!\*|-)' % letters).search, # old expr, inconsistent punc, failed to cross newlines.
):
r=expr(s)
if r:
start, end = r.span(1)
return (StructuredTextStrong(s[start:end]), start-2, end+2)
else:
return None
## Some constants to make the doc_href() regex easier to read.
_DQUOTEDTEXT = r'("[ %s0-9\n\r%s]+")' % (letters,dbl_quoted_punc) ## double quoted text
_ABSOLUTE_URL=r'((http|https|ftp|mailto|file|about)[:/]+?[%s0-9_\@\.\,\?\!\/\:\;\-\#\~\=\&\%%\+]+)' % letters
_ABS_AND_RELATIVE_URL=r'([%s0-9_\@\.\,\?\!\/\:\;\-\#\~\=\&\%%\+]+)' % letters
_SPACES = r'(\s*)'
def doc_href1(self, s,
expr=re.compile(_DQUOTEDTEXT + "(:)" + _ABS_AND_RELATIVE_URL + _SPACES).search
):
return self.doc_href(s, expr)
def doc_href2(self, s,
expr=re.compile(_DQUOTEDTEXT + r'(\,\s+)' + _ABSOLUTE_URL + _SPACES).search
):
return self.doc_href(s, expr)
def doc_href(self, s, expr, punctuation=re.compile(r"[\,\.\?\!\;]+").match):
r=expr(s)
if r:
# need to grab the href part and the
# beginning part
start,e = r.span(1)
name = s[start:e]
name = name.replace('"','',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(r"\<[%s0-9\.\=\'\"\:\/\-\#\+\s\*]+\>" % letters).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)
else:
return None
def doc_xref(self, s,
expr = re.compile('\[([%s0-9\-.:/;,\n\r\~]+)\]' % letters).search
):
r = expr(s)
if r:
start, end = r.span(1)
return (StructuredTextXref(s[start:end]), start-1, end+1)
else:
return None
from zope.structuredtext.document import Document as DocumentClass
from zope.structuredtext.stng import (
StructuredTextExample, StructuredTextBullet, StructuredTextNumbered,
StructuredTextDescriptionTitle, StructuredTextDescriptionBody,
StructuredTextDescription, StructuredTextSectionTitle,
StructuredTextSection, StructuredTextTable, StructuredTextRow,
StructuredTextColumn, StructuredTextTableHeader,
StructuredTextTableData, StructuredTextMarkup, StructuredTextLiteral,
StructuredTextEmphasis, StructuredTextStrong, StructuredTextInnerLink,
StructuredTextNamedLink, StructuredTextUnderline, StructuredTextSGML,
StructuredTextLink, StructuredTextXref
)
from zope.deprecation import deprecated
deprecated("DocumentClass",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.document.Document '
'instead.')
......@@ -11,32 +11,15 @@
#
##############################################################################
import re
from DocumentClass import *
class StructuredTextImage(StructuredTextMarkup):
"A simple embedded image"
class DocumentWithImages(DocumentClass):
""" Document with images """
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,
):
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
from zope.structuredtext.stng import StructuredTextImage
from zope.structuredtext.document import DocumentWithImages
from zope.deprecation import deprecated
deprecated("StructuredTextImage",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stng.StructuredTextImage '
'instead.')
deprecated("DocumentWithImages",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.document.DocumentWithImages '
'instead.')
......@@ -11,227 +11,8 @@
#
##############################################################################
from cgi import escape
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):
node_name = doc.getNodeName()
element_type = self.element_types[node_name]
element_method = getattr(self, element_type)
element_method(doc, level, output)
def __call__(self, doc, level=1, header=1):
r=[]
self.header = header
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):
children=doc.getChildNodes()
if self.header:
output('<html>\n')
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:
self.dispatch(c, level, output)
if self.header:
output('</body>\n')
output('</html>\n')
def section(self, doc, level, output):
children=doc.getChildNodes()
for c in children:
self.dispatch(c, level+1, output)
def sectionTitle(self, doc, level, output):
output('<h%d>' % (level))
for c in doc.getChildNodes():
self.dispatch(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():
self.dispatch(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():
self.dispatch(c, level, output)
output('</dt>\n')
def descriptionBody(self, doc, level, output):
output('<dd>')
for c in doc.getChildNodes():
self.dispatch(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('\n<ul>\n')
output('<li>')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
n=doc.getNextSibling()
output('</li>\n')
if n is None or n.getNodeName() is not doc.getNodeName():
output('\n</ul>\n')
def numbered(self, doc, level, output):
p=doc.getPreviousSibling()
if p is None or p.getNodeName() is not doc.getNodeName():
output('\n<ol>\n')
output('<li>')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
n=doc.getNextSibling()
output('</li>\n')
if n is None or n.getNodeName() is not doc.getNodeName():
output('\n</ol>\n')
def example(self, doc, level, output):
i=0
for c in doc.getChildNodes():
if i==0:
output('\n<pre>\n')
output(escape(c.getNodeValue()))
output('\n</pre>\n')
else:
self.dispatch(c, level, output)
def paragraph(self, doc, level, output):
output('<p>')
for c in doc.getChildNodes():
if c.getNodeName() in ['StructuredTextParagraph']:
self.dispatch(c, level, output)
else:
self.dispatch(c, level, output)
output('</p>\n')
def link(self, doc, level, output):
output('<a href="%s">' % doc.href)
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output('</a>')
def emphasis(self, doc, level, output):
output('<em>')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output('</em>')
def literal(self, doc, level, output):
output('<code>')
for c in doc.getChildNodes():
output(escape(c.getNodeValue()))
output('</code>')
def strong(self, doc, level, output):
output('<strong>')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output('</strong>')
def underline(self, doc, level, output):
output("<u>")
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output("</u>")
def innerLink(self, doc, level, output):
output('<a href="#ref');
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output('">[')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output(']</a>')
def namedLink(self, doc, level, output):
output('<a name="ref')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output('">[')
for c in doc.getChildNodes():
self.dispatch(c, level, output)
output(']</a>')
def sgml(self,doc,level,output):
for c in doc.getChildNodes():
self.dispatch(c, level, output)
def xref(self, doc, level, output):
val = doc.getNodeValue()
output('<a href="#ref%s">[%s]</a>' % (val, val) )
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]:
if hasattr(column,"getAlign"):
str = '<%s colspan="%s" align="%s" valign="%s">' % (column.getType(),
column.getSpan(),
column.getAlign(),
column.getValign())
else:
str = '<td colspan="%s">' % column.getSpan()
output(str)
for c in column.getChildNodes():
self.dispatch(c, level, output)
if hasattr(column,"getType"):
output("</"+column.getType()+">\n")
else:
output("</td>\n")
output("</tr>\n")
output("</table>\n")
from zope.structuredtext.html import HTML as HTMLClass
from zope.deprecation import deprecated
deprecated("HTMLClass",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.html.HTML instead.')
......@@ -11,20 +11,9 @@
#
##############################################################################
from HTMLClass import HTMLClass
ets = HTMLClass.element_types
ets.update({'StructuredTextImage': 'image'})
class HTMLWithImages(HTMLClass):
element_types = ets
def image(self, doc, level, output):
if hasattr(doc, 'key'):
output('<a name="%s"></a>\n' % doc.key)
output('<img src="%s" alt="%s" />\n' % (doc.href, doc.getNodeValue()))
if doc.getNodeValue() and hasattr(doc, 'key'):
output('<p><b>Figure %s</b> %s</p>\n' % (doc.key, doc.getNodeValue()))
from zope.structuredtext.html import HTMLWithImages
from zope.deprecation import deprecated
deprecated("HTMLWithImages",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.html.HTMLWithImages '
'instead.')
......@@ -11,288 +11,23 @@
#
##############################################################################
import re, STDOM
from types import ListType
#####################################################################
# Updated functions #
#####################################################################
def indention(str,front = re.compile("^\s+").match):
"""
Find the number of leading spaces. If none, return 0.
"""
result = front(str)
if result is not None:
start, end = result.span()
return end-start
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)):
if struct:
return struct[len(struct)-1].getSubparagraphs()
return struct
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
para_delim = r'(\n\s*\n|\r\n\s*\r\n)' # UNIX or DOS line endings, respectively
#####################################################################
# Golly, the capitalization of this function always makes me think it's a class
def StructuredText(paragraphs, delimiter=re.compile(para_delim)):
"""
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 = paragraphs.expandtabs()
paragraphs = '%s%s%s' % ('\n\n', paragraphs, '\n\n')
paragraphs = delimiter.split(paragraphs)
paragraphs = [ x for x in paragraphs if x.strip() ]
if not paragraphs: return StructuredTextDocument()
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
if not level:
struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
else:
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
currentindent = indent
run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel))
return StructuredTextDocument(struct)
from zope.structuredtext.stng import \
indention, insert, display, display2, findlevel
from zope.structuredtext.stng import structurize as StructuredText
from zope.structuredtext.stng import \
StructuredTextParagraph, StructuredTextDocument
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):
src=self._src
if not isinstance(src, ListType): 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))
else:
return None
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 '\n'.join(r)
"""
create aliases for all above functions in the pythony way.
"""
def _get_Children(self):
return self.getChildren()
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):
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 '\n'.join(r)
"""
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)
from zope.deprecation import deprecated
deprecated(("StructuredText", "Basic"),
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stng.structurize '
'instead.')
deprecated("StructuredTextParagraph",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stng.StructuredTextParagraph '
'instead.')
deprecated("StructuredTextDocument",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stng.StructuredTextDocument '
'instead.')
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
DOM implementation in StructuredText : Read-Only methods
All standard Zope objects support DOM to a limited extent.
"""
from types import StringType, UnicodeType
StringTypes = (StringType, UnicodeType)
# 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, sts=StringTypes):
"""
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) in sts: n=TextNode(n)
r.append(n.__of__(self))
return NodeList(r)
def getFirstChild(self, type=type, sts=StringTypes):
"""
The first child of this node. If there is no such node
this returns None
"""
children = self.getChildren()
if not children:
return None
n=children[0]
if type(n) in sts:
n=TextNode(n)
return n.__of__(self)
def getLastChild(self, type=type, sts=StringTypes):
"""
The last child of this node. If there is no such node
this returns None.
"""
children = self.getChildren()
if not children: return None
n=children[-1]
if type(n) in sts: n=TextNode(n)
return n.__of__(self)
"""
create aliases for all above functions in the pythony way.
"""
def _get_ChildNodes(self, type=type, sts=StringTypes):
return self.getChildNodes(type,sts)
def _get_FirstChild(self, type=type, sts=StringTypes):
return self.getFirstChild(type,sts)
def _get_LastChild(self, type=type, sts=StringTypes):
return self.getLastChild(type,sts)
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):
"""
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) in StringTypes:
n=TextNode(n)
n._DOMIndex=index
return n.__of__(self)
def getNextSibling(self):
"""
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) in StringTypes:
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):
return self.getPreviousSibling()
def _get_NextSibling(self):
return self.getNextSibling()
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,
sts=StringTypes,
getattr=getattr):
"""
The node immediately preceding this node. If
there is no such node, this returns None.
"""
def getNextSibling(self, type=type, sts=StringTypes):
"""
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):
return self.getPreviousSibling()
def _get_NextSibling(self):
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):
r=[]
for c in self.getChildren():
if type(c) not in StringTypes:
c=c.getNodeValue()
r.append(c)
return ''.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 not hasattr(child, 'getNodeType'): continue
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):
return self.getNodeValue()
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, sts=StringTypes):
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()
Using Structured Text
WARNING! The 'StructuredText' package has been deprecated and will
be removed in Zope 2.12. Use 'zope.structuredtext' instead.
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
......@@ -108,9 +111,3 @@ 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.
import string
def punc_func(exclude):
punc = r''
for char in string.punctuation:
if char not in exclude:
punc = punc + r'\%s' % char
return punc
digits = string.digits
letters = string.letters
literal_punc = punc_func("'")
dbl_quoted_punc = punc_func("\"")
strongem_punc = punc_func('*')
under_punc = punc_func('_<>')
phrase_delimiters = r'\s\.\,\?\/\!\&\(\)'
......@@ -10,49 +10,21 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
""" Alias module for StructuredTextClassic compatibility which makes
use of StructuredTextNG """
import HTMLClass, DocumentClass
import DocumentWithImages, HTMLWithImages
from ST import Basic
import re, sys
from STletters import letters
Document = DocumentClass.DocumentClass()
HTMLNG = HTMLClass.HTMLClass()
DocumentImages = DocumentWithImages.DocumentWithImages()
HTMLNGImages = HTMLWithImages.HTMLWithImages()
def HTML(aStructuredString, level=1, header=1):
st = Basic(aStructuredString)
doc = DocumentImages(st)
return HTMLNGImages(doc,header=header,level=level)
def StructuredText(aStructuredString, level=1):
return HTML(aStructuredString,level)
def html_with_references(text, level=1, header=1):
text = re.sub(
r'[\000\n]\.\. \[([0-9_%s-]+)\]' % letters,
r'\n <a name="\1">[\1]</a>',
text)
text = re.sub(
r'([\000- ,])\[(?P<ref>[0-9_%s-]+)\]([\000- ,.:])' % letters,
r'\1<a href="#\2">[\2]</a>\3',
text)
text = re.sub(
r'([\000- ,])\[([^]]+)\.html\]([\000- ,.:])',
r'\1<a href="\2.html">[\2]</a>\3',
text)
return HTML(text,level=level,header=header)
"""Alias module for StructuredTextClassic compatibility which makes
use of StructuredTextNG"""
import re
from zope.structuredtext import stx2html as HTML
from zope.structuredtext import stx2htmlWithReferences as html_with_references
StructuredText = HTML
from zope.deprecation import deprecated
deprecated(("HTML, StructuredText"),
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stx2html instead.')
deprecated("html_with_references",
'The StructuredText package is deprecated and will be removed '
'in Zope 2.12. Use zope.structuredtext.stx2htmlWithReferences '
'instead.')
def html_quote(v,
character_entities=(
......@@ -66,7 +38,6 @@ def html_quote(v,
text=re.sub(name,text)
return text
if __name__=='__main__':
import getopt
......
......@@ -11,36 +11,35 @@
#
##############################################################################
from zope.structuredtext import html, document, docbook
from zope.structuredtext.stng import structurize as Basic
import warnings
warnings.warn('Using StructuredText is deprecated (will be removed in Zope '
'2.12). Instead use zope.structuredtext.',
DeprecationWarning,
stacklevel=2)
from StructuredText import html_quote
from zope.structuredtext import stx2html as HTML
from zope.structuredtext import stx2htmlWithReferences as html_with_references
from types import StringType, UnicodeType
# BBB -- 2006/01/08 -- Remove in Zope 2.12
import sys
import zope.structuredtext.stletters
import zope.structuredtext.stdom
sys.modules['StructuredText.STletters'] = zope.structuredtext.stletters
sys.modules['StructuredText.STDOM'] = zope.structuredtext.stdom
import HTMLClass, DocumentClass
import ClassicDocumentClass
from StructuredText import html_with_references, HTML, html_quote
from ST import Basic
import DocBookClass
import HTMLWithImages
from types import StringType, UnicodeType
import DocumentWithImages
Classic = ClassicDocumentClass.DocumentClass()
Document = document.Document()
DocumentWithImages = document.DocumentWithImages()
HTMLWithImages = html.HTMLWithImages()
ClassicHTML = html.HTML
HTMLNG = html.HTML()
ClassicHTML=HTML
HTMLNG=HTMLClass.HTMLClass()
DocBookBook = docbook.DocBookBook()
DocBookChapter = docbook.DocBookChapter()
DocBookChapterWithFigures = docbook.DocBookChapterWithFigures()
DocBookArticle = docbook.DocBookArticle()
def HTML(src, level=1):
if isinstance(src, StringType) or isinstance(src, UnicodeType):
if isinstance(src, basestring):
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()
......@@ -11,6 +11,7 @@
#
##############################################################################
import zope.deprecation
from StructuredText import ST
from StructuredText import DocumentClass
from StructuredText import ClassicDocumentClass
......@@ -46,6 +47,12 @@ def readFile(dirname,fname):
class StructuredTextTests(unittest.TestCase):
def setUp(self):
zope.deprecation.__show__.off()
def tearDown(self):
zope.deprecation.__show__.on()
def testStructuredText(self):
""" testing StructuredText """
......@@ -134,6 +141,12 @@ class StructuredTextTests(unittest.TestCase):
class BasicTests(unittest.TestCase):
def setUp(self):
zope.deprecation.__show__.off()
def tearDown(self):
zope.deprecation.__show__.on()
def _test(self,stxtxt , expected):
if not isinstance(stxtxt, UnicodeType):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment