1
0
mirror of https://github.com/gryf/vimblogger_ft.git synced 2025-12-17 03:20:26 +01:00

Pygments sourcecode directive improvements

This commit is contained in:
2010-12-25 15:19:08 +01:00
parent ceb2c3d308
commit 55e51cbe6f
7 changed files with 413 additions and 57 deletions

View File

@@ -4,11 +4,11 @@
vimblogger_ft
=============
vimblogger_ft is a simple reStructuredText_ to Blogger Interface through VIm_.
vimblogger_ft is a simple reStructuredText_ to Blogger interface through VIm_.
As the name suggest it is a filetype plugin, which helps to create blog articles
in rsST format and send them to blog site. It also provides commands for preview
in browser and delete articles.
As the name suggest it is a filetype plugin, which helps to create blog
articles in rsST format and send them to blog site. It also provides commands
for preview in browser and delete articles.
Requirements
------------
@@ -22,7 +22,7 @@ Other requirements:
- gdata_
- docutils_
- pygments_ (optional)
- Pygments_ (optional)
- Blogger account
@@ -33,7 +33,6 @@ Download_, edit the vba with VIm and type::
:so %
Or, clone this repository and put files in your ``~/.vim`` directory.
Usage
@@ -93,7 +92,7 @@ reST document structure
It is assumed, that following template will be used::
:Id:
:Title: Title for the blog
:Title: Title for the blog article
:Date:
:Modified:
:Tags: some, tags
@@ -146,15 +145,62 @@ Note, that ``.. more`` will became HTML comment ``<!-- more -->`` which will
prevent from displaying entire post on the bloggers front page, but will
not have any visible effect during preview in browser.
Additionally, if pygments is installed, there is sourcecode directive,
simple syntax highlighter using Pygments module. Very simple usage could
be as follows::
Pygments code highlighting
--------------------------
Additionally, if Pygments is installed, there is ``sourcecode`` directive,
simple syntax highlighter using Pygments module. Very simple usage for Python
code could be as follows::
.. sourcecode:: python
import vim
print vim.current.buffer.name
Note, that ``sourcecode`` directive requires argument with the name of the
lexer to use. If wrong/non existent lexer is provided, it will fall back to
*text* lexer. For more information about available lexers, please refer to
Pygments documentation.
Directive ``sourcecode`` supports two options: ``:linenos:`` and
``:cssclass:``.
``:linenos:`` takes zero or one argument - if no arguments is provided, line
numbers will be visible starting form 1. Provided integer will be the number
of the first line.
``:cssclass:`` can be use for changing default class name for block of code.
Default class can be changed by appropriate option for plugin (see
documentation), and defaults to "highlight".
It is possible to use VIm colorschemes like desert (which is distributed with
VIm), Zenburn_, Lucius_, Wombat_, inkpot_ or any other with Pygments.
Assuming, that colorscheme *desert* should be used, there are two steps to
achive it.
First, python module containing Pygments *Style* class has to be generated.
There is apropriate convertion tool in Pygments distribution -
``scripts/vim2pygments.py``. Uage is simple as::
python Pygments/scripts/vim2pygments.py [path/to/vim/colors]/desert.vim > desert.py
Which will create new python module ``desert.py`` containing class
``DessertStyle``.
To generate CSS stylesheet, it's enough to::
python rst2blogger/scripts/style2css.py desert.py -c VimDesert > desert.css
VimDesert is the name of the class, which passed as an argument to
``:cssclass:`` option of directive ``sourceocode``. It will be used as a main
CSS class for code top ``<div>`` element. So, above example will looks like
this::
.. sourcecode:: python
:cssclass: VimDesert
import vim
print vim.current.buffer.name
Note: All headings for generated HTML by ``:SendBlogArticle`` will be
shifted by 3, so the first heading will become <h3>, second <h4> and so
@@ -165,6 +211,10 @@ limitation.
.. _VIm: http://www.vim.org
.. _gdata: http://code.google.com/p/gdata-python-client
.. _docutils: http://docutils.sourceforge.net
.. _pygments: http://pygments.org
.. _Pygments: http://pygments.org
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _Download: http://www.vim.org/scripts/script.php?script_id=3367
.. _Zenburn: http://www.vim.org/scripts/script.php?script_id=415
.. _inkpot: http://www.vim.org/scripts/script.php?script_id=1143
.. _Lucius: http://www.vim.org/scripts/script.php?script_id=2536
.. _Wombat: http://www.vim.org/scripts/script.php?script_id=1778

View File

@@ -1,4 +1,4 @@
*vimblogger_ft.txt* reStructuredText to Blogger Interface
*vimblogger_ft.txt* reStructuredText to Blogger interface
Author: Roman Dobosz, gryf73 at gmail com
Simple interface to create blog articles in rsST format. It provides
@@ -15,7 +15,7 @@ Other requirements:
- Python (tested with version 2.6, should work also in others)
- gdata http://code.google.com/p/gdata-python-client
- docutils http://docutils.sourceforge.net
- pygments http://pygments.org (optional)
- Pygments http://pygments.org (optional)
- Blogger account
-----------------------------------------------------------------------
@@ -44,8 +44,8 @@ When article is done, |:SendBlogArticle| will send it to the server.
Output provided by |:PreviewBlogArticle| without any
css stylesheet will look pretty raw, so it is generally good idea to
grab stylesheets from blog itself, and tweak it a little, and add to
list in |g:blogger_stylesheets|. They will be automatically linked to
grab stylesheets from blog itself, tweak it a little, and add to list
in |g:blogger_stylesheets|. They will be automatically linked to
generated preview file.
Unfortunately, this script has several limitations, like it is
@@ -110,6 +110,12 @@ g:blogger_stylesheets (default: [])
one wanted to save stylesheets from his own blog, so that article
can be displayed almost in the same way as in blog.
*g:blogger_pygments_class*
g:blogger_pygments_class (default: "")
Name of default CSS class for usage with Pygments. When not
provided or empty, it'll use defaults from Pygments: "highlight".
========================================================================
Commands~
@@ -136,18 +142,17 @@ Commands~
reST document structure~
It is assumed, that following template will be used:
-----8<-----
>
:Id:
:Title: Title for the blog
:Title: Title for the blog article
:Date:
:Modified:
:Tags: some, tags
Penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla
facilisis massa ut massa. Sed nisi purus, malesuada eu, porta vulputate,
suscipit auctor, nunc. Vestibulum convallis, augue eu luctus malesuada,
mi ante mattis odio, ac venenatis neque sem vitae nisi.
Penatibus et magnis dis parturient montes, nascetur ridiculus mus.
Nulla facilisis massa ut massa. Sed nisi purus, malesuada eu, porta
vulputate, suscipit auctor, nunc. Vestibulum convallis, augue eu luctus
malesuada, mi ante mattis odio, ac venenatis neque sem vitae nisi.
.. more
@@ -156,13 +161,13 @@ heading
-------
**Congue** mi, quis posuere augue nulla a augue. Pellentesque sed est.
Mauris cursus urna id lectus. Integer dignissim feugiat eros. Sed tempor
volutpat dolor. Vestibulum vel lectus nec mauris semper adipiscing.
Mauris cursus urna id lectus. Integer dignissim feugiat eros. Sed
tempor volutpat dolor. Vestibulum vel lectus nec mauris semper
adipiscing.
Aliquam tincidunt enim sit amet tellus. Sed mauris nulla, semper
tincidunt, luctus a, sodales eget, leo. Sed ligula augue, cursus et.
----->8-----
<
reST document (optionally) starts with *docinfo* section (first several
lines, that are starting from ":" character) separaded from other
content with one empty line.
@@ -203,18 +208,65 @@ Note, that `.. more' will became HTML comment `<!-- more -->' which will
prevent from displaying entire post on the bloggers front page, but will
not have any visible effect during preview in browser.
Additionally, if pygments is installed, there is sourcecode directive,
simple syntax highlighter using Pygments module. Very simple usage could
be as follows:
========================================================================
Pygments code highlighting~
-----8<-----
Additionally, if Pygments is installed, there is ``sourcecode``
directive, simple syntax highlighter using Pygments module. Very simple
usage for Python code could be as follows:
>
.. sourcecode:: python
import vim
print vim.current.buffer.name
<
Note, that `sourcecode' directive requires argument with the name of the
lexer to use. If wrong/non existent lexer is provided, it will fall back
to `text' lexer. For more information about available lexers, please
refer to Pygments documentation.
----->8-----
Directive `sourcecode' supports two options: `:linenos:' and
`:cssclass:'.
`:linenos:' takes zero or one argument - if no arguments is provided,
line numbers will be visible starting form 1. Provided integer will be
the number of the first line.
`:cssclass:' can be use for changing default class name for block of
code. Default class can be changed by appropriate option for plugin
(see documentation), and defaults to "highlight".
It is possible to use VIm colorschemes like desert (which is distributed
with VIm), Zenburn, Lucius, Wombat, inkpot or any other with Pygments.
Assuming, that colorscheme `desert' should be used, there are two steps
to achive it.
First, python module containing Pygments `Style' class has to be
generated. There is appropriate conversion tool in Pygments
distribution - `scripts/vim2pygments.py'. Uage is simple as:
>
python Pygments/scripts/vim2pygments.py \
path/to/vim/colors/desert.vim > desert.py
<
Which will create new python module ``desert.py`` containing class
`DessertStyle`'.
To generate CSS stylesheet, it's enough to:
>
python rst2blogger/scripts/style2css.py desert.py \
-c VimDesert > desert.css
<
VimDesert is the name of the class, which passed as an argument to
`:cssclass:' option of directive `sourceocode'. It will be used as a
main CSS class for code top `<div>' element. So, above example will
looks like this:
>
.. sourcecode:: python
:cssclass: VimDesert
import vim
print vim.current.buffer.name
<
Note: All headings for generated HTML by |:SendBlogArticle| will be
shifted by 3, so the first heading will become <h3>, second <h4> and so
on, to fit into blogger template (well, most of them). Remember, that
@@ -224,6 +276,7 @@ limitation.
========================================================================
Changelog~
0.2 Pygments sourcecode directive improvements
0.1 First release
vim:tw=72:fo=tcq2:isk=!-~,^*,^|,^":ts=8:ft=help:norl:

View File

@@ -13,6 +13,11 @@ from xml.parsers.expat import ExpatError
import vim
from rst2blogger.rest import blogPreview, blogArticleString
try:
from rst2blogger.rest import register
except ImportError:
pass
from rst2blogger.blogger import VimBlogger
@@ -35,6 +40,12 @@ class Rst2Blogger(object):
self.maxarticles = int(vim.eval("g:blogger_maxarticles"))
self.confirm_del = int(vim.eval("g:blogger_confirm_del"))
self.stylesheets = vim.eval("g:blogger_stylesheets")
self.pygments_class = vim.eval("g:blogger_pygments_class")
print self.pygments_class
try:
register(self.pygments_class)
except NameError:
pass
def preview(self):
"""

View File

@@ -17,6 +17,32 @@ try:
from pygments.lexers import get_lexer_by_name, TextLexer
from pygments.formatters import HtmlFormatter
def register(cssclass=None):
print "register"
if cssclass:
Pygments.cssclass = cssclass
directives.register_directive('sourcecode', Pygments)
def _positive_int_or_1(argument):
"""
Converts the argument into an integer. Returns positive integer. In
case of integers smaller than 1, returns 1. In case of None, returns
1.
"""
if argument is None:
return 1
retval = 1
try:
retval = int(argument)
except ValueError:
pass
if retval < 1:
return 1
return retval
class Pygments(Directive):
"""
Source code syntax highlighting.
@@ -24,7 +50,11 @@ try:
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {'linenos': _positive_int_or_1,
'cssclass': directives.unchanged_required}
has_content = True
cssclass = None
def run(self):
self.assert_has_content()
@@ -33,12 +63,26 @@ try:
except ValueError:
# no lexer found - use the text one instead of an exception
lexer = TextLexer()
# take an arbitrary option if more than one is given
formatter = HtmlFormatter(noclasses=True)
kwargs = {'full': False,
'noclasses': False}
if self.options and 'linenos' in self.options:
kwargs['linenos'] = 'inline'
kwargs['linenostart'] = self.options['linenos']
if Pygments.cssclass:
kwargs['cssclass'] = Pygments.cssclass
if self.options and 'cssclass' in self.options:
kwargs['cssclass'] = self.options['cssclass']
formatter = HtmlFormatter(**kwargs)
parsed = highlight(u'\n'.join(self.content), lexer, formatter)
return [nodes.raw('', parsed, format='html')]
directives.register_directive('sourcecode', Pygments)
register()
except ImportError:
pass

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env python
"""
Generate CSS stylesheet out of provided Style class module, which is an output
from the vim2pygments.py[1] script.
That stylesheet (with any necessary, additional modifications) can be used
with vimblogger_ft[2] VIm plugin, but also for general pygments usage.
Usage:
style2css <module>
[1] vim2pygments is part of the Pygments module, and can be found in scripts
directory of the Pygments <http://pygments.org> distribution.
[2] <http://www.vim.org/scripts/script.php?script_id=3367>
"""
import optparse
import os
from pygments.formatters import HtmlFormatter
class Pygments2CSS(object):
def __init__(self, modulefn, cssclass):
self.style_class = None
self.cssclass = cssclass
if not self.cssclass.startswith("."):
self.cssclass = "." + self.cssclass
mod = os.path.splitext(os.path.basename(modulefn))[0]
try:
module = __import__("%s" % mod)
except ImportError:
print('Error: %s should be in PYTHONPATH or current'
' directory, and should contain valid Style derived'
' class' % modulefn)
raise
for item in dir(module):
if item != 'Style' and item.endswith('Style'):
self.style_class = getattr(module, item)
break
else:
raise ValueError("Error: Wrong module?")
def out(self):
formatter = HtmlFormatter(style=self.style_class)
print "%s { background-color: %s }" % \
(self.cssclass, self.style_class.background_color)
for line in formatter.get_style_defs().split("\n"):
print "%s" % self.cssclass, line
if __name__ == "__main__":
parser = optparse.OptionParser("usage: %prog [options] stylefile.py\n"
"Where stylefile.py is a product of the"
" vim2pygments.py script Pygments "
"distribution.")
parser.add_option("-c", "--class",
dest="cssclass",
type="str",
help="Main CSS class name. Defaults to 'syntax'",
default="syntax")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("stylefile.py is required")
if not (os.path.exists(args[0]) and os.path.isfile(args[0])):
parser.error("%s not found" % args[0])
p2css = Pygments2CSS(args[0], options.cssclass)
p2css.out()

View File

@@ -11,6 +11,69 @@ sys.path.insert(0, this_dir)
from rst2blogger.rest import blogArticleString, blogPreview
from rst2blogger.tests.shared import REST_ARTICLE
LINENOS1 = """
.. sourcecode:: python
:linenos:
import vim
print vim.current.buffer.name
"""
LINENOS2 = """
.. sourcecode:: python
:linenos: -1
import vim
print vim.current.buffer.name
"""
LINENOS3 = """
.. sourcecode:: python
:linenos: 0
import vim
print vim.current.buffer.name
"""
LINENOS4 = """
.. sourcecode:: python
:linenos: 12
import vim
print vim.current.buffer.name
"""
LINENOS5 = """
.. sourcecode:: python
:linenos: this is wrong
import vim
print vim.current.buffer.name
"""
CSSCLASS1 = """
.. sourcecode:: python
:cssclass:
import vim
print vim.current.buffer.name
"""
CSSCLASS2 = """
.. sourcecode:: python
:cssclass: Dessert256
import vim
print vim.current.buffer.name
"""
class TestBlogPreview(unittest.TestCase):
"""
@@ -75,5 +138,64 @@ class TestBlogArticleString(unittest.TestCase):
self.assertEqual(attrs['date'], "2010-12-12T12:36:36+01:00")
self.assertEqual(attrs['tags'], "this is a test, Blogger, rest")
class TestBlogArticlePytgments(unittest.TestCase):
"""
Test cases for sourcecode directive
"""
def test_linenos_no_args(self):
"""
Test linenos option with no additional arguments
"""
html_out, _ = blogArticleString(LINENOS1)
self.assertTrue('<pre><span class="lineno">1</span>' in html_out)
def test_linenos_with_arg1(self):
"""
Test linenos option with correct argument type but wrong value.
Should count from 1 in this case.
"""
html_out, _ = blogArticleString(LINENOS2)
self.assertTrue('<pre><span class="lineno">1</span>' in html_out)
def test_linenos_with_arg2(self):
"""
Test linenos option with correct argument type but wrong value.
Should count from 1 in this case.
"""
html_out, _ = blogArticleString(LINENOS3)
self.assertTrue('<pre><span class="lineno">1</span>' in html_out)
def test_linenos_with_arg3(self):
"""
Test linenos option with correct argument type and correct value.
Should count from 1 in this case.
"""
html_out, _ = blogArticleString(LINENOS4)
self.assertTrue('<pre><span class="lineno">12</span>' in html_out)
def test_linenos_with_wrong_arg(self):
"""
Test linenos option with wrong argument type. Should count from 1.
"""
html_out, _ = blogArticleString(LINENOS5)
self.assertTrue('<pre><span class="lineno">1</span>' in html_out)
def test_cssclass_failure(self):
"""
Test cssclass option with no arguments. Should complain with system
message.
"""
html_out, _ = blogArticleString(CSSCLASS1)
self.assertTrue('System Message: ERROR/3' in html_out)
def test_cssclass_correct(self):
"""
Test cssclass option with Dessert256 as an argument. Should be used as
a main div CSS class.
"""
html_out, _ = blogArticleString(CSSCLASS2)
self.assertTrue('<div class="Dessert256">' in html_out)
if __name__ == "__main__":
unittest.main()

View File

@@ -1,6 +1,7 @@
" reST to blogger vim interface.
" Provide some convinient commands for creating preview from the reST file
" and to send articles to blog.
" VERSION: 0.2
if exists("b:did_rst_plugin")
finish " load only once
@@ -44,6 +45,10 @@ if !exists("g:blogger_stylesheets")
let g:blogger_stylesheets = []
endif
if !exists("g:blogger_pygments_class")
let g:blogger_pygments_class = ""
endif
python << EOF
import os
import sys
@@ -53,10 +58,8 @@ import vim
scriptdir = os.path.dirname(vim.eval('expand("<sfile>")'))
sys.path.insert(0, scriptdir)
try:
# Will raise exception, if one of required moudles is missing
from rst2blogger.main import Rst2Blogger
except ImportError:
print "Plugin vimblogger cannot be loaded, due to lack of required modules"
EOF
if !exists(":PreviewBlogArticle")