def __call__(self, match): url = match.groups()[0] scheme, netloc, path, query, query, fragment = urlparse(url) if (scheme or netloc or not utils.is_markdown_file(path)): # Ignore URLs unless they are a relative link to a markdown file. return 'a href="%s"' % url if self.nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = self.nav.file_context.make_absolute(path) if target_file not in self.nav.source_files: source_file = self.nav.file_context.current_file msg = ( 'The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.' ) assert False, msg % (source_file, target_file) path = utils.get_url_path(target_file) path = self.nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip('/') # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return 'a href="%s"' % url
def path_to_url(url, nav): scheme, netloc, path, query, query, fragment = urlparse(url) if scheme or netloc or not path: # Ignore URLs unless they are a relative link to a markdown file. return url if nav and not utils.is_markdown_file(path): path = utils.create_media_urls(nav, [path])[0] elif nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = nav.file_context.make_absolute(path) if target_file not in nav.source_files: source_file = nav.file_context.current_file msg = ( 'The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.' ) assert False, msg % (source_file, target_file) path = utils.get_url_path(target_file, nav.use_directory_urls) path = nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip('/') # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return url
def path_to_url(url, nav, strict): scheme, netloc, path, query, query, fragment = urlparse(url) if scheme or netloc or not path: # Ignore URLs unless they are a relative link to a markdown file. return url if nav and not utils.is_markdown_file(path): path = utils.create_relative_media_url(nav, path) elif nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = nav.file_context.make_absolute(path) if target_file not in nav.source_files: source_file = nav.file_context.current_file msg = ( 'The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.' ) % (source_file, target_file) # In strict mode raise an error at this point. if strict: raise MarkdownNotFound(msg) # Otherwise, when strict mode isn't enabled, print out a warning # to the user and leave the URL as it is. #print(msg) #return url path = utils.get_url_path(target_file, nav.use_directory_urls) path = nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip('/') # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return url
def path_to_url(url, nav): scheme, netloc, path, query, query, fragment = urlparse(url) if scheme or netloc or not path: # Ignore URLs unless they are a relative link to a markdown file. return url if nav and not utils.is_markdown_file(path): path = utils.create_media_urls(nav, [path])[0] elif nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = nav.file_context.make_absolute(path) if target_file not in nav.source_files: source_file = nav.file_context.current_file msg = ('The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.') assert False, msg % (source_file, target_file) path = utils.get_url_path(target_file, nav.use_directory_urls) path = nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip('/') # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return url
def do_GET(self): """ The SimpleHTTPRequestHandler isn't designed to work with query strings. Everything we do with the query string is handle on the client-side, so throw it away here. """ scheme, netloc, path, query, query, fragment = urlparse(self.path) if query is not '': self.path = urlunparse((scheme, netloc, path, '', '', fragment)) return httpserver.SimpleHTTPRequestHandler.do_GET(self)
def create_media_urls(nav, url_list): """ Return a list of URLs that have been processed correctly for inclusion in a page. """ final_urls = [] for url in url_list: # Allow links to fully qualified URL's parsed = urlparse(url) if parsed.netloc: final_urls.append(url) else: relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url) final_urls.append(relative_url) return final_urls
def create_media_urls(nav, path_list): """ Return a list of URLs that have been processed correctly for inclusion in a page. """ final_urls = [] for path in path_list: # Allow links to fully qualified URL's parsed = urlparse(path) if parsed.netloc: final_urls.append(path) continue # We must be looking at a local path. url = path_to_url(path) relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url) final_urls.append(relative_url) return final_urls
def create_relative_media_url(nav, url): """ For a current page, create a relative url based on the given URL. On index.md (which becomes /index.html): image.png -> ./image.png /image.png -> ./image.png on sub/page.md (which becomes /sub/page/index.html): image.png -> ../image.png /image.png -> ../../image.png """ # Allow links to fully qualified URL's parsed = urlparse(url) if parsed.netloc: return url # If the URL we are looking at starts with a /, then it should be # considered as absolute and will be 'relative' to the root. if url.startswith('/'): base = '/' url = url[1:] else: base = nav.url_context.base_path relative_url = '%s/%s' % (nav.url_context.make_relative(base), url) # TODO: Fix this, this is a hack. Relative urls are not being calculated # correctly for images in the same directory as the markdown. I think this # is due to us moving it into a directory with index.html, but I'm not sure if nav.url_context.base_path is not '/' and relative_url.startswith("./"): relative_url = ".%s" % relative_url return relative_url
def validate_config(user_config): config = DEFAULT_CONFIG.copy() theme_in_config = 'theme' in user_config config.update(user_config) if not config['site_name']: raise ConfigurationError("Config must contain 'site_name' setting.") # Validate that the docs_dir and site_dir don't contain the # other as this will lead to copying back and forth on each # and eventually make a deep nested mess. abs_site_dir = os.path.abspath(config['site_dir']) abs_docs_dir = os.path.abspath(config['docs_dir']) if abs_docs_dir.startswith(abs_site_dir): raise ConfigurationError( "The 'docs_dir' can't be within the 'site_dir'.") elif abs_site_dir.startswith(abs_docs_dir): raise ConfigurationError( "The 'site_dir' can't be within the 'docs_dir'.") # If not specified, then the 'pages' config simply includes all # markdown files in the docs dir, without generating any header items # for them. pages = [] extra_css = [] extra_javascript = [] for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']): for filename in sorted(filenames): fullpath = os.path.join(dirpath, filename) relpath = os.path.relpath(fullpath, config['docs_dir']) if utils.is_markdown_file(filename): # index pages should always be the first listed page. if os.path.splitext(relpath)[0] == 'index': pages.insert(0, relpath) else: pages.append(relpath) elif utils.is_css_file(filename): extra_css.append(relpath) elif utils.is_javascript_file(filename): extra_javascript.append(relpath) if config['pages'] is None: config['pages'] = pages if config['extra_css'] is None: config['extra_css'] = extra_css if config['extra_javascript'] is None: config['extra_javascript'] = extra_javascript package_dir = os.path.dirname(__file__) theme_dir = [os.path.join(package_dir, 'themes', config['theme'])] if config['theme_dir'] is not None: # If the user has given us a custom theme but not a # builtin theme name then we don't want to merge them. if not theme_in_config: theme_dir = [] theme_dir.insert(0, config['theme_dir']) config['theme_dir'] = theme_dir if config['repo_url'] is not None and config['repo_name'] is None: repo_host = urlparse(config['repo_url']).netloc.lower() if repo_host == 'github.com': config['repo_name'] = 'GitHub' elif repo_host == 'bitbucket.org': config['repo_name'] = 'Bitbucket' else: config['repo_name'] = repo_host.split('.')[0].title() if config['include_next_prev'] is None: config['include_next_prev'] = len(config['pages']) > 1 if config['include_nav'] is None: config['include_nav'] = len(config['pages']) > 1 # To Do: # The docs dir must exist. # The theme dir must exist. # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom' # A homepage 'index' must exist. # The theme 'base.html' file must exist. # Cannot set repo_name without setting repo_url. # Cannot set 'include_next_prev: true' when only one page exists. # Cannot set 'include_nav: true' when only one page exists. # Error if any config keys provided that are not in the DEFAULT_CONFIG. return config
def validate_config(user_config): config = DEFAULT_CONFIG.copy() config.update(user_config) assert config['site_name'], "Config must contain 'site_name' setting." # If not specified, then the 'pages' config simply includes all # markdown files in the docs dir, without generating any header items # for them. pages = [] extra_css = [] extra_javascript = [] for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']): for filename in sorted(filenames): fullpath = os.path.join(dirpath, filename) relpath = os.path.relpath(fullpath, config['docs_dir']) if utils.is_markdown_file(filename): # index pages should always be the first listed page. if os.path.splitext(relpath)[0] == 'index': pages.insert(0, relpath) else: pages.append(relpath) elif utils.is_css_file(filename): extra_css.append(relpath) elif utils.is_javascript_file(filename): extra_javascript.append(relpath) if config['pages'] is None: config['pages'] = pages if config['extra_css'] is None: config['extra_css'] = extra_css if config['extra_javascript'] is None: config['extra_javascript'] = extra_javascript if config['theme_dir'] is None: package_dir = os.path.dirname(__file__) config['theme_dir'] = os.path.join(package_dir, 'themes', config['theme']) if config['repo_url'] is not None and config['repo_name'] is None: repo_host = urlparse(config['repo_url']).netloc.lower() if repo_host == 'github.com': config['repo_name'] = 'GitHub' elif repo_host == 'bitbucket.com': config['repo_name'] = 'Bitbucket' else: config['repo_name'] = repo_host.split('.')[0].title() if config['include_next_prev'] is None: config['include_next_prev'] = len(config['pages']) > 1 if config['include_nav'] is None: config['include_nav'] = len(config['pages']) > 1 # To Do: # The docs dir must exist. # The theme dir must exist. # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom' # A homepage 'index' must exist. # The theme 'base.html' file must exist. # Cannot set repo_name without setting repo_url. # Cannot set 'include_next_prev: true' when only one page exists. # Cannot set 'include_nav: true' when only one page exists. # Error if any config keys provided that are not in the DEFAULT_CONFIG. return config
def validate_config(user_config): config = DEFAULT_CONFIG.copy() config.update(user_config) if not config['site_name']: sys.stderr.write("Config must contain 'site_name' setting.") sys.exit(errno.EINVAL) # If not specified, then the 'pages' config simply includes all # markdown files in the docs dir, without generating any header items # for them. pages = [] extra_css = [] extra_javascript = [] for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']): for filename in sorted(filenames): fullpath = os.path.join(dirpath, filename) relpath = os.path.relpath(fullpath, config['docs_dir']) if utils.is_markdown_file(filename): # index pages should always be the first listed page. if os.path.splitext(relpath)[0] == 'index': pages.insert(0, relpath) else: pages.append(relpath) elif utils.is_css_file(filename): extra_css.append(relpath) elif utils.is_javascript_file(filename): extra_javascript.append(relpath) if config['pages'] is None: config['pages'] = pages if config['extra_css'] is None: config['extra_css'] = extra_css if config['extra_javascript'] is None: config['extra_javascript'] = extra_javascript package_dir = os.path.dirname(__file__) theme_dir = [os.path.join(package_dir, 'themes', config['theme'])] if config['theme_dir'] is not None: theme_dir.insert(0, config['theme_dir']) config['theme_dir'] = theme_dir if config['repo_url'] is not None and config['repo_name'] is None: repo_host = urlparse(config['repo_url']).netloc.lower() if repo_host == 'github.com': config['repo_name'] = 'GitHub' elif repo_host == 'bitbucket.com': config['repo_name'] = 'Bitbucket' else: config['repo_name'] = repo_host.split('.')[0].title() if config['include_next_prev'] is None: config['include_next_prev'] = len(config['pages']) > 1 if config['include_nav'] is None: config['include_nav'] = len(config['pages']) > 1 # To Do: # The docs dir must exist. # The theme dir must exist. # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom' # A homepage 'index' must exist. # The theme 'base.html' file must exist. # Cannot set repo_name without setting repo_url. # Cannot set 'include_next_prev: true' when only one page exists. # Cannot set 'include_nav: true' when only one page exists. # Error if any config keys provided that are not in the DEFAULT_CONFIG. return config
def validate_config(user_config): config = DEFAULT_CONFIG.copy() config.update(user_config) assert config["site_name"], "Config must contain 'site_name' setting." # If not specified, then the 'pages' config simply includes all # markdown files in the docs dir, without generating any header items # for them. pages = [] extra_css = [] extra_javascript = [] for (dirpath, dirnames, filenames) in os.walk(config["docs_dir"]): for filename in sorted(filenames): fullpath = os.path.join(dirpath, filename) relpath = os.path.relpath(fullpath, config["docs_dir"]) if utils.is_markdown_file(filename): # index pages should always be the first listed page. if os.path.splitext(relpath)[0] == "index": pages.insert(0, relpath) else: pages.append(relpath) elif utils.is_css_file(filename): extra_css.append(relpath) elif utils.is_javascript_file(filename): extra_javascript.append(relpath) if config["pages"] is None: config["pages"] = pages if config["extra_css"] is None: config["extra_css"] = extra_css if config["extra_javascript"] is None: config["extra_javascript"] = extra_javascript if config["theme_dir"] is None: package_dir = os.path.dirname(__file__) config["theme_dir"] = os.path.join(package_dir, "themes", config["theme"]) if config["repo_url"] is not None and config["repo_name"] is None: repo_host = urlparse(config["repo_url"]).netloc.lower() if repo_host == "github.com": config["repo_name"] = "GitHub" elif repo_host == "bitbucket.com": config["repo_name"] = "Bitbucket" else: config["repo_name"] = repo_host.split(".")[0].title() if config["include_next_prev"] is None: config["include_next_prev"] = len(config["pages"]) > 1 if config["include_nav"] is None: config["include_nav"] = len(config["pages"]) > 1 # To Do: # The docs dir must exist. # The theme dir must exist. # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom' # A homepage 'index' must exist. # The theme 'base.html' file must exist. # Cannot set repo_name without setting repo_url. # Cannot set 'include_next_prev: true' when only one page exists. # Cannot set 'include_nav: true' when only one page exists. # Error if any config keys provided that are not in the DEFAULT_CONFIG. return config