summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2011-03-12 15:45:53 +0100
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2011-03-12 15:45:53 +0100
commit9c1d0dd3041f1a062f2d9708c0dc6eaa7f089c80 (patch)
tree17e3f101f557ae049454038a7d1a1a38feb5f208
parent7d9f81622846a5d775703b765819d887f23dd29c (diff)
Calculate the number of comments for each article. Add Google Code Prettify.
-rw-r--r--COPYING.prettify6
-rw-r--r--mulkcms-hunchentoot.lisp5
-rw-r--r--mulkcms.lisp48
-rw-r--r--package-hunchentoot.lisp3
-rw-r--r--static-files/journal/prettify/lang-apollo.js1
-rw-r--r--static-files/journal/prettify/lang-css.js1
-rw-r--r--static-files/journal/prettify/lang-hs.js1
-rw-r--r--static-files/journal/prettify/lang-lisp.js93
-rw-r--r--static-files/journal/prettify/lang-lua.js1
-rw-r--r--static-files/journal/prettify/lang-ml.js1
-rw-r--r--static-files/journal/prettify/lang-proto.js1
-rw-r--r--static-files/journal/prettify/lang-sql.js1
-rw-r--r--static-files/journal/prettify/lang-vb.js1
-rw-r--r--static-files/journal/prettify/lang-wiki.js1
-rw-r--r--static-files/journal/prettify/prettify.css1
-rw-r--r--static-files/journal/prettify/prettify.js46
-rw-r--r--static-files/style/journal.css203
-rw-r--r--templates/article.html4
-rw-r--r--templates/journal_page.html7
-rw-r--r--templates/page_skeleton.html2
20 files changed, 409 insertions, 18 deletions
diff --git a/COPYING.prettify b/COPYING.prettify
new file mode 100644
index 0000000..53f920a
--- /dev/null
+++ b/COPYING.prettify
@@ -0,0 +1,6 @@
+Code in the static-files/journal/prettify directory is from the Google
+Code Prettify project and licensed under the Apache License, version
+2.0.
+
+See http://www.apache.org/licenses/LICENSE-2.0 and
+http://code.google.com/p/google-code-prettify/ for details.
diff --git a/mulkcms-hunchentoot.lisp b/mulkcms-hunchentoot.lisp
index 3a554a7..6c5e039 100644
--- a/mulkcms-hunchentoot.lisp
+++ b/mulkcms-hunchentoot.lisp
@@ -13,10 +13,7 @@
(defun dispatch-mulkcms-request (request)
(let* ((relative-path (subseq (script-name request) 1)))
- (or (mulkcms::find-journal-archive-request-handler
- relative-path
- (assoc "full" (get-parameters*) :test #'equal))
- (mulkcms::find-article-request-handler relative-path))))
+ (mulkcms:find-request-handler relative-path(get-parameters*))))
(defun setup-handlers ()
(setq *dispatch-table*
diff --git a/mulkcms.lisp b/mulkcms.lisp
index d305fbf..f44e4c4 100644
--- a/mulkcms.lisp
+++ b/mulkcms.lisp
@@ -34,6 +34,7 @@
(:view (cond (comment-id (values "/~A#comment-~D" article-base comment-id))
(article-id (values "/~A" article-base))
(t "/")))
+ (:view-comments (values "/~A#comments" article-base))
((:edit :preview) (values "/~A?preview" article-base))
(:post-comment (values "/~A" article-base))
(:trackback (values "/~A?trackback" article-base))
@@ -76,7 +77,7 @@
(let ((article-template (template "article")))
(expand-template article-template article-params)))
-(defun paramify-article (revision-data &optional (comments nil commentary-p))
+(defun paramify-article-data (revision-data comment-num &optional (comments nil commentary-p))
(destructuring-bind (rid article date title content author format status
global-id &rest args)
revision-data
@@ -101,8 +102,11 @@
:edit-button-label "Edit"
:comment-feed (link-to :view-comment-feed :article-id article)
:comment-feed-label "Comment feed"
- :comments-label "Comments"
- :comments-link (link-to :view :article-id article)
+ :comments-label (case comment-num
+ (0 "no comments")
+ (1 "1 comment")
+ (otherwise (format nil "~D comments" comment-num)))
+ :comments-link (link-to :view-comments :article-id article)
:comments-heading "Comments")))
(defun format-comment-content (text)
@@ -308,8 +312,8 @@
:head head
:body body)))))))
-(defun find-article-params (article characteristics &optional commentary-p)
- (let* ((revisions (find-article-revisions article characteristics))
+(defun paramify-article (revision-data &optional commentary-p)
+ (let* ((article (second revision-data))
(comment-data (if commentary-p
(query "SELECT id FROM comments WHERE article = $1"
article
@@ -328,17 +332,35 @@
:lists)))
comment-data)))
(comments (mapcar #'paramify-comment comment-revision-data))
+ (comment-num
+ (if commentary-p
+ (length comment-revision-data)
+ (query "SELECT count(*)
+ FROM comments
+ WHERE article = $1
+ AND EXISTS (SELECT *
+ FROM comment_revisions
+ WHERE comment = comments.id
+ AND status IN ('approved', 'trusted'))"
+ article
+ :single))))
+ (cond ((null revision-data)
+ nil)
+ (commentary-p
+ (paramify-article-data revision-data comment-num comments))
+ (t
+ (paramify-article-data revision-data comment-num)))))
+
+(defun find-article-params (article characteristics &optional commentary-p)
+ (let* ((revisions (find-article-revisions article characteristics))
(revision (first revisions))
(revision-data (query "SELECT * FROM article_revisions WHERE id = $1"
revision
:row)))
(cond ((null revision-data)
nil)
- (commentary-p
- (paramify-article revision-data comments))
(t
- (paramify-article revision-data)))))
-
+ (paramify-article revision-data commentary-p)))))
(defun find-article-request-handler (path &optional action characteristics)
(with-db
@@ -371,3 +393,11 @@
(expand-template page-skeleton (list :title (getf article-params :title)
:head head
:body body))))))))
+
+
+
+(defun find-request-handler (path params)
+ (or (find-journal-archive-request-handler
+ path
+ (assoc "full" params :test #'equal))
+ (find-article-request-handler path)))
diff --git a/package-hunchentoot.lisp b/package-hunchentoot.lisp
index c1e8bba..955c25a 100644
--- a/package-hunchentoot.lisp
+++ b/package-hunchentoot.lisp
@@ -2,4 +2,5 @@
(:use #:common-lisp #:hunchentoot #:cl-who #:cl-ppcre #:alexandria #:cl-fad
#:mulkcms)
(:nicknames #:mulkcms-ht)
- (:shadow #:copy-file #:copy-stream))
+ (:shadow #:copy-file #:copy-stream)
+ (:export #:start-server))
diff --git a/static-files/journal/prettify/lang-apollo.js b/static-files/journal/prettify/lang-apollo.js
new file mode 100644
index 0000000..4042030
--- /dev/null
+++ b/static-files/journal/prettify/lang-apollo.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_COMMENT,/^#[^\r\n]*/,null,'#'],[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,' \n\r \xa0'],[PR.PR_STRING,/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'\"']],[[PR.PR_KEYWORD,/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,null],[PR.PR_TYPE,/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],[PR.PR_LITERAL,/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],[PR.PR_PLAIN,/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0()\"\\\';]+/]]),['apollo','agc','aea']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-css.js b/static-files/journal/prettify/lang-css.js
new file mode 100644
index 0000000..c650d8f
--- /dev/null
+++ b/static-files/journal/prettify/lang-css.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null,' \r\n ']],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],['lang-css-str',/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],['lang-css-kw',/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),['css']),PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),['css-kw']),PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),['css-str']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-hs.js b/static-files/journal/prettify/lang-hs.js
new file mode 100644
index 0000000..27b221a
--- /dev/null
+++ b/static-files/journal/prettify/lang-hs.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\x0B\x0C\r ]+/,null,' \n \r '],[PR.PR_STRING,/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'\"'],[PR.PR_STRING,/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,'\''],[PR.PR_LITERAL,/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,'0123456789']],[[PR.PR_COMMENT,/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],[PR.PR_KEYWORD,/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,null],[PR.PR_PLAIN,/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],[PR.PR_PUNCTUATION,/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),['hs']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-lisp.js b/static-files/journal/prettify/lang-lisp.js
new file mode 100644
index 0000000..60cf97d
--- /dev/null
+++ b/static-files/journal/prettify/lang-lisp.js
@@ -0,0 +1,93 @@
+// Copyright (C) 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+/**
+ * @fileoverview
+ * Registers a language handler for Common Lisp and related languages.
+ *
+ *
+ * To use, include prettify.js and this file in your HTML page.
+ * Then put your code in an HTML tag like
+ * <pre class="prettyprint lang-lisp">(my lisp code)</pre>
+ * The lang-cl class identifies the language as common lisp.
+ * This file supports the following language extensions:
+ * lang-cl - Common Lisp
+ * lang-el - Emacs Lisp
+ * lang-lisp - Lisp
+ * lang-scm - Scheme
+ *
+ *
+ * I used http://www.devincook.com/goldparser/doc/meta-language/grammar-LISP.htm
+ * as the basis, but added line comments that start with ; and changed the atom
+ * production to disallow unquoted semicolons.
+ *
+ * "Name" = 'LISP'
+ * "Author" = 'John McCarthy'
+ * "Version" = 'Minimal'
+ * "About" = 'LISP is an abstract language that organizes ALL'
+ * | 'data around "lists".'
+ *
+ * "Start Symbol" = [s-Expression]
+ *
+ * {Atom Char} = {Printable} - {Whitespace} - [()"\'']
+ *
+ * Atom = ( {Atom Char} | '\'{Printable} )+
+ *
+ * [s-Expression] ::= [Quote] Atom
+ * | [Quote] '(' [Series] ')'
+ * | [Quote] '(' [s-Expression] '.' [s-Expression] ')'
+ *
+ * [Series] ::= [s-Expression] [Series]
+ * |
+ *
+ * [Quote] ::= '' !Quote = do not evaluate
+ * |
+ *
+ *
+ * I used <a href="http://gigamonkeys.com/book/">Practical Common Lisp</a> as
+ * the basis for the reserved word list.
+ *
+ *
+ * @author mikesamuel@gmail.com
+ */
+
+PR.registerLangHandler(
+ PR.createSimpleLexer(
+ [
+ ['opn', /^\(|\[/, null, ''],
+ ['clo', /^\)|\]/, null, ''],
+ // A line comment that starts with ;
+ [PR.PR_COMMENT, /^;[^\r\n]*/, null, ';'],
+ // Whitespace
+ [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'],
+ // A double quoted, possibly multi-line, string.
+ [PR.PR_STRING, /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"']
+ ],
+ [
+ [PR.PR_KEYWORD, /^(?:block|c[ad]+r|catch|cons|defun|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind|loop|with--*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?|define--*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?|for|in|from|to|fn|defn|def)\b/, null],
+ [PR.PR_LITERAL,
+ /^[+\-]?(?:0x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],
+ // A single quote or a colon possibly followed by a word that optionally ends with
+ // = ! or ?.
+ [PR.PR_LITERAL,
+ /^(\'|\:)(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],
+ // A word that optionally ends with = ! or ?.
+ [PR.PR_PLAIN,
+ /^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],
+ // A printable non-space non-special character
+ [PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0\"\\\';]+/]
+ ]),
+ ['cl', 'el', 'lisp', 'scm']);
diff --git a/static-files/journal/prettify/lang-lua.js b/static-files/journal/prettify/lang-lua.js
new file mode 100644
index 0000000..d107bab
--- /dev/null
+++ b/static-files/journal/prettify/lang-lua.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,' \n\r \xa0'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],[PR.PR_STRING,/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],[PR.PR_KEYWORD,/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_]\w*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),['lua']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-ml.js b/static-files/journal/prettify/lang-ml.js
new file mode 100644
index 0000000..698d6de
--- /dev/null
+++ b/static-files/journal/prettify/lang-ml.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,' \n\r \xa0'],[PR.PR_COMMENT,/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,'#'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],[PR.PR_KEYWORD,/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],[PR.PR_LITERAL,/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],[PR.PR_PUNCTUATION,/^[^\t\n\r \xA0\"\'\w]+/]]),['fs','ml']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-proto.js b/static-files/journal/prettify/lang-proto.js
new file mode 100644
index 0000000..e67967f
--- /dev/null
+++ b/static-files/journal/prettify/lang-proto.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.sourceDecorator({keywords:'bool bytes default double enum extend extensions false fixed32 fixed64 float group import int32 int64 max message option optional package repeated required returns rpc service sfixed32 sfixed64 sint32 sint64 string syntax to true uint32 uint64',cStyleComments:true}),['proto']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-sql.js b/static-files/journal/prettify/lang-sql.js
new file mode 100644
index 0000000..ff381cd
--- /dev/null
+++ b/static-files/journal/prettify/lang-sql.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,' \n\r \xa0'],[PR.PR_STRING,/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],[PR.PR_KEYWORD,/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_][\w-]*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),['sql']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-vb.js b/static-files/journal/prettify/lang-vb.js
new file mode 100644
index 0000000..cabce85
--- /dev/null
+++ b/static-files/journal/prettify/lang-vb.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0\u2028\u2029]+/,null,' \n\r \xa0\u2028\u2029'],[PR.PR_STRING,/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'\"\u201c\u201d'],[PR.PR_COMMENT,/^[\'\u2018\u2019][^\r\n\u2028\u2029]*/,null,'\'\u2018\u2019']],[[PR.PR_KEYWORD,/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,null],[PR.PR_COMMENT,/^REM[^\r\n\u2028\u2029]*/i],[PR.PR_LITERAL,/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],[PR.PR_PLAIN,/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],[PR.PR_PUNCTUATION,/^(?:\[|\])/]]),['vb','vbs']) \ No newline at end of file
diff --git a/static-files/journal/prettify/lang-wiki.js b/static-files/journal/prettify/lang-wiki.js
new file mode 100644
index 0000000..00a1b6b
--- /dev/null
+++ b/static-files/journal/prettify/lang-wiki.js
@@ -0,0 +1 @@
+PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t \xA0a-gi-z0-9]+/,null,' \xa0abcdefgijklmnopqrstuvwxyz0123456789'],[PR.PR_PUNCTUATION,/^[=*~\^\[\]]+/,null,'=*~^[]']],[['lang-wiki.meta',/(?:^^|\r\n?|\n)(#[a-z]+)\b/],[PR.PR_LITERAL,/^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\b/],['lang-',/^\{\{\{([\s\S]+?)\}\}\}/],['lang-',/^`([^\r\n`]+)`/],[PR.PR_STRING,/^https?:\/\/[^\/?#\s]*(?:\/[^?#\s]*)?(?:\?[^#\s]*)?(?:#\S*)?/i],[PR.PR_PLAIN,/^(?:\r\n|[\s\S])[^#=*~^A-Zh\{`\[\r\n]*/]]),['wiki']),PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_KEYWORD,/^#[a-z]+/i,null,'#']],[]),['wiki.meta']) \ No newline at end of file
diff --git a/static-files/journal/prettify/prettify.css b/static-files/journal/prettify/prettify.css
new file mode 100644
index 0000000..2eb91bf
--- /dev/null
+++ b/static-files/journal/prettify/prettify.css
@@ -0,0 +1 @@
+.str,.atv{color:#080}.kwd,.tag{color:#008}.com{color:#800}.typ,.atn,.dec{color:#606}.lit{color:#066}.pun{color:#660}.pln{color:#000}pre.prettyprint{padding:2px;border:1px solid #888}@media print{.str{color:#060}.kwd,.tag{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{font-weight:bold}.lit{color:#044}.pun{color:#440}.atn,.typ{color:#404}.atv{color:#060}} \ No newline at end of file
diff --git a/static-files/journal/prettify/prettify.js b/static-files/journal/prettify/prettify.js
new file mode 100644
index 0000000..b112125
--- /dev/null
+++ b/static-files/journal/prettify/prettify.js
@@ -0,0 +1,46 @@
+window.PR_SHOULD_USE_CONTINUATION=true,window.PR_TAB_WIDTH=8,window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void
+0,window._pr_isIE6=function(){var a=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);return a=a?+a[1]:false,window._pr_isIE6=function(){return a},a},(function(){var
+a=true,b=null,c='break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof ',d=c+'alignof align_union asm axiom bool '+'concept concept_map const_cast constexpr decltype '+'dynamic_cast explicit export friend inline late_check '+'mutable namespace nullptr reinterpret_cast static_assert static_cast '+'template typeid typename using virtual wchar_t where ',e=c+'abstract boolean byte extends final finally implements import '+'instanceof null native package strictfp super synchronized throws '+'transient ',f=e+'as base by checked decimal delegate descending event '+'fixed foreach from group implicit in interface internal into is lock '+'object out override orderby params partial readonly ref sbyte sealed '+'stackalloc string select uint ulong unchecked unsafe ushort var ',g=c+'debugger eval export function get null set undefined var with '+'Infinity NaN ',h='caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ',i='break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ',j='break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ',k='break continue do else for if return while case done elif esac eval fi function in local set then until ',l=d+f+g+h+i+j+k,m=(function(){var
+a=['!','!=','!==','#','%','%=','&','&&','&&=','&=','(','*','*=','+=',',','-=','->','/','/=',':','::',';','<','<<','<<=','<=','=','==','===','>','>=','>>','>>=','>>>','>>>=','?','@','[','^','^=','^^','^^=','{','|','|=','||','||=','~','break','case','continue','delete','do','else','finally','instanceof','return','throw','try','typeof'],b='(?:^^|[+-]',c;for(c=0;c<a.length;++c)b+='|'+a[c].replace(/([^=<>:&a-z])/g,'\\$1');return b+=')\\s*',b})(),n=/&/g,o=/</g,p=/>/g,q=/\"/g,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F;function
+G(a){return a.replace(n,'&amp;').replace(o,'&lt;').replace(p,'&gt;').replace(q,'&quot;')}function
+ H(a){return a.replace(n,'&amp;').replace(o,'&lt;').replace(p,'&gt;')}C=/&lt;/g,B=/&gt;/g,w=/&apos;/g,E=/&quot;/g,v=/&amp;/g,D=/&nbsp;/g;function
+I(a){var b=a.indexOf('&'),c,d,e,f;if(b<0)return a;for(--b;(b=a.indexOf('&#',b+1))>=0;)d=a.indexOf(';',b),d>=0&&(e=a.substring(b+3,d),f=10,e&&e.charAt(0)==='x'&&(e=e.substring(1),f=16),c=parseInt(e,f),isNaN(c)||(a=a.substring(0,b)+String.fromCharCode(c)+a.substring(d+1)));return a.replace(C,'<').replace(B,'>').replace(w,'\'').replace(E,'\"').replace(D,' ').replace(v,'&')}function
+J(a){return'XMP'===a.tagName}u=/[\r\n]/g;function K(c,d){var e;return'PRE'===c.tagName?a:u.test(d)?(e='',c.currentStyle?(e=c.currentStyle.whiteSpace):window.getComputedStyle&&(e=window.getComputedStyle(c,b).whiteSpace),!e||e==='pre'):a}function
+L(a,b){var c,d,e,f;switch(a.nodeType){case 1:f=a.tagName.toLowerCase(),b.push('<',f);for(e=0;e<a.attributes.length;++e){c=a.attributes[e];if(!c.specified)continue;b.push(' '),L(c,b)}b.push('>');for(d=a.firstChild;d;d=d.nextSibling)L(d,b);(a.firstChild||!/^(?:br|link|img)$/.test(f))&&b.push('</',f,'>');break;case
+2:b.push(a.name.toLowerCase(),'=\"',G(a.value),'\"');break;case 3:case 4:b.push(H(a.nodeValue))}}function
+M(b){var c=0,d=false,e=false,f,g,h,i;for(f=0,g=b.length;f<g;++f){h=b[f];if(h.ignoreCase)e=a;else
+if(/[a-z]/i.test(h.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,''))){d=a,e=false;break}}function
+j(a){if(a.charAt(0)!=='\\')return a.charCodeAt(0);switch(a.charAt(1)){case'b':return 8;case't':return 9;case'n':return 10;case'v':return 11;case'f':return 12;case'r':return 13;case'u':case'x':return parseInt(a.substring(2),16)||a.charCodeAt(1);case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':return parseInt(a.substring(1),8);default:return a.charCodeAt(1)}}function
+k(a){var b;return a<32?(a<16?'\\x0':'\\x')+a.toString(16):(b=String.fromCharCode(a),(b==='\\'||b==='-'||b==='['||b===']')&&(b='\\'+b),b)}function
+l(a){var b=a.substring(1,a.length-1).match(new RegExp('\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]','g')),c=[],d=[],e=b[0]==='^',f,g,h,i,m,n,o,p,q;for(h=e?1:0,m=b.length;h<m;++h){o=b[h];switch(o){case'\\B':case'\\b':case'\\D':case'\\d':case'\\S':case'\\s':case'\\W':case'\\w':c.push(o);continue}q=j(o),h+2<m&&'-'===b[h+1]?(g=j(b[h+2]),h+=2):(g=q),d.push([q,g]),g<65||q>122||(g<65||q>90||d.push([Math.max(65,q)|32,Math.min(g,90)|32]),g<97||q>122||d.push([Math.max(97,q)&-33,Math.min(g,122)&-33]))}d.sort(function(a,b){return a[0]-b[0]||b[1]-a[1]}),f=[],i=[NaN,NaN];for(h=0;h<d.length;++h)p=d[h],p[0]<=i[1]+1?(i[1]=Math.max(i[1],p[1])):f.push(i=p);n=['['],e&&n.push('^'),n.push.apply(n,c);for(h=0;h<f.length;++h)p=f[h],n.push(k(p[0])),p[1]
+>p[0]&&(p[1]+1>p[0]&&n.push('-'),n.push(k(p[1])));return n.push(']'),n.join('')}function
+m(a){var b=a.source.match(new RegExp('(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)','g')),e=b.length,f=[],g,h,i,j,k;for(j=0,i=0;j<e;++j)k=b[j],k==='('?++i:'\\'===k.charAt(0)&&(h=+k.substring(1),h&&h<=i&&(f[h]=-1));for(j=1;j<f.length;++j)-1===f[j]&&(f[j]=++c);for(j=0,i=0;j<e;++j)k=b[j],k==='('?(++i,f[i]===void
+0&&(b[j]='(?:')):'\\'===k.charAt(0)&&(h=+k.substring(1),h&&h<=i&&(b[j]='\\'+f[i]));for(j=0,i=0;j<e;++j)'^'===b[j]&&'^'!==b[j+1]&&(b[j]='');if(a.ignoreCase&&d)for(j=0;j<e;++j)k=b[j],g=k.charAt(0),k.length>=2&&g==='['?(b[j]=l(k)):g!=='\\'&&(b[j]=k.replace(/[a-zA-Z]/g,function(a){var
+b=a.charCodeAt(0);return'['+String.fromCharCode(b&-33,b|32)+']'}));return b.join('')}i=[];for(f=0,g=b.length;f<g;++f){h=b[f];if(h.global||h.multiline)throw new
+Error(''+h);i.push('(?:'+m(h)+')')}return new RegExp(i.join('|'),e?'gi':'g')}r=b;function
+N(a){var c,d,e,f;b===r&&(f=document.createElement('PRE'),f.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC \"foo bar\">\n<foo />')),r=!/</.test(f.innerHTML));if(r)return d=a.innerHTML,J(a)?(d=H(d)):K(a,d)||(d=d.replace(/(<br\s*\/?>)[\r\n]+/g,'$1').replace(/(?:[\r\n]+[ \t]*)+/g,' ')),d;e=[];for(c=a.firstChild;c;c=c.nextSibling)L(c,e);return e.join('')}function
+O(a){var c=0;return function(d){var e=b,f=0,g,h,i,j;for(h=0,i=d.length;h<i;++h){g=d.charAt(h);switch(g){case' ':e||(e=[]),e.push(d.substring(f,h)),j=a-c%a,c+=j;for(;j>=0;j-=' '.length)e.push(' '.substring(0,j));f=h+1;break;case'\n':c=0;break;default:++c}}return e?(e.push(d.substring(f)),e.join('')):d}}z=new
+RegExp('[^<]+|<!--[\\s\\S]*?-->|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>|<','g'),A=/^<\!--/,y=/^<!\[CDATA\[/,x=/^<br\b/i,F=/^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;function
+P(a){var b=a.match(z),c=[],d=0,e=[],f,g,h,i,j,k,l,m;if(b)for(g=0,k=b.length;g<k;++g){j=b[g];if(j.length>1&&j.charAt(0)==='<'){if(A.test(j))continue;if(y.test(j))c.push(j.substring(9,j.length-3)),d+=j.length-12;else
+if(x.test(j))c.push('\n'),++d;else if(j.indexOf('nocode')>=0&&Q(j)){l=(j.match(F))[2],f=1;for(h=g+1;h<k;++h){m=b[h].match(F);if(m&&m[2]===l)if(m[1]==='/'){if(--f===0)break}else++f}h<k?(e.push(d,b.slice(g,h+1).join('')),g=h):e.push(d,j)}else
+e.push(d,j)}else i=I(j),c.push(i),d+=i.length}return{source:c.join(''),tags:e}}function
+Q(a){return!!a.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1=\"$2$3$4\"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)}function
+R(a,b,c,d){var e;if(!b)return;e={source:b,basePos:a},c(e),d.push.apply(d,e.decorations)}function
+S(a,c){var d={},e,f,g,h;return(function(){var e=a.concat(c),f=[],g={},i,j,k,l,m,n,o;for(j=0,l=e.length;j<l;++j){m=e[j],o=m[3];if(o)for(i=o.length;--i>=0;)d[o.charAt(i)]=m;n=m[1],k=''+n,g.hasOwnProperty(k)||(f.push(n),g[k]=b)}f.push(/[\0-\uffff]/),h=M(f)})(),f=c.length,g=/\S/,e=function(a){var
+b=a.source,g=a.basePos,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y;i=[g,'pln'],s=0,y=b.match(h)||[],u={};for(v=0,q=y.length;v<q;++v){w=y[v],t=u[w],p=void
+0;if(typeof t==='string')n=false;else{r=d[w.charAt(0)];if(r)p=w.match(r[1]),t=r[0];else{for(m=0;m<f;++m){r=c[m],p=w.match(r[1]);if(p){t=r[0];break}}p||(t='pln')}n=t.length>=5&&'lang-'===t.substring(0,5),n&&!(p&&typeof
+p[1]==='string')&&(n=false,t='src'),n||(u[w]=t)}x=s,s+=w.length,n?(j=p[1],l=w.indexOf(j),k=l+j.length,p[2]&&(k=w.length-p[2].length,l=k-j.length),o=t.substring(5),R(g+x,w.substring(0,l),e,i),R(g+x+l,j,W(o,j),i),R(g+x+k,w.substring(k),e,i)):i.push(g+x,t)}a.decorations=i},e}function
+T(a){var c=[],d=[],e,f;return a.tripleQuotedStrings?c.push(['str',/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,b,'\'\"']):a.multiLineStrings?c.push(['str',/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,b,'\'\"`']):c.push(['str',/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,b,'\"\'']),a.verbatimStrings&&d.push(['str',/^@\"(?:[^\"]|\"\")*(?:\"|$)/,b]),a.hashComments&&(a.cStyleComments?(c.push(['com',/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,b,'#']),d.push(['str',/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,b])):c.push(['com',/^#[^\r\n]*/,b,'#'])),a.cStyleComments&&(d.push(['com',/^\/\/[^\r\n]*/,b]),d.push(['com',/^\/\*[\s\S]*?(?:\*\/|$)/,b])),a.regexLiterals&&(e='/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/',d.push(['lang-regex',new
+RegExp('^'+m+'('+e+')')])),f=a.keywords.replace(/^\s+|\s+$/g,''),f.length&&d.push(['kwd',new
+RegExp('^(?:'+f.replace(/\s+/g,'|')+')\\b'),b]),c.push(['pln',/^\s+/,b,' \r\n \xa0']),d.push(['lit',/^@[a-z_$][a-z_$@0-9]*/i,b],['typ',/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,b],['pln',/^[a-z_$][a-z_$@0-9]*/i,b],['lit',new
+RegExp('^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*','i'),b,'0123456789'],['pun',/^.[^\s\w\.$@\'\"\`\/\#]*/,b]),S(c,d)}s=T({keywords:l,hashComments:a,cStyleComments:a,multiLineStrings:a,regexLiterals:a});function
+U(c){var d=c.source,e=c.extractedTags,f=c.decorations,g=[],h=0,i=b,j=b,k=0,l=0,m=O(window.PR_TAB_WIDTH),n=/([\r\n ]) /g,o=/(^| ) /gm,p=/\r\n?|\n/g,q=/[ \r\n]$/,r=a,s;function
+t(a){var c,e;a>h&&(i&&i!==j&&(g.push('</span>'),i=b),!i&&j&&(i=j,g.push('<span class=\"',i,'\">')),c=H(m(d.substring(h,a))).replace(r?o:n,'$1&nbsp;'),r=q.test(c),e=window._pr_isIE6()?'&nbsp;<br />':'<br />',g.push(c.replace(p,e)),h=a)}while(a){k<e.length?l<f.length?(s=e[k]<=f[l]):(s=a):(s=false);if(s)t(e[k]),i&&(g.push('</span>'),i=b),g.push(e[k+1]),k+=2;else
+if(l<f.length)t(f[l]),j=f[l+1],l+=2;else break}t(d.length),i&&g.push('</span>'),c.prettyPrintedHtml=g.join('')}t={};function
+V(a,b){var c,d;for(d=b.length;--d>=0;)c=b[d],t.hasOwnProperty(c)?'console'in window&&console.warn('cannot override language handler %s',c):(t[c]=a)}function
+W(a,b){return a&&t.hasOwnProperty(a)||(a=/^\s*</.test(b)?'default-markup':'default-code'),t[a]}V(s,['default-code']),V(S([],[['pln',/^[^<?]+/],['dec',/^<!\w[^>]*(?:>|$)/],['com',/^<\!--[\s\S]*?(?:-\->|$)/],['lang-',/^<\?([\s\S]+?)(?:\?>|$)/],['lang-',/^<%([\s\S]+?)(?:%>|$)/],['pun',/^(?:<[%?]|[%?]>)/],['lang-',/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],['lang-js',/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],['lang-css',/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],['lang-in.tag',/^(<\/?[a-z][^<>]*>)/i]]),['default-markup','htm','html','mxml','xhtml','xml','xsl']),V(S([['pln',/^[\s]+/,b,' \r\n'],['atv',/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,b,'\"\'']],[['tag',/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],['atn',/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],['lang-uq.val',/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],['pun',/^[=<>\/]+/],['lang-js',/^on\w+\s*=\s*\"([^\"]+)\"/i],['lang-js',/^on\w+\s*=\s*\'([^\']+)\'/i],['lang-js',/^on\w+\s*=\s*([^\"\'>\s]+)/i],['lang-css',/^style\s*=\s*\"([^\"]+)\"/i],['lang-css',/^style\s*=\s*\'([^\']+)\'/i],['lang-css',/^style\s*=\s*([^\"\'>\s]+)/i]]),['in.tag']),V(S([],[['atv',/^[\s\S]+/]]),['uq.val']),V(T({keywords:d,hashComments:a,cStyleComments:a}),['c','cc','cpp','cxx','cyc','m']),V(T({keywords:'null true false'}),['json']),V(T({keywords:f,hashComments:a,cStyleComments:a,verbatimStrings:a}),['cs']),V(T({keywords:e,cStyleComments:a}),['java']),V(T({keywords:k,hashComments:a,multiLineStrings:a}),['bsh','csh','sh']),V(T({keywords:i,hashComments:a,multiLineStrings:a,tripleQuotedStrings:a}),['cv','py']),V(T({keywords:h,hashComments:a,multiLineStrings:a,regexLiterals:a}),['perl','pl','pm']),V(T({keywords:j,hashComments:a,multiLineStrings:a,regexLiterals:a}),['rb']),V(T({keywords:g,cStyleComments:a,regexLiterals:a}),['js']),V(S([],[['str',/^[\s\S]+/]]),['regex']);function
+X(a){var b=a.sourceCodeHtml,c=a.langExtension,d,e;a.prettyPrintedHtml=b;try{e=P(b),d=e.source,a.source=d,a.basePos=0,a.extractedTags=e.tags,W(c,d)(a),U(a)}catch(f){'console'in
+window&&(console.log(f),console.trace())}}function Y(a,b){var c={sourceCodeHtml:a,langExtension:b};return X(c),c.prettyPrintedHtml}function
+Z(c){var d=window._pr_isIE6(),e=d===6?'\r\n':'\r',f=[document.getElementsByTagName('pre'),document.getElementsByTagName('code'),document.getElementsByTagName('xmp')],g=[],h,i,j,k,l,m;for(i=0;i<f.length;++i)for(j=0,l=f[i].length;j<l;++j)g.push(f[i][j]);f=b,h=Date,h.now||(h={now:function(){return(new
+Date).getTime()}}),k=0;function n(){var b=window.PR_SHOULD_USE_CONTINUATION?h.now()+250:Infinity,d,e,f,i,j;for(;k<g.length&&h.now()<b;++k){e=g[k];if(e.className&&e.className.indexOf('prettyprint')>=0){f=e.className.match(/\blang-(\w+)\b/),f&&(f=f[1]),i=false;for(j=e.parentNode;j;j=j.parentNode)if((j.tagName==='pre'||j.tagName==='code'||j.tagName==='xmp')&&j.className&&j.className.indexOf('prettyprint')>=0){i=a;break}i||(d=N(e),d=d.replace(/(?:\r\n?|\n)$/,''),m={sourceCodeHtml:d,langExtension:f,sourceNode:e},X(m),o())}}k<g.length?setTimeout(n,250):c&&c()}function
+o(){var a=m.prettyPrintedHtml,b,c,f,g,h,i,j,k;if(!a)return;f=m.sourceNode;if(!J(f))f.innerHTML=a;else{k=document.createElement('PRE');for(g=0;g<f.attributes.length;++g)b=f.attributes[g],b.specified&&(c=b.name.toLowerCase(),c==='class'?(k.className=b.value):k.setAttribute(b.name,b.value));k.innerHTML=a,f.parentNode.replaceChild(k,f),f=k}if(d&&f.tagName==='PRE'){j=f.getElementsByTagName('br');for(h=j.length;--h>=0;)i=j[h],i.parentNode.replaceChild(document.createTextNode(e),i)}}n()}window.PR_normalizedHtml=L,window.prettyPrintOne=Y,window.prettyPrint=Z,window.PR={combinePrefixPatterns:M,createSimpleLexer:S,registerLangHandler:V,sourceDecorator:T,PR_ATTRIB_NAME:'atn',PR_ATTRIB_VALUE:'atv',PR_COMMENT:'com',PR_DECLARATION:'dec',PR_KEYWORD:'kwd',PR_LITERAL:'lit',PR_NOCODE:'nocode',PR_PLAIN:'pln',PR_PUNCTUATION:'pun',PR_SOURCE:'src',PR_STRING:'str',PR_TAG:'tag',PR_TYPE:'typ'}})() \ No newline at end of file
diff --git a/static-files/style/journal.css b/static-files/style/journal.css
new file mode 100644
index 0000000..4d35bee
--- /dev/null
+++ b/static-files/style/journal.css
@@ -0,0 +1,203 @@
+/*-*- mode: css; coding: utf-8 -*-*/
+/* CSS version 3.0 */
+/* Copyright 2007, 2008, Matthias Andreas Benkard. */
+
+/*-----------------------------------------------------------------------
+ * This file is part of The Mulkblog Project.
+ *
+ * The Mulkblog Project is free software. You can redistribute it and/or
+ * modify it under the terms of the Affero General Public License as
+ * published by Affero, Inc.; either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * The Mulkblog Project 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the Affero General Public
+ * License in the COPYING file that comes with The Mulkblog Project; if
+ * not, write to Affero, Inc., 510 Third Street, Suite 225, San
+ * Francisco, CA 94107 USA.
+ *-----------------------------------------------------------------------
+ */
+
+html {
+ /* Epiphany chooses a sans-serif font for this because it recognises both
+ Calibri and Candara as requesting such a font even if neither of them
+ is installed. Consequently, everything looks much nicer in Firefox, which
+ falls back to URW Palladio L, as it should. Weird. */
+
+ font-family: Optima, Calibri, 'MgOpen Cosmetica', 'MgOpen Moderna', Candara, Palatino, 'Palatino Linotype', 'Book Antiqua', 'URW Palladio L', 'Gentium Alt', 'Gentium', Geneva, 'Trebuchet MS', Georgia, sans-serif;
+
+ /* font-family: "MgOpen Modata" */
+}
+
+#main-title {
+ font-stretch: wider;
+ font-variant: small-caps;
+ font-weight: bolder;
+ text-align: center;
+}
+
+#main-title a {
+ text-decoration: none;
+}
+
+#main-subtitle {
+ text-align: center;
+}
+
+#main-title-box {
+}
+
+.article-header {
+ font-size: x-small;
+ color: #444;
+ background-color: inherit;
+ font-weight: lighter;
+ text-align: left;
+}
+
+.article h1 {
+ border-bottom: 2px solid #000;
+ font-size: 1.6em;
+}
+
+.article h1 > a {
+ text-decoration: none;
+}
+
+.article h2 {
+ font-size: 1.15em;
+}
+
+.article h3 {
+ font-size: 1em;
+}
+
+.article h4 {
+ font-size: 0.9em;
+}
+
+.article {
+ border: 3px outset #666;
+ color: #000;
+ background-color: #f8f8e0;
+ margin: 1em 0 0 0;
+ padding: 0 0.3em 0 0.3em;
+ text-align: justify;
+}
+
+.article-body p {
+ text-indent: 1em;
+}
+
+.article-body pre {
+ overflow: auto;
+ /* overflow: scroll; */
+}
+
+.article-body blockquote {
+ font-style: oblique;
+}
+
+img.article-portrait {
+ margin-right: 6px;
+ margin-bottom: 6px;
+ float: left;
+}
+
+.article-footer {
+ font-size: small;
+ padding-top: 0.5em;
+ text-align: right;
+ clear: both;
+}
+
+.journal-comments h2 {
+ width: 80%;
+}
+
+.journal-comment {
+ margin-top: 1em;
+ border: 1px solid #aaa;
+ padding: 0.5em 0.5em 0.5em 0.5em;
+}
+
+.journal-comment-header {
+ margin-bottom: 1em;
+}
+
+.journal-comment-body {
+ text-align: justify;
+ text-indent: 1em;
+}
+
+.journal-comment-body blockquote {
+ font-style: oblique;
+}
+
+#warnings {
+ align: center;
+ width: 100%;
+}
+
+.journal-warning {
+ position: relative;
+ left: 15%;
+ width: 70%;
+ border: 3px outset #666;
+ color: #000;
+ background-color: #ffd0c0;
+ margin: 1em 0 0 0;
+ padding: 0 0.3em 0 0.3em;
+ text-align: justify;
+}
+
+.old-entries {
+ border: 3px outset #666;
+ color: #000;
+ background-color: #e8e8e8;
+ margin: 1em 0 0 0;
+ padding: 0 0.3em 0 0.3em;
+ text-align: justify;
+}
+
+td {
+ padding: 0.2em 0.4em 0.2em 0.4em;
+ vertical-align: top;
+ border: 1px solid #aaa;
+ margin: 0 0 0 0;
+}
+
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+ margin: 0 0 0.3em 0;
+}
+
+table.old-entry-table {
+ border-spacing: 0;
+ border-collapse: collapse;
+ margin: 0 0 0.3em 0;
+}
+
+table.old-entry-table td {
+ padding: 0.2em 0.4em 0.2em 0.4em;
+ vertical-align: top;
+ border: 1px solid #aaa;
+ margin: 0 0 0 0;
+}
+
+a:link {
+ color: #0c2db2;
+}
+
+a:visited {
+ color: #38597f;
+}
+
+h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
+ color: #0c2db2;
+}
diff --git a/templates/article.html b/templates/article.html
index 61cc9de..8be086b 100644
--- a/templates/article.html
+++ b/templates/article.html
@@ -1,4 +1,5 @@
<article>
+<div class="article">
<h1><a href="{link|html-attr-value}">{title|html}</a></h1>
<div class="article-header">
@@ -32,10 +33,11 @@
<a href="{comments-link|html-attr-value}">{comments-label|html}</a>
</footer>
</div>
+</div>
</article>
{.section commentary}
-<div class="comments">
+<div class="comments" id="comments">
<h2>{comments-heading|html}</h2>
{.repeated section comments}
diff --git a/templates/journal_page.html b/templates/journal_page.html
index d567d2f..828ec31 100644
--- a/templates/journal_page.html
+++ b/templates/journal_page.html
@@ -1,6 +1,9 @@
{.section head}
-<link rel="stylesheet" type="text/css"
- href="{root|html-attr-value}/style/journal.css" />
+ <link rel="stylesheet" type="text/css"
+ href="{root|html-attr-value}style/journal.css" />
+ <link href="/journal/prettify/prettify.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="/journal/prettify/prettify.js"></script>
+ <script type="text/javascript" src="/journal/prettify/lang-lisp.js"></script>
{.end}
{.section body}
diff --git a/templates/page_skeleton.html b/templates/page_skeleton.html
index daa8781..842b617 100644
--- a/templates/page_skeleton.html
+++ b/templates/page_skeleton.html
@@ -8,7 +8,7 @@
{head}
</head>
- <body>
+ <body onload="if (prettyPrint) prettyPrint();">
{body}
</body>
</html>