Robot Framework Integrated Development Environment (RIDE)
htmlwriter.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import re
17 try:
18  from urllib import quote
19 except ImportError:
20  from urllib.parse import quote
21 
22 from robotide.lib.robot.errors import DataError
23 from robotide.lib.robot.htmldata import HtmlFileWriter, ModelWriter, JsonWriter, LIBDOC
24 from robotide.lib.robot.utils import get_timestamp, html_escape, html_format, NormalizedDict
25 from robotide.lib.robot.utils.htmlformatters import HeaderFormatter
26 
27 
29 
30  def write(self, libdoc, output):
31  model_writer = LibdocModelWriter(output, libdoc)
32  HtmlFileWriter(output, model_writer).write(LIBDOC)
33 
34 
36 
37  def __init__(self, output, libdoc):
38  self._output_output = output
39  formatter = DocFormatter(libdoc.keywords, libdoc.doc, libdoc.doc_format)
40  self._libdoc_libdoc = JsonConverter(formatter).convert(libdoc)
41 
42  def write(self, line):
43  self._output_output.write('<script type="text/javascript">\n')
44  self.write_datawrite_data()
45  self._output_output.write('</script>\n')
46 
47  def write_data(self):
48  JsonWriter(self._output_output).write_json('libdoc = ', self._libdoc_libdoc)
49 
50 
51 class JsonConverter():
52 
53  def __init__(self, doc_formatter):
54  self._doc_formatter_doc_formatter = doc_formatter
55 
56  def convert(self, libdoc):
57  return {
58  'name': libdoc.name,
59  'doc': self._doc_formatter_doc_formatter.html(libdoc.doc, intro=True),
60  'version': libdoc.version,
61  'named_args': libdoc.named_args,
62  'scope': libdoc.scope,
63  'generated': get_timestamp(daysep='-', millissep=None),
64  'inits': self._get_keywords_get_keywords(libdoc.inits),
65  'keywords': self._get_keywords_get_keywords(libdoc.keywords),
66  'all_tags': tuple(libdoc.all_tags),
67  'contains_tags': bool(libdoc.all_tags)
68  }
69 
70  def _get_keywords(self, keywords):
71  return [self._convert_keyword_convert_keyword(kw) for kw in keywords]
72 
73  def _convert_keyword(self, kw):
74  return {
75  'name': kw.name,
76  'args': kw.args,
77  'doc': self._doc_formatter_doc_formatter.html(kw.doc),
78  'shortdoc': ' '.join(kw.shortdoc.splitlines()),
79  'tags': tuple(kw.tags),
80  'matched': True
81  }
82 
83 
84 class DocFormatter():
85 
88  _header_regexp = re.compile(r'<h([234])>(.+?)</h\1>')
89 
92  _name_regexp = re.compile('`(.+?)`')
93 
94  def __init__(self, keywords, introduction, doc_format='ROBOT'):
95  self._doc_to_html_doc_to_html = DocToHtml(doc_format)
96  self._targets_targets = self._get_targets_get_targets(keywords, introduction,
97  robot_format=doc_format == 'ROBOT')
98 
99  def _get_targets(self, keywords, introduction, robot_format):
100  targets = {
101  'introduction': 'Introduction',
102  'library introduction': 'Introduction',
103  'importing': 'Importing',
104  'library importing': 'Importing',
105  'shortcuts': 'Shortcuts',
106  'keywords': 'Keywords'
107  }
108  for kw in keywords:
109  targets[kw.name] = kw.name
110  if robot_format:
111  for header in self._yield_header_targets_yield_header_targets(introduction):
112  targets[header] = header
113  return self._escape_and_encode_targets_escape_and_encode_targets(targets)
114 
115  def _yield_header_targets(self, introduction):
116  headers = HeaderFormatter()
117  for line in introduction.splitlines():
118  match = headers.match(line)
119  if match:
120  yield match.group(2)
121 
122  def _escape_and_encode_targets(self, targets):
123  return NormalizedDict((html_escape(key), self._encode_uri_component_encode_uri_component(value))
124  for key, value in targets.items())
125 
126  def _encode_uri_component(self, value):
127  # Emulates encodeURIComponent javascript function
128  return quote(value.encode('UTF-8'), safe="-_.!~*'()")
129 
130  def html(self, doc, intro=False):
131  doc = self._doc_to_html_doc_to_html(doc)
132  if intro:
133  doc = self._header_regexp_header_regexp.sub(r'<h\1 id="\2">\2</h\1>', doc)
134  return self._name_regexp_name_regexp.sub(self._link_keywords_link_keywords, doc)
135 
136  def _link_keywords(self, match):
137  name = match.group(1)
138  if name in self._targets_targets:
139  return '<a href="#%s" class="name">%s</a>' % (self._targets_targets[name], name)
140  return '<span class="name">%s</span>' % name
141 
142 
143 class DocToHtml():
144 
145  def __init__(self, doc_format):
146  self._formatter_formatter = self._get_formatter_get_formatter(doc_format)
147 
148  def _get_formatter(self, doc_format):
149  try:
150  return {'ROBOT': html_format,
151  'TEXT': self._format_text_format_text,
152  'HTML': self._format_html_format_html,
153  'REST': self._format_rest_format_rest}[doc_format]
154  except KeyError:
155  raise DataError("Invalid documentation format '%s'." % doc_format)
156 
157  def _format_text(self, doc):
158  return '<p style="white-space: pre-wrap">%s</p>' % html_escape(doc)
159 
160  def _format_html(self, doc):
161  return '<div style="margin: 0">%s</div>' % doc
162 
163  def _format_rest(self, doc):
164  try:
165  from docutils.core import publish_parts
166  except ImportError:
167  raise DataError("reST format requires 'docutils' module to be installed.")
168  parts = publish_parts(doc, writer_name='html',
169  settings_overrides={'syntax_highlight': 'short'})
170  return self._format_html_format_html(parts['html_body'])
171 
172  def __call__(self, doc):
173  return self._formatter_formatter(doc)
Used when variable does not exist.
Definition: errors.py:67
def _get_targets(self, keywords, introduction, robot_format)
Definition: htmlwriter.py:99
def __init__(self, keywords, introduction, doc_format='ROBOT')
Definition: htmlwriter.py:94
def html_escape(text, linkify=True)
Definition: markuputils.py:40
def get_timestamp(daysep='', daytimesep=' ', timesep=':', millissep='.')
Definition: robottime.py:296