creole_reader.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #-*- conding: utf-8 -*-
  2. '''
  3. Creole Reader
  4. -------------
  5. This plugins allows you to write your posts using the wikicreole syntax. Give to
  6. these files the creole extension.
  7. For the syntax, look at: http://www.wikicreole.org/
  8. '''
  9. from pelican import readers
  10. from pelican import signals
  11. from pelican import settings
  12. from pelican.utils import pelican_open
  13. try:
  14. from creole import creole2html
  15. creole = True
  16. except ImportError:
  17. creole = False
  18. try:
  19. from pygments import lexers
  20. from pygments.formatters import HtmlFormatter
  21. from pygments import highlight
  22. PYGMENTS = True
  23. except:
  24. PYGMENTS = False
  25. class CreoleReader(readers.BaseReader):
  26. enabled = creole
  27. file_extensions = ['creole']
  28. def __init__(self, settings):
  29. super(CreoleReader, self).__init__(settings)
  30. def _parse_header_macro(self, text):
  31. for line in text.split('\n'):
  32. name, value = line.split(':')
  33. name, value = name.strip(), value.strip()
  34. if name == 'title':
  35. self._metadata[name] = value
  36. else:
  37. self._metadata[name] = self.process_metadata(name, value)
  38. return u''
  39. def _no_highlight(self, text):
  40. html = u'\n<pre><code>{}</code></pre>\n'.format(text)
  41. return html
  42. def _get_lexer(self, source_type, code):
  43. try:
  44. return lexers.get_lexer_by_name(source_type)
  45. except:
  46. return lexers.guess_lexer(code)
  47. def _get_formatter(self):
  48. formatter = HtmlFormatter(lineos = True, encoding='utf-8',
  49. style='colorful', outencoding='utf-8',
  50. cssclass='pygments')
  51. return formatter
  52. def _parse_code_macro(self, ext, text):
  53. if not PYGMENTS:
  54. return self._no_highlight(text)
  55. try:
  56. source_type = ''
  57. if '.' in ext:
  58. source_type = ext.strip().split('.')[1]
  59. else:
  60. source_type = ext.strip()
  61. except IndexError:
  62. source_type = ''
  63. lexer = self._get_lexer(source_type, text)
  64. formatter = self._get_formatter()
  65. try:
  66. return highlight(text, lexer, formatter).decode('utf-8')
  67. except:
  68. return self._no_highlight(text)
  69. # You need to have a read method, which takes a filename and returns
  70. # some content and the associated metadata.
  71. def read(self, source_path):
  72. """Parse content and metadata of creole files"""
  73. self._metadata = {}
  74. with pelican_open(source_path) as text:
  75. content = creole2html(text, macros={'header': self._parse_header_macro,
  76. 'code': self._parse_code_macro})
  77. return content, self._metadata
  78. def add_reader(readers):
  79. readers.reader_classes['creole'] = CreoleReader
  80. def register():
  81. signals.readers_init.connect(add_reader)