'''Generate one page API document from rustdoc. This script parses HTML files generated by rustoc and generates a single page API document. ''' from html.parser import HTMLParser pages = ['index.html', 'struct.BlazeSymbolizer.html', 'struct.SymbolizedResult.html', 'enum.SymbolSrcCfg.html', 'enum.SymbolizerFeature.html', 'fn.blazesym_new.html', 'fn.blazesym_free.html', 'fn.blazesym_symbolize.html', 'fn.blazesym_result_free.html', 'struct.blazesym.html', 'struct.sym_src_cfg.html', 'enum.blazesym_src_type.html', 'union.ssc_params.html', 'struct.ssc_elf.html', 'struct.ssc_kernel.html', 'struct.ssc_process.html', 'struct.blazesym_result.html', 'struct.blazesym_entry.html', 'struct.blazesym_csym.html', ] def replace_text(src, replace, start, stop): lines = src.split('\n') if start[0] == stop[0]: lineno = start[0] lines[lineno] = lines[lineno][:start[1]] + replace + lines[lineno][stop[1]:] else: lines[start[0]] = lines[start[0]][:start[1]] lines[stop[0]] = lines[stop[0]][stop[1]:] lines[start[0] + 1: stop[0]] = [replace] pass return '\n'.join(lines) class MyParser(HTMLParser): def get_doc_range(self, start, end): lines = self.raw_data.split('\n') lines = lines[start[0] - 1: end[0]] lines[-1] = lines[-1][:end[1]] lines[0] = lines[0][start[1]:] content = '\n'.join(lines) if hasattr(self, 'replaces'): for replace, rstart, rstop in reversed(self.replaces): rstart = list(rstart) rstop = list(rstop) rstart[0] -= start[0] rstop[0] -= start[0] if rstart[0] == 0: rstart[1] -= start[1] pass if rstop[0] == 0: rstop[1] -= start[1] pass content = replace_text(content, replace, rstart, rstop) pass pass return content def get_pos_end_tag(self): pos = self.getpos() lines = self.raw_data.split('\n') line = lines[pos[0] - 1] col = line.find('>', pos[1]) + 1 return (pos[0], col) def handle_starttag(self, tag, attrs): attrs = dict(attrs) if tag == 'body': self.doc_type = attrs['class'].split()[-1] elif tag == 'section' and 'id' in attrs and attrs['id'] == 'main-content': if self.doc_type == 'crate': self.start_pos = self.getpos() elif self.doc_type in ('struct', 'enum', 'union'): if not hasattr(self, 'start_pos'): self.start_pos = self.getpos() pass pass elif self.doc_type == 'fn': if not hasattr(self, 'start_pos'): self.start_pos = self.getpos() pass pass pass elif 'class' in attrs and 'example-wrap' in attrs['class'].split(): self.replacing = '  ......<<EXAMPLE>>......
' self.replace_depth = 0 self.replace_start = self.getpos(); elif 'class' in attrs and 'item-decl' in attrs['class'].split(): self.replacing = '  ......<<DECLARATION>>......
' self.replace_depth = 0 self.replace_start = self.getpos() elif hasattr(self, 'replace_depth'): self.replace_depth += 1 elif hasattr(self, 'depth'): self.depth += 1 pass elif hasattr(self, 'start_pos'): if self.doc_type in ('struct', 'enum', 'union'): if 'id' in attrs and attrs['id'].endswith('implementations'): print('%s\n' % self.get_doc_range(self.start_pos, self.getpos())) self.doc_type = '' pass elif self.doc_type == 'fn' and not hasattr(self, 'depth'): self.depth = 0 pass elif self.doc_type == 'crate' and 'class' in attrs and attrs['class'].endswith('top-doc'): self.depth = 0 pass pass pass def handle_endtag(self, tag): if hasattr(self, 'replace_depth'): if self.replace_depth > 0: self.replace_depth -= 1 else: del self.replace_depth if not hasattr(self, 'replaces'): self.replaces = [] pass self.replaces.append((self.replacing, self.replace_start, self.get_pos_end_tag())) pass elif hasattr(self, 'depth'): if self.depth > 0: self.depth -= 1 pass else: del self.depth if self.doc_type == 'crate': content = self.get_doc_range(self.start_pos, self.get_pos_end_tag()) print('%s\n' % content) pass elif self.doc_type == 'fn': print('%s\n' % self.get_doc_range(self.start_pos, self.get_pos_end_tag())) self.doc_type = '' pass pass pass pass pass print('') print('') print('') print('') print('') print(''' ''') print('') print('') for page in pages: print('' % page) p = MyParser() fo = open('blazesym/' + page, 'r') data = fo.read() p.raw_data = data p.feed(data) print('') pass print('') print('')