diff --git a/generators/generator.py b/generators/generator.py index d99de02..0851fa7 100644 --- a/generators/generator.py +++ b/generators/generator.py @@ -21,6 +21,7 @@ class StrictUTF8Writer(codecs.StreamWriter): object = object.replace('>', '>') object = object.replace('"', '"') object = object.replace(''', "'") + object = object.replace('&', "&") if not type(object) == unicode: self.value = self.value + unicode(object, "utf-8") diff --git a/generators/index.py b/generators/index.py index e74700f..5c2302c 100644 --- a/generators/index.py +++ b/generators/index.py @@ -3,7 +3,7 @@ import datetime import xml from xml.parsers.expat import * from xml.dom.minidom import parse, parseString -from dynastie.generators.generator import DynastieGenerator +from dynastie.generators.generator import DynastieGenerator, StrictUTF8Writer from django.db import models class Index(DynastieGenerator): @@ -83,6 +83,25 @@ class Index(DynastieGenerator): post_content = f.read() f.close() + while True: + start = post_content.find('') + + if start == -1: break + + if end < start: + self.addError('Invalid tags in ' + filename) + break + + try: + dom2 = parseString(post_content[start:end+11]) + except xml.dom.DOMException as e: + self.addError('Error parsing ' + filename) + break + + res = self.createCode(dom2, dom2.firstChild) + post_content = post_content.replace(post_content[start:end+11], res) + self.simpleTransform(values, dom, post_elem, root) content_nodes = post_elem.getElementsByTagName('div') @@ -93,7 +112,6 @@ class Index(DynastieGenerator): continue new_node = dom.createTextNode(post_content) content_node.appendChild(new_node) - def createPosts(self, posts, dom, root, node): posts_elem = self.createElement(dom, 'posts') @@ -177,13 +195,68 @@ class Index(DynastieGenerator): return tags_elem + def createCode(self, dom, node): + try: + from pygments import highlight + from pygments.util import ClassNotFound + from pygments.lexers import get_lexer_by_name + from pygments.formatters import get_formatter_by_name + except ImportError: + self.addError('Pygments package is missing, please install it in order to use ') + return + + language = node.getAttribute('language') + + if language is None: + self.addWarning('No language defined for assuming C language') + language = "c" + else: + language = language.lower() + + lexer_options = {} + try: + lexer = get_lexer_by_name(language, **lexer_options) + except ClassNotFound: + self.addWarning('Language ' + language + ' not supported by current version of pygments') + lexer = get_lexer_by_name('c', **lexer_options) + + formatter_options = {'classprefix' : 'color_', 'style' : 'emacs'} + + for k in node.attributes.keys(): + attr = node.attributes[k] + if attr.prefix != '': continue + if attr.name == 'language': continue + name = attr.name + value = attr.value + if name == 'colouring': name = style + formatter_options[name] = value + + formatter = get_formatter_by_name('html', **formatter_options) + + lexer.encoding = 'utf-8' + formatter.encoding = 'utf-8' + + writer = StrictUTF8Writer() + node.firstChild.firstChild.writexml(writer) + code = writer.getvalue().encode('utf-8') + + r,w = os.pipe() + r,w=os.fdopen(r,'r',0), os.fdopen(w,'w',0) + highlight(code, lexer, formatter, w) + w.close() + + code = r.read() + r.close() + + return code + def generate(self, blog, src, output): from dynastie.models import Post, Blog self.hooks = {'posts' : self.createPosts, - 'navigation' : self.createNavigation, - 'recents' : self.createRecents, - 'tags' : self.createTags} + 'navigation' : self.createNavigation, + 'recents' : self.createRecents, + 'tags' : self.createTags} if not os.path.exists(src + '/_index.html'): self.addError('No _index.html found, exiting') diff --git a/sites/blog.soutade.fr/css/blog.css b/sites/blog.soutade.fr/css/blog.css index b43e686..11e3b28 100755 --- a/sites/blog.soutade.fr/css/blog.css +++ b/sites/blog.soutade.fr/css/blog.css @@ -378,4 +378,66 @@ ul li #email { display:none; -} \ No newline at end of file +} + +.color_hll { background-color: #ffffcc } +.color_c { color: #008800; font-style: italic } /* Comment */ +.color_err { border: 1px solid #FF0000 } /* Error */ +.color_k { color: #AA22FF; font-weight: bold } /* Keyword */ +.color_o { color: #666666 } /* Operator */ +.color_cm { color: #008800; font-style: italic } /* Comment.Multiline */ +.color_cp { color: #008800 } /* Comment.Preproc */ +.color_c1 { color: #008800; font-style: italic } /* Comment.Single */ +.color_cs { color: #008800; font-weight: bold } /* Comment.Special */ +.color_gd { color: #A00000 } /* Generic.Deleted */ +.color_ge { font-style: italic } /* Generic.Emph */ +.color_gr { color: #FF0000 } /* Generic.Error */ +.color_gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.color_gi { color: #00A000 } /* Generic.Inserted */ +.color_go { color: #808080 } /* Generic.Output */ +.color_gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.color_gs { font-weight: bold } /* Generic.Strong */ +.color_gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.color_gt { color: #0040D0 } /* Generic.Traceback */ +.color_kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */ +.color_kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */ +.color_kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */ +.color_kp { color: #AA22FF } /* Keyword.Pseudo */ +.color_kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */ +.color_kt { color: #00BB00; font-weight: bold } /* Keyword.Type */ +.color_m { color: #666666 } /* Literal.Number */ +.color_s { color: #BB4444 } /* Literal.String */ +.color_na { color: #BB4444 } /* Name.Attribute */ +.color_nb { color: #AA22FF } /* Name.Builtin */ +.color_nc { color: #0000FF } /* Name.Class */ +.color_no { color: #880000 } /* Name.Constant */ +.color_nd { color: #AA22FF } /* Name.Decorator */ +.color_ni { color: #999999; font-weight: bold } /* Name.Entity */ +.color_ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.color_nf { color: #00A000 } /* Name.Function */ +.color_nl { color: #A0A000 } /* Name.Label */ +.color_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.color_nt { color: #008000; font-weight: bold } /* Name.Tag */ +.color_nv { color: #B8860B } /* Name.Variable */ +.color_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.color_w { color: #bbbbbb } /* Text.Whitespace */ +.color_mf { color: #666666 } /* Literal.Number.Float */ +.color_mh { color: #666666 } /* Literal.Number.Hex */ +.color_mi { color: #666666 } /* Literal.Number.Integer */ +.color_mo { color: #666666 } /* Literal.Number.Oct */ +.color_sb { color: #BB4444 } /* Literal.String.Backtick */ +.color_sc { color: #BB4444 } /* Literal.String.Char */ +.color_sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */ +.color_s2 { color: #BB4444 } /* Literal.String.Double */ +.color_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.color_sh { color: #BB4444 } /* Literal.String.Heredoc */ +.color_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.color_sx { color: #008000 } /* Literal.String.Other */ +.color_sr { color: #BB6688 } /* Literal.String.Regex */ +.color_s1 { color: #BB4444 } /* Literal.String.Single */ +.color_ss { color: #B8860B } /* Literal.String.Symbol */ +.color_bp { color: #AA22FF } /* Name.Builtin.Pseudo */ +.color_vc { color: #B8860B } /* Name.Variable.Class */ +.color_vg { color: #B8860B } /* Name.Variable.Global */ +.color_vi { color: #B8860B } /* Name.Variable.Instance */ +.color_il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/static/js/dynastie.js b/static/js/dynastie.js index 34891f1..78e54b4 100644 --- a/static/js/dynastie.js +++ b/static/js/dynastie.js @@ -3,16 +3,18 @@ tinyMCE.init({ // General options mode : "textareas", theme : "advanced", - plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template", + plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,dynastiecolor", editor_selector : "mceAdvanced", encoding : "raw", entities : "", entity_encoding : "raw", + valid_elements : '*[*]', + preformatted : true, // Theme options theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,fontselect,fontsizeselect", theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor", - theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr", + theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr,dynastiecolor", // theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage", theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", diff --git a/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/dynastiecolor.html b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/dynastiecolor.html new file mode 100644 index 0000000..105e378 --- /dev/null +++ b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/dynastiecolor.html @@ -0,0 +1,70 @@ + + + + + + + + Dynastie Code + + +
+ + + + + + + +
+ +
+ +
+ + +
+
+ + diff --git a/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js new file mode 120000 index 0000000..3a96ace --- /dev/null +++ b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js @@ -0,0 +1 @@ +editor_plugin_src.js \ No newline at end of file diff --git a/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin_src.js b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin_src.js new file mode 100644 index 0000000..d80cd83 --- /dev/null +++ b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin_src.js @@ -0,0 +1,50 @@ +/** + * editor_plugin_src.js + * + * Copyright 2012, Grégory Soutadé + * Released under LGPL License. + * + */ + +(function() { + tinymce.create('tinymce.plugins.DynastieColor', { + init : function(ed, url) { + var t = this, css = tinymce.explode(ed.settings.content_css); + + t.editor = ed; + + // Force absolute CSS urls + tinymce.each(css, function(u, k) { + css[k] = ed.documentBaseURI.toAbsolute(u); + }); + + ed.addCommand('mceDynastieColor', function() { + ed.windowManager.open({ + file : ed.getParam("plugin_dynastiecolor_pageurl", url + "/dynastiecolor.html"), + width : parseInt(ed.getParam("plugin_dynastiecolor_width", "700")), + height : parseInt(ed.getParam("plugin_dynastiecolor_height", "800")), + resizable : "yes", + scrollbars : "yes", + popup_css : css ? css.join(',') : ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css"), + }, { + base : ed.documentBaseURI.getURI() + }); + }); + + ed.addButton('dynastiecolor', {title : 'Insert code', cmd : 'mceDynastieColor'}); + }, + + getInfo : function() { + return { + longname : 'DynastieColor', + author : 'Grégory Soutadé', + authorurl : 'http://soutade.fr', + infourl : 'http://indefero.soutade.fr/p/dynastie', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('dynastiecolor', tinymce.plugins.DynastieColor); +})(); \ No newline at end of file diff --git a/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/jscripts/embed.js b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/jscripts/embed.js new file mode 100644 index 0000000..61b4598 --- /dev/null +++ b/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/jscripts/embed.js @@ -0,0 +1,17 @@ +tinyMCEPopup.requireLangPack(); + +var DynastieColorDialog = { + + insert : function() { + // Insert the contents from the input into the document + val = document.forms[0].code.value; + if (val != '') + { + language = document.forms[0].language.value; + colouring = document.forms[0].colouring.value; + val = '
' + val + '
'; + tinyMCEPopup.editor.execCommand('mceInsertContent', false, val); + } + tinyMCEPopup.close(); + } +}; diff --git a/views.py b/views.py index b4bd77e..4cf16d5 100644 --- a/views.py +++ b/views.py @@ -249,7 +249,7 @@ def edit_tag(request, tag_id): form = TagForm(request.POST, instance=tag) # A form bound to the POST data if form.is_valid(): # All validation rules pass if request.POST['name'] != name: - tag.remove() + tag.remove(b) form.save() return HttpResponseRedirect('/blog/' + str(b.id)) else: