# Path: simiki/jinja_exts.py
# def rfc3339(dt_obj):
# 
# Path: simiki/utils.py
# def import_string(import_name, silent=False):
#     """Imports an object based on a string.  This is useful if you want to
#     use import paths as endpoints or something similar.  An import path can
#     be specified either in dotted notation (``xml.sax.saxutils.escape``)
#     or with a colon as object delimiter (``xml.sax.saxutils:escape``).
#     If `silent` is True the return value will be `None` if the import fails.
#     :param import_name: the dotted name for the object to import.
#     :param silent: if set to `True` import errors are ignored and
#                    `None` is returned instead.
#     :return: imported object
#     """
#     # ref: https://github.com/pallets/werkzeug/blob/master/werkzeug/utils.py
# 
#     # force the import name to automatically convert to strings
#     # __import__ is not able to handle unicode strings in the fromlist
#     # if the module is a package
#     import_name = str(import_name).replace(':', '.')
#     try:
#         try:
#             __import__(import_name)
#         except ImportError:
#             if '.' not in import_name:
#                 raise
#         else:
#             return sys.modules[import_name]
# 
#         module_name, obj_name = import_name.rsplit('.', 1)
#         try:
#             module = __import__(module_name, None, None, [obj_name])
#         except ImportError:
#             # support importing modules not yet set up by the parent module
#             # (or package for that matter)
#             module = import_string(module_name)
# 
#         try:
#             return getattr(module, obj_name)
#         except AttributeError as e:
#             raise ImportError(e)
# 
#     except ImportError as e:
#         if not silent:
#             raise ImportError(e)
# 
# Path: simiki/compat.py



import os
import os.path
import io
import copy
import re
import traceback
import warnings
import markdown
import yaml
    from collections import OrderedDict
    from ordereddict import OrderedDict
from jinja2 import (Environment, FileSystemLoader, TemplateError)
from simiki import jinja_exts
from simiki.utils import import_string
from simiki.compat import is_py2, is_py3, basestring
    from functools import cmp_to_key
PLAT_LINE_SEP = '\n'


class BaseGenerator(object):
    """Base generator class"""

    def __init__(self, site_config, base_path):
        """
        :site_config: site global configuration parsed from _config.yml
        :base_path: root path of wiki directory
        """
        self.site_config = copy.deepcopy(site_config)
        self.base_path = base_path
        self._templates = {}  # templates cache
        self._template_vars = self._get_template_vars()
        _template_path = os.path.join(
            self.base_path,
            site_config["themes_dir"],
            site_config["theme"]
        )
        if not os.path.exists(_template_path):
            raise Exception("Theme `{0}' not exists".format(_template_path))
        self.env = Environment(
            loader=FileSystemLoader(_template_path)
        )
        self._jinja_load_exts()

    def _jinja_load_exts(self):
        """Load jinja custom filters and extensions"""
        for _filter in jinja_exts.filters:

# Path: simiki/jinja_exts.py
# def rfc3339(dt_obj):
# 
# Path: simiki/utils.py
# def import_string(import_name, silent=False):
#     """Imports an object based on a string.  This is useful if you want to
#     use import paths as endpoints or something similar.  An import path can
#     be specified either in dotted notation (``xml.sax.saxutils.escape``)
#     or with a colon as object delimiter (``xml.sax.saxutils:escape``).
#     If `silent` is True the return value will be `None` if the import fails.
#     :param import_name: the dotted name for the object to import.
#     :param silent: if set to `True` import errors are ignored and
#                    `None` is returned instead.
#     :return: imported object
#     """
#     # ref: https://github.com/pallets/werkzeug/blob/master/werkzeug/utils.py
# 
#     # force the import name to automatically convert to strings
#     # __import__ is not able to handle unicode strings in the fromlist
#     # if the module is a package
#     import_name = str(import_name).replace(':', '.')
#     try:
#         try:
#             __import__(import_name)
#         except ImportError:
#             if '.' not in import_name:
#                 raise
#         else:
#             return sys.modules[import_name]
# 
#         module_name, obj_name = import_name.rsplit('.', 1)
#         try:
#             module = __import__(module_name, None, None, [obj_name])
#         except ImportError:
#             # support importing modules not yet set up by the parent module
#             # (or package for that matter)
#             module = import_string(module_name)
# 
#         try:
#             return getattr(module, obj_name)
#         except AttributeError as e:
#             raise ImportError(e)
# 
#     except ImportError as e:
#         if not silent:
#             raise ImportError(e)
# 
# Path: simiki/compat.py



# Path: simiki/generators.py
import os
import os.path
import io
import copy
import re
import traceback
import warnings
import markdown
import yaml
    from collections import OrderedDict
    from ordereddict import OrderedDict
from jinja2 import (Environment, FileSystemLoader, TemplateError)
from simiki import jinja_exts
from simiki.utils import import_string
from simiki.compat import is_py2, is_py3, basestring
    from functools import cmp_to_key

PLAT_LINE_SEP = '\n'


class BaseGenerator(object):
    """Base generator class"""

    def __init__(self, site_config, base_path):
        """
        :site_config: site global configuration parsed from _config.yml
        :base_path: root path of wiki directory
        """
        self.site_config = copy.deepcopy(site_config)
        self.base_path = base_path
        self._templates = {}  # templates cache
        self._template_vars = self._get_template_vars()
        _template_path = os.path.join(
            self.base_path,
            site_config["themes_dir"],
            site_config["theme"]
        )
        if not os.path.exists(_template_path):
            raise Exception("Theme `{0}' not exists".format(_template_path))
        self.env = Environment(
            loader=FileSystemLoader(_template_path)
        )
        self._jinja_load_exts()

    def _jinja_load_exts(self):
        """Load jinja custom filters and extensions"""
        for _filter in jinja_exts.filters:

            self.env.filters[_filter] = getattr(jinja_exts, _filter)