#!python ## Copyright (c) 2021 Thakee Nathees ## Licensed under: MIT License from markdown import markdown from os.path import join import os, sys, shutil ## TODO: This is a quick and dirty script to generate html ## from markdown. Refactor this file in the future. ## Usage: ## to generate pages : python generate.py ## to clean pages : python generate.py (-c, --clean) TEMPLATE_PATH = 'static/template.html' ROOT_URL = 'http://localhost:8000/' ROOT_URL = 'https://thakeenathees.github.io/pocketlang/' ## Home page should be in the SOURCE_DIR. HOME_PAGE = 'home.md' TRY_PAGE = 'try it now.html' SOURCE_DIR = 'pages/' TARGET_DIR = 'build/' STATIC_DIR = 'static/' ## Additional source files of wasm try online page. WASM_SOURCE_FILES = '''\ ''' ## Navigation pages in order. Should match the path names. PAGES = [ ('Getting Started', [ TRY_PAGE, 'build from source.md', 'contributing.md', ]), ('Language API', [ 'variables.md', 'functions.md', ]), ] def new_context(): return { '{{ TITLE }}' : '', '{{ NAVIGAION }}' : '', '{{ CONTENT }}' : '', '{{ HOME_URL }}' : '', '{{ STATIC_DIR }}' : '', } def main(): ## Remove generated files and create empty target dir with static files. if os.path.exists(TARGET_DIR): remove_ignore = ( '.git', ) for _dir in os.listdir(TARGET_DIR): if _dir in remove_ignore: continue if os.path.isdir(join(TARGET_DIR,_dir)): shutil.rmtree(join(TARGET_DIR, _dir)) else: os.remove(join(TARGET_DIR, _dir)) shutil.copytree(STATIC_DIR, join(TARGET_DIR, STATIC_DIR)) open(join(TARGET_DIR, '.nojekyll'), 'w').close() ## Initialize the template and navigation. template = '' navigation = generate_navigation() with open(TEMPLATE_PATH, 'r') as f: template = f.read() ## Generate the home page. index_html = join(TARGET_DIR, 'index.html') ctx = generate_page_context(join(SOURCE_DIR, HOME_PAGE), index_html, navigation) write_page(ctx, template, index_html) for entry in PAGES: _dir = entry[0] for file in entry[1]: ext = get_validated_ext(file) path = join(SOURCE_DIR, _dir, file) dst = '' if ext == '.md' : dst = join(TARGET_DIR, _dir, file.replace('.md', '.html')) else: dst = join(TARGET_DIR, _dir, file) ctx = generate_page_context(path, dst, navigation) _template = template if file == TRY_PAGE: _template = template.replace('{{ WASM_SOURCE_FILES }}', WASM_SOURCE_FILES) write_page(ctx, _template, dst) pass def generate_navigation(): navigation = '' for entry in PAGES: _dir = entry[0] navigation += '\n' return navigation def generate_page_context(src, dst, navigation): title = path_to_title(src) static_dir = relative_static_dir(dst) content = path_to_content(src) ctx = new_context() ctx[ '{{ TITLE }}' ] = title ctx[ '{{ NAVIGAION }}' ] = navigation ctx[ '{{ CONTENT }}' ] = content ctx[ '{{ HOME_URL }}' ] = ROOT_URL + 'index.html' ctx[ '{{ STATIC_DIR }}'] = static_dir return ctx; def get_validated_ext(path) : ext = '' if path.endswith('.md'): ext = '.md' elif path.endswith('.html'): ext = '.html' else: raise Exception('Expected .md / .html file.') return ext ## Get the title from the src path. def path_to_title(path): ext = get_validated_ext(path) title = os.path.basename(path).replace(ext, '').title() title += ' - PocketLang' return title ## Return the static dir relative path. def relative_static_dir(dst): _dir = os.path.dirname(dst) static_dir = os.path.relpath(join(TARGET_DIR, STATIC_DIR), _dir) static_dir = static_dir.replace('\\', '/') if static_dir[-1] != '/': static_dir += '/' return static_dir ## Generate html content from the markdown source path. ## If the path is an .html file return it's content. def path_to_content(src): text = '' with open(src, 'r') as home_md: text = home_md.read() ## If html file we're done. if get_validated_ext(src) == '.html': return text content = markdown(text, extensions=['codehilite', 'fenced_code']) ## FIXME: I should create a pygment lexer. ## A dirty way to inject our keyword (to ruby's). addnl_keywords = [ 'null', 'from', 'import', 'as', 'func', 'native', 'elif', 'continue' ] not_keyword = [ 'alias', 'begin', 'case', 'class', 'next', 'nil', 'redo', 'rescue', 'retry', 'elsif', 'ensure', 'undef', 'unless', 'super', 'until', 'when', 'defined', ] for kw in addnl_keywords: content = content.replace('%s' % kw, '%s' % kw) for nk in not_keyword: content = content.replace('%s' % nk, '%s' % nk) return content def write_page(ctx, template, dst): _dir = os.path.dirname(dst) if _dir not in ('.', './', '') and not os.path.exists(_dir): os.makedirs(os.path.dirname(dst)) page = template for key, value in ctx.items(): page = page.replace(key, value) page = page.replace('{{ WASM_SOURCE_FILES }}', '') with open(dst, 'w') as f: f.write(page) if __name__ == '__main__': main() print('Static pages generated.')