cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / document_renderer.py
blob2e3556f850423115501bd23fa1b5e18fab1d5ee8
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import logging
6 import os
7 from document_parser import ParseDocument
8 from platform_util import ExtractPlatformFromURL
9 from third_party.json_schema_compiler.model import UnixName
12 class DocumentRenderer(object):
13 '''Performs document-level rendering such as the title, references,
14 and table of contents: pulling that data out of the document, then
15 replacing the $(title), $(ref:...) and $(table_of_contents) tokens with them.
17 This can be thought of as a parallel to TemplateRenderer; while
18 TemplateRenderer is responsible for interpreting templates and rendering files
19 within the template engine, DocumentRenderer is responsible for interpreting
20 higher-level document concepts like the title and TOC, then performing string
21 replacement for them. The syntax for this replacement is $(...) where ... is
22 the concept. Currently title and table_of_contents are supported.
23 '''
25 def __init__(self, table_of_contents_renderer, platform_bundle):
26 self._table_of_contents_renderer = table_of_contents_renderer
27 self._platform_bundle = platform_bundle
29 def _RenderLinks(self, document, path):
30 ''' Replaces all $(ref:...) references in |document| with html links.
32 References have two forms:
34 $(ref:api.node) - Replaces the reference with a link to node on the
35 API page. The title is set to the name of the node.
37 $(ref:api.node Title) - Same as the previous form, but title is set
38 to "Title".
39 '''
40 START_REF = '$(ref:'
41 END_REF = ')'
42 MAX_REF_LENGTH = 256
44 new_document = []
46 # Keeps track of position within |document|
47 cursor_index = 0
48 start_ref_index = document.find(START_REF)
50 while start_ref_index != -1:
51 end_ref_index = document.find(END_REF, start_ref_index)
53 if (end_ref_index == -1 or
54 end_ref_index - start_ref_index > MAX_REF_LENGTH):
55 end_ref_index = document.find(' ', start_ref_index)
56 logging.error('%s:%s has no terminating ) at line %s' % (
57 path,
58 document[start_ref_index:end_ref_index],
59 document.count('\n', 0, end_ref_index)))
61 new_document.append(document[cursor_index:end_ref_index + 1])
62 else:
63 ref = document[start_ref_index:end_ref_index]
64 ref_parts = ref[len(START_REF):].split(None, 1)
66 # Guess the api name from the html name, replacing '_' with '.' (e.g.
67 # if the page is app_window.html, guess the api name is app.window)
68 api_name = os.path.splitext(os.path.basename(path))[0].replace('_', '.')
69 title = ref_parts[0] if len(ref_parts) == 1 else ref_parts[1]
71 platform = ExtractPlatformFromURL(path)
72 if platform is None:
73 logging.error('Cannot resolve reference without a platform.')
74 continue
75 ref_dict = self._platform_bundle.GetReferenceResolver(
76 platform).SafeGetLink(ref_parts[0],
77 namespace=api_name,
78 title=title,
79 path=path)
81 new_document.append(document[cursor_index:start_ref_index])
82 new_document.append('<a href=%s/%s>%s</a>' % (
83 self._platform_bundle._base_path + platform,
84 ref_dict['href'],
85 ref_dict['text']))
87 cursor_index = end_ref_index + 1
88 start_ref_index = document.find(START_REF, cursor_index)
90 new_document.append(document[cursor_index:])
92 return ''.join(new_document)
94 def Render(self, document, path, render_title=False):
95 ''' |document|: document to be rendered.
96 |path|: request path to the document.
97 |render_title|: boolean representing whether or not to render a title.
98 '''
99 # Render links first so that parsing and later replacements aren't
100 # affected by $(ref...) substitutions
101 document = self._RenderLinks(document, path)
103 parsed_document = ParseDocument(document, expect_title=render_title)
104 toc_text, toc_warnings = self._table_of_contents_renderer.Render(
105 parsed_document.sections)
107 # Only 1 title and 1 table of contents substitution allowed; in the common
108 # case, save necessarily running over the entire file.
109 if parsed_document.title:
110 document = document.replace('$(title)', parsed_document.title, 1)
111 return (document.replace('$(table_of_contents)', toc_text, 1),
112 parsed_document.warnings + toc_warnings)