Changeset 389
- Timestamp:
- 01/19/2010 05:03:28 PM (8 months ago)
- Location:
- projects/wikiparser/trunk
- Files:
-
- 1 added
- 3 modified
-
tests/test_matches.py (modified) (2 diffs)
-
wikiparser/formats/textbook/matchers.py (modified) (2 diffs)
-
wikiparser/match/core.py (modified) (4 diffs)
-
wikiparser/textify.py (added)
Legend:
- Unmodified
- Added
- Removed
-
projects/wikiparser/trunk/tests/test_matches.py
r386 r389 2 2 import re 3 3 4 from wikiparser.markup import BREAK, StreamTree, tostring4 from wikiparser.markup import ATTR, BREAK, StreamTree, tostring 5 5 from wikiparser.match.blocks import LineStart, BlockStart, BreakBefore, BreakAfter, PyConsole 6 from wikiparser.match.core import Suppress, OneOrMore, ZeroOrMore, StringEnd, Not, FollowedBy 7 from wikiparser.match.data import Element 6 from wikiparser.match.core import (Literal, Events, 7 Suppress, OneOrMore, ZeroOrMore, StringEnd, Not, 8 FollowedBy) 9 from wikiparser.match.data import Element, Attr 8 10 from wikiparser.match.text import Mixed, Regex, Until 9 11 … … 135 137 (BREAK, (0, 0, {})), 'Nice, huh?\n', 85 136 138 ]) 137 139 140 def test_orelse(self): 141 m = Suppress(":") + Attr("type", Regex("[^:]+") | Events("item")) + Suppress(":") 142 stream = list(m.stream(":blah:")) 143 self.assertEqual(stream, [(ATTR, ('type', 'blah', True)), 6]) 144 stream = list(m.stream("::")) 145 self.assertEqual(stream, [(ATTR, ('type', 'item', True)), 2]) 138 146 139 147 if __name__ == '__main__': -
projects/wikiparser/trunk/wikiparser/formats/textbook/matchers.py
r376 r389 16 16 17 17 from wikiparser.markup import HTML, WIKI 18 from wikiparser.match.blocks import BlockStart, BreakAfter, IndentChange, LineStart, StartMarker 19 from wikiparser.match.core import Choice, Escape, FollowedBy, Optional, Suppress, ZeroOrMore 20 from wikiparser.match.data import AttrIf, Element, RegexAttr 18 from wikiparser.match.blocks import (BlockStart, BreakAfter, IndentChange, LineStart, 19 StartMarker) 20 from wikiparser.match.core import (Choice, Escape, Events, FollowedBy, Optional, Suppress, 21 ZeroOrMore) 22 from wikiparser.match.data import Attr, AttrIf, Element, RegexAttr 21 23 from wikiparser.match.text import (CharacterEntities, Mixed, Regex, SmartQuotes, 22 24 Substitution, Until) … … 134 136 bullet = LineStart(type="bullet") + StartMarker("[*-]+ ", first_chars="*-") 135 137 ordinal = LineStart(type="ord") + StartMarker("#+\\.? ", first_chars="#") 136 item = (LineStart( type="item")137 + Suppress(": :")138 item = (LineStart() 139 + Suppress(":") + Attr("type", Regex("[A-Za-z_][A-Za-z_0-9]*") | Events("item")) + Suppress(":") 138 140 + Mixed(inlinecontent_lb, ":", inlineonly=True) 139 141 + Suppress(":\n")) -
projects/wikiparser/trunk/wikiparser/match/core.py
r384 r389 19 19 20 20 from wikiparser.events import BREAK, br, isbr 21 from wikiparser.filters.streams import textof 21 22 22 23 … … 555 556 class Apply(Wrapper): 556 557 """Buffers events from the sub-matcher, then calls a function on the queued 557 events. The events returned by the function, if any, are then yielded. 558 """ 559 560 def __init__(self, function, matcher): 558 events. Any event(s) returned by the function are then emitted. 559 """ 560 561 def __init__(self, function, matcher, astext=False): 562 """ 563 :param function: the function to call on the wrapped matcher's events. 564 :param matcher: the wrapped matcher. 565 :param astext: if True, the text from the wrapped matcher's events is 566 extracted and the function is called on the extracted string, 567 instead of on a list of events. 568 """ 569 561 570 Wrapper.__init__(self, matcher) 562 571 self.function = function 572 self.astext = astext 563 573 564 574 def parse(self, input, position, ctx): … … 571 581 572 582 if queue: 573 for ev in self.function(queue): 574 yield ev 583 if self.astext: 584 yield self.function(textof(queue)) 585 else: 586 for ev in self.function(queue): 587 yield ev 575 588 yield position 576 589 … … 595 608 596 609 597 class Replace(Wrapper): 598 """Replaces the output of the wrapped matcher with a pre-defined stream. 610 class Events(Matcher): 611 """Inserts events into the stream. This is useful as a kind of "else" 612 clause when used as the last matcher in a Choice matcher, to insert 613 pre-determined events in the case where the other matchers don't match. 614 615 For example, say you want a matcher that either matches a pattern like 616 `:typename:`, or allows the "typename" to be missing, in which case it 617 should be set to "item":: 618 619 Suppress(":") + Attr("type", Regex("[^:]+") | Events("item")) + Suppress(":") 620 """ 621 622 def __init__(self, *events): 623 """Takes a variable number of arguments, where the arguments are used 624 as the list of events to emit. 625 """ 626 self.events = events 627 628 def parse(self, input, position, ctx): 629 for ev in self.events: 630 yield ev 631 yield position 632 633 634 class EventsIf(Wrapper): 635 """If the wrapped matcher matches, replaces its events with a predefined 636 stream. 599 637 """ 600 638
