From 4e8f57cbd9d0d2667e785dde381ad3bbf3c11dc3 Mon Sep 17 00:00:00 2001
From: mdipierro
Date: Wed, 11 Jul 2012 23:13:59 -0500
Subject: [PATCH] better markmin, thanks Vladyslav
---
VERSION | 2 +-
applications/admin/languages/bg.py | 49 +--
gluon/contrib/markmin/markmin.html | 59 ++--
gluon/contrib/markmin/markmin2html.py | 488 +++++++++++++++++++-------
4 files changed, 419 insertions(+), 179 deletions(-)
diff --git a/VERSION b/VERSION
index d704d636..300c3ea9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.00.0 (2012-07-11 22:40:45) dev
+Version 2.00.0 (2012-07-11 23:13:56) dev
diff --git a/applications/admin/languages/bg.py b/applications/admin/languages/bg.py
index 72a76c3d..577a74f5 100644
--- a/applications/admin/languages/bg.py
+++ b/applications/admin/languages/bg.py
@@ -14,7 +14,7 @@
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.',
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.',
'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!',
-'About': 'About',
+'About': 'about',
'About application': 'About application',
'Additional code for your application': 'Additional code for your application',
'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel',
@@ -24,6 +24,7 @@
'Application name:': 'Application name:',
'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?',
'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?',
+'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
'Are you sure you want to uninstall application "%s"': 'Are you sure you want to uninstall application "%s"',
'Are you sure you want to uninstall application "%s"?': 'Are you sure you want to uninstall application "%s"?',
'Are you sure you want to upgrade web2py now?': 'Are you sure you want to upgrade web2py now?',
@@ -31,20 +32,30 @@
'Cannot be empty': 'Cannot be empty',
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Cannot compile: there are errors in your app. Debug it, correct errors and try again.',
'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:',
+'Change admin password': 'change admin password',
+'Check for upgrades': 'check for upgrades',
'Check to delete': 'Check to delete',
'Checking for upgrades...': 'Checking for upgrades...',
+'Clean': 'clean',
+'Compile': 'compile',
'Controllers': 'Controllers',
+'Create': 'create',
'Create new simple application': 'Create new simple application',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'DESIGN': 'DESIGN',
'Date and Time': 'Date and Time',
+'Debug': 'Debug',
'Delete': 'Delete',
'Delete:': 'Delete:',
+'Deploy': 'deploy',
'Deploy on Google App Engine': 'Deploy on Google App Engine',
+'Deploy to OpenShift': 'Deploy to OpenShift',
'Design for': 'Design for',
+'Disable': 'Disable',
'EDIT': 'EDIT',
+'Edit': 'edit',
'Edit application': 'Edit application',
'Edit current record': 'Edit current record',
'Editing Language file': 'Editing Language file',
@@ -52,11 +63,15 @@
'Editing file "%s"': 'Editing file "%s"',
'Enterprise Web Framework': 'Enterprise Web Framework',
'Error logs for "%(app)s"': 'Error logs for "%(app)s"',
+'Errors': 'errors',
'Exception instance attributes': 'Exception instance attributes',
'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.',
+'Get from URL:': 'Get from URL:',
'Hello World': 'Здравей, свят',
+'Help': 'help',
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.',
'Import/Export': 'Import/Export',
+'Install': 'install',
'Installed applications': 'Installed applications',
'Internal State': 'Internal State',
'Invalid Query': 'Невалидна заявка',
@@ -67,6 +82,7 @@
'License for': 'License for',
'Login': 'Login',
'Login to the Administrative Interface': 'Login to the Administrative Interface',
+'Logout': 'logout',
'Models': 'Models',
'Modules': 'Modules',
'NO': 'NO',
@@ -75,17 +91,25 @@
'New simple application': 'New simple application',
'No databases in this application': 'No databases in this application',
'Original/Translation': 'Original/Translation',
+'Overwrite installed app': 'overwrite installed app',
'PAM authenticated user, cannot change password here': 'PAM authenticated user, cannot change password here',
+'Pack all': 'pack all',
+'Pack compiled': 'pack compiled',
'Peeking at file': 'Peeking at file',
'Plugin "%s" in application': 'Plugin "%s" in application',
'Plugins': 'Plugins',
'Powered by': 'Powered by',
'Query:': 'Query:',
+'Reload routes': 'Reload routes',
+'Remove compiled': 'remove compiled',
'Resolve Conflict file': 'Resolve Conflict file',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
+'Running on %s': 'Running on %s',
'Saved file hash:': 'Saved file hash:',
'Searching:': 'Searching:',
+'Site': 'site',
+'Start wizard': 'start wizard',
'Static files': 'Static files',
'Sure you want to delete this object?': 'Сигурен ли си, че искаш да изтриеш този обект?',
'TM': 'TM',
@@ -110,9 +134,11 @@
'Unable to download': 'Unable to download',
'Unable to download app because:': 'Unable to download app because:',
'Unable to download because': 'Unable to download because',
+'Uninstall': 'uninstall',
'Update:': 'Update:',
'Upload & install packed application': 'Upload & install packed application',
'Upload a package:': 'Upload a package:',
+'Upload and install packed application': 'Upload and install packed application',
'Upload existing application': 'Upload existing application',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use an url:': 'Use an url:',
@@ -120,7 +146,6 @@
'Views': 'Views',
'Welcome to web2py': 'Добре дошъл в web2py',
'YES': 'YES',
-'About': 'about',
'additional code for your application': 'additional code for your application',
'admin disabled because no admin password': 'admin disabled because no admin password',
'admin disabled because not supported on google app engine': 'admin disabled because not supported on google apps engine',
@@ -139,19 +164,14 @@
'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned',
'cannot create file': 'cannot create file',
'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"',
-'Change admin password': 'change admin password',
'check all': 'check all',
-'Check for upgrades': 'check for upgrades',
-'Clean': 'clean',
'click here for online examples': 'щракни тук за онлайн примери',
'click here for the administrative interface': 'щракни тук за административния интерфейс',
'click to check for upgrades': 'click to check for upgrades',
'code': 'code',
'collapse/expand all': 'collapse/expand all',
-'Compile': 'compile',
'compiled application removed': 'compiled application removed',
'controllers': 'controllers',
-'Create': 'create',
'create file with filename:': 'create file with filename:',
'create new application:': 'create new application:',
'created by': 'created by',
@@ -167,16 +187,13 @@
'delete': 'delete',
'delete all checked': 'delete all checked',
'delete plugin': 'delete plugin',
-'Deploy': 'deploy',
'design': 'дизайн',
'direction: ltr': 'direction: ltr',
'done!': 'готово!',
'download layouts': 'download layouts',
'download plugins': 'download plugins',
-'Edit': 'edit',
'edit controller': 'edit controller',
'edit views:': 'edit views:',
-'Errors': 'errors',
'export as csv file': 'export as csv file',
'exposes': 'exposes',
'extends': 'extends',
@@ -193,12 +210,10 @@
'file saved on %s': 'file saved on %s',
'files': 'files',
'filter': 'filter',
-'Help': 'help',
'htmledit': 'htmledit',
'includes': 'includes',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
-'Install': 'install',
'internal error': 'internal error',
'invalid password': 'invalid password',
'invalid request': 'невалидна заявка',
@@ -208,7 +223,6 @@
'languages updated': 'languages updated',
'loading...': 'loading...',
'login': 'login',
-'Logout': 'logout',
'merge': 'merge',
'models': 'models',
'modules': 'modules',
@@ -220,9 +234,6 @@
'or import from csv file': 'or import from csv file',
'or provide app url:': 'or provide app url:',
'or provide application url:': 'or provide application url:',
-'Overwrite installed app': 'overwrite installed app',
-'Pack all': 'pack all',
-'Pack compiled': 'pack compiled',
'pack plugin': 'pack plugin',
'password changed': 'password changed',
'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted',
@@ -231,16 +242,13 @@
'record': 'record',
'record does not exist': 'записът не съществува',
'record id': 'record id',
-'Remove compiled': 'remove compiled',
'restore': 'restore',
'revert': 'revert',
'save': 'save',
'selected': 'selected',
'session expired': 'session expired',
'shell': 'shell',
-'Site': 'site',
'some files could not be removed': 'some files could not be removed',
-'Start wizard': 'start wizard',
'state': 'състояние',
'static': 'static',
'submit': 'submit',
@@ -261,7 +269,6 @@
'unable to uninstall "%s"': 'unable to uninstall "%s"',
'unable to upgrade because "%s"': 'unable to upgrade because "%s"',
'uncheck all': 'uncheck all',
-'Uninstall': 'uninstall',
'update': 'update',
'update all languages': 'update all languages',
'upgrade web2py now': 'upgrade web2py now',
@@ -277,5 +284,3 @@
'web2py is up to date': 'web2py is up to date',
'web2py upgraded; please restart it': 'web2py upgraded; please restart it',
}
-
-
diff --git a/gluon/contrib/markmin/markmin.html b/gluon/contrib/markmin/markmin.html
index 76c06f12..db637503 100644
--- a/gluon/contrib/markmin/markmin.html
+++ b/gluon/contrib/markmin/markmin.html
@@ -1,13 +1,13 @@
-
Markmin markup language
About
This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the markmin2html function in the markmin2html.py.
Example of usage:
>>> m = "Hello **world** [[link http://web2py.com]]"
->>> from markmin2html import markmin2html
->>> print markmin2html(m)
->>> from markmin2latex import markmin2latex
->>> print markmin2latex(m)
->>> from markmin2pdf import markmin2pdf # requires pdflatex
->>> print markmin2pdf(m)
Why?
We wanted a markup language with the following requirements:
less than 100 lines of functional code
easy to read
secure
support table, ul, ol, code
support html5 video and audio elements (html serialization only)
can align images and resize them
can specify class for tables and code elements
can add anchors
does not use _ for markup (since it creates odd behavior)
automatically links urls
fast
easy to extend
supports latex and pdf including references
allows to describe the markup in the markup (this document is generated from markmin syntax)
(results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster)
The web2py book published by lulu, for example, was entirely generated with markmin2pdf from the online web2py wiki
The format is always [[title link]]. Notice you can nest bold, italic and code inside the link title.
Anchors
You can place an anchor anywhere in the text using the syntax [[name]] where name is the name of the anchor.
-You can then link the anchor with link, i.e. [[link #myanchor]].
Images
-This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code
[[some image http://www.web2py.com/examples/static/web2py_logo.png right 200px]].
Unordered Lists
- Dog
+
Markmin markup language
About
This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the markmin2html function in the markmin2html.py.
The format is always [[title link]] or [[title [extra] link]]. Notice you can nest bold, italic, strikeout and code inside the link title.
Anchors
You can place an anchor anywhere in the text using the syntax [[name]] where name is the name of the anchor.
+You can then link the anchor with link, i.e. [[link #myanchor]] or link with an extra info, i.e.
+[[link with an extra info [extra info] #myanchor]].
Images
+This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code
[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]].
Unordered Lists
- Dog
- Cat
- Mouse
is rendered as
Dog
Cat
Mouse
Two new lines between items break the list in two lists.
Ordered Lists
+ Dog
+ Cat
@@ -19,17 +19,34 @@ This paragraph has an image aligned to the right with a width of 200px. Its is p
X | 0 | 0
-----:abc
is a table and is rendered as
-
A
B
C
0
0
X
0
X
0
X
0
0
Four or more dashes delimit the table and | separates the columns.
-The :abc at the end sets the class for the table and it is optional.
Blockquote
A table with a single cell is rendered as a blockquote:
Hello world
-
Code, <code>, escaping and extra stuff
def test():
- return "this is Python code"
Optionally a ` inside a ``...`` block can be inserted escaped with !`!.
-The :python after the markup is also optional. If present, by default, it is used to set the class of the <code> block.
-The behavior can be overridden by passing an argument extra to the render function. For example:
Citations are treated as internal links in html and proper citations in latex if there is a final section called "References". Items like
- [[key]] value
in the References will be translated into Latex
\bibitem{key} value
Here is an example of usage:
As shown in Ref.``mdipierro``:cite
+
A
B
C
0
0
X
0
X
0
X
0
0
+Four or more dashes delimit the table and | separates the columns.
+The :abc at the end sets the class for the table and it is optional.
Blockquote
A table with a single cell is rendered as a blockquote:
Hello world
Code, <code>, escaping and extra stuff
def test():
+ return "this is Python code"
Optionally a ` inside a ``...`` block can be inserted escaped with !`!.
NOTE: You can escape markmin constructions ('',``,**,~~,[,{,]},$,@) with '\' character:
+so \`\` can replace !`!`! escape string
The :python after the markup is also optional. If present, by default, it is used to set the class of the <code> block.
+The behavior can be overridden by passing an argument extra to the render function. For example:
Citations are treated as internal links in html and proper citations in latex if there is a final section called "References". Items like
- [[key]] value
in the References will be translated into Latex
\bibitem{key} value
Here is an example of usage:
As shown in Ref.``mdipierro``:cite
## References
- [[mdipierro]] web2py Manual, 3rd Edition, lulu.com
Caveats
<ul/>, <ol/>, <code/>, <table/>, <blockquote/>, <h1/>, ..., <h6/> do not have <p>...</p> around them.
diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py
index 9b7d52a7..7ae2fd4c 100755
--- a/gluon/contrib/markmin/markmin2html.py
+++ b/gluon/contrib/markmin/markmin2html.py
@@ -1,5 +1,6 @@
-#!/usr/bin/env python
-# created my Massimo Di Pierro
+#!/usr/bin/env python
+# created by Massimo Di Pierro
+# improved by Vladyslav Kozlovskyy
# license MIT/BSD/GPL
import re
import cgi
@@ -20,7 +21,7 @@ MathJax.Hub.Config({
"""
-__all__ = ['render', 'markmin2html']
+__all__ = ['render', 'markmin2html', 'markmin_escape']
__doc__ = """
# Markmin markup language
@@ -44,7 +45,7 @@ print markmin2pdf(m)
## Why?
We wanted a markup language with the following requirements:
-- less than 100 lines of functional code
+- less than 200 lines of functional code
- easy to read
- secure
- support table, ul, ol, code
@@ -75,33 +76,38 @@ markmin2html.py and markmin2latex.py are single files and have no web2py depende
### Bold, italic, code and links
---------------------------------------------------
-**SOURCE** | **OUTPUT**
-``# title`` | **title**
-``## section`` | **section**
-``### subsection`` | **subsection**
-``**bold**`` | **bold**
-``''italic''`` | ''italic''
-``!`!`verbatim`!`!`` | ``verbatim``
-``http://google.com`` | http://google.com
-``[[click me #myanchor]]`` | [[click me #myanchor]]
----------------------------------------------------
+------------------------------------------------------------------------------
+**SOURCE** | **OUTPUT**
+``# title`` | **title**
+``## section`` | **section**
+``### subsection`` | **subsection**
+``**bold**`` | **bold**
+``''italic''`` | ''italic''
+``~~strikeout~~`` | ~~strikeout~~
+``!`!`verbatim`!`!`` | ``verbatim``
+``\`\`color with **bold**\`\`:red`` | ``color with **bold**``:red
+``\`\`many colors\`\`:color[blue:#ffff00]`` | ``many colors``:color[blue:#ffff00]
+``http://google.com`` | http://google.com
+``[[**click** me #myanchor]]`` | [[**click** me #myanchor]]
+``[[click me [extra info] #myanchor popup]]`` | [[click me [extra info] #myanchor popup]]
+-------------------------------------------------------------------------------
### More on links
-The format is always ``[[title link]]``. Notice you can nest bold, italic and code inside the link title.
+The format is always ``[[title link]]`` or ``[[title [extra] link]]``. Notice you can nest bold, italic, strikeout and code inside the link ``title``.
### Anchors [[myanchor]]
You can place an anchor anywhere in the text using the syntax ``[[name]]`` where ''name'' is the name of the anchor.
-You can then link the anchor with [[link #myanchor]], i.e. ``[[link #myanchor]]``.
+You can then link the anchor with [[link #myanchor]], i.e. ``[[link #myanchor]]`` or [[link with an extra info [extra info] #myanchor]], i.e.
+``[[link with an extra info [extra info] #myanchor]]``.
### Images
-[[some image http://www.web2py.com/examples/static/web2py_logo.png right 200px]]
+[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]]
This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code
-``[[some image http://www.web2py.com/examples/static/web2py_logo.png right 200px]]``.
+``[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]]``.
### Unordered Lists
@@ -169,6 +175,10 @@ def test():
``:python
Optionally a ` inside a ``!`!`...`!`!`` block can be inserted escaped with !`!.
+
+**NOTE:** You can escape markmin constructions (\\'\\',\`\`,\*\*,\~\~,\[,\{,\]\},\$,\@) with '\\\\' character:
+ so \\\\`\\\\` can replace !`!`! escape string
+
The ``:python`` after the markup is also optional. If present, by default, it is used to set the class of the block.
The behavior can be overridden by passing an argument ``extra`` to the ``render`` function. For example:
@@ -183,23 +193,26 @@ generates
(the ``!`!`...`!`!:custom`` block is rendered by the ``custom=lambda`` function passed to ``render``).
-
### Html5 support
Markmin also supports the