diff --git a/previewer_code/MANIFEST.in b/previewer_code/MANIFEST.in
new file mode 100644
index 0000000..93a0256
--- /dev/null
+++ b/previewer_code/MANIFEST.in
@@ -0,0 +1 @@
+graft indico_previewer_code/templates
diff --git a/previewer_code/indico_previewer_code/__init__.py b/previewer_code/indico_previewer_code/__init__.py
new file mode 100644
index 0000000..fa5246d
--- /dev/null
+++ b/previewer_code/indico_previewer_code/__init__.py
@@ -0,0 +1,21 @@
+# This file is part of Indico.
+# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
+#
+# Indico is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# Indico is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Indico; if not, see .
+
+"""Syntax highlighting for common programming languages and related formats."""
+
+from .plugin import CodePreviewerPlugin
+
+__all__ = ('CodePreviewerPlugin',)
diff --git a/previewer_code/indico_previewer_code/plugin.py b/previewer_code/indico_previewer_code/plugin.py
new file mode 100644
index 0000000..46e57a7
--- /dev/null
+++ b/previewer_code/indico_previewer_code/plugin.py
@@ -0,0 +1,84 @@
+# This file is part of Indico.
+# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
+#
+# Indico is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# Indico is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Indico; if not, see .
+
+from __future__ import unicode_literals
+
+import mimetypes
+
+from flask import render_template
+from pygments import highlight
+from pygments.lexers import get_lexer_for_mimetype, CppLexer, PhpLexer, JavaLexer, RubyLexer
+from pygments.formatters import HtmlFormatter
+
+from indico.core import signals
+from indico.core.plugins import IndicoPlugin
+from indico.modules.attachments.preview import Previewer
+
+
+def register_custom_mimetypes():
+ mimetypes.add_type(b'text/x-csharp', b'.cs')
+
+
+register_custom_mimetypes()
+
+
+class PygmentsPreviewer(Previewer):
+ # All supported MIME types
+ MIMETYPES = ('text/css', 'text/x-python', 'text/x-ruby-script', 'text/x-java-source', 'text/x-c',
+ 'application/javascript', 'text/x-c', 'text/x-fortran', 'text/x-csharp', 'text/php',
+ 'text/x-php')
+
+ # Python's mimetypes lib and Pygments do not quite agree on some MIME types
+ CUSTOM_LEXERS = {
+ 'text/x-c': CppLexer(),
+ 'text/x-java-source': JavaLexer(),
+ 'text/x-ruby-script': RubyLexer(),
+ 'text/php': PhpLexer()
+ }
+
+ @classmethod
+ def can_preview(cls, attachment_file):
+ return attachment_file.content_type in cls.MIMETYPES
+
+ @classmethod
+ def generate_content(cls, attachment):
+ mime_type = attachment.file.content_type
+
+ lexer = cls.CUSTOM_LEXERS.get(mime_type)
+ if lexer is None:
+ lexer = get_lexer_for_mimetype(mime_type)
+
+ with attachment.file.open() as f:
+ html_formatter = HtmlFormatter(style='tango', linenos='inline', prestyles='mono')
+ html_code = highlight(f.read(), lexer, html_formatter)
+
+ css_code = html_formatter.get_style_defs('.highlight')
+
+ return render_template('previewer_code:pygments_preview.html', attachment=attachment,
+ html_code=html_code, css_code=css_code)
+
+
+class CodePreviewerPlugin(IndicoPlugin):
+ """Syntax highlighter (Pygments)"""
+
+ configurable = False
+
+ def init(self):
+ super(CodePreviewerPlugin, self).init()
+ self.connect(signals.attachments.get_file_previewers, self._get_file_previewers)
+
+ def _get_file_previewers(self, sender, **kwargs):
+ yield PygmentsPreviewer
diff --git a/previewer_code/indico_previewer_code/templates/pygments_preview.html b/previewer_code/indico_previewer_code/templates/pygments_preview.html
new file mode 100644
index 0000000..735ba1d
--- /dev/null
+++ b/previewer_code/indico_previewer_code/templates/pygments_preview.html
@@ -0,0 +1,18 @@
+
+
+
+ {{ html_code | safe }}
+
diff --git a/previewer_code/setup.py b/previewer_code/setup.py
new file mode 100644
index 0000000..5226be4
--- /dev/null
+++ b/previewer_code/setup.py
@@ -0,0 +1,38 @@
+# This file is part of Indico.
+# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
+#
+# Indico is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# Indico is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Indico; if not, see .
+
+from __future__ import unicode_literals
+
+from setuptools import setup, find_packages
+
+
+setup(
+ name='indico_previewer_code',
+ version='0.1',
+ url='https://github.com/indico/indico-plugins',
+ license='https://www.gnu.org/licenses/gpl-3.0.txt',
+ author='Indico Team',
+ author_email='indico-team@cern.ch',
+ packages=find_packages(),
+ zip_safe=False,
+ include_package_data=True,
+ platforms='any',
+ install_requires=[
+ 'indico>=1.9.4',
+ 'pygments'
+ ],
+ entry_points={'indico.plugins': {'previewer_code = indico_previewer_code:CodePreviewerPlugin'}}
+)