listing20-5.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. class Rule:
  2. """
  3. Base class for all rules.
  4. """
  5. def action(self, block, handler):
  6. handler.start(self.type)
  7. handler.feed(block)
  8. handler.end(self.type)
  9. return True
  10. class HeadingRule(Rule):
  11. """
  12. A heading is a single line that is at most 70 characters and
  13. that doesn't end with a colon.
  14. """
  15. type = 'heading'
  16. def condition(self, block):
  17. return not '\n' in block and len(block) <= 70 and not block[-1] == ':'
  18. class TitleRule(HeadingRule):
  19. """
  20. The title is the first block in the document, provided that
  21. it is a heading.
  22. """
  23. type = 'title'
  24. first = True
  25. def condition(self, block):
  26. if not self.first: return False
  27. self.first = False
  28. return HeadingRule.condition(self, block)
  29. class ListItemRule(Rule):
  30. """
  31. A list item is a paragraph that begins with a hyphen. As part of the
  32. formatting, the hyphen is removed.
  33. """
  34. type = 'listitem'
  35. def condition(self, block):
  36. return block[0] == '-'
  37. def action(self, block, handler):
  38. handler.start(self.type)
  39. handler.feed(block[1:].strip())
  40. handler.end(self.type)
  41. return True
  42. class ListRule(ListItemRule):
  43. """
  44. A list begins between a block that is not a list item and a
  45. subsequent list item. It ends after the last consecutive list item.
  46. """
  47. type = 'list'
  48. inside = False
  49. def condition(self, block):
  50. return True
  51. def action(self, block, handler):
  52. if not self.inside and ListItemRule.condition(self, block):
  53. handler.start(self.type)
  54. self.inside = True
  55. elif self.inside and not ListItemRule.condition(self, block):
  56. handler.end(self.type)
  57. self.inside = False
  58. return False
  59. class ParagraphRule(Rule):
  60. """
  61. A paragraph is simply a block that isn't covered by any of the other rules.
  62. """
  63. type = 'paragraph'
  64. def condition(self, block):
  65. return True