From 3b0142cedcde39e4c2097ecd916a870a3ced5ec6 Mon Sep 17 00:00:00 2001 From: Vito Graffagnino Date: Tue, 8 Sep 2020 18:10:49 +0100 Subject: Added the relevent parts of the .config directory. Alss add ssh config --- .config/qutebrowser/scripts/asciidoc2html.py | 303 +++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100755 .config/qutebrowser/scripts/asciidoc2html.py (limited to '.config/qutebrowser/scripts/asciidoc2html.py') diff --git a/.config/qutebrowser/scripts/asciidoc2html.py b/.config/qutebrowser/scripts/asciidoc2html.py new file mode 100755 index 0000000..c4af174 --- /dev/null +++ b/.config/qutebrowser/scripts/asciidoc2html.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2014-2018 Florian Bruhin (The Compiler) + +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Generate the html documentation based on the asciidoc files.""" + +import re +import os +import os.path +import sys +import subprocess +import glob +import shutil +import tempfile +import argparse +import io + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) + +from scripts import utils + + +class AsciiDoc: + + """Abstraction of an asciidoc subprocess.""" + + FILES = ['faq', 'changelog', 'contributing', 'quickstart', 'userscripts'] + + def __init__(self, args): + self._cmd = None + self._args = args + self._homedir = None + self._themedir = None + self._tempdir = None + self._failed = False + + def prepare(self): + """Get the asciidoc command and create the homedir to use.""" + self._cmd = self._get_asciidoc_cmd() + self._homedir = tempfile.mkdtemp() + self._themedir = os.path.join( + self._homedir, '.asciidoc', 'themes', 'qute') + self._tempdir = os.path.join(self._homedir, 'tmp') + os.makedirs(self._tempdir) + os.makedirs(self._themedir) + + def cleanup(self): + """Clean up the temporary home directory for asciidoc.""" + if self._homedir is not None and not self._failed: + shutil.rmtree(self._homedir) + + def build(self): + """Build either the website or the docs.""" + if self._args.website: + self._build_website() + else: + self._build_docs() + self._copy_images() + + def _build_docs(self): + """Render .asciidoc files to .html sites.""" + files = [('doc/{}.asciidoc'.format(f), + 'qutebrowser/html/doc/{}.html'.format(f)) + for f in self.FILES] + for src in glob.glob('doc/help/*.asciidoc'): + name, _ext = os.path.splitext(os.path.basename(src)) + dst = 'qutebrowser/html/doc/{}.html'.format(name) + files.append((src, dst)) + + # patch image links to use local copy + replacements = [ + ("https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png", + "qute://help/img/cheatsheet-big.png"), + ("https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-small.png", + "qute://help/img/cheatsheet-small.png") + ] + asciidoc_args = ['-a', 'source-highlighter=pygments'] + + for src, dst in files: + src_basename = os.path.basename(src) + modified_src = os.path.join(self._tempdir, src_basename) + with open(modified_src, 'w', encoding='utf-8') as modified_f, \ + open(src, 'r', encoding='utf-8') as f: + for line in f: + for orig, repl in replacements: + line = line.replace(orig, repl) + modified_f.write(line) + self.call(modified_src, dst, *asciidoc_args) + + def _copy_images(self): + """Copy image files to qutebrowser/html/doc.""" + print("Copying files...") + dst_path = os.path.join('qutebrowser', 'html', 'doc', 'img') + try: + os.mkdir(dst_path) + except FileExistsError: + pass + for filename in ['cheatsheet-big.png', 'cheatsheet-small.png']: + src = os.path.join('doc', 'img', filename) + dst = os.path.join(dst_path, filename) + shutil.copy(src, dst) + + def _build_website_file(self, root, filename): + """Build a single website file.""" + src = os.path.join(root, filename) + src_basename = os.path.basename(src) + parts = [self._args.website[0]] + dirname = os.path.dirname(src) + if dirname: + parts.append(os.path.relpath(os.path.dirname(src))) + parts.append( + os.extsep.join((os.path.splitext(src_basename)[0], + 'html'))) + dst = os.path.join(*parts) + os.makedirs(os.path.dirname(dst), exist_ok=True) + + modified_src = os.path.join(self._tempdir, src_basename) + shutil.copy('www/header.asciidoc', modified_src) + + outfp = io.StringIO() + + with open(modified_src, 'r', encoding='utf-8') as header_file: + header = header_file.read() + header += "\n\n" + + with open(src, 'r', encoding='utf-8') as infp: + outfp.write("\n\n") + hidden = False + found_title = False + title = "" + last_line = "" + + for line in infp: + line = line.rstrip() + if line == '// QUTE_WEB_HIDE': + assert not hidden + hidden = True + elif line == '// QUTE_WEB_HIDE_END': + assert hidden + hidden = False + elif line == "The Compiler ": + continue + elif re.fullmatch(r':\w+:.*', line): + # asciidoc field + continue + + if not found_title: + if re.fullmatch(r'=+', line): + line = line.replace('=', '-') + found_title = True + title = last_line + " | qutebrowser\n" + title += "=" * (len(title) - 1) + elif re.fullmatch(r'= .+', line): + line = '==' + line[1:] + found_title = True + title = last_line + " | qutebrowser\n" + title += "=" * (len(title) - 1) + + if not hidden: + outfp.write(line.replace(".asciidoc[", ".html[") + '\n') + last_line = line + + current_lines = outfp.getvalue() + outfp.close() + + with open(modified_src, 'w+', encoding='utf-8') as final_version: + final_version.write(title + "\n\n" + header + current_lines) + + asciidoc_args = ['--theme=qute', '-a toc', '-a toc-placement=manual', + '-a', 'source-highlighter=pygments'] + self.call(modified_src, dst, *asciidoc_args) + + def _build_website(self): + """Prepare and build the website.""" + theme_file = os.path.abspath(os.path.join('www', 'qute.css')) + shutil.copy(theme_file, self._themedir) + + outdir = self._args.website[0] + + for root, _dirs, files in os.walk(os.getcwd()): + for filename in files: + basename, ext = os.path.splitext(filename) + if (ext != '.asciidoc' or + basename in ['header', 'OpenSans-License']): + continue + self._build_website_file(root, filename) + + copy = {'icons': 'icons', 'doc/img': 'doc/img', 'www/media': 'media/'} + + for src, dest in copy.items(): + full_dest = os.path.join(outdir, dest) + try: + shutil.rmtree(full_dest) + except FileNotFoundError: + pass + shutil.copytree(src, full_dest) + + for dst, link_name in [ + ('README.html', 'index.html'), + (os.path.join('doc', 'quickstart.html'), 'quickstart.html')]: + try: + os.symlink(dst, os.path.join(outdir, link_name)) + except FileExistsError: + pass + + def _get_asciidoc_cmd(self): + """Try to find out what commandline to use to invoke asciidoc.""" + if self._args.asciidoc is not None: + return self._args.asciidoc + + try: + subprocess.run(['asciidoc'], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + except OSError: + pass + else: + return ['asciidoc'] + + try: + subprocess.run(['asciidoc.py'], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + except OSError: + pass + else: + return ['asciidoc.py'] + + raise FileNotFoundError + + def call(self, src, dst, *args): + """Call asciidoc for the given files. + + Args: + src: The source .asciidoc file. + dst: The destination .html file, or None to auto-guess. + *args: Additional arguments passed to asciidoc. + """ + print("Calling asciidoc for {}...".format(os.path.basename(src))) + cmdline = self._cmd[:] + if dst is not None: + cmdline += ['--out-file', dst] + cmdline += args + cmdline.append(src) + try: + env = os.environ.copy() + env['HOME'] = self._homedir + subprocess.run(cmdline, check=True, env=env) + except (subprocess.CalledProcessError, OSError) as e: + self._failed = True + utils.print_col(str(e), 'red') + print("Keeping modified sources in {}.".format(self._homedir)) + sys.exit(1) + + +def main(colors=False): + """Generate html files for the online documentation.""" + utils.change_cwd() + utils.use_color = colors + parser = argparse.ArgumentParser() + parser.add_argument('--website', help="Build website into a given " + "directory.", nargs=1) + parser.add_argument('--asciidoc', help="Full path to python and " + "asciidoc.py. If not given, it's searched in PATH.", + nargs=2, required=False, + metavar=('PYTHON', 'ASCIIDOC')) + args = parser.parse_args() + try: + os.mkdir('qutebrowser/html/doc') + except FileExistsError: + pass + + asciidoc = AsciiDoc(args) + try: + asciidoc.prepare() + except FileNotFoundError: + utils.print_col("Could not find asciidoc! Please install it, or use " + "the --asciidoc argument to point this script to the " + "correct python/asciidoc.py location!", 'red') + sys.exit(1) + + try: + asciidoc.build() + finally: + asciidoc.cleanup() + + +if __name__ == '__main__': + main(colors=True) -- cgit v1.2.3