bbcode.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.formatters.bbcode
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. BBcode formatter.
  6. :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. from pygments.formatter import Formatter
  10. from pygments.util import get_bool_opt
  11. __all__ = ['BBCodeFormatter']
  12. class BBCodeFormatter(Formatter):
  13. """
  14. Format tokens with BBcodes. These formatting codes are used by many
  15. bulletin boards, so you can highlight your sourcecode with pygments before
  16. posting it there.
  17. This formatter has no support for background colors and borders, as there
  18. are no common BBcode tags for that.
  19. Some board systems (e.g. phpBB) don't support colors in their [code] tag,
  20. so you can't use the highlighting together with that tag.
  21. Text in a [code] tag usually is shown with a monospace font (which this
  22. formatter can do with the ``monofont`` option) and no spaces (which you
  23. need for indentation) are removed.
  24. Additional options accepted:
  25. `style`
  26. The style to use, can be a string or a Style subclass (default:
  27. ``'default'``).
  28. `codetag`
  29. If set to true, put the output into ``[code]`` tags (default:
  30. ``false``)
  31. `monofont`
  32. If set to true, add a tag to show the code with a monospace font
  33. (default: ``false``).
  34. """
  35. name = 'BBCode'
  36. aliases = ['bbcode', 'bb']
  37. filenames = []
  38. def __init__(self, **options):
  39. Formatter.__init__(self, **options)
  40. self._code = get_bool_opt(options, 'codetag', False)
  41. self._mono = get_bool_opt(options, 'monofont', False)
  42. self.styles = {}
  43. self._make_styles()
  44. def _make_styles(self):
  45. for ttype, ndef in self.style:
  46. start = end = ''
  47. if ndef['color']:
  48. start += '[color=#%s]' % ndef['color']
  49. end = '[/color]' + end
  50. if ndef['bold']:
  51. start += '[b]'
  52. end = '[/b]' + end
  53. if ndef['italic']:
  54. start += '[i]'
  55. end = '[/i]' + end
  56. if ndef['underline']:
  57. start += '[u]'
  58. end = '[/u]' + end
  59. # there are no common BBcodes for background-color and border
  60. self.styles[ttype] = start, end
  61. def format_unencoded(self, tokensource, outfile):
  62. if self._code:
  63. outfile.write('[code]')
  64. if self._mono:
  65. outfile.write('[font=monospace]')
  66. lastval = ''
  67. lasttype = None
  68. for ttype, value in tokensource:
  69. while ttype not in self.styles:
  70. ttype = ttype.parent
  71. if ttype == lasttype:
  72. lastval += value
  73. else:
  74. if lastval:
  75. start, end = self.styles[lasttype]
  76. outfile.write(''.join((start, lastval, end)))
  77. lastval = value
  78. lasttype = ttype
  79. if lastval:
  80. start, end = self.styles[lasttype]
  81. outfile.write(''.join((start, lastval, end)))
  82. if self._mono:
  83. outfile.write('[/font]')
  84. if self._code:
  85. outfile.write('[/code]')
  86. if self._code or self._mono:
  87. outfile.write('\n')