Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / server2 / document_renderer.py
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.
4
5 import logging
6 import os
7 from document_parser import ParseDocument
8 from third_party.json_schema_compiler.model import UnixName
9
10
11 class DocumentRenderer(object):
12   '''Performs document-level rendering such as the title, references,
13   and table of contents: pulling that data out of the document, then
14   replacing the $(title), $(ref:...) and $(table_of_contents) tokens with them.
15
16   This can be thought of as a parallel to TemplateRenderer; while
17   TemplateRenderer is responsible for interpreting templates and rendering files
18   within the template engine, DocumentRenderer is responsible for interpreting
19   higher-level document concepts like the title and TOC, then performing string
20   replacement for them. The syntax for this replacement is $(...) where ... is
21   the concept. Currently title and table_of_contents are supported.
22   '''
23
24   def __init__(self, table_of_contents_renderer, ref_resolver):
25     self._table_of_contents_renderer = table_of_contents_renderer
26     self._ref_resolver = ref_resolver
27
28   def _RenderLinks(self, document, path):
29     ''' Replaces all $(ref:...) references in |document| with html links
30     '''
31     START_REF = '$(ref:'
32     END_REF = ')'
33     MAX_REF_LENGTH = 100
34
35     new_document = []
36
37     # Keeps track of position within |document|
38     cursor_index = 0
39     start_ref_index = document.find(START_REF)
40
41     while start_ref_index != -1:
42       end_ref_index = document.find(END_REF, start_ref_index)
43
44       if (end_ref_index == -1 or
45           end_ref_index - start_ref_index > MAX_REF_LENGTH):
46         end_ref_index = document.find(' ', start_ref_index)
47         logging.error('%s:%s has no terminating ) at line %s' % (
48             path,
49             document[start_ref_index:end_ref_index],
50             document.count('\n', 0, end_ref_index)))
51
52         new_document.append(document[cursor_index:end_ref_index + 1])
53       else:
54         ref = document[start_ref_index:end_ref_index]
55         ref_parts = ref[len(START_REF):].split(' ', 1)
56
57         # Guess the api name from the html name, replacing '_' with '.' (e.g.
58         # if the page is app_window.html, guess the api name is app.window)
59         api_name = os.path.splitext(os.path.basename(path))[0].replace('_', '.')
60         title = ref_parts[0] if len(ref_parts) == 1 else ref_parts[1]
61
62         ref_dict = self._ref_resolver.SafeGetLink(ref_parts[0],
63                                                   namespace=api_name,
64                                                   title=title)
65
66         new_document.append(document[cursor_index:start_ref_index])
67         new_document.append('<a href=%s>%s</a>' % (ref_dict['href'],
68                                                    ref_dict['text']))
69
70       cursor_index = end_ref_index + 1
71       start_ref_index = document.find(START_REF, cursor_index)
72
73     new_document.append(document[cursor_index:])
74
75     return ''.join(new_document)
76
77   def Render(self, document, path, render_title=False):
78     # Render links first so that parsing and later replacements aren't
79     # affected by $(ref...) substitutions
80     document = self._RenderLinks(document, path)
81
82     parsed_document = ParseDocument(document, expect_title=render_title)
83     toc_text, toc_warnings = self._table_of_contents_renderer.Render(
84         parsed_document.sections)
85
86     # Only 1 title and 1 table of contents substitution allowed; in the common
87     # case, save necessarily running over the entire file.
88     if parsed_document.title:
89       document = document.replace('$(title)', parsed_document.title, 1)
90     return (document.replace('$(table_of_contents)', toc_text, 1),
91             parsed_document.warnings + toc_warnings)