From beac56a57a0f6917df63ab3db886d2fdda6248e4 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 20 Jul 2012 17:37:53 -0500 Subject: [PATCH] other improvements, thanks Vladyslav --- VERSION | 2 +- applications/admin/controllers/default.py | 6 +- applications/admin/static/css/styles.css | 1 + gluon/contrib/markmin/markmin.html | 37 +++++++----- gluon/contrib/markmin/markmin2html.py | 70 ++++++++++++++++------- gluon/utf8.py | 47 +++++++-------- 6 files changed, 100 insertions(+), 63 deletions(-) diff --git a/VERSION b/VERSION index 02cb0948..45616fdb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-07-20 16:47:55) dev +Version 2.00.0 (2012-07-20 17:37:48) dev diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index 102cac82..711f0330 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -392,7 +392,7 @@ def peek(): app = get_app(request.vars.app) filename = '/'.join(request.args) if request.vars.app: - path = abspath(filename, gluon=False) + path = abspath(filename) else: path = apath(filename, r=request) try: @@ -696,7 +696,7 @@ def edit_language(): s = strings[key] (prefix, sep, key) = key.partition('\x01') if sep: - prefix = SPAN(prefix+': ', _style='color: blue;') + prefix = SPAN(prefix+': ', _class='tm_ftag') k = key else: (k, prefix) = (prefix, '') @@ -1034,7 +1034,7 @@ def create_file(): anchor='#'+request.vars.id if request.vars.id else '' if request.vars.app: app = get_app(request.vars.app) - path = abspath(request.vars.location, gluon=False) + path = abspath(request.vars.location) else: app = get_app(name=request.vars.location.split('/')[0]) path = apath(request.vars.location, r=request) diff --git a/applications/admin/static/css/styles.css b/applications/admin/static/css/styles.css index f75bdfe1..8375f145 100644 --- a/applications/admin/static/css/styles.css +++ b/applications/admin/static/css/styles.css @@ -1248,3 +1248,4 @@ color: #222; .error, .error a {color:red} .pluralsform thead td {font-weight:bold; font-size:1.2em; padding-bottom:5px} .pluralsform td {padding-left:5px} +.tm_ftag {color:blue} diff --git a/gluon/contrib/markmin/markmin.html b/gluon/contrib/markmin/markmin.html index d68ae23a..450d599b 100644 --- a/gluon/contrib/markmin/markmin.html +++ b/gluon/contrib/markmin/markmin.html @@ -1,17 +1,22 @@ - - -

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]]"
+  td.num { text-align: right; }
+  pre { background-color: #E0E0E0; }
+
+Markmin markup language
+
+
+

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
@@ -24,7 +29,7 @@ line 2
   line 3
This item finishes with this paragraph.

Item in sublevel 3 can be continued with paragraphs.

  this is another
 code block
     in the
-  sublevel 3 item
  1. The last item in sublevel 3

This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.

  • item 3 in sublevel 2
    • item 1 in sublevel 2 (new unordered list)
    • item 2 in sublevel 2
    • item 3 in sublevel 2
    1. item 1 in sublevel 2 (new ordered list)
    2. item 2 in sublevel 2
    3. item 3 in sublevle 2
  • item 2 in level 1
  • item 3 in level 1
    • new unordered list (item 1 in level 1)
    • level 2 in level 1
    • level 3 in level 1
    • level 4 in level 1

    This is the last section of the test

    Single paragraph with '----' in it will be turned into separator:


    And this is the last paragraph in the test. Be happy!

    ====================

    Why?

    We wanted a markup language with the following requirements:

    • less than 300 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

    Download

    markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.

    Examples

    Bold, italic, code and links

    SOURCEOUTPUT
    # titletitle
    ## sectionsection
    ### subsectionsubsection
    **bold**bold
    ''italic''italic
    ~~strikeout~~strikeout
    ``verbatim``verbatim
    ``color with **bold**``:redcolor with bold
    ``many colors``:color[blue:#ffff00]many colors
    http://google.comhttp://google.com
    [[**click** me #myanchor]]click me
    [[click me [extra info] #myanchor popup]]click me

    More on links

    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

    alt-string for the image 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
    +  sublevel 3 item
    1. The last item in sublevel 3

    This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.

  • item 3 in sublevel 2
    • item 1 in sublevel 2 (new unordered list)
    • item 2 in sublevel 2
    • item 3 in sublevel 2
    1. item 1 in sublevel 2 (new ordered list)
    2. item 2 in sublevel 2
    3. item 3 in sublevle 2
  • item 2 in level 1
  • item 3 in level 1
    • new unordered list (item 1 in level 1)
    • level 2 in level 1
    • level 3 in level 1
    • level 4 in level 1

    This is the last section of the test

    Single paragraph with '----' in it will be turned into separator:


    And this is the last paragraph in the test. Be happy!

    ====================

    Why?

    We wanted a markup language with the following requirements:

    • less than 300 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

    Download

    markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.

    Examples

    Bold, italic, code and links

    SOURCEOUTPUT
    # titletitle
    ## sectionsection
    ### subsectionsubsection
    **bold**bold
    ''italic''italic
    ~~strikeout~~strikeout
    ``verbatim``verbatim
    ``color with **bold**``:redcolor with bold
    ``many colors``:color[blue:#ffff00]many colors
    http://google.comhttp://google.com
    [[**click** me #myanchor]]click me
    [[click me [extra info] #myanchor popup]]click me

    More on links

    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

    alt-string for the image 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
    @@ -79,4 +84,6 @@ markmin2html(text,{'latex':lambda code: LATEX % code.replace('"','\"')})<
     
     ## References
     
    -- [[mdipierro]] web2py Manual, 3rd Edition, lulu.com

    Caveats

    <ul/>, <ol/>, <code/>, <table/>, <blockquote/>, <h1/>, ..., <h6/> do not have <p>...</p> around them.

    +- [[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 2b305608..2c6da1e7 100755 --- a/gluon/contrib/markmin/markmin2html.py +++ b/gluon/contrib/markmin/markmin2html.py @@ -667,19 +667,19 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo '

    [[probe]]

    ' >>> render(r"\\\\[[probe]]") - '

    \\\\

    ' + '

    \\\\

    ' >>> render(r"\\\\\\[[probe]]") '

    \\\\[[probe]]

    ' >>> render(r"\\\\\\\\[[probe]]") - '

    \\\\\\\\

    ' + '

    \\\\\\\\

    ' >>> render(r"\\\\\\\\\[[probe]]") '

    \\\\\\\\[[probe]]

    ' >>> render(r"\\\\\\\\\\\[[probe]]") - '

    \\\\\\\\\\\\

    ' + '

    \\\\\\\\\\\\

    ' >>> render("``[[ [\\[[probe\]\\]] URL\\[x\\]]]``:red[dummy_params]") 'URL[x]' @@ -725,6 +725,10 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo >>> render("**@{probe}**", environment=dict(probe="this is a test")) '

    this is a test

    ' + + >>> render('[[id1 [span **messag** in ''markmin''] ]] ... [[**link** to id [link\\\'s title] #mark1]]') + '

    span messag in markmin ... link to id

    ' + """ text = str(text or '') text = regex_backslash.sub(lambda m: m.group(1).translate(ttab_in), text) @@ -855,7 +859,7 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo """ paragraphs in lists """ lent=len(t) if lent>lev: - return parse_list(t, '.', s, 'ul', lev, mtag) + return parse_list(t, '.', s, 'ul', lev, mtag, lineno) elif lentlent: ltags.pop() @@ -986,7 +990,9 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo URL, environment, latex, - auto) + auto, + class_prefix, + id_prefix) ) mtag='q' else: @@ -1100,7 +1106,8 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo elif p in ('left','right'): style = ' style="float:%s"' % p if p in ('video','audio'): - t = render(t, {}, {}, 'br', URL, environment, latex, auto) + t = render(t, {}, {}, 'br', URL, environment, latex, + auto, class_prefix, id_prefix) return '<%(p)s controls="controls"%(title)s%(width)s>%(t)s' \ % dict(p=p, title=title, width=width, k=k, t=t) alt = ' alt="%s"'%escape(t).replace(META, DISABLED_META) if t else '' @@ -1115,13 +1122,19 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo t = t or '' a = escape(a) if a else '' if k: + if k.startswith('#'): + k = '#'+id_prefix+k[1:] k = escape(k) title = ' title="%s"' % a.replace(META, DISABLED_META) if a else '' target = ' target="_blank"' if p == 'popup' else '' - t = render(t, {}, {}, 'br', URL, environment, latex, auto) if t else k + t = render(t, {}, {}, 'br', URL, environment, latex, auto, + class_prefix, id_prefix) if t else k return '%(t)s' \ % dict(k=k, title=title, target=target, t=t) - return '%s' % (escape(t),a) + return '%s' % (escape(id_prefix+t), + render(a, {},{},'br', URL, + environment, latex, auto, + class_prefix, id_prefix)) parts = text.split(LINK) text = parts[0] @@ -1183,21 +1196,36 @@ def markmin2html(text, extra={}, allowed={}, sep='p', auto=True): if __name__ == '__main__': import sys import doctest + from textwrap import dedent + + html=dedent(""" + + + + + %(style)s + %(title)s + + + %(body)s + + """)[1:] + if sys.argv[1:2] == ['-h']: - print """ - """)[1:] - td.num { text-align: right; } - pre { background-color: #E0E0E0; } - - """+markmin2html(__doc__)+'' + print html % dict(title="Markmin markup language", style=style, body=markmin2html(__doc__)) elif sys.argv[1:2] == ['-t']: from timeit import Timer loops=1000 @@ -1208,7 +1236,7 @@ if __name__ == '__main__': elif len(sys.argv) > 1: fargv = open(sys.argv[1],'r') try: - print ''+markmin2html(fargv.read())+'' + print html % dict(title=sys.argv[1], style='', body=markmin2html(fargv.read())) finally: fargv.close() else: diff --git a/gluon/utf8.py b/gluon/utf8.py index e8baf75d..d21efb8f 100644 --- a/gluon/utf8.py +++ b/gluon/utf8.py @@ -15,7 +15,7 @@ import __builtin__ __all__ = ['Utf8'] repr_escape_tab={} -for i in xrange(1,32): repr_escape_tab[i]=ur'\x%02i'%i +for i in range(1,32): repr_escape_tab[i]=ur'\x%02x'%i repr_escape_tab[7]=u'\\a' repr_escape_tab[8]=u'\\b' repr_escape_tab[9]=u'\\t' @@ -71,6 +71,24 @@ def size(string): """ return Utf8(string).__size__() +def truncate(string, length, dots='...'): + """ returns string of length < *length* or truncate + string with adding *dots* suffix to the string's end + + args: + length (int): max length of string + dots (str or unicode): string suffix, when string is cutted + + returns: + (utf8-str): original or cutted string + """ + text = unicode(string, 'utf-8') + dots = unicode(dots, 'utf-8') if isinstance(dots, str) else dots + if len(text) > length: + text = text[:length-len(dots)] + dots + return str.__new__(Utf8, text.encode('utf-8')) + + class Utf8(str): """ Class for utf8 string storing and manipulations @@ -131,23 +149,6 @@ class Utf8(str): else: return "'"+unicode(self, 'utf-8').translate(repr_escape_tab2).encode('utf-8')+"'" - def truncate(self, length, dots='...'): - """ returns string of length < *length* or truncate - string with adding *dots* suffix to the string's end - - args: - length (int): max length of string - dots (str or unicode): string suffix, when string is cutted - - returns: - (utf8-str): original or cutted string - """ - text = unicode(self, 'utf-8') - dots = unicode(dots, 'utf-8') if isinstance(dots, str) else dots - if len(text) > length: - text = text[:length-len(dots)] + dots - return str.__new__(Utf8, text.encode('utf-8')) - def __size__(self): """ length of utf-8 string in bytes """ return str.__len__(self) @@ -419,15 +420,15 @@ if __name__ == '__main__': 'прОБА є prOBE' >>> type(s.swapcase()) - >>> s.truncate(10) + >>> truncate(s, 10) 'ПРоба Є...' - >>> s.truncate(20) + >>> truncate(s, 20) 'ПРоба Є PRobe' - >>> s.truncate(10, '•••') # utf-8 string as *dots* + >>> truncate(s, 10, '•••') # utf-8 string as *dots* 'ПРоба Є•••' - >>> s.truncate(10, u'®') # you can use unicode string as *dots* + >>> truncate(s, 10, u'®') # you can use unicode string as *dots* 'ПРоба Є P®' - >>> type(s.truncate(10)) + >>> type(truncate(s, 10)) >>> Utf8(s.encode('koi8-u'), 'koi8-u') 'ПРоба Є PRobe'