diff --git a/doc/tags b/doc/tags
index 992ba44..855d974 100644
--- a/doc/tags
+++ b/doc/tags
@@ -27,10 +27,6 @@
'snippets' snipMate.txt /*'snippets'*
.snippet snipMate.txt /*.snippet*
.snippets snipMate.txt /*.snippets*
-:AcpDisable acp.txt /*:AcpDisable*
-:AcpEnable acp.txt /*:AcpEnable*
-:AcpLock acp.txt /*:AcpLock*
-:AcpUnlock acp.txt /*:AcpUnlock*
:CVSEdit vcscommand.txt /*:CVSEdit*
:CVSEditors vcscommand.txt /*:CVSEditors*
:CVSUnedit vcscommand.txt /*:CVSUnedit*
@@ -40,6 +36,8 @@
:CVSWatchOn vcscommand.txt /*:CVSWatchOn*
:CVSWatchRemove vcscommand.txt /*:CVSWatchRemove*
:CVSWatchers vcscommand.txt /*:CVSWatchers*
+:Date: vimblogger_ft.txt /*:Date:*
+:DeleteBlogArticle vimblogger_ft.txt /*:DeleteBlogArticle*
:DelimitMateReload delimitMate.txt /*:DelimitMateReload*
:DelimitMateSwitch delimitMate.txt /*:DelimitMateSwitch*
:DelimitMateTest delimitMate.txt /*:DelimitMateTest*
@@ -77,9 +75,15 @@
:FufTag fuf.txt /*:FufTag*
:FufTagWithCursorWord fuf.txt /*:FufTagWithCursorWord*
:FufTaggedFile fuf.txt /*:FufTaggedFile*
+:Id: vimblogger_ft.txt /*:Id:*
:Loremipsum loremipsum.txt /*:Loremipsum*
:Loreplace loremipsum.txt /*:Loreplace*
:Mark mark.txt /*:Mark*
+:Modified: vimblogger_ft.txt /*:Modified:*
+:PreviewBlogArticle vimblogger_ft.txt /*:PreviewBlogArticle*
+:SendBlogArticle vimblogger_ft.txt /*:SendBlogArticle*
+:Tags: vimblogger_ft.txt /*:Tags:*
+:Title: vimblogger_ft.txt /*:Title:*
:VCSAdd vcscommand.txt /*:VCSAdd*
:VCSAnnotate vcscommand.txt /*:VCSAnnotate*
:VCSBlame vcscommand.txt /*:VCSBlame*
@@ -122,9 +126,16 @@
:VimwikiToggleListItem vimwiki.txt /*:VimwikiToggleListItem*
:VimwikiUISelect vimwiki.txt /*:VimwikiUISelect*
:VimwikiVSplitLink vimwiki.txt /*:VimwikiVSplitLink*
+AnsiEsc AnsiEsc.txt /*AnsiEsc*
+AnsiEsc-contents AnsiEsc.txt /*AnsiEsc-contents*
+AnsiEsc-copyright AnsiEsc.txt /*AnsiEsc-copyright*
+AnsiEsc-history AnsiEsc.txt /*AnsiEsc-history*
+AnsiEsc-manual AnsiEsc.txt /*AnsiEsc-manual*
+AnsiEsc.txt AnsiEsc.txt /*AnsiEsc.txt*
ExtractSnips() snipMate.txt /*ExtractSnips()*
ExtractSnipsFile() snipMate.txt /*ExtractSnipsFile()*
Filename() snipMate.txt /*Filename()*
+Id vimblogger_ft.txt /*Id*
ResetSnippets() snipMate.txt /*ResetSnippets()*
ShowMarksClearAll showmarks.txt /*ShowMarksClearAll*
ShowMarksClearMark showmarks.txt /*ShowMarksClearMark*
@@ -156,21 +167,6 @@ VCSCommandSplit vcscommand.txt /*VCSCommandSplit*
VCSCommandVCSTypeOverride vcscommand.txt /*VCSCommandVCSTypeOverride*
VimwikiWeblinkHandler vimwiki.txt /*VimwikiWeblinkHandler*
abc fuf.txt /*abc*
-acp acp.txt /*acp*
-acp-about acp.txt /*acp-about*
-acp-author acp.txt /*acp-author*
-acp-changelog acp.txt /*acp-changelog*
-acp-commands acp.txt /*acp-commands*
-acp-contact acp.txt /*acp-contact*
-acp-installation acp.txt /*acp-installation*
-acp-introduction acp.txt /*acp-introduction*
-acp-options acp.txt /*acp-options*
-acp-perl-omni acp.txt /*acp-perl-omni*
-acp-snipMate acp.txt /*acp-snipMate*
-acp-thanks acp.txt /*acp-thanks*
-acp-usage acp.txt /*acp-usage*
-acp.txt acp.txt /*acp.txt*
-autocomplpop acp.txt /*autocomplpop*
b:VCSCommandCommand vcscommand.txt /*b:VCSCommandCommand*
b:VCSCommandOriginalBuffer vcscommand.txt /*b:VCSCommandOriginalBuffer*
b:VCSCommandSourceFile vcscommand.txt /*b:VCSCommandSourceFile*
@@ -204,6 +200,7 @@ delimitMateSyntax delimitMate.txt /*delimitMateSyntax*
delimitMateTodo delimitMate.txt /*delimitMateTodo*
delimitMateVisualWrapping delimitMate.txt /*delimitMateVisualWrapping*
delimitMate_WithinEmptyPair delimitMate.txt /*delimitMate_WithinEmptyPair*
+docinfo vimblogger_ft.txt /*docinfo*
ds surround.txt /*ds*
fuf fuf.txt /*fuf*
fuf#setOneTimeVariables() fuf.txt /*fuf#setOneTimeVariables()*
@@ -272,32 +269,14 @@ fuf-usage fuf.txt /*fuf-usage*
fuf-vimrc-example fuf.txt /*fuf-vimrc-example*
fuf.txt fuf.txt /*fuf.txt*
fuzzyfinder fuf.txt /*fuzzyfinder*
-g:acp_behavior acp.txt /*g:acp_behavior*
-g:acp_behavior-command acp.txt /*g:acp_behavior-command*
-g:acp_behavior-completefunc acp.txt /*g:acp_behavior-completefunc*
-g:acp_behavior-meets acp.txt /*g:acp_behavior-meets*
-g:acp_behavior-onPopupClose acp.txt /*g:acp_behavior-onPopupClose*
-g:acp_behavior-repeat acp.txt /*g:acp_behavior-repeat*
-g:acp_behaviorCssOmniPropertyLength acp.txt /*g:acp_behaviorCssOmniPropertyLength*
-g:acp_behaviorCssOmniValueLength acp.txt /*g:acp_behaviorCssOmniValueLength*
-g:acp_behaviorFileLength acp.txt /*g:acp_behaviorFileLength*
-g:acp_behaviorHtmlOmniLength acp.txt /*g:acp_behaviorHtmlOmniLength*
-g:acp_behaviorKeywordCommand acp.txt /*g:acp_behaviorKeywordCommand*
-g:acp_behaviorKeywordIgnores acp.txt /*g:acp_behaviorKeywordIgnores*
-g:acp_behaviorKeywordLength acp.txt /*g:acp_behaviorKeywordLength*
-g:acp_behaviorPerlOmniLength acp.txt /*g:acp_behaviorPerlOmniLength*
-g:acp_behaviorPythonOmniLength acp.txt /*g:acp_behaviorPythonOmniLength*
-g:acp_behaviorRubyOmniMethodLength acp.txt /*g:acp_behaviorRubyOmniMethodLength*
-g:acp_behaviorRubyOmniSymbolLength acp.txt /*g:acp_behaviorRubyOmniSymbolLength*
-g:acp_behaviorSnipmateLength acp.txt /*g:acp_behaviorSnipmateLength*
-g:acp_behaviorUserDefinedFunction acp.txt /*g:acp_behaviorUserDefinedFunction*
-g:acp_behaviorUserDefinedMeets acp.txt /*g:acp_behaviorUserDefinedMeets*
-g:acp_behaviorXmlOmniLength acp.txt /*g:acp_behaviorXmlOmniLength*
-g:acp_completeOption acp.txt /*g:acp_completeOption*
-g:acp_completeoptPreview acp.txt /*g:acp_completeoptPreview*
-g:acp_enableAtStartup acp.txt /*g:acp_enableAtStartup*
-g:acp_ignorecaseOption acp.txt /*g:acp_ignorecaseOption*
-g:acp_mappingDriven acp.txt /*g:acp_mappingDriven*
+g:blogger_browser vimblogger_ft.txt /*g:blogger_browser*
+g:blogger_confirm_del vimblogger_ft.txt /*g:blogger_confirm_del*
+g:blogger_draft vimblogger_ft.txt /*g:blogger_draft*
+g:blogger_login vimblogger_ft.txt /*g:blogger_login*
+g:blogger_maxarticles vimblogger_ft.txt /*g:blogger_maxarticles*
+g:blogger_name vimblogger_ft.txt /*g:blogger_name*
+g:blogger_pass vimblogger_ft.txt /*g:blogger_pass*
+g:blogger_stylesheets vimblogger_ft.txt /*g:blogger_stylesheets*
g:fuf_abbrevMap fuf.txt /*g:fuf_abbrevMap*
g:fuf_autoPreview fuf.txt /*g:fuf_autoPreview*
g:fuf_bookmarkdir_keyDelete fuf.txt /*g:fuf_bookmarkdir_keyDelete*
@@ -440,18 +419,6 @@ mark-usage mark.txt /*mark-usage*
mark.txt mark.txt /*mark.txt*
mark.vim mark.txt /*mark.vim*
multi_snip snipMate.txt /*multi_snip*
-project project.txt /*project*
-project-adding-mappings project.txt /*project-adding-mappings*
-project-example project.txt /*project-example*
-project-flags project.txt /*project-flags*
-project-inheritance project.txt /*project-inheritance*
-project-invoking project.txt /*project-invoking*
-project-mappings project.txt /*project-mappings*
-project-plugin project.txt /*project-plugin*
-project-settings project.txt /*project-settings*
-project-syntax project.txt /*project-syntax*
-project-tips project.txt /*project-tips*
-project.txt project.txt /*project.txt*
py2stdlib py2stdlib.txt /*py2stdlib*
py2stdlib-__future__ py2stdlib.txt /*py2stdlib-__future__*
py2stdlib-__main__ py2stdlib.txt /*py2stdlib-__main__*
@@ -903,6 +870,7 @@ vcscommand-ssh-wrapper vcscommand.txt /*vcscommand-ssh-wrapper*
vcscommand-statusline vcscommand.txt /*vcscommand-statusline*
vcscommand.txt vcscommand.txt /*vcscommand.txt*
vgS surround.txt /*vgS*
+vimblogger_ft.txt vimblogger_ft.txt /*vimblogger_ft.txt*
vimwiki vimwiki.txt /*vimwiki*
vimwiki-calendar vimwiki.txt /*vimwiki-calendar*
vimwiki-changelog vimwiki.txt /*vimwiki-changelog*
diff --git a/doc/vimblogger_ft.txt b/doc/vimblogger_ft.txt
index cb00b41..077f32d 100644
--- a/doc/vimblogger_ft.txt
+++ b/doc/vimblogger_ft.txt
@@ -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
+ - pygments http://pygments.org (optional)
- Blogger account
-----------------------------------------------------------------------
@@ -138,22 +138,22 @@ 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
+lines, that are starting from ":" character) separaded from other
content with one empty line.
Docinfo items holds article attributes, and are updated automatically
every each of upload to blogger, which is triggered by
-*:SendBlogArticle* command.
+":SendBlogArticle" command.
*:Id:*
Holds article id on blogger side. If not defined, new article will
be created (even if there is already existing one with the very same
- content). If wrong id is entered (or an Id of deleted article),
+ content). If wrong Id is entered (or an Id of deleted article),
exception will be raised, and no action on blogger side will be
performed.
*:Title:*
- Holds article title. Can be changed when *:Id:* is obtained.
+ Holds article title. Can be changed when |:Id:| is obtained.
*:Date:*
This is published date in RFC 3339
@@ -173,8 +173,9 @@ All other items are ignored.
After docinfo block, article body should be placed using markup for
reStructuredText.
-Additionally, there is sourcecode directive, simple syntax highlighter
-using Pygments module. Very simple usage could be as follows:
+Additionally, if pytgments is installed, there is sourcecode directive, simple
+syntax highlighter using Pygments module. Very simple usage could be as
+follows:
-----8<-----
.. sourcecode:: python
@@ -184,7 +185,7 @@ using Pygments module. Very simple usage could be as follows:
----->8-----
-Note: All headings for generated HTML by *:SendBlogArticle* will be
+Note: All headings for generated HTML by |:SendBlogArticle| will be
shifted by 3, so the first heading will become
, second
and so
on, to fit into blogger template (well, most of them). Remember, that
HTML allow up to 6 level of headings, while reST doesn't have this
diff --git a/ftplugin/rst/rst2blogger/__init__.py b/ftplugin/rst/rst2blogger/__init__.py
index a402df0..97ea5bd 100644
--- a/ftplugin/rst/rst2blogger/__init__.py
+++ b/ftplugin/rst/rst2blogger/__init__.py
@@ -1 +1 @@
-# module vimblogger
+# module rst2blogger
diff --git a/ftplugin/rst/rst2blogger/blogger.py b/ftplugin/rst/rst2blogger/blogger.py
index 67714f9..1c3db91 100644
--- a/ftplugin/rst/rst2blogger/blogger.py
+++ b/ftplugin/rst/rst2blogger/blogger.py
@@ -1,46 +1,12 @@
-# vim: fileencoding=utf8
-#
-# Blogger interface to make easy way to create/update articles for specified
-# blog.
-#
-# It is assumed one way communication only, so you may create or update an
-# article from reST source files. There is no way to recreate article from
-# html to reST format.
-#
-# requirements:
-#
-# - Vim compiled with +python
-# - python 2.x (tested with 2.6)
-# - modules
-# - gdata (http://code.google.com/p/gdata-python-client)
-# - docutils (http://docutils.sourceforge.net)
-#
-# USE CASES:
-# 1. Create new post
-#
-# use reST template:
-# ===8<---
-# :Title: Blog post title
-# :Date: optional publish date (for example: 2010-11-28 18:47:05),
-# default: now()
-# :Modified: optional, default: None
-# :Tags: comma separated blog tags
-#
-# .. more
-#
-# --->8===
-#
-# All four docinfo are optional, however it is nice to give at least a title
-# to the article :)
-#
-#
-#
-# which is provided under templates directory or as a
-# snipMate shoortcut (see .vim/snippets/rst.snippets)
-#
+"""
+File: blogger.py
+Author: Roman 'gryf' Dobosz
+Description: This is blogger activity connected module. It is using gdata[1]
+ blogger module to provide add/modify/delete articles interface.
+
+ [1] http://code.google.com/p/gdata-python-client
+"""
-#-----------------------------------------------------------------------------
-#
import datetime
import re
@@ -51,6 +17,7 @@ from gdata.blogger.data import BlogPost
class VimBlogger(object):
"""
+ Communicate with blogger through gdata.blogger modules
"""
DATE_PATTERN = re.compile(r"^(\d{4}-\d{2}-\d{2})"
"T(\d{2}:\d{2}:\d{2})(\.\d{3})?[+-]"
@@ -59,12 +26,9 @@ class VimBlogger(object):
TIME_FORMAT = "%H:%M:%S"
TZ_FORMAT = "%H:%M"
- # TODO: dodać usuwanie artykułów (prosta lista, wybieramy art,
- # potwierdzamy)
- # TODO: Dokumentacja jako vimdoc!
-
def __init__(self, blogname, login, password):
"""
+ Initialization.
"""
self.draft = True
self.blog_id = None
@@ -79,7 +43,6 @@ class VimBlogger(object):
"""
Return list of articles
"""
-
feed = self.client.get_posts(self.blog_id)
posts = []
@@ -91,7 +54,6 @@ class VimBlogger(object):
self._extract_date(entry.published.text)))
return posts
-
def create_article(self, html_doc, attrs=None):
"""
Create new article
@@ -118,7 +80,7 @@ class VimBlogger(object):
new_post.published = atom.data.Published(text=attrs['date'])
if self.draft:
- new_post.control = atom.data.Control(\
+ new_post.control = atom.data.Control(\
draft=atom.data.Draft(text='yes'))
return self.client.post(new_post, BLOG_POST_URL % self.blog_id)
@@ -137,7 +99,7 @@ class VimBlogger(object):
post = self._get_post(attrs['id'])
post.content = atom.data.Content(text=html_doc, type="html")
- # update publish date
+ # update published date
if 'date' in attrs and attrs['date'] and \
self._check_date(attrs['date']):
post.published = atom.data.Published(text=attrs['date'])
@@ -168,9 +130,9 @@ class VimBlogger(object):
self.client.delete(post)
return None
-
def _get_post(self, post_id):
"""
+ Return post with specified ID
"""
post_href = self.blog.get_post_link().href
return self.client.get_feed(post_href + "/%s" % post_id,
@@ -227,18 +189,13 @@ class VimBlogger(object):
return True
- def _update_date(self, post, attrs):
- """
- Update articles published date
- """
-
def _authorize(self, login, password):
"""
Try to authorize in Google service.
Authorization is kept in client object. In case of wrong credentials,
exception is thrown.
"""
- source = 'Blogger_Python_Sample-2.0'
+ source = 'Vim rst2blogger interface'
service = 'blogger'
self.client.client_login(login,
@@ -255,4 +212,3 @@ class VimBlogger(object):
self.blog_id = blog.get_blog_id()
self.blog = blog
break
-
diff --git a/ftplugin/rst/rst2blogger/main.py b/ftplugin/rst/rst2blogger/main.py
index da4e87f..b2acde6 100644
--- a/ftplugin/rst/rst2blogger/main.py
+++ b/ftplugin/rst/rst2blogger/main.py
@@ -1,4 +1,11 @@
# vim: fileencoding=utf8
+"""
+File: main.py
+Author: Roman 'gryf' Dobosz
+Description: main file to provide fuctionality between vim and moudles rest
+ and blogger
+"""
+
import webbrowser
from xml.dom import minidom
from xml.parsers.expat import ExpatError
@@ -35,7 +42,7 @@ class Rst2Blogger(object):
systems' web browser
"""
bufcontent = "\n".join(self.buff)
- name = vim.current.buffer.name
+ name = self.buff.name
name = name[:-4] + ".html"
html = blogPreview(bufcontent, self.stylesheets)
@@ -51,7 +58,10 @@ class Rst2Blogger(object):
return "Generated HTML has been written to %s" % name
def post(self):
- bufcontent = "\n".join(vim.current.buffer)
+ """
+ Do post article
+ """
+ bufcontent = "\n".join(self.buff)
html, attrs = blogArticleString(bufcontent)
parse_msg = self._check_html(html, True)
@@ -60,7 +70,8 @@ class Rst2Blogger(object):
return "There are errors in generated document"
if not self.password:
- self.password = vim.eval('inputsecret("Enter your gmail password: ")')
+ self.password = \
+ vim.eval('inputsecret("Enter your gmail password: ")')
blog = VimBlogger(self.blogname, self.login, self.password)
blog.draft = self.draft > 0
@@ -74,9 +85,6 @@ class Rst2Blogger(object):
msg = "New article with id %s has been created" % \
post.get_post_id()
- if not post:
- return "There is something fishy with creating new article."
-
for item, value in (('id', post.get_post_id()),
('date', post.published.text),
('title', post.title.text),
@@ -92,14 +100,15 @@ class Rst2Blogger(object):
delete
"""
if not self.password:
- self.password = vim.eval('inputsecret("Enter your gmail password: ")')
+ self.password = \
+ vim.eval('inputsecret("Enter your gmail password: ")')
blog = VimBlogger(self.blogname, self.login, self.password)
posts = blog.get_articles(self.maxarticles)
msg = u"inputlist(["
for index, entries in enumerate(posts):
- line = "%2d %s %s" % (index+1,
+ line = "%2d %s %s" % (index + 1,
entries[1],
entries[2])
msg += u'"' + line.replace('"', '\\"') + u'",'
@@ -109,8 +118,9 @@ class Rst2Blogger(object):
choice = int(vim.eval(msg))
if choice:
- art = posts[choice-1]
- msg = 'confirm("You are about to delete article \'%s\'. Are you sure?"'
+ art = posts[choice - 1]
+ msg = 'confirm("You are about to delete article \'%s\'. '
+ msg += 'Are you sure?"'
msg = unicode(msg % art[1]).encode(self.vim_encoding)
msg += ', "&No\n&Yes")'
@@ -120,14 +130,10 @@ class Rst2Blogger(object):
choice = 2
if choice == 2:
- result = blog.delete_article(art[0])
- if result is None:
- return "Article deleted"
- else:
- return result
+ blog.delete_article(art[0])
+ return "Article deleted"
return "No articles deleted"
-
def _update_docinfo(self, attr, val):
"""
Update current buffer with attributes value
@@ -183,6 +189,9 @@ class Rst2Blogger(object):
returns empty string if parses succeed, else exception message.
"""
+ # minidom doesn't understand html entities like ' ' For checking
+ # purpose it is perfectly ok, to switch them with '&'
+ html = html.replace(" ", "&")
if add_container:
html = "
" + html + "
"
@@ -193,5 +202,3 @@ class Rst2Blogger(object):
message = str(ex)
return message
-
-
diff --git a/ftplugin/rst/rst2blogger/rest.py b/ftplugin/rst/rst2blogger/rest.py
index 44f93fd..d5cabe4 100644
--- a/ftplugin/rst/rst2blogger/rest.py
+++ b/ftplugin/rst/rst2blogger/rest.py
@@ -1,3 +1,10 @@
+"""
+File: rest.py
+Author: Roman 'gryf' Dobosz
+Description: This module is responsible for conversion between reST and HTML
+ with some goods added.
+"""
+
import re
from docutils import core
@@ -5,35 +12,40 @@ from docutils import nodes
from docutils.parsers.rst import directives, Directive
from docutils.writers.html4css1 import Writer, HTMLTranslator
-from pygments import highlight
-from pygments.lexers import get_lexer_by_name, TextLexer
-from pygments.formatters import HtmlFormatter
+try:
+ from pygments import highlight
+ from pygments.lexers import get_lexer_by_name, TextLexer
+ from pygments.formatters import HtmlFormatter
+
+ class Pygments(Directive):
+ """
+ Source code syntax highlighting.
+ """
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = True
+ has_content = True
+
+ def run(self):
+ self.assert_has_content()
+ try:
+ lexer = get_lexer_by_name(self.arguments[0])
+ 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)
+ parsed = highlight(u'\n'.join(self.content), lexer, formatter)
+ return [nodes.raw('', parsed, format='html')]
+
+ directives.register_directive('sourcecode', Pygments)
+except ImportError:
+ pass
+
class Attrs(object):
ATTRS = {}
-class Pygments(Directive):
- """
- Source code syntax highlighting.
- """
- required_arguments = 1
- optional_arguments = 0
- final_argument_whitespace = True
- has_content = True
-
- def run(self):
- self.assert_has_content()
- try:
- lexer = get_lexer_by_name(self.arguments[0])
- 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)
- parsed = highlight(u'\n'.join(self.content), lexer, formatter)
- return [nodes.raw('', parsed, format='html')]
-
-directives.register_directive('sourcecode', Pygments)
class CustomHTMLTranslator(HTMLTranslator):
"""
@@ -41,7 +53,6 @@ class CustomHTMLTranslator(HTMLTranslator):
There are couple of customizations for docinfo fields behaviour and
abbreviations and acronyms.
"""
-
def __init__(self, document):
"""
Set some nice defaults for articles translations
@@ -143,6 +154,7 @@ class CustomHTMLTranslator(HTMLTranslator):
else:
self.body.append(self.starttag(node, 'abbr', ''))
+
class NoHeaderHTMLTranslator(CustomHTMLTranslator):
"""
Special subclass for generating only body of an article
@@ -154,7 +166,7 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator):
CustomHTMLTranslator.__init__(self, document)
self.head = []
self.meta = []
- self.head_prefix = ['','','','','']
+ self.head_prefix = ['', '', '', '', '']
self.body_prefix = []
self.body_suffix = []
self.stylesheet = []
@@ -173,11 +185,13 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator):
"""
Attrs.ATTRS['date'] = node.astext()
+
class PreviewHTMLTranslator(CustomHTMLTranslator):
"""
Class for display article in the browser as a preview.
"""
CSS = []
+
def __init__(self, document):
"""
Alter levels for the heading tags, define custom, blog specific
@@ -193,7 +207,6 @@ class PreviewHTMLTranslator(CustomHTMLTranslator):
for css in self.default_stylesheets]
self.body_ = []
-
def depart_docinfo(self, node):
"""
Overwrite body with some custom one. body_ will hold the first heading
@@ -203,7 +216,7 @@ class PreviewHTMLTranslator(CustomHTMLTranslator):
def visit_field(self, node):
"""
- Additional 'keyword' for the ODF metadata
+ Make title visible as a heading
"""
key, node_ = [n.astext() for n in node]
key = key.lower()
@@ -212,6 +225,7 @@ class PreviewHTMLTranslator(CustomHTMLTranslator):
self.body_.append('
"
+ self.assertEqual(self.obj._check_html(html),
+ "junk after document element: line 1, column 22")
+ self.assertEqual(self.obj._check_html(html, True), "")
+
+ def test_check_html3(self):
+ """
+ Parse wrong html string (crossed tags)
+ """
+ html = "
first paragraph
another paragraph"
+ self.assertEqual(self.obj._check_html(html),
+ "mismatched tag: line 1, column 23")
+ self.assertEqual(self.obj._check_html(html, True),
+ "mismatched tag: line 1, column 28")
+
+
+class TestRst2BloggerDelete(unittest.TestCase):
+ """
+ Test delete method
+ """
+ def setUp(self):
+ """
+ Create Rst2Blogger object
+ """
+ self.obj = Rst2Blogger()
+ self.obj.login = LOGIN
+ self.obj.password = PASS
+ self.obj.blogname = "test"
+ self.obj.vim_encoding = "utf-8"
+
+ def test_delete_without_password(self):
+ """
+ Delete article, while password is incorrect/nonexistend
+ """
+ self.obj.password = ""
+ self.assertRaises(BadAuthentication, self.obj.delete)
+
+ def test_delete(self):
+ """
+ Delete article. Set confirmation attribute.
+ """
+ self.obj.confirm_del = 1
+ Eval.value = 2 # set choice to answer "Y" for confirmation
+ Eval.blog = "test"
+ self.assertEqual(self.obj.delete(), "Article deleted")
+
+ def test_delete2(self):
+ """
+ Delete article. Set confirmation attribute. Refuse to delete.
+ """
+ self.obj.confirm_del = 1
+ Eval.value = 1 # set choice to answer "N" for confirmation
+ Eval.blog = "test"
+ self.assertEqual(self.obj.delete(), "No articles deleted")
+
+ def test_delete3(self):
+ """
+ Delete article. Unset confirmation attribute. Delete returns something
+ else then None.
+ """
+ Eval.value = 2
+ Eval.blog = "test"
+ Eval.gdata_delete = 1
+ self.assertEqual(self.obj.delete(), "Article deleted")
+
+
+class TestRst2BloggerPost(unittest.TestCase):
+ """
+ Test post method
+ """
+ def setUp(self):
+ """
+ Create Rst2Blogger object
+ """
+ self.obj = Rst2Blogger()
+ self.obj.login = LOGIN
+ self.obj.password = PASS
+ self.obj.blogname = "test"
+ self.obj.vim_encoding = "utf-8"
+ self.obj.buffer_encoding = "utf-8"
+ # create copy of the buffer list and assign copy to the buff attribute
+ self._rest = MockBuffer(self.obj.buff[:])
+ self.obj.buff = self._rest
+
+ def test_without_password(self):
+ """
+ Post article, while password is incorrect/nonexistend
+ """
+ self.obj.password = ""
+ self.assertRaises(BadAuthentication, self.obj.post)
+
+ def test_with_wrong_data(self):
+ """
+ Try to post not well formed html
+ """
+ self.obj.buff.append('')
+ self.obj.buff.append('.. raw:: html')
+ self.obj.buff.append('')
+ self.obj.buff.append('
foobar
baz')
+ self.obj.buff.append('')
+ self.obj.post()
+ self.assertEqual(self.obj.post(),
+ 'There are errors in generated document')
+
+ def test_post_create(self):
+ """
+ Try to post well formed html, as a new article
+ """
+ self.assertEqual(self.obj.post(),
+ 'New article with id 1234567890 has been created')
+
+ def test_post_update(self):
+ """
+ Try to post well formed html, as a new article
+ """
+ self.obj.buff.append(':Id: 1234567890', 0)
+ self.assertEqual(self.obj.post(),
+ "Article 'Title \xe2\x80\x94 This is a test' "
+ "has been updated")
+
+
+class TestRst2BloggerUpdateDocinfo(unittest.TestCase):
+ """
+ Test _update_docinfo
+ """
+ def setUp(self):
+ """
+ Create Rst2Blogger object
+ """
+ self.obj = Rst2Blogger()
+ self.obj.login = LOGIN
+ self.obj.password = PASS
+ self.obj.blogname = "test"
+ self.obj.vim_encoding = "utf-8"
+ self.obj.buffer_encoding = "utf-8"
+ # create copy of the buffer list and assign copy to the buff attribute
+ self._rest = MockBuffer(self.obj.buff[:])
+ self.obj.buff = self._rest
+
+ def test_with_empty_docinfo(self):
+ """
+ Try to post not well formed html
+ """
+ self.obj.buff = MockBuffer(self.obj.buff[4:])
+ self.obj.docinfo_len = 0
+ self.obj._update_docinfo('title', 'title2')
+
+
+class TestRst2BloggerPreview(unittest.TestCase):
+ """
+ Test preview
+ """
+ def setUp(self):
+ """
+ Create Rst2Blogger object
+ """
+ self.obj = Rst2Blogger()
+ self.obj.login = LOGIN
+ self.obj.password = PASS
+ self.obj.blogname = "test"
+
+ def tearDown(self):
+ """
+ Remove leftovers in fs
+ """
+ try:
+ os.unlink(self.obj.buff.name[:-4])
+ except OSError:
+ pass
+ try:
+ os.unlink(self.obj.buff.name[:-4] + ".html")
+ except OSError:
+ pass
+
+ def test_preview_open_in_browser(self):
+ """
+ Try to post not well formed html
+ """
+ Eval.value = 1
+ print self.obj.preview()
+
+ def test_preview_save_to_file(self):
+ """
+ Try to post not well formed html
+ """
+ Eval.value = 0
+ name = self.obj.buff.name[:-4] + ".html"
+ self.assertEqual(self.obj.preview(),
+ "Generated HTML has been written to %s" % name)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/ftplugin/rst/rst2blogger/tests/test_rest.py b/ftplugin/rst/rst2blogger/tests/test_rest.py
new file mode 100644
index 0000000..aade474
--- /dev/null
+++ b/ftplugin/rst/rst2blogger/tests/test_rest.py
@@ -0,0 +1,79 @@
+# vim: set fileencoding=utf-8
+import os
+import sys
+import unittest
+import re
+
+this_dir = os.path.dirname(os.path.abspath(__file__))
+this_dir = os.path.abspath(os.path.join(this_dir, "../.."))
+sys.path.insert(0, this_dir)
+
+from rst2blogger.rest import blogArticleString, blogPreview
+from rst2blogger.tests.shared import REST_ARTICLE
+
+
+class TestBlogPreview(unittest.TestCase):
+ """
+ Test generating HTML out of prepared reST text. It tests only for some
+ aspects of the entire thing, because it is not intendend to test all of
+ reST directives.
+ """
+ def test_content(self):
+ """
+ Simple case, check output
+ """
+ html_out = blogPreview(REST_ARTICLE)
+ self.assertTrue(len(html_out) > 0)
+ self.assertTrue("" in html_out)
+ self.assertTrue("\n\n" in html_out)
+ self.assertTrue("Title — This is a test" in html_out)
+ self.assertTrue('type="text/css"' not in html_out)
+ self.assertTrue(re.search(r"Title — This is a"
+ " test", html_out))
+ self.assertTrue(re.search(r"
Section 1
", html_out))
+ self.assertTrue(re.search(r"
Subsection 1.1
", html_out))
+ self.assertTrue("description" not in html_out)
+
+ def test_stylesheets(self):
+ """
+ Test output for stylesheets
+ """
+ html_out = blogPreview(REST_ARTICLE, ["css/style1.css",
+ "css/blogger1.css"])
+ self.assertTrue('type="text/css"' in html_out)
+ match = re.search(r'', html_out)
+ self.assertTrue(match is not None)
+ self.assertEqual(len(match.span()), 2)
+
+
+class TestBlogArticleString(unittest.TestCase):
+ """
+ Test blogArticleString function, wich should return part of html and
+ dictionary with attributes.
+ """
+ def test_blogArticleString(self):
+ html_out, attrs = blogArticleString(REST_ARTICLE)
+ self.assertEqual(len(attrs), 3)
+ self.assertTrue(len(html_out) > 0)
+ self.assertTrue("" not in html_out)
+ self.assertTrue("\n\n" in html_out)
+ self.assertTrue("Title — This is a test" not in
+ html_out)
+ self.assertTrue('type="text/css"' not in html_out)
+ self.assertTrue(re.search(r"
Section 1
", html_out))
+ self.assertTrue(re.search(r"
Subsection 1.1
", html_out))
+ self.assertTrue("description" not in html_out)
+
+ self.assertEqual(attrs['title'], u"Title — This is a test")
+ self.assertEqual(attrs['date'], "2010-12-12T12:36:36+01:00")
+ self.assertEqual(attrs['tags'], "this is a test, Blogger, rest")
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/ftplugin/rst/vimblogger_ft.vim b/ftplugin/rst/vimblogger_ft.vim
index 283ea0c..137b2ce 100644
--- a/ftplugin/rst/vimblogger_ft.vim
+++ b/ftplugin/rst/vimblogger_ft.vim
@@ -25,7 +25,7 @@ if !exists("g:blogger_login")
endif
if !exists("g:blogger_pass")
- let g:blogger_pass = "Kurcz4czek"
+ let g:blogger_pass = ""
endif
if !exists("g:blogger_draft")