Blob Blame History Raw
From 41978a7af0f4807c4dfa8d3dc794ac671540bf6e Mon Sep 17 00:00:00 2001
From: "Gabriel L. Somlo" <gsomlo@gmail.com>
Date: Tue, 1 Oct 2019 15:23:50 -0400
Subject: [PATCH] Revert "Change theme to Sphinx Material Design"

This reverts commit de5eec38c4333eac947579d4c6b5695b3edb2499.

Reverting this change should allow building the PDF manual as
part of a Fedora RPM package.

Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
---
 docs/.gitignore                |   1 -
 docs/Makefile                  |  30 ++----
 docs/_static/.keepme           |   0
 docs/conf.py                   | 116 ++++-----------------
 docs/markdown_code_symlinks.py | 179 +++++++++++++++++++++++++++++++++
 docs/requirements.txt          |   7 +-
 6 files changed, 209 insertions(+), 124 deletions(-)
 delete mode 100644 docs/_static/.keepme
 create mode 100644 docs/markdown_code_symlinks.py

diff --git a/docs/.gitignore b/docs/.gitignore
index 13856a1..e35d885 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -1,2 +1 @@
-venv
 _build
diff --git a/docs/Makefile b/docs/Makefile
index cb6f107..b52c668 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,15 +1,13 @@
 # Minimal makefile for Sphinx documentation
 #
 
-MAKEDIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
 # You can set these variables from the command line.
-SPHINXOPTS      =
-SPHINXBUILD     = [ -e venv/bin/activate ] && source venv/bin/activate; sphinx-build
-SPHINXAUTOBUILD = [ -e venv/bin/activate ] && source venv/bin/activate; sphinx-autobuild
-SPHINXPROJ      = ProjectTrellis
-SOURCEDIR       = .
-BUILDDIR        = _build
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+SPHINXAUTOBUILD   = sphinx-autobuild
+SPHINXPROJ    = ProjectX-Ray
+SOURCEDIR     = .
+BUILDDIR      = _build
 
 # Put it first so that "make" without argument is like "make help".
 help:
@@ -18,21 +16,9 @@ help:
 livehtml:
 	@$(SPHINXAUTOBUILD) -b html --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
 
-.PHONY: help livehtml Makefile
-
-venv:
-	rm -rf venv
-	virtualenv --python=python3 venv
-	source venv/bin/activate; pip install -r requirements.txt
-
-.PHONY: venv
-
-links:
-	@true
-
-.PHONY: links
+.PHONY: help livereload Makefile
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile links
+%: Makefile
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/.keepme b/docs/_static/.keepme
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/conf.py b/docs/conf.py
index e847b58..8989469 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -24,7 +24,7 @@ import recommonmark
 import os
 import sys
 sys.path.insert(0, os.path.abspath('.'))
-from markdown_code_symlinks import LinkParser, MarkdownSymlinksDomain
+from markdown_code_symlinks import MarkdownCodeSymlinks
 
 # -- General configuration ------------------------------------------------
 
@@ -36,13 +36,8 @@ from markdown_code_symlinks import LinkParser, MarkdownSymlinksDomain
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = [
-    'sphinx.ext.autodoc',
-    'sphinx.ext.autosummary',
-    'sphinx.ext.doctest',
-    'sphinx.ext.imgmath',
-    'sphinx.ext.napoleon',
-    'sphinx.ext.todo',
-    'sphinx_markdown_tables',
+    'sphinx.ext.imgmath', 'sphinx.ext.autodoc', 'sphinx.ext.doctest',
+    'sphinx.ext.autosummary', 'sphinx.ext.napoleon', 'sphinx.ext.todo'
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -52,7 +47,7 @@ templates_path = ['_templates']
 # You can specify multiple suffix as a list of string:
 source_suffix = ['.rst', '.md']
 source_parsers = {
-    '.md': 'markdown_code_symlinks.LinkParser',
+    '.md': 'recommonmark.parser.CommonMarkParser',
 }
 
 # The master toctree document.
@@ -63,24 +58,6 @@ project = u'Project Trellis'
 copyright = u'2018, SymbiFlow Team'
 author = u'SymbiFlow Team'
 
-# Enable github links when not on readthedocs
-on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
-if not on_rtd:
-    html_context = {
-        "display_github": True,  # Integrate GitHub
-        "github_user": "symbiflow",  # Username
-        "github_repo": "prjtrellis",  # Repo name
-        "github_version": "master",  # Version
-        "conf_py_path": "/doc/",
-    }
-else:
-    docs_dir = os.path.abspath(os.path.dirname(__file__))
-    print("Docs dir is:", docs_dir)
-    import subprocess
-    subprocess.call('git fetch origin --unshallow', cwd=docs_dir, shell=True)
-    subprocess.check_call('git fetch origin --tags', cwd=docs_dir, shell=True)
-    subprocess.check_call('make links', cwd=docs_dir, shell=True)
-
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
@@ -100,10 +77,10 @@ language = None
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
 # This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = ['_build', 'venv', 'Thumbs.db', '.DS_Store']
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'default'
+pygments_style = 'sphinx'
 
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = True
@@ -113,67 +90,24 @@ todo_include_todos = True
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 #
-html_theme = 'sphinx_materialdesign_theme'
+html_theme = 'sphinx_rtd_theme'
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
 #
-html_theme_options = {
-    # Specify a list of menu in Header.
-    # Tuples forms:
-    #  ('Name', 'external url or path of pages in the document', boolean, 'icon name')
-    #
-    # Third argument:
-    # True indicates an external link.
-    # False indicates path of pages in the document.
-    #
-    # Fourth argument:
-    # Specify the icon name.
-    # For details see link.
-    # https://material.io/icons/
-    'header_links': [
-        ('Home', 'index', False, 'home'),
-        ("GitHub", "https://github.com/SymbiFlow/prjtrellis", True, 'link')
-    ],
+# html_theme_options = {}
 
-    # Customize css colors.
-    # For details see link.
-    # https://getmdl.io/customize/index.html
-    #
-    # Values: amber, blue, brown, cyan deep_orange, deep_purple, green, grey, indigo, light_blue,
-    #         light_green, lime, orange, pink, purple, red, teal, yellow(Default: indigo)
-    'primary_color':
-    'deep_purple',
-    # Values: Same as primary_color. (Default: pink)
-    'accent_color':
-    'purple',
-
-    # Customize layout.
-    # For details see link.
-    # https://getmdl.io/components/index.html#layout-section
-    'fixed_drawer':
-    True,
-    'fixed_header':
-    True,
-    'header_waterfall':
-    True,
-    'header_scroll':
-    False,
-
-    # Render title in header.
-    # Values: True, False (Default: False)
-    'show_header_title':
-    False,
-    # Render title in drawer.
-    # Values: True, False (Default: True)
-    'show_drawer_title':
-    True,
-    # Render footer.
-    # Values: True, False (Default: True)
-    'show_footer':
-    True
-}
+# Enable github links when not on readthedocs
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+if not on_rtd:
+    html_context = {
+        "display_github": True,  # Integrate GitHub
+        "github_user": "symbiflow",  # Username
+        "github_repo": "prjtrellis",  # Repo name
+        "github_version": "master",  # Version
+        "conf_py_path": "/doc/",
+    }
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
@@ -250,17 +184,9 @@ intersphinx_mapping = {'https://docs.python.org/': None}
 
 
 def setup(app):
-    github_code_repo = 'https://github.com/SymbiFlow/prjtrellis/'
-    github_code_branch = 'blob/master/'
-
-    docs_root_dir = os.path.realpath(os.path.dirname(__file__))
-    code_root_dir = os.path.realpath(os.path.join(docs_root_dir, ".."))
-
-    MarkdownSymlinksDomain.init_domain(
-        github_code_repo, github_code_branch, docs_root_dir, code_root_dir)
-    MarkdownSymlinksDomain.find_links()
-    app.add_domain(MarkdownSymlinksDomain)
+    MarkdownCodeSymlinks.find_links()
     app.add_config_value(
         'recommonmark_config', {
-            'github_code_repo': github_code_repo,
+            'github_code_repo': 'https://github.com/SymbiFlow/prjtrellis',
         }, True)
+    app.add_transform(MarkdownCodeSymlinks)
diff --git a/docs/markdown_code_symlinks.py b/docs/markdown_code_symlinks.py
new file mode 100644
index 0000000..1955493
--- /dev/null
+++ b/docs/markdown_code_symlinks.py
@@ -0,0 +1,179 @@
+import logging
+import os
+
+from recommonmark import transform
+"""
+Allow linking of Markdown documentation from the source code tree into the Sphinx
+documentation tree.
+
+The Markdown documents will have links relative to the source code root, rather
+than the place they are now linked too - this code fixes these paths up.
+
+We also want links from two Markdown documents found in the Sphinx docs to
+work, so that is also fixed up.
+"""
+
+
+def path_contains(parent_path, child_path):
+    """Check a path contains another path.
+
+    >>> path_contains("a/b", "a/b")
+    True
+    >>> path_contains("a/b", "a/b/")
+    True
+    >>> path_contains("a/b", "a/b/c")
+    True
+    >>> path_contains("a/b", "c")
+    False
+    >>> path_contains("a/b", "c/b")
+    False
+    >>> path_contains("a/b", "c/../a/b/d")
+    True
+    >>> path_contains("../a/b", "../a/b/d")
+    True
+    >>> path_contains("../a/b", "../a/c")
+    False
+    >>> path_contains("a", "abc")
+    False
+    >>> path_contains("aa", "abc")
+    False
+    """
+    # Append a separator to the end of both paths to work around the fact that
+    # os.path.commonprefix does character by character comparisons rather than
+    # path segment by path segment.
+    parent_path = os.path.join(os.path.normpath(parent_path), '')
+    child_path = os.path.join(os.path.normpath(child_path), '')
+    common_path = os.path.commonprefix((parent_path, child_path))
+    return common_path == parent_path
+
+
+def relative(parent_dir, child_path):
+    """Get the relative between a path that contains another path."""
+    child_dir = os.path.dirname(child_path)
+    assert path_contains(parent_dir, child_dir), "{} not inside {}".format(
+        child_path, parent_dir)
+    return os.path.relpath(child_path, start=parent_dir)
+
+
+class MarkdownCodeSymlinks(transform.AutoStructify, object):
+    docs_root_dir = os.path.realpath(os.path.dirname(__file__))
+    code_root_dir = os.path.realpath(os.path.join(docs_root_dir, "..", ".."))
+
+    mapping = {
+        'docs2code': {},
+        'code2docs': {},
+    }
+
+    @classmethod
+    def relative_code(cls, url):
+        """Get a value relative to the code directory."""
+        return relative(cls.code_root_dir, url)
+
+    @classmethod
+    def relative_docs(cls, url):
+        """Get a value relative to the docs directory."""
+        return relative(cls.docs_root_dir, url)
+
+    @classmethod
+    def add_mapping(cls, docs_rel, code_rel):
+        assert docs_rel not in cls.mapping['docs2code'], """\
+Assertion error! Document already in mapping!
+    New Value: {}
+Current Value: {}
+""".format(docs_rel, cls.mapping['docs2code'][docs_rel])
+        assert code_rel not in cls.mapping['code2docs'], """\
+Assertion error! Document already in mapping!
+    New Value: {}
+Current Value: {}
+""".format(docs_rel, cls.mapping['code2docs'][code_rel])
+
+        cls.mapping['docs2code'][docs_rel] = code_rel
+        cls.mapping['code2docs'][code_rel] = docs_rel
+
+    @classmethod
+    def find_links(cls):
+        """Walk the docs dir and find links to docs in the code dir."""
+        for root, dirs, files in os.walk(cls.docs_root_dir):
+            for fname in files:
+                fpath = os.path.abspath(os.path.join(root, fname))
+
+                if not os.path.islink(fpath):
+                    continue
+
+                link_path = os.path.join(root, os.readlink(fpath))
+                # Is link outside the code directory?
+                if not path_contains(cls.code_root_dir, link_path):
+                    continue
+
+                # Is link internal to the docs directory?
+                if path_contains(cls.docs_root_dir, link_path):
+                    continue
+
+                docs_rel = cls.relative_docs(fpath)
+                code_rel = cls.relative_code(link_path)
+
+                cls.add_mapping(docs_rel, code_rel)
+        import pprint
+        pprint.pprint(cls.mapping)
+
+    @property
+    def url_resolver(self):
+        return self._url_resolver
+
+    @url_resolver.setter
+    def url_resolver(self, value):
+        print(self, value)
+
+    # Resolve a link from one markdown to another document.
+    def _url_resolver(self, ourl):
+        """Resolve a URL found in a markdown file."""
+        assert self.docs_root_dir == os.path.realpath(self.root_dir), """\
+Configuration error! Document Root != Current Root
+Document Root: {}
+ Current Root: {}
+""".format(self.docs_root_dir, self.root_dir)
+
+        src_path = os.path.abspath(self.document['source'])
+        src_dir = os.path.dirname(src_path)
+        dst_path = os.path.abspath(os.path.join(self.docs_root_dir, ourl))
+        dst_rsrc = os.path.relpath(dst_path, start=src_dir)
+
+        src_rdoc = self.relative_docs(src_path)
+
+        print
+        print("url_resolver")
+        print(src_path)
+        print(dst_path)
+        print(dst_rsrc)
+        print(src_rdoc)
+
+        # Is the source document a linked one?
+        if src_rdoc not in self.mapping['docs2code']:
+            # Don't do any rewriting on non-linked markdown.
+            url = ourl
+
+        # Is the destination also inside docs?
+        elif dst_rsrc not in self.mapping['code2docs']:
+            # Return a path to the GitHub repo.
+            url = "{}/blob/master/{}".format(
+                self.config['github_code_repo'], dst_rsrc)
+        else:
+            url = os.path.relpath(
+                os.path.join(
+                    self.docs_root_dir, self.mapping['code2docs'][dst_rsrc]),
+                start=src_dir)
+            base_url, ext = os.path.splitext(url)
+            assert ext in (".md",
+                           ".markdown"), ("Unknown extension {}".format(ext))
+            url = "{}.html".format(base_url)
+
+        print("---")
+        print(ourl)
+        print(url)
+        print
+        return url
+
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
diff --git a/docs/requirements.txt b/docs/requirements.txt
index ec9e872..56c1f78 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,13 +1,8 @@
-sphinx_materialdesign_theme
-
 docutils
 sphinx
 sphinx-autobuild
 
 breathe
 recommonmark
-sphinx-markdown-tables
+sphinx_rtd_theme
 sphinxcontrib-napoleon
-
-# Markdown cross-reference solver library
-git+https://github.com/SymbiFlow/sphinxcontrib-markdown-symlinks
-- 
2.21.0