Add a special lexer for sphinx/pygments
authorIustin Pop <iustin@google.com>
Mon, 26 Mar 2012 12:57:26 +0000 (14:57 +0200)
committerIustin Pop <iustin@google.com>
Mon, 26 Mar 2012 15:26:24 +0000 (17:26 +0200)
This will be used throughout our docs for better formatting example
shell sessions, with custom markup for comments, user fixed input and
user variable input.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: RenĂ© Nussbaumer <rn@google.com>

Makefile.am
doc/conf.py
lib/build/shell_example_lexer.py [new file with mode: 0644]

index 90d5169..f779eab 100644 (file)
@@ -197,7 +197,8 @@ nodist_pkgpython_PYTHON = \
 
 noinst_PYTHON = \
        lib/build/__init__.py \
-       lib/build/sphinx_ext.py
+       lib/build/sphinx_ext.py \
+       lib/build/shell_example_lexer.py
 
 pkgpython_PYTHON = \
        lib/__init__.py \
@@ -427,7 +428,8 @@ $(RUN_IN_TEMPDIR): | $(all_dirfiles)
 # successfully, but we certainly don't want the docs to be rebuilt if
 # it changes
 doc/html/index.html: $(docrst) $(docpng) doc/conf.py configure.ac \
-       $(RUN_IN_TEMPDIR) lib/build/sphinx_ext.py lib/opcodes.py lib/ht.py \
+       $(RUN_IN_TEMPDIR) lib/build/sphinx_ext.py \
+       lib/build/shell_example_lexer.py lib/opcodes.py lib/ht.py \
        | $(BUILT_PYTHON_SOURCES)
        @test -n "$(SPHINX)" || \
            { echo 'sphinx-build' not found during configure; exit 1; }
@@ -991,7 +993,8 @@ man/footer.html: man/footer.rst
          { echo 'pandoc' not found during configure; exit 1; }
        $(PANDOC) -f rst -t html -o $@ $<
 
-man/%.gen: man/%.rst lib/query.py lib/build/sphinx_ext.py
+man/%.gen: man/%.rst lib/query.py lib/build/sphinx_ext.py \
+       lib/build/shell_example_lexer.py
        PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(DOCPP) < $< > $@
 
 man/%.7.in man/%.8.in man/%.1.in: man/%.gen man/footer.man
index 88d59fe..57b0aae 100644 (file)
@@ -29,6 +29,7 @@ extensions = [
   "sphinx.ext.todo",
   "sphinx.ext.graphviz",
   "ganeti.build.sphinx_ext",
+  "ganeti.build.shell_example_lexer",
   ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -45,7 +46,7 @@ master_doc = "index"
 
 # General information about the project.
 project = u"Ganeti"
-copyright = u"2006, 2007, 2008, 2009, 2010, 2011, Google Inc."
+copyright = u"2006, 2007, 2008, 2009, 2010, 2011, 2012, Google Inc."
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
diff --git a/lib/build/shell_example_lexer.py b/lib/build/shell_example_lexer.py
new file mode 100644 (file)
index 0000000..c250615
--- /dev/null
@@ -0,0 +1,72 @@
+#
+#
+
+# Copyright (C) 2012 Google Inc.
+#
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Pygments lexer for our custom shell example sessions.
+
+The lexer support the following custom markup:
+
+  - comments: # this is a comment
+  - command lines: '$ ' at the beginning of a line denotes a command
+  - variable input: %input% (works in both commands and screen output)
+  - otherwise, regular text output from commands will be plain
+
+"""
+
+from pygments.lexer import RegexLexer, bygroups, include
+from pygments.token import Name, Text, Generic, Comment
+
+
+class ShellExampleLexer(RegexLexer):
+  name = "ShellExampleLexer"
+  aliases = "shell-example"
+  filenames = []
+
+  tokens = {
+    "root": [
+      include("comments"),
+      include("userinput"),
+      # switch to state input on '$ ' at the start of the line
+      (r"^\$ ", Text, "input"),
+      (r"\s+", Text),
+      (r"[^#%\s]+", Text),
+      ],
+    "input": [
+      include("comments"),
+      include("userinput"),
+      (r"[^%\\\s]+", Generic.Strong),
+      (r"\\\n", Generic.Strong),
+      (r"\\", Generic.Strong),
+      # switch to prev state at non-escaped new-line
+      (r"\n", Text, "#pop"),
+      (r"\s+", Text),
+      ],
+    "comments": [
+      (r"#.*\n", Comment.Single),
+      ],
+    "userinput": [
+      (r"\\%", Text),
+      (r"(%)([^%]*)(%)", bygroups(None, Name.Variable, None)),
+      ],
+    }
+
+
+def setup(app):
+  app.add_lexer("shell-example", ShellExampleLexer())