author | Samuel Trégouët <samuel.tregouet@logilab.fr> |
Fri, 11 Sep 2015 14:28:06 +0200 | |
changeset 10588 | fdaa0e4b7eaf |
parent 10212 | dccce2be3101 |
child 10603 | 65ad6980976e |
permissions | -rw-r--r-- |
9322
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
1 |
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
3 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
4 |
# This file is part of CubicWeb. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
5 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
9 |
# any later version. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
10 |
# |
5424
8ecbcbff9777
replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5421
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
14 |
# details. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
15 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4771
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
0 | 18 |
"""rest publishing functions |
19 |
||
996 | 20 |
contains some functions and setup of docutils for cubicweb. Provides the |
21 |
following ReST directives: |
|
22 |
||
23 |
* `eid`, create link to entity in the repository by their eid |
|
24 |
||
25 |
* `card`, create link to card entity in the repository by their wikiid |
|
26 |
(proposing to create it when the refered card doesn't exist yet) |
|
27 |
||
28 |
* `winclude`, reference to a web documentation file (in wdoc/ directories) |
|
29 |
||
30 |
* `sourcecode` (if pygments is installed), source code colorization |
|
0 | 31 |
|
9322
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
32 |
* `rql-table`, create a table from a RQL query |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
33 |
|
0 | 34 |
""" |
35 |
__docformat__ = "restructuredtext en" |
|
36 |
||
37 |
from itertools import chain |
|
38 |
from logging import getLogger |
|
39 |
from os.path import join |
|
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
40 |
from urlparse import urlsplit |
0 | 41 |
|
42 |
from docutils import statemachine, nodes, utils, io |
|
4771
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
43 |
from docutils.core import Publisher |
9322
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
44 |
from docutils.parsers.rst import Parser, states, directives, Directive |
0 | 45 |
from docutils.parsers.rst.roles import register_canonical_role, set_classes |
46 |
||
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2311
diff
changeset
|
47 |
from logilab.mtconverter import ESC_UCAR_TABLE, ESC_CAR_TABLE, xml_escape |
0 | 48 |
|
2467
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
49 |
from cubicweb import UnknownEid |
704
0c2c8f0a6ded
new ext package for modules depending on an option third party package
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
50 |
from cubicweb.ext.html4zope import Writer |
0 | 51 |
|
6938
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
52 |
from cubicweb.web.views import vid_from_rset # XXX better not to import c.w.views here... |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
53 |
|
0 | 54 |
# We provide our own parser as an attempt to get rid of |
55 |
# state machine reinstanciation |
|
56 |
||
57 |
import re |
|
58 |
# compile states.Body patterns |
|
59 |
for k, v in states.Body.patterns.items(): |
|
60 |
if isinstance(v, str): |
|
61 |
states.Body.patterns[k] = re.compile(v) |
|
62 |
||
63 |
# register ReStructured Text mimetype / extensions |
|
64 |
import mimetypes |
|
65 |
mimetypes.add_type('text/rest', '.rest') |
|
66 |
mimetypes.add_type('text/rest', '.rst') |
|
67 |
||
68 |
||
69 |
LOGGER = getLogger('cubicweb.rest') |
|
70 |
||
71 |
def eid_reference_role(role, rawtext, text, lineno, inliner, |
|
72 |
options={}, content=[]): |
|
73 |
try: |
|
74 |
try: |
|
75 |
eid_num, rest = text.split(u':', 1) |
|
7815
2a164a9cf81c
[exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7732
diff
changeset
|
76 |
except ValueError: |
0 | 77 |
eid_num, rest = text, '#'+text |
78 |
eid_num = int(eid_num) |
|
79 |
if eid_num < 0: |
|
80 |
raise ValueError |
|
81 |
except ValueError: |
|
82 |
msg = inliner.reporter.error( |
|
83 |
'EID number must be a positive number; "%s" is invalid.' |
|
84 |
% text, line=lineno) |
|
85 |
prb = inliner.problematic(rawtext, rawtext, msg) |
|
86 |
return [prb], [msg] |
|
87 |
# Base URL mainly used by inliner.pep_reference; so this is correct: |
|
88 |
context = inliner.document.settings.context |
|
2467
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
89 |
try: |
3418
7b49fa7e942d
[api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2680
diff
changeset
|
90 |
refedentity = context._cw.entity_from_eid(eid_num) |
2467
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
91 |
except UnknownEid: |
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
92 |
ref = '#' |
3418
7b49fa7e942d
[api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2680
diff
changeset
|
93 |
rest += u' ' + context._cw._('(UNEXISTANT EID)') |
2467
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
94 |
else: |
6983631f5d0d
don't fail on unknown eid, simply issue a warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
95 |
ref = refedentity.absolute_url() |
0 | 96 |
set_classes(options) |
97 |
return [nodes.reference(rawtext, utils.unescape(rest), refuri=ref, |
|
98 |
**options)], [] |
|
99 |
||
6938
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
100 |
def rql_role(role, rawtext, text, lineno, inliner, options={}, content=[]): |
10023
c3ab46842b2d
[book] fix docstrings to please sphinx
David Douard <david.douard@logilab.fr>
parents:
9592
diff
changeset
|
101 |
"""``:rql:`<rql-expr>``` or ``:rql:`<rql-expr>:<vid>``` |
8710
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
102 |
|
10023
c3ab46842b2d
[book] fix docstrings to please sphinx
David Douard <david.douard@logilab.fr>
parents:
9592
diff
changeset
|
103 |
Example: ``:rql:`Any X,Y WHERE X is CWUser, X login Y:table``` |
8710
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
104 |
|
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
105 |
Replace the directive with the output of applying the view to the resultset |
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
106 |
returned by the query. |
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
107 |
|
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
108 |
"X eid %(userid)s" can be used in the RQL query for this query will be |
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
109 |
executed with the argument {'userid': _cw.user.eid}. |
becbbbc840b8
[ext/rest] fix docstring of rql_role()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
110 |
""" |
6938
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
111 |
_cw = inliner.document.settings.context._cw |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
112 |
text = text.strip() |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
113 |
if ':' in text: |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
114 |
rql, vid = text.rsplit(u':', 1) |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
115 |
rql = rql.strip() |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
116 |
else: |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
117 |
rql, vid = text, None |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
118 |
_cw.ensure_ro_rql(rql) |
7732
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
119 |
try: |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
120 |
rset = _cw.execute(rql, {'userid': _cw.user.eid}) |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
121 |
if rset: |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
122 |
if vid is None: |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
123 |
vid = vid_from_rset(_cw, rset, _cw.vreg.schema) |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
124 |
else: |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
125 |
vid = 'noresult' |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
126 |
view = _cw.vreg['views'].select(vid, _cw, rset=rset) |
5430d0db52ab
[web] rql directive breaks if explicit vid and empty rset (closes #1893433)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7577
diff
changeset
|
127 |
content = view.render() |
8695
358d8bed9626
[toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
128 |
except Exception as exc: |
9517
3338b2205ea3
Typo in comments and error messages
Dimitri Papadopoulos <dimitri.papadopoulos@cea.fr>
parents:
9322
diff
changeset
|
129 |
content = 'an error occurred while interpreting this rql directive: %r' % exc |
6938
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
130 |
set_classes(options) |
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
131 |
return [nodes.raw('', content, format='html')], [] |
0 | 132 |
|
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
133 |
def bookmark_role(role, rawtext, text, lineno, inliner, options={}, content=[]): |
10023
c3ab46842b2d
[book] fix docstrings to please sphinx
David Douard <david.douard@logilab.fr>
parents:
9592
diff
changeset
|
134 |
"""``:bookmark:`<bookmark-eid>``` or ``:bookmark:`<eid>:<vid>``` |
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
135 |
|
10023
c3ab46842b2d
[book] fix docstrings to please sphinx
David Douard <david.douard@logilab.fr>
parents:
9592
diff
changeset
|
136 |
Example: ``:bookmark:`1234:table``` |
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
137 |
|
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
138 |
Replace the directive with the output of applying the view to the resultset |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
139 |
returned by the query stored in the bookmark. By default, the view is the one |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
140 |
stored in the bookmark, but it can be overridden by the directive as in the |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
141 |
example above. |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
142 |
|
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
143 |
"X eid %(userid)s" can be used in the RQL query stored in the Bookmark, for |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
144 |
this query will be executed with the argument {'userid': _cw.user.eid}. |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
145 |
""" |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
146 |
_cw = inliner.document.settings.context._cw |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
147 |
text = text.strip() |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
148 |
try: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
149 |
if ':' in text: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
150 |
eid, vid = text.rsplit(u':', 1) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
151 |
eid = int(eid) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
152 |
else: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
153 |
eid, vid = int(text), None |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
154 |
except ValueError: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
155 |
msg = inliner.reporter.error( |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
156 |
'EID number must be a positive number; "%s" is invalid.' |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
157 |
% text, line=lineno) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
158 |
prb = inliner.problematic(rawtext, rawtext, msg) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
159 |
return [prb], [msg] |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
160 |
try: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
161 |
bookmark = _cw.entity_from_eid(eid) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
162 |
except UnknownEid: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
163 |
msg = inliner.reporter.error('Unknown EID %s.' % text, line=lineno) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
164 |
prb = inliner.problematic(rawtext, rawtext, msg) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
165 |
return [prb], [msg] |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
166 |
try: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
167 |
params = dict(_cw.url_parse_qsl(urlsplit(bookmark.path).query)) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
168 |
rql = params['rql'] |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
169 |
if vid is None: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
170 |
vid = params.get('vid') |
10588
fdaa0e4b7eaf
[py3k] except as
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents:
10212
diff
changeset
|
171 |
except (ValueError, KeyError) as exc: |
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
172 |
msg = inliner.reporter.error('Could not parse bookmark path %s [%s].' |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
173 |
% (bookmark.path, exc), line=lineno) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
174 |
prb = inliner.problematic(rawtext, rawtext, msg) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
175 |
return [prb], [msg] |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
176 |
try: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
177 |
rset = _cw.execute(rql, {'userid': _cw.user.eid}) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
178 |
if rset: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
179 |
if vid is None: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
180 |
vid = vid_from_rset(_cw, rset, _cw.vreg.schema) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
181 |
else: |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
182 |
vid = 'noresult' |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
183 |
view = _cw.vreg['views'].select(vid, _cw, rset=rset) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
184 |
content = view.render() |
10588
fdaa0e4b7eaf
[py3k] except as
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents:
10212
diff
changeset
|
185 |
except Exception as exc: |
9517
3338b2205ea3
Typo in comments and error messages
Dimitri Papadopoulos <dimitri.papadopoulos@cea.fr>
parents:
9322
diff
changeset
|
186 |
content = 'An error occurred while interpreting directive bookmark: %r' % exc |
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
187 |
set_classes(options) |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
188 |
return [nodes.raw('', content, format='html')], [] |
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
189 |
|
0 | 190 |
def winclude_directive(name, arguments, options, content, lineno, |
191 |
content_offset, block_text, state, state_machine): |
|
192 |
"""Include a reST file as part of the content of this reST file. |
|
193 |
||
194 |
same as standard include directive but using config.locate_doc_resource to |
|
195 |
get actual file to include. |
|
196 |
||
197 |
Most part of this implementation is copied from `include` directive defined |
|
198 |
in `docutils.parsers.rst.directives.misc` |
|
199 |
""" |
|
200 |
context = state.document.settings.context |
|
4769
5b878b02b67b
[rest] cleanup, avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
201 |
cw = context._cw |
0 | 202 |
source = state_machine.input_lines.source( |
203 |
lineno - state_machine.input_offset - 1) |
|
204 |
#source_dir = os.path.dirname(os.path.abspath(source)) |
|
205 |
fid = arguments[0] |
|
4769
5b878b02b67b
[rest] cleanup, avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
206 |
for lang in chain((cw.lang, cw.vreg.property_value('ui.language')), |
5b878b02b67b
[rest] cleanup, avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
207 |
cw.vreg.config.available_languages()): |
0 | 208 |
rid = '%s_%s.rst' % (fid, lang) |
4769
5b878b02b67b
[rest] cleanup, avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
209 |
resourcedir = cw.vreg.config.locate_doc_file(rid) |
0 | 210 |
if resourcedir: |
211 |
break |
|
212 |
else: |
|
213 |
severe = state_machine.reporter.severe( |
|
214 |
'Problems with "%s" directive path:\nno resource matching %s.' |
|
215 |
% (name, fid), |
|
216 |
nodes.literal_block(block_text, block_text), line=lineno) |
|
217 |
return [severe] |
|
218 |
path = join(resourcedir, rid) |
|
219 |
encoding = options.get('encoding', state.document.settings.input_encoding) |
|
220 |
try: |
|
221 |
state.document.settings.record_dependencies.add(path) |
|
222 |
include_file = io.FileInput( |
|
223 |
source_path=path, encoding=encoding, |
|
224 |
error_handler=state.document.settings.input_encoding_error_handler, |
|
225 |
handle_io_errors=None) |
|
8695
358d8bed9626
[toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
226 |
except IOError as error: |
0 | 227 |
severe = state_machine.reporter.severe( |
228 |
'Problems with "%s" directive path:\n%s: %s.' |
|
229 |
% (name, error.__class__.__name__, error), |
|
230 |
nodes.literal_block(block_text, block_text), line=lineno) |
|
231 |
return [severe] |
|
232 |
try: |
|
233 |
include_text = include_file.read() |
|
8695
358d8bed9626
[toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7879
diff
changeset
|
234 |
except UnicodeError as error: |
0 | 235 |
severe = state_machine.reporter.severe( |
236 |
'Problem with "%s" directive:\n%s: %s' |
|
237 |
% (name, error.__class__.__name__, error), |
|
238 |
nodes.literal_block(block_text, block_text), line=lineno) |
|
239 |
return [severe] |
|
8697
574bb05e40a4
[toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8695
diff
changeset
|
240 |
if 'literal' in options: |
0 | 241 |
literal_block = nodes.literal_block(include_text, include_text, |
242 |
source=path) |
|
243 |
literal_block.line = 1 |
|
244 |
return literal_block |
|
245 |
else: |
|
246 |
include_lines = statemachine.string2lines(include_text, |
|
247 |
convert_whitespace=1) |
|
248 |
state_machine.insert_input(include_lines, path) |
|
249 |
return [] |
|
250 |
||
251 |
winclude_directive.arguments = (1, 0, 1) |
|
252 |
winclude_directive.options = {'literal': directives.flag, |
|
253 |
'encoding': directives.encoding} |
|
254 |
||
9322
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
255 |
class RQLTableDirective(Directive): |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
256 |
"""rql-table directive |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
257 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
258 |
Example: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
259 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
260 |
.. rql-table:: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
261 |
:vid: mytable |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
262 |
:headers: , , progress |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
263 |
:colvids: 2=progress |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
264 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
265 |
Any X,U,X WHERE X is Project, X url U |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
266 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
267 |
All fields but the RQL string are optionnal. The ``:headers:`` option can |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
268 |
contain empty column names. |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
269 |
""" |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
270 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
271 |
required_arguments = 0 |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
272 |
optional_arguments = 0 |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
273 |
has_content= True |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
274 |
final_argument_whitespace = True |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
275 |
option_spec = {'vid': directives.unchanged, |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
276 |
'headers': directives.unchanged, |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
277 |
'colvids': directives.unchanged} |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
278 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
279 |
def run(self): |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
280 |
errid = "rql-table directive" |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
281 |
self.assert_has_content() |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
282 |
if self.arguments: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
283 |
raise self.warning('%s does not accept arguments' % errid) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
284 |
rql = ' '.join([l.strip() for l in self.content]) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
285 |
_cw = self.state.document.settings.context._cw |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
286 |
_cw.ensure_ro_rql(rql) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
287 |
try: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
288 |
rset = _cw.execute(rql) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
289 |
except Exception as exc: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
290 |
raise self.error("fail to execute RQL query in %s: %r" % |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
291 |
(errid, exc)) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
292 |
if not rset: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
293 |
raise self.warning("empty result set") |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
294 |
vid = self.options.get('vid', 'table') |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
295 |
try: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
296 |
view = _cw.vreg['views'].select(vid, _cw, rset=rset) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
297 |
except Exception as exc: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
298 |
raise self.error("fail to select '%s' view in %s: %r" % |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
299 |
(vid, errid, exc)) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
300 |
headers = None |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
301 |
if 'headers' in self.options: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
302 |
headers = [h.strip() for h in self.options['headers'].split(',')] |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
303 |
while headers.count(''): |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
304 |
headers[headers.index('')] = None |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
305 |
if len(headers) != len(rset[0]): |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
306 |
raise self.error("the number of 'headers' does not match the " |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
307 |
"number of columns in %s" % errid) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
308 |
cellvids = None |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
309 |
if 'colvids' in self.options: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
310 |
cellvids = {} |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
311 |
for f in self.options['colvids'].split(','): |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
312 |
try: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
313 |
idx, vid = f.strip().split('=') |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
314 |
except ValueError: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
315 |
raise self.error("malformatted 'colvids' option in %s" % |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
316 |
errid) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
317 |
cellvids[int(idx.strip())] = vid.strip() |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
318 |
try: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
319 |
content = view.render(headers=headers, cellvids=cellvids) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
320 |
except Exception as exc: |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
321 |
raise self.error("Error rendering %s (%s)" % (errid, exc)) |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
322 |
return [nodes.raw('', content, format='html')] |
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
323 |
|
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
324 |
|
996 | 325 |
try: |
326 |
from pygments import highlight |
|
4719
aaed3f813ef8
kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4483
diff
changeset
|
327 |
from pygments.lexers import get_lexer_by_name |
7879
9aae456abab5
[pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7815
diff
changeset
|
328 |
from pygments.formatters.html import HtmlFormatter |
996 | 329 |
except ImportError: |
4118
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
330 |
pygments_directive = None |
996 | 331 |
else: |
332 |
_PYGMENTS_FORMATTER = HtmlFormatter() |
|
333 |
||
334 |
def pygments_directive(name, arguments, options, content, lineno, |
|
335 |
content_offset, block_text, state, state_machine): |
|
336 |
try: |
|
337 |
lexer = get_lexer_by_name(arguments[0]) |
|
338 |
except ValueError: |
|
339 |
# no lexer found |
|
340 |
lexer = get_lexer_by_name('text') |
|
341 |
parsed = highlight(u'\n'.join(content), lexer, _PYGMENTS_FORMATTER) |
|
4483
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
342 |
# don't fail if no context set on the sourcecode directive |
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
343 |
try: |
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
344 |
context = state.document.settings.context |
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
345 |
context._cw.add_css('pygments.css') |
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
346 |
except AttributeError: |
7577
9892937d9041
[all] remove pattern "try: function() except AttributeError: pass" (closes #1787966)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6938
diff
changeset
|
347 |
# used outside cubicweb XXX use hasattr instead |
4483
918fd9931cb7
cleanup, don't fail if no context set on the sourcecode directive
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4334
diff
changeset
|
348 |
pass |
996 | 349 |
return [nodes.raw('', parsed, format='html')] |
1447
a1ca676294f0
don't use a singleton rest parser which may leads to concurrency bugs
sylvain.thenault@logilab.fr
parents:
1323
diff
changeset
|
350 |
|
996 | 351 |
pygments_directive.arguments = (1, 0, 1) |
352 |
pygments_directive.content = 1 |
|
353 |
||
354 |
||
0 | 355 |
class CubicWebReSTParser(Parser): |
356 |
"""The (customized) reStructuredText parser.""" |
|
357 |
||
358 |
def __init__(self): |
|
359 |
self.initial_state = 'Body' |
|
360 |
self.state_classes = states.state_classes |
|
361 |
self.inliner = states.Inliner() |
|
362 |
self.statemachine = states.RSTStateMachine( |
|
363 |
state_classes=self.state_classes, |
|
364 |
initial_state=self.initial_state, |
|
365 |
debug=0) |
|
366 |
||
367 |
def parse(self, inputstring, document): |
|
368 |
"""Parse `inputstring` and populate `document`, a document tree.""" |
|
369 |
self.setup_parse(inputstring, document) |
|
370 |
inputlines = statemachine.string2lines(inputstring, |
|
371 |
convert_whitespace=1) |
|
372 |
self.statemachine.run(inputlines, document, inliner=self.inliner) |
|
373 |
self.finish_parse() |
|
374 |
||
375 |
||
4771
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
376 |
# XXX docutils keep a ref on context, can't find a correct way to remove it |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
377 |
class CWReSTPublisher(Publisher): |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
378 |
def __init__(self, context, settings, **kwargs): |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
379 |
Publisher.__init__(self, **kwargs) |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
380 |
self.set_components('standalone', 'restructuredtext', 'pseudoxml') |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
381 |
self.process_programmatic_settings(None, settings, None) |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
382 |
self.settings.context = context |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
383 |
|
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
384 |
|
0 | 385 |
def rest_publish(context, data): |
386 |
"""publish a string formatted as ReStructured Text to HTML |
|
1447
a1ca676294f0
don't use a singleton rest parser which may leads to concurrency bugs
sylvain.thenault@logilab.fr
parents:
1323
diff
changeset
|
387 |
|
0 | 388 |
:type context: a cubicweb application object |
389 |
||
390 |
:type data: str |
|
391 |
:param data: some ReST text |
|
392 |
||
393 |
:rtype: unicode |
|
394 |
:return: |
|
6109
47d9c0e0f7b7
integrate Celso's work on translation file: proper/complete spanish translation, fixed some typos in french translation, occured -> occurred fix in various places
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5424
diff
changeset
|
395 |
the data formatted as HTML or the original data if an error occurred |
0 | 396 |
""" |
3418
7b49fa7e942d
[api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2680
diff
changeset
|
397 |
req = context._cw |
0 | 398 |
if isinstance(data, unicode): |
399 |
encoding = 'unicode' |
|
2311
f178182b1305
actually close #344401 by removing unprintable characters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
400 |
# remove unprintable characters unauthorized in xml |
f178182b1305
actually close #344401 by removing unprintable characters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
401 |
data = data.translate(ESC_UCAR_TABLE) |
0 | 402 |
else: |
403 |
encoding = req.encoding |
|
2311
f178182b1305
actually close #344401 by removing unprintable characters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
404 |
# remove unprintable characters unauthorized in xml |
f178182b1305
actually close #344401 by removing unprintable characters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
405 |
data = data.translate(ESC_CAR_TABLE) |
0 | 406 |
settings = {'input_encoding': encoding, 'output_encoding': 'unicode', |
10212
dccce2be3101
[ext] Remove use of cStringIO
Rémi Cardona <remi.cardona@free.fr>
parents:
10023
diff
changeset
|
407 |
'warning_stream': False, |
6275
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
408 |
'traceback': True, # don't sys.exit |
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
409 |
'stylesheet': None, # don't try to embed stylesheet (may cause |
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
410 |
# obscure bug due to docutils computing |
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
411 |
# relative path according to the directory |
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
412 |
# used *at import time* |
0 | 413 |
# dunno what's the max, severe is 4, and we never want a crash |
6275
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
414 |
# (though try/except may be a better option...). May be the |
20f30e01ae59
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
415 |
# above traceback option will avoid this? |
1447
a1ca676294f0
don't use a singleton rest parser which may leads to concurrency bugs
sylvain.thenault@logilab.fr
parents:
1323
diff
changeset
|
416 |
'halt_level': 10, |
0 | 417 |
} |
418 |
if context: |
|
419 |
if hasattr(req, 'url'): |
|
420 |
base_url = req.url() |
|
421 |
elif hasattr(context, 'absolute_url'): |
|
422 |
base_url = context.absolute_url() |
|
423 |
else: |
|
424 |
base_url = req.base_url() |
|
425 |
else: |
|
426 |
base_url = None |
|
427 |
try: |
|
4771
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
428 |
pub = CWReSTPublisher(context, settings, |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
429 |
parser=CubicWebReSTParser(), |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
430 |
writer=Writer(base_url=base_url), |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
431 |
source_class=io.StringInput, |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
432 |
destination_class=io.StringOutput) |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
433 |
pub.set_source(data) |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
434 |
pub.set_destination() |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
435 |
res = pub.publish(enable_exit_status=None) |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
436 |
# necessary for proper garbage collection, else a ref is kept somewhere in docutils... |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
437 |
del pub.settings.context |
e27d23f875c6
custom rest publisher instead of using rest_publish. Avoid to keep a ref on the latest context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4769
diff
changeset
|
438 |
return res |
9592
6fd2651719bc
[ext/rest] Catch SystemExit raised by docutils
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
9517
diff
changeset
|
439 |
except BaseException: |
0 | 440 |
LOGGER.exception('error while publishing ReST text') |
441 |
if not isinstance(data, unicode): |
|
442 |
data = unicode(data, encoding, 'replace') |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2311
diff
changeset
|
443 |
return xml_escape(req._('error while publishing ReST text') |
0 | 444 |
+ '\n\n' + data) |
4118
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
445 |
|
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
446 |
|
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
447 |
_INITIALIZED = False |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
448 |
def cw_rest_init(): |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
449 |
global _INITIALIZED |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
450 |
if _INITIALIZED: |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
451 |
return |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
452 |
_INITIALIZED = True |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
453 |
register_canonical_role('eid', eid_reference_role) |
6938
6c1a960735f5
add a rql directive to restructuredtext
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6275
diff
changeset
|
454 |
register_canonical_role('rql', rql_role) |
8852
59a29405688c
[ext/rest] add directive bookmark to rest (closes #2545595)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8711
diff
changeset
|
455 |
register_canonical_role('bookmark', bookmark_role) |
4118
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
456 |
directives.register_directive('winclude', winclude_directive) |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
457 |
if pygments_directive is not None: |
8a9a00a9405c
quick and dirty fix trying to avoid rest directive conflicts when using sphinx (which seems to import the code)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2680
diff
changeset
|
458 |
directives.register_directive('sourcecode', pygments_directive) |
9322
2dae5bf5ea68
[ReST] Implement a rql-table reST directive. Closes #3252856
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
8852
diff
changeset
|
459 |
directives.register_directive('rql-table', RQLTableDirective) |