class Edition(mg.Grammar): '''Parse an edition comment.''' grammar = (mg.OPTIONAL(WhiteSpace), mg.OR(Digit, TwoDigit), mg.OR(mg.L('nd'), mg.L('rd'), mg.L('st'), mg.L('th')), mg.OPTIONAL(mg.OR(mg.L('facsimile'), mg.L('revised'))), mg.L('edition'), mg.L(';')) def grammar_elem_init(self, sessiondata): '''initialize the element.''' self.edition_num = self[1].string
class UnorderedListItem(modgrammar.Grammar): """Defines the grammar for an unordered list item.""" grammar = (modgrammar.BOL, modgrammar.OR(modgrammar.L("* "), modgrammar.L("- "), modgrammar.L("+ ")), modgrammar.REPEAT(modgrammar.OR(Bold, Italic, InlineCode, Link, AutomaticLink, SimpleText), collapse=True)) def grammar_elem_init(self, sessiondata): """Saves the text for later use.""" self.tag = "li"
class MetaCharacter(modgrammar.Grammar): grammar_whitespace_mode = 'explicit' grammar = (modgrammar.OR(modgrammar.L(';'), modgrammar.L('='), modgrammar.L('|'), modgrammar.L('*'), modgrammar.L('+'), modgrammar.L('<'), modgrammar.L('>'), modgrammar.L('('), modgrammar.L(')'), modgrammar.L('['), modgrammar.L(']'), modgrammar.L('{'), modgrammar.L('}'), modgrammar.L('/*'), modgrammar.L('*/'), modgrammar.L('//'), modgrammar.L(" "), modgrammar.L('"')))
class Text(modgrammar.Grammar): """Defines the grammar for normal text.""" grammar = (modgrammar.REPEAT(modgrammar.BOL, modgrammar.REPEAT(modgrammar.OR( Bold, Italic, InlineCode, Link, AutomaticLink, SimpleText), collapse=True), modgrammar.EOL, collapse=True)) def grammar_elem_init(self, sessiondata): """Appends a space to each SimpleText that is followed by an EOL character.""" highest_index = len(self.elements) - 1 current_index = -1 add_space_at_start = False for elem in self.elements: current_index += 1 _length = len(elem.elements) _eol_index = _length - 1 _first_content_index = 1 _last_content_index = _eol_index - 1 if add_space_at_start and elem[ _first_content_index].grammar_name == "SimpleText": elem[_first_content_index].text = " " + elem[ _first_content_index].text add_space_at_start = False if current_index < highest_index: if elem[_last_content_index].grammar_name == "SimpleText": text = elem[_last_content_index].text.rstrip() elem[_last_content_index].text = text + " " else: add_space_at_start = True
class Time(mg.Grammar): grammar_whitespace_mode = 'explicit' unit_lookup = { 's': 'sec', 'sec': 'sec', 'm': 'min', 'min': 'min', 'h': 'hour', 'hour': 'hour', } grammar = ( mg.OPTIONAL(QUANTITY_RANGE_APPROX_FLAG), PosNumber, mg.OPTIONAL(mg.GRAMMAR( QUANTITY_RANGE_SEPARATOR, PosNumber, ), ), mg.OPTIONAL(QUANTITY_RANGE_APPROX_FLAG), mg.WHITESPACE, mg.OR(*unit_lookup.keys()), ) def value(self): return { 'less_ok': True if self[0] else False, 'base': self[1].value().numerator, 'base_den': self[1].value().denominator, 'range': self[2][1].value().numerator if self[2] else 0, 'range_den': self[2][1].value().denominator if self[2] else 1, 'units': self.unit_lookup[self[5].string], }
class QuoteLine(modgrammar.Grammar): """Defines the grammar for a single line quote.""" grammar = (modgrammar.BOL, modgrammar.L(">"), modgrammar.REPEAT(modgrammar.OR(Bold, Italic, InlineCode, Link, AutomaticLink, SimpleText), collapse=True), modgrammar.EOL) grammar_collapse = False
class PosDecimal(mg.Grammar): grammar_whitespace_mode = 'explicit' grammar = mg.OR( (NonNegInteger, DECIMAL_SEPARATOR, PosInteger), (PosInteger, DECIMAL_SEPARATOR, NonNegInteger), ) def value(self): return fractions.Fraction(self.string)
class PosMixedNum(mg.Grammar): grammar_whitespace_mode = 'explicit' grammar = mg.OR( (PosInteger, MIXED_NUM_SEPARATOR, NonNegFraction), (NonNegInteger, MIXED_NUM_SEPARATOR, PosFraction), ) def value(self): return self[0][0].value() + self[0][2].value()
class MarkdownGrammar(modgrammar.Grammar): """Provides the grammar for Markdown.""" grammar = (modgrammar.REPEAT(modgrammar.OR(Heading, UnorderedList, OrderedList, Quote, Paragraph, EmptyLine, PreBlock), collapse=True)) def grammar_elem_init(self, sessiondata): """Saves the text for later use.""" self.content = self[0].string
class VariantSlotFilter(mg.Grammar): grammar = ( VARIANT_SLOT_SIGIL, mg.OR( SlotFilterAllowAll, SlotFilterBlockAll, SlotFilterCustom, ), ) def value(self): return self[1].value()
class SlotIndices(mg.Grammar): grammar = mg.LIST_OF(mg.OR(SlotIndex, SlotIndexRange), sep=SEQUENCE_ITEM_SEPARATOR, min=1) def value(self): return frozenset(self.yield_value()) def yield_value(self): yield from itertools.chain.from_iterable( s.yield_value() for s in self[0] if s.string != SEQUENCE_ITEM_SEPARATOR)
class Word2(mg.Grammar): '''unicode word or abbreviation''' grammar = (mg.OR(Word, Abrv))
class Comment(mg.Grammar): '''Parse a comment string.''' grammar = (mg.OR(Edition, Compilers, Contributors, Reference, Reprint, Editors, Translation, Publishers, Language, Other))
class Reprint(mg.Grammar): '''Parse a reprint comment.''' grammar = (mg.OPTIONAL(WhiteSpace), mg.L('reprint of'), mg.OR(AJBNum, Year), mg.L(';'))
class PosNumber(mg.Grammar): grammar = mg.OR(PosMixedNum, PosFraction, PosDecimal, PosInteger) def value(self): return self[0].value()
class NonNegNumber(mg.Grammar): grammar = mg.OR(NonNegMixedNum, NonNegFraction, NonNegDecimal, NonNegInteger) def value(self): return self[0].value()