Browse Source

Working bold/italics implementation (ugly, will clean up)

tags/v0.3
Ben Kurtovic 10 years ago
parent
commit
992e7018ae
1 changed files with 126 additions and 29 deletions
  1. +126
    -29
      mwparserfromhell/parser/tokenizer.py

+ 126
- 29
mwparserfromhell/parser/tokenizer.py View File

@@ -632,8 +632,8 @@ class Tokenizer(object):
def _really_parse_style(self, context):
"""Parse wiki-style bold or italics. Raises :py:exc:`BadRoute`."""
stack = self._parse(context)
markup = "''" if context == contexts.STYLE_ITALICS else "'''"
tag = "i" if context == contexts.STYLE_ITALICS else "b"
markup = "''" if context & contexts.STYLE_ITALICS else "'''"
tag = "i" if context & contexts.STYLE_ITALICS else "b"

self._emit(tokens.TagOpenOpen(wiki_markup=markup))
self._emit_text(tag)
@@ -659,27 +659,128 @@ class Tokenizer(object):
self._emit_text("'")
ticks = 3

if ticks == 5:
raise NotImplementedError()
if ticks == 3:
try:
return self._really_parse_style(contexts.STYLE_BOLD)
except BadRoute:
if ticks == 2:
if self._context & contexts.STYLE_ITALICS:
return self._pop()
if self._can_recurse():
try:
self._really_parse_style(contexts.STYLE_ITALICS)
except BadRoute:
self._head = reset
try: ## only if STYLE_PASS_AGAIN in destroyed context
self._really_parse_style(contexts.STYLE_ITALICS|contexts.STYLE_PASS_2)
except BadRoute:
self._head = reset
self._emit_text("''")
else:
self._emit_text("''")
elif ticks == 3:
if self._context & contexts.STYLE_BOLD:
return self._pop()
elif self._can_recurse():
try:
self._really_parse_style(contexts.STYLE_BOLD)
except BadRoute:
self._head = reset
if self._context & contexts.STYLE_ITALICS:
if self._context & contexts.STYLE_PASS_2:
self._emit_text("'")
return self._pop()
self._emit_text("'''") ## here is our hook for STYLE_PASS_AGAIN
else:
self._emit_text("'")
try:
self._really_parse_style(contexts.STYLE_ITALICS)
except BadRoute:
self._head = reset
try: ## only if STYLE_PASS_AGAIN in destroyed context
self._really_parse_style(contexts.STYLE_ITALICS|contexts.STYLE_PASS_2)
except BadRoute:
self._head = reset
self._emit_text("''")
elif self._context & contexts.STYLE_ITALICS and self._context & contexts.STYLE_PASS_2:
self._emit_text("'")
self._head = reset
try:
self._really_parse_style(contexts.STYLE_ITALICS)
except BadRoute:
self._emit_text("''")
self._head = reset - 1

def _handle_style_end(self):
"""Handle the end of wiki-style italics or bold (``''`` or ``'''``)."""
self._head += 1 if self._context & contexts.STYLE_ITALICS else 2
while self._read(1) == "'":
self._emit_text("'")
self._head += 1
return self._pop()
return self._pop()
else: ## here is our hook for STYLE_PASS_AGAIN
self._emit_text("'''")
elif ticks == 5:
if self._context & contexts.STYLE_ITALICS:
self._head -= 3
return self._pop()
elif self._context & contexts.STYLE_BOLD:
self._head -= 2
return self._pop()
elif self._can_recurse():
try:
stack = self._parse(contexts.STYLE_BOLD)
except BadRoute:
self._head = reset
try:
stack = self._parse(contexts.STYLE_ITALICS)
except BadRoute:
self._head = reset
self._emit_text("'''''")
else:
reset = self._head
try:
stack2 = self._parse(contexts.STYLE_BOLD)
except BadRoute:
self._head = reset
self._emit_text("'''")
self._emit(tokens.TagOpenOpen(wiki_markup="''"))
self._emit_text("i")
self._emit(tokens.TagCloseOpen())
self._emit_all(stack)
self._emit(tokens.TagOpenClose())
self._emit_text("i")
self._emit(tokens.TagCloseClose())
else:
self._emit(tokens.TagOpenOpen(wiki_markup="'''"))
self._emit_text("b")
self._emit(tokens.TagCloseOpen())
self._emit(tokens.TagOpenOpen(wiki_markup="''"))
self._emit_text("i")
self._emit(tokens.TagCloseOpen())
self._emit_all(stack)
self._emit(tokens.TagOpenClose())
self._emit_text("i")
self._emit(tokens.TagCloseClose())
self._emit_all(stack2)
self._emit(tokens.TagOpenClose())
self._emit_text("b")
self._emit(tokens.TagCloseClose())
else:
reset = self._head
try:
stack2 = self._parse(contexts.STYLE_ITALICS)
except BadRoute:
self._head = reset
self._emit_text("''")
self._emit(tokens.TagOpenOpen(wiki_markup="'''"))
self._emit_text("b")
self._emit(tokens.TagCloseOpen())
self._emit_all(stack)
self._emit(tokens.TagOpenClose())
self._emit_text("b")
self._emit(tokens.TagCloseClose())
else:
self._emit(tokens.TagOpenOpen(wiki_markup="''"))
self._emit_text("i")
self._emit(tokens.TagCloseOpen())
self._emit(tokens.TagOpenOpen(wiki_markup="'''"))
self._emit_text("b")
self._emit(tokens.TagCloseOpen())
self._emit_all(stack)
self._emit(tokens.TagOpenClose())
self._emit_text("b")
self._emit(tokens.TagCloseClose())
self._emit_all(stack2)
self._emit(tokens.TagOpenClose())
self._emit_text("i")
self._emit(tokens.TagCloseClose())
else:
self._emit_text("'''''")
self._head -= 1

def _handle_list_marker(self):
"""Handle a list marker at the head (``#``, ``*``, ``;``, ``:``)."""
@@ -871,13 +972,9 @@ class Tokenizer(object):
elif this == ">" and self._context & contexts.TAG_CLOSE:
return self._handle_tag_close_close()
elif this == next == "'":
if not self._context & contexts.STYLE and self._can_recurse():
self._parse_style()
elif (self._context & contexts.STYLE_ITALICS or
self._read(2) == "'" and self._context & contexts.STYLE_BOLD):
return self._handle_style_end()
else:
self._emit_text("'")
result = self._parse_style()
if result is not None:
return result
elif self._read(-1) in ("\n", self.START):
if this in ("#", "*", ";", ":"):
self._handle_list()


Loading…
Cancel
Save