[PYTHON] mkdocs: How HTML is generated

Document root

$ ls mkdocs.yml
mkdocs.yml

$ ipython

Load config

In [1]: from mkdocs.config import load_config
In [2]: conf = load_config()
In [4]: type(conf)
Out[4]: instance
Out[5]:
['__cmp__',
 '__contains__',
 '__delitem__',
 '__doc__',
 '__getitem__',
 '__hash__',
 '__init__',
 '__len__',
 '__module__',
 '__repr__',
 '__setitem__',
 '_post_validate',
 '_pre_validate',
 '_schema',
 '_schema_keys',
 '_validate',
 'clear',
 'copy',
 'data',
 'fromkeys',
 'get',
 'has_key',
 'items',
 'iteritems',
 'iterkeys',
 'itervalues',
 'keys',
 'load_dict',
 'load_file',
 'pop',
 'popitem',
 'set_defaults',
 'setdefault',
 'update',
 'user_configs',
 'validate',
 'values']
In [8]: type(conf['pages'])
Out[8]: list

In [9]: conf['use_directory_urls']
Out[9]: True

Create a document list

In [10]: from mkdocs import nav

In [11]: site_navigation = nav.SiteNavigation(conf['pages'], conf['use_directory_urls'])

In [12]: type(site_navigation)
Out[12]: mkdocs.nav.SiteNavigation

Jinja2 loader

In [14]: import jinja2
In [15]: loader = jinja2.FileSystemLoader(conf['theme_dir'] + [conf['mkdocs_templates'], ])

In [16]: type(loader)
Out[16]: jinja2.loaders.FileSystemLoader

Jinja2 environment

In [17]: env = jinja2.Environment(loader=loader)

In [18]: type(env)
Out[18]: jinja2.environment.Environment

Get Markdown page from navigation

In [20]: site_navigation.walk_pages()
Out[20]: <generator object walk_pages at 0x105c32eb0>

In [21]: _.next()
Out[21]: <mkdocs.nav.Page at 0x105abb710>

In [22]: page = _

Markdown path

In [24]: import os
In [25]: input_path = os.path.join(conf['docs_dir'], page.input_path)
In [27]: input_path
Out[27]: u'/Users/hide/Dropbox/\u30a2\u30d5\u309a\u30ea/scriptogram/index.md'

Load Markdown

In [29]: import io

In [30]: input_content = io.open(input_path, 'r', encoding='utf-8').read()

Convert Markdown to HTML

Settings such as expansion

In [31]: from mkdocs import utils
In [32]: from mkdocs.relative_path_ext import RelativePathExtension
In [33]: extensions = [RelativePathExtension(site_navigation, conf['strict'])] + conf['markdown_extensions']

In [34]: extensions
Out[34]:
[<mkdocs.relative_path_ext.RelativePathExtension at 0x105c3fdd0>,
 u'meta',
 u'toc',
 u'tables',
 u'fenced_code']

Markdwon -> HTML

In [35]: md = utils.convert_markdown(markdown_source=input_content, extensions=extensions,  extension_configs=conf['mdx_configs'])


In [37]: len(md)
Out[37]: 3

In [38]: [type(i) for i in md]
Out[38]: [unicode, mkdocs.toc.TableOfContents, dict]

Decompose into HTML, TOC, metadata

In [41]: html_content, table_of_contents, meta = md

context

Global context

In [43]: from mkdocs.commands.build import get_global_context
In [44]: context = get_global_context(site_navigation, conf)
In [46]: type(context)
Out[46]: dict

Page context

In [47]: from mkdocs.commands.build import get_page_context
In [49]: page_context = get_page_context(page, html_content, table_of_contents, meta, conf)
In [50]: type(page_context)
Out[50]: dict


In [51]: context.update(page_context)

rendering

HTML page using template

In [53]: template = env.get_template('base.html')
In [54]: output_content = template.render(context)

File output

In [57]: output_path = os.path.join(conf['site_dir'], page.output_path)

In [58]: output_path
Out[58]: u'/Users/hide/Dropbox/\u30a2\u30d5\u309a\u30ea/build/index.html'

In [59]: utils.write_file(output_content.encode('utf-8'), output_path)

Recommended Posts

mkdocs: How HTML is generated
How Python __dict__ is used
Flask reuse How to write html
LowMemoryKiller ~ How Android Activity is destroyed ~