16 <div style="background-color: #e8ffe8; padding: 2; border: #c0ffc0 1px solid;">
19 This page is for %(package_name)s-%(package_version)s (%(branch_str)s). <br>
21 <address><font size="-1">
22 Report errors to <a href="%(mail_address_url)s">%(mail_address)s</a>.</font></address>
27 header_tag = '<!-- header_tag -->'
28 footer_tag = '<!-- footer_tag -->'
33 language_available = _ ("Other languages: %s.") % "%(language_menu)s"
34 browser_language = _ ("Using <A HREF='%s'>automatic language selection</A>.") \
35 % "/web/about/browser-language"
37 LANGUAGES_TEMPLATE = '''\
39 %(language_available)s
46 html_re = re.compile ('(.*?)(?:[.]([^/.]*))?[.]html$')
48 def build_pages_dict (filelist):
49 """Build dictionnary of available translations of each page"""
55 if len (g) <= 1 or g[1] == None:
59 if not g[0] in pages_dict.keys():
60 pages_dict[g[0]] = [e]
62 pages_dict[g[0]].append (e)
66 def do_file (prefix, lang_ext, target, header, footer, pages_dict, out_root, name_filter,
67 package_name, package_version, branch_str, mail_address_url, mail_address):
68 file_name = langdefs.lang_file_name (prefix, lang_ext, '.html')
69 in_f = open (file_name)
73 s = re.sub ('%', '%%', s)
76 if re.search (header_tag, s) == None:
77 body = '<BODY BGCOLOR=WHITE TEXT=BLACK>'
78 s = re.sub ('(?i)<body>', body, s)
79 if re.search ('(?i)<BODY', s):
80 s = re.sub ('(?i)<body[^>]*>', body + header, s, 1)
81 elif re.search ('(?i)<html', s):
82 s = re.sub ('(?i)<html>', '<HTML>' + header, s, 1)
86 s = header_tag + '\n' + s
88 if re.search ('(?i)<!DOCTYPE', s) == None:
89 doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n'
92 # remove info's annoying's indication of referencing external document
93 s = re.sub (' \((lilypond|lilypond-internals|music-glossary)\)</a>', '</a>', s)
96 # maybe find first node?
97 fallback_web_title = '-- --'
98 m = re.match ('.*?<title>(.*?)</title>', s, re.DOTALL)
100 fallback_web_title = m.group (1)
101 s = re.sub ('@WEB-TITLE@', fallback_web_title, s)
105 if re.search (footer_tag, s) == None:
106 if re.search ('(?i)</body', s):
107 s = re.sub ('(?i)</body>', footer_tag + footer + '\n' + '</BODY>', s, 1)
108 elif re.search ('(?i)</html', s):
109 s = re.sub ('(?i)</html>', footer_tag + footer + '\n' + '</HTML>', s, 1)
111 s += footer_tag + footer + '\n'
113 # Find available translations of this page.
116 for l in langdefs.LANGUAGES:
119 if e in pages_dict[prefix]:
121 elif lang_ext == '' and l.enabled: # English version of missing translated pages will be written
124 if target == 'online':
125 # Strip .html, .png suffix for auto language selection (content
126 # negotiation). The menu must keep the full extension, so do
127 # this before adding the menu.
128 # Don't strip .html suffix for documentation index because of
129 # lilypond/ vs. lilypond.html conflict
130 if prefix == 'Documentation/out-www/index':
131 page_flavors[file_name] = s
133 page_flavors[file_name] = re.sub (
134 '''(href|src)=[\'"]([^/][.]*[^.:\'"]*)(.html|.png)(#[^"\']*|)[\'"]''',
136 elif target == 'offline':
138 page_flavors[file_name] = s
140 page_flavors[langdefs.lang_file_name (prefix, e, '.html')] = re.sub (
141 '''href=[\'"]([^/][.]*[^.:\'"]*)(.html)(#[^"\']*|)[\'"]''',
142 'href="\\1.' + e + '\\2\\3"', s)
144 page_flavors[file_name] = re.sub (
145 '''href=[\'"]([^/][.]*[^.:\'"]*)(.html)(#[^"\']*|)[\'"]''',
146 'href="\\1.' + lang_ext + '\\2\\3"', s)
148 # Add menu after stripping: must not have autoselection for language menu.
150 for lang in available:
151 lang_file = lang.file_name (os.path.basename (prefix), '.html')
152 if language_menu != '':
153 language_menu += ', '
154 language_menu += '<a href="%s">%s</a>' % (lang_file, lang.name)
158 languages = LANGUAGES_TEMPLATE % vars ()
160 # Put language menu before '</body>' and '</html>' tags
161 for k in page_flavors.keys():
162 if re.search ('(?i)</body', page_flavors[k]):
163 page_flavors[k] = re.sub ('(?i)</body>', languages + '</BODY>', page_flavors[k], 1)
164 elif re.search ('(?i)</html', page_flavors[k]):
165 page_flavors[k] = re.sub ('(?i)</html>', languages + '</HTML>', page_flavors[k], 1)
167 page_flavors[k] += languages
169 for e in [l.webext for l in langdefs.LANGUAGES]:
170 if not e in pages_dict[prefix]:
171 page_flavors[langdefs.lang_file_name (prefix, e, '.html')] = s
173 for k in page_flavors.keys():
174 page_flavors[k] = page_flavors[k] % vars ()
176 out_f = open (os.path.join (out_root, name_filter (k)), 'w')
177 out_f.write (page_flavors[k])
181 def add_html_footer (package_name = '',
182 package_version = '',
183 header = default_header,
184 footer = default_footer,
186 mail_address = '(address unknown)',
189 name_filter = lambda s: s):
190 """Add header, footer to a number of HTML files
193 package_name=NAME set package_name to NAME
194 package_version=VERSION set package version to VERSION
195 header=TEXT use TEXT as header
196 footer=TEXT use TEXT as footer
197 targets=offline|online set page processing depending on the target
198 offline is for reading HTML pages locally
199 online is for hosting the HTML pages on a website with content
201 mail_address set \"Report errors to\" link
202 pages_dict a dictionnary returned by build_pages_dict()
203 out_root a path prefix where to write HTML pages
204 name_filter a HTML file name filter
206 localtime = time.strftime ('%c %Z', time.localtime (time.time ()))
208 if re.search ("http://", mail_address):
209 mail_address_url = mail_address
211 mail_address_url= 'mailto:' + mail_address
213 versiontup = package_version.split ('.')
214 branch_str = 'stable-branch'
215 if int ( versiontup[1]) % 2:
216 branch_str = 'development-branch'
218 for page, ext_list in pages_dict.items ():
220 do_file (page, e, target, header, footer, pages_dict, out_root, name_filter,
221 package_name, package_version, branch_str, mail_address_url, mail_address)
222 # if the page is translated, a .en.html symlink is necessary for content negotiation
223 if target == 'online' and ext_list != ['']:
224 os.symlink (os.path.basename (page) + '.html', os.path.join (out_root, name_filter (page + '.en.html')))