#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2021 Oscar Benedito # License: Affero General Public License version 3 or later # Convert text/gemini files to HTML. # # Usage: # # ./gemini-to-html.py [file.gmi] # # If no file is specified, standard input is used. import sys import re css = """ body { margin: 1em auto; max-width: 700px; line-height: 1.5; font-family: sans-serif; padding: 0 1em; } a { color: #02d; } a:hover { color: #309; } .a:before { content: "⇒ "; color: #888; } pre { background-color: #eee; padding: 1rem; overflow-x: auto; } blockquote { padding: 0 0 0 1.2rem; border-left: 3px solid; } """ if len(sys.argv) == 1: data = sys.stdin.readlines() elif len(sys.argv) == 2: try: with open(sys.argv[1], 'r') as f: data = f.readlines() except IOError: sys.stderr.write('Error reading file {}.\n'.format(sys.argv[1])) sys.exit(1) else: sys.stderr.write('Usage: {} file.gmi.\n'.format(sys.argv[0])) sys.exit(1) print('') print('') print('') print('') print('') if data[0][:1] == '#' and data[0][:2] != '##': print('{}'.format(data[0][1:].strip())) if css is not None: print(''.format(css)) print('') print('') state = '' for line in data: line = line[:-1] if state == 'ul': if line[:2] == '* ': print('
  • {}
  • '.format(line[2:])) continue else: print('') state = '' elif state[:3] == 'pre': if line[:3] == '```': print('') state = '' continue else: if state == 'pre-first': sys.stdout.write('{}'.format(line)) state = 'pre' else: sys.stdout.write('\n{}'.format(line)) continue if line[:2] == '=>': # re.sub m = re.match('^=>[ \t]*(\S+)(?:[ \t]+(.+))?', line) if m is None: sys.stderr.write('Incorrect syntax on line of type link:\n' ' {}'.format(line)) print('

    {}

    '.format(line)) continue text = m.group(2) if m.group(2) is not None else m.group(1) print('

    {}

    '.format(m.group(1), text)) elif line[:3] == '```': if len(line) > 3: sys.stdout.write('
    '.format(line[3:]))
            else:
                sys.stdout.write('
    ')
            state = 'pre-first'
        elif line[:3] == '###':
            print('

    {}

    '.format(line[3:])) elif line[:2] == '##': print('

    {}

    '.format(line[2:])) elif line[:1] == '#': print('

    {}

    '.format(line[1:])) elif line[:2] == '* ': print('
      \n
    • {}
    • '.format(line[2:])) state = 'ul' elif line[:1] == '>': print('
      {}
      '.format(line[1:])) else: print('

      {}

      '.format(line)) print('\n')