diff options
author | milde <milde@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2010-11-30 11:59:33 +0000 |
---|---|---|
committer | milde <milde@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2010-11-30 11:59:33 +0000 |
commit | c5880303ec69f984827af77f08cf3d9a54f83cd2 (patch) | |
tree | 8730121b4af5e5ae5a3d01f5f8b3027b394aeef6 /sandbox/code-block-directive | |
parent | 976cec43efc64e68a9e2a1fc27135a11b27938aa (diff) | |
download | docutils-c5880303ec69f984827af77f08cf3d9a54f83cd2.tar.gz |
Prepare CodeBlock directive for inclusion in the Docutils core.
Rename directive and class from "code-block" to "code".
Fix fallback if pygments not found.
Use class-based interface.
Add "number-lines" option.
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@6488 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
Diffstat (limited to 'sandbox/code-block-directive')
-rw-r--r-- | sandbox/code-block-directive/data/pygments-default.css | 8 | ||||
-rw-r--r-- | sandbox/code-block-directive/data/pygments-docutilsroles.sty | 48 | ||||
-rw-r--r-- | sandbox/code-block-directive/docs/myfunction.py.htm | 118 | ||||
-rw-r--r-- | sandbox/code-block-directive/docs/myfunction.py.pdf | bin | 25434 -> 25692 bytes | |||
-rw-r--r-- | sandbox/code-block-directive/docs/myfunction.py.tex | 131 | ||||
-rw-r--r-- | sandbox/code-block-directive/docs/myfunction.py.txt | 16 | ||||
-rwxr-xr-x | sandbox/code-block-directive/pygments_code_block_directive.py | 143 | ||||
-rwxr-xr-x | sandbox/code-block-directive/rst2html-highlight | 17 | ||||
-rwxr-xr-x | sandbox/code-block-directive/tools/test_pygments_code_block_directive.py | 2 |
9 files changed, 211 insertions, 272 deletions
diff --git a/sandbox/code-block-directive/data/pygments-default.css b/sandbox/code-block-directive/data/pygments-default.css index 5d933198c..b4dbdae19 100644 --- a/sandbox/code-block-directive/data/pygments-default.css +++ b/sandbox/code-block-directive/data/pygments-default.css @@ -12,7 +12,7 @@ /* --------------------------------------- */ /* :: */ -@import url("/stylesheets/html4css1.css"); +@import url("/stylesheets/html4css1.css"); /* Indent the code block */ /* --------------------- */ @@ -20,12 +20,16 @@ /* Content copied from the `html4css1.css` rule for literal blocks. */ /* Selector adapted to the output of Pygments_. :: */ -div.highlight { +pre.code { margin-left: 2em ; margin-right: 2em ; background-color: #eeeeee } +pre.code .ln { /* line numbers */ +/* color: grey; */ + font-size: small; +} /* Colour code blocks */ /* ------------------ */ diff --git a/sandbox/code-block-directive/data/pygments-docutilsroles.sty b/sandbox/code-block-directive/data/pygments-docutilsroles.sty index d22319772..55c4f8c11 100644 --- a/sandbox/code-block-directive/data/pygments-docutilsroles.sty +++ b/sandbox/code-block-directive/data/pygments-docutilsroles.sty @@ -1,6 +1,6 @@ % Stylesheet for pygments enhanced reStructured Text % ================================================== -% +% % :Author: Günter Milde % :Contact: milde@users.berlios.de % :Revision: $Revision: 5534 $ @@ -9,14 +9,14 @@ % Released without warranties or conditions of any kind % under the terms of the Apache License, Version 2.0 % http://www.apache.org/licenses/LICENSE-2.0 -% +% % This example style sheet provides syntax highlight for documents generated % with the `rst2latex-highlight` pygments-enhanced Docutils front end. -% -% +% +% % Separate paragraphs by vertical space % ------------------------------------- -% +% % This is not required for syntax highlight, but usually a good idea for % documents with lots of source code. % :: @@ -25,13 +25,13 @@ % Highlight code blocks % --------------------- -% +% % Pygments_ has an option to generate stylesheets for HTML and LaTeX. % However, the "kryptic" codes used for HTML and LaTeX differ, so that % the output of the command % `pygmentize -S default -f latex -O commandprefix=docutilsrole` % fails to work with rst2latex-highlight. -% :: +% :: % Colours with LaTeX \usepackage{color} @@ -46,38 +46,38 @@ \renewcommand{\ttdefault}{txtt} % keyword -\newcommand\docutilsrolek[1]{\textbf{\textbf{#1}}} +\newcommand\DUrolek[1]{\textbf{\textbf{#1}}} % new function -\newcommand\docutilsrolenf[1]{\textcolor[rgb]{0.00,0.25,0.82}{#1}} +\newcommand\DUrolenf[1]{\textcolor[rgb]{0.00,0.25,0.82}{#1}} % punktuation -% \newcommand\docutilsrolep[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}} +% \newcommand\DUrolep[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}} % string -\newcommand\docutilsroles[1]{\textcolor[rgb]{0.40,0.40,0.40}{\textit{#1}}} +\newcommand\DUroles[1]{\textcolor[rgb]{0.40,0.40,0.40}{\textit{#1}}} % number -% \newcommand\docutilsrolemf[1]{\textcolor[rgb]{0.00,0.53,0.00}{#1}} +% \newcommand\DUrolemf[1]{\textcolor[rgb]{0.00,0.53,0.00}{#1}} % operator -\newcommand\docutilsrolear[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}} +\newcommand\DUrolear[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}} -% Incomplete! +% Incomplete! % All STANDARD_TYPES below may appear in the output. (But only the ones % you like to style need to be defined :-) % STANDARD_TYPES = { % Token: '', -% +% % Text: '', % Whitespace: 'w', % Error: 'err', % Other: 'x', -% +% % Keyword: 'k', % Keyword.Constant: 'kc', % Keyword.Declaration: 'kd', % Keyword.Pseudo: 'kp', % Keyword.Reserved: 'kr', % Keyword.Type: 'kt', -% +% % Name: 'n', % Name.Attribute: 'na', % Name.Builtin: 'nb', @@ -97,10 +97,10 @@ % Name.Variable.Class: 'vc', % Name.Variable.Global: 'vg', % Name.Variable.Instance: 'vi', -% +% % Literal: 'l', % Literal.Date: 'ld', -% +% % String: 's', % String.Backtick: 'sb', % String.Char: 'sc', @@ -113,25 +113,25 @@ % String.Regex: 'sr', % String.Single: 's1', % String.Symbol: 'ss', -% +% % Number: 'm', % Number.Float: 'mf', % Number.Hex: 'mh', % Number.Integer: 'mi', % Number.Integer.Long: 'il', % Number.Oct: 'mo', -% +% % Operator: 'o', % Operator.Word: 'ow', -% +% % Punctuation: 'p', -% +% % Comment: 'c', % Comment.Multiline: 'cm', % Comment.Preproc: 'cp', % Comment.Single: 'c1', % Comment.Special: 'cs', -% +% % Generic: 'g', % Generic.Deleted: 'gd', % Generic.Emph: 'ge', diff --git a/sandbox/code-block-directive/docs/myfunction.py.htm b/sandbox/code-block-directive/docs/myfunction.py.htm index 62f7ae00f..617f4b671 100644 --- a/sandbox/code-block-directive/docs/myfunction.py.htm +++ b/sandbox/code-block-directive/docs/myfunction.py.htm @@ -3,124 +3,30 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.8: http://docutils.sourceforge.net/" /> <title></title> -<style type="text/css"> - -/* Stylesheet for pygments enhanced reStructured Text */ -/* ================================================== */ - -/* :Author: Guenter Milde */ -/* :Copyright: 2007 G. Milde */ -/* This stylesheet is released under the GPL v. 2 or later */ - -/* This stylesheet provides syntax highlight for documents generated with a */ -/* pygments_ enhanced reStructured Text -> html converter. */ - -/* Import the default docutils style sheet */ -/* --------------------------------------- */ -/* :: */ - -@import url("/stylesheets/html4css1.css"); - -/* Indent the code block */ -/* --------------------- */ - -/* Content copied from the `html4css1.css` rule for literal blocks. */ -/* Selector adapted to the output of Pygments_. :: */ - -div.highlight { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee - } - - -/* Colour code blocks */ -/* ------------------ */ - -/* Pygments_ has an option to generate stylesheets for html and latex. */ -/* The following code is generated with the command */ -/* `pygmentize -S default -f html > pygments-default.css`:: */ - -.c { color: #008800; font-style: italic } /* Comment */ -.err { border: 1px solid #FF0000 } /* Error */ -.k { color: #AA22FF; font-weight: bold } /* Keyword */ -.o { color: #666666 } /* Operator */ -.cm { color: #008800; font-style: italic } /* Comment.Multiline */ -.cp { color: #008800 } /* Comment.Preproc */ -.c1 { color: #008800; font-style: italic } /* Comment.Single */ -.gd { color: #A00000 } /* Generic.Deleted */ -.ge { font-style: italic } /* Generic.Emph */ -.gr { color: #FF0000 } /* Generic.Error */ -.gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.gi { color: #00A000 } /* Generic.Inserted */ -.go { color: #808080 } /* Generic.Output */ -.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -.gs { font-weight: bold } /* Generic.Strong */ -.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.gt { color: #0040D0 } /* Generic.Traceback */ -.kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */ -.kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */ -.kp { color: #AA22FF } /* Keyword.Pseudo */ -.kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */ -.kt { color: #AA22FF; font-weight: bold } /* Keyword.Type */ -.m { color: #666666 } /* Literal.Number */ -.s { color: #BB4444 } /* Literal.String */ -.na { color: #BB4444 } /* Name.Attribute */ -.nb { color: #AA22FF } /* Name.Builtin */ -.nc { color: #0000FF } /* Name.Class */ -.no { color: #880000 } /* Name.Constant */ -.nd { color: #AA22FF } /* Name.Decorator */ -.ni { color: #999999; font-weight: bold } /* Name.Entity */ -.ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -.nf { color: #00A000 } /* Name.Function */ -.nl { color: #A0A000 } /* Name.Label */ -.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -.nt { color: #008000; font-weight: bold } /* Name.Tag */ -.nv { color: #B8860B } /* Name.Variable */ -.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.mf { color: #666666 } /* Literal.Number.Float */ -.mh { color: #666666 } /* Literal.Number.Hex */ -.mi { color: #666666 } /* Literal.Number.Integer */ -.mo { color: #666666 } /* Literal.Number.Oct */ -.sb { color: #BB4444 } /* Literal.String.Backtick */ -.sc { color: #BB4444 } /* Literal.String.Char */ -.sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */ -.s2 { color: #BB4444 } /* Literal.String.Double */ -.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -.sh { color: #BB4444 } /* Literal.String.Heredoc */ -.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -.sx { color: #008000 } /* Literal.String.Other */ -.sr { color: #BB6688 } /* Literal.String.Regex */ -.s1 { color: #BB4444 } /* Literal.String.Single */ -.ss { color: #B8860B } /* Literal.String.Symbol */ -.bp { color: #AA22FF } /* Name.Builtin.Pseudo */ -.vc { color: #B8860B } /* Name.Variable.Class */ -.vg { color: #B8860B } /* Name.Variable.Global */ -.vi { color: #B8860B } /* Name.Variable.Instance */ -.il { color: #666666 } /* Literal.Number.Integer.Long */ - -/* .. _pygments: http://pygments.org/ */ - -</style> +<link rel="stylesheet" href="../data/pygments-default.css" type="text/css" /> </head> <body> <div class="document"> -<p>This is a test of the new code-block directive:</p> +<p>This is a test of the new "code" directive:</p> <!-- Translate this document to HTML with a pygments enhanced frontend, e.g. ../rst2html-highlight - -stylesheet=../data/pygments-default.css ../rst2latex-highlight - -stylesheet=../data/pygments-docutileroles.sty --> -<pre class="code-block python literal-block"> -<span class="k">def</span> <span class="nf">my_function</span><span class="p">():</span> - <span class="s">"just a test"</span> - <span class="k">print</span> <span class="mf">8</span><span class="o">/</span><span class="mf">2</span> - +<pre class="code python silly literal-block"> +<span class="ln">1 </span><span class="k">def</span> <span class="nf">my_function</span><span class="p">():</span> +<span class="ln">2 </span> <span class="sd">"""Test the lexer. +</span><span class="ln">3 </span><span class="sd"> +</span><span class="ln">4 </span><span class="sd"> just a test"""</span> +<span class="ln">5 </span> +<span class="ln">6 </span> <span class="c"># and now for something completely different</span> +<span class="ln">7 </span> <span class="k">print</span> <span class="mi">8</span><span class="o">/</span><span class="mi">2</span> </pre> +<p>The end.</p> </div> </body> </html> diff --git a/sandbox/code-block-directive/docs/myfunction.py.pdf b/sandbox/code-block-directive/docs/myfunction.py.pdf Binary files differindex 05fba74ea..b6624d223 100644 --- a/sandbox/code-block-directive/docs/myfunction.py.pdf +++ b/sandbox/code-block-directive/docs/myfunction.py.pdf diff --git a/sandbox/code-block-directive/docs/myfunction.py.tex b/sandbox/code-block-directive/docs/myfunction.py.tex index 6d5ddd5dd..c72da4eac 100644 --- a/sandbox/code-block-directive/docs/myfunction.py.tex +++ b/sandbox/code-block-directive/docs/myfunction.py.tex @@ -1,93 +1,66 @@ -\documentclass[10pt,a4paper,english]{scrartcl} -\usepackage{babel} -\usepackage[T1]{fontenc} -\usepackage{shortvrb} -\usepackage{ucs} -\usepackage[utf8x]{inputenc} -\usepackage{tabularx} -\usepackage{longtable} -\usepackage{booktabs} -\setlength{\extrarowheight}{2pt} -\usepackage{amsmath} -\usepackage{graphicx} -\usepackage{color} -\usepackage{multirow} -\usepackage{ifthen} -\typearea{12} +\documentclass[a4paper]{article} % generated by Docutils <http://docutils.sourceforge.net/> -\newlength{\admonitionwidth} -\setlength{\admonitionwidth}{0.9\textwidth} -\newlength{\docinfowidth} -\setlength{\docinfowidth}{0.9\textwidth} -\newlength{\locallinewidth} -\newcommand{\optionlistlabel}[1]{\bf #1 \hfill} -\newenvironment{optionlist}[1] -{\begin{list}{} - {\setlength{\labelwidth}{#1} - \setlength{\rightmargin}{1cm} - \setlength{\leftmargin}{\rightmargin} - \addtolength{\leftmargin}{\labelwidth} - \addtolength{\leftmargin}{\labelsep} - \renewcommand{\makelabel}{\optionlistlabel}} -}{\end{list}} -\newlength{\lineblockindentation} -\setlength{\lineblockindentation}{2.5em} -\newenvironment{lineblock}[1] -{\begin{list}{} - {\setlength{\partopsep}{\parskip} - \addtolength{\partopsep}{\baselineskip} - \topsep0pt\itemsep0.15\baselineskip\parsep0pt - \leftmargin#1} - \raggedright} -{\end{list}} -% begin: floats for footnotes tweaking. -\setlength{\floatsep}{0.5em} -\setlength{\textfloatsep}{\fill} -\addtolength{\textfloatsep}{3em} -\renewcommand{\textfraction}{0.5} -\renewcommand{\topfraction}{0.5} -\renewcommand{\bottomfraction}{0.5} -\setcounter{totalnumber}{50} -\setcounter{topnumber}{50} -\setcounter{bottomnumber}{50} -% end floats for footnotes -% some commands, that could be overwritten in the style file. -\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}} -\newcommand{\titlereference}[1]{\textsl{#1}} -% end of "some commands" -% user specified packages and stylesheets: +\usepackage{fixltx2e} % LaTeX patches, \textsubscript +\usepackage{cmap} % fix search and cut-and-paste in Acrobat +\usepackage{ifthen} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\setcounter{secnumdepth}{0} + +%%% Custom LaTeX preamble +% suppress the (LaTeX-added) References section heading +\AtBeginDocument{\renewcommand{\refname}{\vspace{-1em}}} +\newlength{\DUlineblockindent} +\setlength{\DUlineblockindent}{1em} + +%%% User specified packages and stylesheets \usepackage{../data/pygments-docutilsroles} -\ifthenelse{\isundefined{\hypersetup}}{ -\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref} -}{} -% Custom roles: -% \DUrole{NAME}{content} calls \docutilsroleNAME if it exists -\providecommand{\DUrole}[2]{% - \ifcsname docutilsrole#1\endcsname% - \csname docutilsrole#1\endcsname{#2}% - \else% - #2% + +%%% Fallback definitions for Docutils-specific commands + +% inline markup (custom roles) +% \DUrole{#1}{#2} tries \DUrole#1{#2} +\providecommand*{\DUrole}[2]{% + \ifcsname DUrole#1\endcsname% + \csname DUrole#1\endcsname{#2}% + \else% backwards compatibility: try \docutilsrole#1{#2} + \ifcsname docutilsrole#1\endcsname% + \csname docutilsrole#1\endcsname{#2}% + \else% + #2% + \fi% \fi% } -\title{} -\author{} -\date{} -\raggedbottom + +% hyperlinks: +\ifthenelse{\isundefined{\hypersetup}}{ + \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue,citecolor=black]{hyperref} + \urlstyle{same} % normal text font (alternatives: tt, rm, sf) +}{} + + +%%% Body \begin{document} -\setlength{\locallinewidth}{\linewidth} +This is a test of the new ``code'' directive: -This is a test of the new code-block directive: % Translate this document to HTML with a pygments enhanced frontend, e.g. % -% rst2html-highlight --stylesheet=../data/pygments-default.css --link-stylesheet +% ../rst2html-highlight --stylesheet=../data/pygments-default.css % -% rst2latex-highlight --stylesheet=../data/pygments-docutileroles.sty +% ../rst2latex-highlight --stylesheet=../data/pygments-docutilsroles.sty +% \begin{quote}{\ttfamily \raggedright \noindent -\DUrole{k}{def}~\DUrole{nf}{my{\_}function}\DUrole{p}{():}~\\ -~~~~\DUrole{s}{"just~a~test"}~\\ -~~~~\DUrole{k}{print}~\DUrole{mf}{8}\DUrole{o}{/}\DUrole{mf}{2}~\\ +\DUrole{ln}{~7~}\DUrole{k}{def}~\DUrole{nf}{my\_function}\DUrole{p}{():}~\\ +\DUrole{ln}{~8~}~~~~\DUrole{sd}{"{}"{}"Test~the~lexer.\\ +}\DUrole{ln}{~9~}\DUrole{sd}{~\\ +}\DUrole{ln}{10~}\DUrole{sd}{~~~~just~a~test"{}"{}"}~\\ +\DUrole{ln}{11~}~\\ +\DUrole{ln}{12~}~~~~\DUrole{c}{\#~and~now~for~something~completely~different}~\\ +\DUrole{ln}{13~}~~~~\DUrole{k}{print}~\DUrole{mi}{8}\DUrole{o}{/}\DUrole{mi}{2} +} +\end{quote} -}\end{quote} +The end. \end{document} diff --git a/sandbox/code-block-directive/docs/myfunction.py.txt b/sandbox/code-block-directive/docs/myfunction.py.txt index 783e5b0b6..b9727e96f 100644 --- a/sandbox/code-block-directive/docs/myfunction.py.txt +++ b/sandbox/code-block-directive/docs/myfunction.py.txt @@ -1,13 +1,21 @@ -This is a test of the new code-block directive: +This is a test of the new "code" directive: .. Translate this document to HTML with a pygments enhanced frontend, e.g. ../rst2html-highlight --stylesheet=../data/pygments-default.css - ../rst2latex-highlight --stylesheet=../data/pygments-docutileroles.sty + ../rst2latex-highlight --stylesheet=../data/pygments-docutilsroles.sty -.. code-block:: python +.. code:: python + :class: silly + :number-lines: 7 def my_function(): - "just a test" + """Test the lexer. + + just a test""" + + # and now for something completely different print 8/2 + +The end. diff --git a/sandbox/code-block-directive/pygments_code_block_directive.py b/sandbox/code-block-directive/pygments_code_block_directive.py index 0a115d905..e2abe30b6 100755 --- a/sandbox/code-block-directive/pygments_code_block_directive.py +++ b/sandbox/code-block-directive/pygments_code_block_directive.py @@ -1,6 +1,7 @@ #!/usr/bin/python +# coding: utf-8 -# :Author: the Pygments team; Felix Wiemann; Guenter Milde +# :Author: Georg Brandl; Felix Wiemann; Günter Milde # :Date: $Date$ # :Copyright: This module has been placed in the public domain. # @@ -9,7 +10,7 @@ # # .. class:: borderless # -# ========== =========================================================== +# ========== ============================================================= # 2007-06-01 Removed redundancy from class values. # 2007-06-04 Merge of successive tokens of same type # (code taken from pygments.formatters.others). @@ -20,26 +21,29 @@ # (misnamed as docutils_formatter) as class DocutilsInterface # 2007-06-08 Failsave implementation (fallback to a standard literal block # if pygments not found) -# ========== =========================================================== +# 2010-11-27 Rename directive and class from "code-block" to "code". +# Fix fallback if pygments not found. +# Use class-based interface. +# Add "number-lines" option. +# ========== ============================================================= # # :: -"""Define and register a code-block directive using pygments -""" +"""Define and register a code directive using pygments""" # Requirements # ------------ # :: from docutils import nodes -from docutils.parsers.rst import directives +from docutils.parsers.rst import directives, Directive try: import pygments from pygments.lexers import get_lexer_by_name from pygments.formatters.html import _get_ttype_class + with_pygments = True except ImportError: - pass - + with_pygments = False # Customisation @@ -50,16 +54,13 @@ except ImportError: unstyled_tokens = [''] -# DocutilsInterface +# Tokenizer # ----------------- # # This interface class combines code from # pygments.formatters.html and pygments.formatters.others. -# -# It does not require anything of docutils and could also become a part of -# pygments:: -class DocutilsInterface(object): +class Tokenizer(object): """Parse `code` string and yield "classified" tokens. Arguments @@ -72,7 +73,6 @@ class DocutilsInterface(object): Yields the tokens as ``(ttype_class, value)`` tuples, where ttype_class is taken from pygments.token.STANDARD_TYPES and corresponds to the class argument used in pygments html output. - """ def __init__(self, code, language): @@ -84,13 +84,15 @@ class DocutilsInterface(object): try: lexer = get_lexer_by_name(self.language) except ValueError: - # info: "no pygments lexer for %s, using 'text'"%self.language + # info: 'no pygments lexer for %s, using "text"' % self.language lexer = get_lexer_by_name('text') return pygments.lex(self.code, lexer) def join(self, tokens): - """join subsequent tokens of same token-type + """Join subsequent tokens of same token-type. + + Also, leave out the final '\n' (added by pygments). """ tokens = iter(tokens) (lasttype, lastval) = tokens.next() @@ -100,54 +102,100 @@ class DocutilsInterface(object): else: yield(lasttype, lastval) (lasttype, lastval) = (ttype, value) - yield(lasttype, lastval) + if lastval != '\n': + yield(lasttype, lastval) def __iter__(self): - """parse code string and yield "clasified" tokens + """parse code string and yield "classified" tokens """ - try: - tokens = self.lex() - except IOError: - print "INFO: Pygments lexer not found, using fallback" - # TODO: write message to INFO - yield ('', self.code) - return - + tokens = self.lex() for ttype, value in self.join(tokens): + # yield (ttype, value) yield (_get_ttype_class(ttype), value) +class NumberLines(object): + """Insert linenumber-tokens in front of every newline + + Nontrivial, as we need to weave these into the possibly + multi-line tokens from pygments. + """ + + def __init__(self, tokens, startline, fmt_str): + self.tokens = tokens + self.lineno = startline + self.fmt_str = fmt_str -# code_block_directive + def __iter__(self): + yield ('ln', self.fmt_str % self.lineno) + for ttype, value in self.tokens: + lines = value.split('\n') + for line in lines[:-1]: + yield (ttype, line + '\n') + self.lineno += 1 + yield ('ln', self.fmt_str % self.lineno) + yield (ttype, lines[-1]) + + +# CodeBlock directive # -------------------- # :: -def code_block_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - """parse and classify content of a code_block +class CodeBlock(Directive): + """Parse and mark up content of a code block. """ - language = arguments[0] - # create a literal block element and set class argument - code_block = nodes.literal_block(classes=["code-block", language]) - - # parse content with pygments and add to code_block element - for cls, value in DocutilsInterface(u'\n'.join(content), language): - if cls in unstyled_tokens: - # insert as Text to decrease the verbosity of the output. - code_block += nodes.Text(value, value) + required_arguments = 1 + option_spec = {'class': directives.class_option, + 'number-lines': directives.unchanged + } + has_content = True + + def run(self): + language = self.arguments[0] + # Process number-lines with optional argument `startline` + startline = self.options.get('number-lines', '1') + try: + startline = int(startline or 1) # default to 1 for empty str + except ValueError: + raise self.error( + ':number-lines: option with non-integer start value') + self.assert_has_content() + + # create a literal block element and set class argument + code_block = nodes.literal_block(classes=['code', language] + + self.options['class']) + + # iterator returning code tokens + if with_pygments: + tokens = Tokenizer(u'\n'.join(self.content), language) else: - code_block += nodes.inline(value, value, classes=[cls]) + # TODO: warning or info? + self.warning('Cannot highlight code, Pygments lexer not found.') + tokens = [('', u'\n'.join(self.content))] + + if 'number-lines' in self.options: + # pad linenumbers, e.g. endline == 100 -> fmt_str = '%3d ' + endline = startline + len(self.content) + fmt_str = "%%%dd " % len(str(endline)) + # print startline, '...', endline, repr(fmt_str) + tokens = NumberLines(tokens, startline, fmt_str) + + # parse content with pygments and add to code_block element + for cls, value in tokens: + if cls in unstyled_tokens: + # insert as Text to decrease the verbosity of the output. + code_block += nodes.Text(value, value) + else: + code_block += nodes.inline(value, value, classes=[cls]) - return [code_block] + return [code_block] # Register Directive # ------------------ # :: -code_block_directive.arguments = (1, 0, 1) -code_block_directive.content = 1 -directives.register_directive('code-block', code_block_directive) +directives.register_directive('code', CodeBlock) # .. _doctutils: http://docutils.sf.net/ # .. _pygments: http://pygments.org/ @@ -163,15 +211,14 @@ directives.register_directive('code-block', code_block_directive) if __name__ == '__main__': from docutils.core import publish_cmdline, default_description - description = "code-block directive test output" + default_description + description = 'code-block directive test output' + default_description try: import locale locale.setlocale(locale.LC_ALL, '') except: pass # Uncomment the desired output format: - publish_cmdline(writer_name='pseudoxml', description=description) + # publish_cmdline(writer_name='pseudoxml', description=description) # publish_cmdline(writer_name='xml', description=description) - # publish_cmdline(writer_name='html', description=description) + publish_cmdline(writer_name='html', description=description) # publish_cmdline(writer_name='latex', description=description) - # publish_cmdline(writer_name='newlatex2e', description=description) diff --git a/sandbox/code-block-directive/rst2html-highlight b/sandbox/code-block-directive/rst2html-highlight index d80b87ec8..ecfa61574 100755 --- a/sandbox/code-block-directive/rst2html-highlight +++ b/sandbox/code-block-directive/rst2html-highlight @@ -1,17 +1,18 @@ #!/usr/bin/python +# coding: utf-8 # rst2html-highlight # ================== -# +# # Docutils front-end with syntax highlight. -# -# :Author: David Goodger, the Pygments team, Günter Milde +# +# :Author: David Goodger, Georg Brandl, Günter Milde # :Date: $Date: 2008-05-22 08:42:52 +0200 (Do, 22. Mai 2008) $ # :Copyright: This module has been placed in the public domain. -# +# # This is a merge of the docutils_ `rst2html` front end with an extension # suggestion taken from the pygments_ documentation. -# +# # :: """ @@ -19,13 +20,13 @@ A front end to docutils, producing HTML with syntax colouring using pygments Generates (X)HTML documents from standalone reStructuredText sources. Uses `pygments` to parse and mark up the content of ``.. code-block::` directives. -Needs an adapted stylesheet +Needs an adapted stylesheet """ # Requirements # ------------ -# -# :: +# +# :: try: import locale diff --git a/sandbox/code-block-directive/tools/test_pygments_code_block_directive.py b/sandbox/code-block-directive/tools/test_pygments_code_block_directive.py index 9d0ea510a..def706889 100755 --- a/sandbox/code-block-directive/tools/test_pygments_code_block_directive.py +++ b/sandbox/code-block-directive/tools/test_pygments_code_block_directive.py @@ -39,7 +39,7 @@ unstyled_tokens = [''] # ---------------------- document = utils.new_document('generated') -literal_block = nodes.literal_block(classes=["code-block", language]) +literal_block = nodes.literal_block(classes=["code", language]) document += literal_block |