diff --git a/mathics/builtin/assignments/assignment.py b/mathics/builtin/assignments/assignment.py
index f3a7a68ba..f960691c5 100644
--- a/mathics/builtin/assignments/assignment.py
+++ b/mathics/builtin/assignments/assignment.py
@@ -11,6 +11,7 @@
assign_store_rules_by_tag,
normalize_lhs,
)
+from mathics.core.atoms import String
from mathics.core.attributes import (
A_HOLD_ALL,
A_HOLD_FIRST,
@@ -66,17 +67,17 @@ class LoadModule(Builtin):
'Load Mathics definitions from the python module $module$
>> LoadModule["nomodule"]
- : Python module nomodule does not exist.
+ : Python import errors with: No module named 'nomodule'.
= $Failed
>> LoadModule["sys"]
- : Python module sys is not a pymathics module.
+ : Python module "sys" is not a Mathics3 module.
= $Failed
"""
name = "LoadModule"
messages = {
- "notfound": "Python module `1` does not exist.",
- "notmathicslib": "Python module `1` is not a pymathics module.",
+ "loaderror": """Python import errors with: `1`.""",
+ "notmathicslib": """Python module "`1`" is not a Mathics3 module.""",
}
summary_text = "load a pymathics module"
@@ -87,8 +88,8 @@ def eval(self, module, evaluation):
except PyMathicsLoadException:
evaluation.message(self.name, "notmathicslib", module)
return SymbolFailed
- except ImportError:
- evaluation.message(self.get_name(), "notfound", module)
+ except Exception as e:
+ evaluation.message(self.get_name(), "loaderror", String(str(e)))
return SymbolFailed
return module
diff --git a/mathics/doc/common_doc.py b/mathics/doc/common_doc.py
index 1c647325e..85c59cd69 100644
--- a/mathics/doc/common_doc.py
+++ b/mathics/doc/common_doc.py
@@ -23,7 +23,7 @@
More importantly, this code should be replaced by Sphinx and autodoc.
Things are such a mess, that it is too difficult to contemplate this right now.
"""
-
+import importlib
import os.path as osp
import pkgutil
import re
@@ -36,6 +36,7 @@
from mathics.core.evaluation import Message, Print
from mathics.core.util import IS_PYPY
from mathics.doc.utils import slugify
+from mathics.eval.pymathics import pymathics_builtins_by_module, pymathics_modules
# These are all the XML/HTML-like tags that documentation supports.
ALLOWED_TAGS = (
@@ -357,6 +358,310 @@ def __init__(self, part: str, title: str, doc=None):
self.title = title
part.chapters_by_slug[self.slug] = self
+ def add_section(
+ self,
+ chapter,
+ section_name: str,
+ section_object,
+ operator,
+ is_guide: bool = False,
+ in_guide: bool = False,
+ ):
+ """
+ Adds a DocSection or DocGuideSection
+ object to the chapter, a DocChapter object.
+ "section_object" is either a Python module or a Class object instance.
+ """
+ installed = check_requires_list(getattr(section_object, "requires", []))
+
+ # FIXME add an additional mechanism in the module
+ # to allow a docstring and indicate it is not to go in the
+ # user manual
+ if not section_object.__doc__:
+ return
+ if is_guide:
+ section = self.doc_guide_section_fn(
+ chapter,
+ section_name,
+ section_object.__doc__,
+ section_object,
+ installed=installed,
+ )
+ chapter.guide_sections.append(section)
+ else:
+ section = self.doc_section_fn(
+ chapter,
+ section_name,
+ section_object.__doc__,
+ operator=operator,
+ installed=installed,
+ in_guide=in_guide,
+ )
+ chapter.sections.append(section)
+
+ return section
+
+ def add_subsection(
+ self,
+ chapter,
+ section,
+ subsection_name: str,
+ instance,
+ operator=None,
+ in_guide=False,
+ ):
+ installed = check_requires_list(getattr(instance, "requires", []))
+
+ # FIXME add an additional mechanism in the module
+ # to allow a docstring and indicate it is not to go in the
+ # user manual
+
+ """
+ Append a subsection for ``instance`` into ``section.subsections``
+ """
+ installed = True
+ for package in getattr(instance, "requires", []):
+ try:
+ importlib.import_module(package)
+ except ImportError:
+ installed = False
+ break
+
+ # FIXME add an additional mechanism in the module
+ # to allow a docstring and indicate it is not to go in the
+ # user manual
+ if not instance.__doc__:
+ return
+ summary_text = (
+ instance.summary_text if hasattr(instance, "summary_text") else ""
+ )
+ subsection = self.doc_subsection_fn(
+ chapter,
+ section,
+ subsection_name,
+ instance.__doc__,
+ operator=operator,
+ installed=installed,
+ in_guide=in_guide,
+ summary_text=summary_text,
+ )
+ section.subsections.append(subsection)
+
+ def doc_part(self, title, modules, builtins_by_module, start):
+ """
+ Produce documentation for a "Part" - reference section or
+ possibly Pymathics modules
+ """
+
+ builtin_part = self.doc_part_fn(self, title, is_reference=start)
+ modules_seen = set([])
+
+ want_sorting = True
+ if want_sorting:
+ module_collection_fn = lambda x: sorted(
+ modules,
+ key=lambda module: module.sort_order
+ if hasattr(module, "sort_order")
+ else module.__name__,
+ )
+ else:
+ module_collection_fn = lambda x: x
+ for module in module_collection_fn(modules):
+ if skip_module_doc(module, modules_seen):
+ continue
+ title, text = get_module_doc(module)
+ chapter = self.doc_chapter_fn(
+ builtin_part, title, self.doc_fn(text, title, None)
+ )
+ builtins = builtins_by_module[module.__name__]
+ sections = [
+ builtin for builtin in builtins if not skip_doc(builtin.__class__)
+ ]
+
+ if module.__file__.endswith("__init__.py"):
+ # We have a Guide Section.
+ name = get_doc_name_from_module(module)
+ guide_section = self.add_section(
+ chapter, name, module, operator=None, is_guide=True
+ )
+ submodules = [
+ value
+ for value in module.__dict__.values()
+ if isinstance(value, ModuleType)
+ ]
+
+ sorted_submodule = lambda x: sorted(
+ submodules,
+ key=lambda submodule: submodule.sort_order
+ if hasattr(submodule, "sort_order")
+ else submodule.__name__,
+ )
+
+ # Add sections in the guide section...
+ for submodule in sorted_submodule(submodules):
+ # FIXME add an additional mechanism in the module
+ # to allow a docstring and indicate it is not to go in the
+ # user manual
+
+ if skip_module_doc(submodule, modules_seen):
+ continue
+ elif IS_PYPY and submodule.__name__ == "builtins":
+ # PyPy seems to add this module on its own,
+ # but it is not something that can be importable
+ continue
+
+ submodule_name = get_doc_name_from_module(submodule)
+ section = self.add_section(
+ chapter,
+ submodule_name,
+ submodule,
+ operator=None,
+ is_guide=False,
+ in_guide=True,
+ )
+ modules_seen.add(submodule)
+ guide_section.subsections.append(section)
+
+ builtins = builtins_by_module.get(submodule.__name__, [])
+ subsections = [builtin for builtin in builtins]
+ for instance in subsections:
+ if hasattr(instance, "no_doc") and instance.no_doc:
+ continue
+
+ modules_seen.add(instance)
+ name = instance.get_name(short=True)
+
+ self.add_subsection(
+ chapter,
+ section,
+ instance.get_name(short=True),
+ instance,
+ instance.get_operator(),
+ in_guide=True,
+ )
+ else:
+ self.doc_sections(sections, modules_seen, chapter)
+ builtin_part.chapters.append(chapter)
+ self.parts.append(builtin_part)
+
+ def doc_sections(self, sections, modules_seen, chapter):
+ for instance in sections:
+ if instance not in modules_seen and (
+ not hasattr(instance, "no_doc") or not instance.no_doc
+ ):
+ name = instance.get_name(short=True)
+ self.add_section(
+ chapter,
+ name,
+ instance,
+ instance.get_operator(),
+ is_guide=False,
+ in_guide=False,
+ )
+ modules_seen.add(instance)
+
+ def gather_doc_data(self):
+ """
+ Extract documentation data from various static XML-like doc files, Mathics3 Built-in functions
+ (inside mathics.builtin), and external Mathics3 Modules.
+
+ The extracted structure is stored in ``self``.
+ """
+
+ # First gather data from static XML-like files. This constitutes "Part 1" of the
+ # documentation.
+ files = listdir(self.doc_dir)
+ files.sort()
+ appendix = []
+
+ for file in files:
+ part_title = file[2:]
+ if part_title.endswith(".mdoc"):
+ part_title = part_title[: -len(".mdoc")]
+ part = self.doc_part_fn(self, part_title)
+ text = open(osp.join(self.doc_dir, file), "rb").read().decode("utf8")
+ text = filter_comments(text)
+ chapters = CHAPTER_RE.findall(text)
+ for title, text in chapters:
+ chapter = self.doc_chapter_fn(part, title)
+ text += ''
+ sections = SECTION_RE.findall(text)
+ for pre_text, title, text in sections:
+ if title:
+ section = self.doc_section_fn(
+ chapter, title, text, operator=None, installed=True
+ )
+ chapter.sections.append(section)
+ subsections = SUBSECTION_RE.findall(text)
+ for subsection_title in subsections:
+ subsection = self.doc_subsection_fn(
+ chapter,
+ section,
+ subsection_title,
+ text,
+ )
+ section.subsections.append(subsection)
+ pass
+ pass
+ else:
+ section = None
+ if not chapter.doc:
+ chapter.doc = self.doc_fn(pre_text, title, section)
+ pass
+
+ part.chapters.append(chapter)
+ if file[0].isdigit():
+ self.parts.append(part)
+ else:
+ part.is_appendix = True
+ appendix.append(part)
+
+ # Next extract data that has been loaded into Mathics3 when it runs.
+ # This is information from `mathics.builtin`.
+ # This is Part 2 of the documentation.
+
+ for title, modules, builtins_by_module, start in [
+ (
+ "Reference of Built-in Symbols",
+ builtin.modules,
+ builtin.builtins_by_module,
+ True,
+ )
+ ]:
+ self.doc_part(title, modules, builtins_by_module, start)
+
+ # Now extract external Mathics3 Modules that have been loaded via
+ # LoadModule, or eval_LoadModule.
+
+ # This is Part 3 of the documentation.
+
+ for title, modules, builtins_by_module, start in [
+ (
+ "Mathics3 Modules",
+ pymathics_modules,
+ pymathics_builtins_by_module,
+ True,
+ )
+ ]:
+ self.doc_part(title, modules, builtins_by_module, start)
+
+ # Now extract Appendix information. This include License text
+
+ # This is the final Part of the documentation.
+
+ for part in appendix:
+ self.parts.append(part)
+
+ # Via the wanderings above, collect all tests that have been
+ # seen.
+ #
+ # Each test is accessble by its part + chapter + section and test number
+ # in that section.
+ for tests in self.get_tests():
+ for test in tests.tests:
+ test.key = (tests.part, tests.chapter, tests.section, test.index)
+ return
+
def get_part(self, part_slug):
return self.parts_by_slug.get(part_slug)
@@ -459,7 +764,14 @@ def all_sections(self):
class DocSection:
def __init__(
- self, chapter, title, text, operator=None, installed=True, in_guide=False
+ self,
+ chapter,
+ title: str,
+ text: str,
+ operator,
+ installed=True,
+ in_guide=False,
+ summary_text="",
):
self.chapter = chapter
@@ -470,7 +782,9 @@ def __init__(
self.slug = slugify(title)
self.subsections = []
self.subsections_by_slug = {}
+ self.summary_text = summary_text
self.title = title
+
if text.count("") != text.count("
"):
raise ValueError(
"Missing opening or closing tag in "
@@ -557,6 +871,7 @@ def __init__(
operator=None,
installed=True,
in_guide=False,
+ summary_text="",
):
"""
Information that goes into a subsection object. This can be a written text, or
@@ -572,6 +887,11 @@ def __init__(
the "section" name for the class Read (the subsection) inside it.
"""
+ title_summary_text = re.split(" -- ", title)
+ n = len(title_summary_text)
+ self.title = title_summary_text[0] if n > 0 else ""
+ self.summary_text = title_summary_text[1] if n > 1 else summary_text
+
self.doc = XMLDoc(text, title, section)
self.chapter = chapter
self.in_guide = in_guide
@@ -583,10 +903,18 @@ def __init__(
self.subsections = []
self.title = title
+ if section:
+ chapter = section.chapter
+ part = chapter.part
+ # Note: we elide section.title
+ key_prefix = (part.title, chapter.title, title)
+ else:
+ key_prefix = None
+
if in_guide:
# Tests haven't been picked out yet from the doc string yet.
# Gather them here.
- self.items = gather_tests(text, DocTests, DocTest, DocText)
+ self.items = gather_tests(text, DocTests, DocTest, DocText, key_prefix)
else:
self.items = []
@@ -689,251 +1017,32 @@ def __str__(self):
return self.test
+# FIXME: think about - do we need this? Or can we use DjangoMathicsDocumentation and
+# LatTeXMathicsDocumentation only?
class MathicsMainDocumentation(Documentation):
+ """
+ This module is used for creating test data and saving it to a Python Pickle file
+ and running tests that appear in the documentation (doctests).
+
+ There are other classes DjangoMathicsDocumentation and LaTeXMathicsDocumentation
+ that format the data accumulated here. In fact I think those can sort of serve
+ instead of this.
+ """
+
def __init__(self, want_sorting=False):
+ self.doc_chapter_fn = DocChapter
self.doc_dir = settings.DOC_DIR
+ self.doc_fn = XMLDoc
+ self.doc_guide_section_fn = DocGuideSection
+ self.doc_part_fn = DocPart
+ self.doc_section_fn = DocSection
+ self.doc_subsection_fn = DocSubsection
self.latex_pcl_path = settings.DOC_LATEX_DATA_PCL
self.parts = []
self.parts_by_slug = {}
self.pymathics_doc_loaded = False
self.doc_data_file = settings.get_doc_latex_data_path(should_be_readable=True)
self.title = "Overview"
- files = listdir(self.doc_dir)
- files.sort()
- appendix = []
-
- for file in files:
- part_title = file[2:]
- if part_title.endswith(".mdoc"):
- part_title = part_title[: -len(".mdoc")]
- part = DocPart(self, part_title)
- text = open(osp.join(self.doc_dir, file), "rb").read().decode("utf8")
- text = filter_comments(text)
- chapters = CHAPTER_RE.findall(text)
- for title, text in chapters:
- chapter = DocChapter(part, title)
- text += ''
- sections = SECTION_RE.findall(text)
- for pre_text, title, text in sections:
- if title:
- section = DocSection(
- chapter, title, text, operator=None, installed=True
- )
- chapter.sections.append(section)
- subsections = SUBSECTION_RE.findall(text)
- for subsection_title in subsections:
- subsection = DocSubsection(
- chapter,
- section,
- subsection_title,
- text,
- )
- section.subsections.append(subsection)
- pass
- pass
- else:
- section = None
- if not chapter.doc:
- chapter.doc = XMLDoc(pre_text, title, section)
-
- part.chapters.append(chapter)
- if file[0].isdigit():
- self.parts.append(part)
- else:
- part.is_appendix = True
- appendix.append(part)
-
- for title, modules, builtins_by_module, start in [
- (
- "Reference of Built-in Symbols",
- builtin.modules,
- builtin.builtins_by_module,
- True,
- )
- ]: # nopep8
- # ("Reference of optional symbols", optional.modules,
- # optional.optional_builtins_by_module, False)]:
-
- builtin_part = DocPart(self, title, is_reference=start)
- modules_seen = set()
- if want_sorting:
- module_collection_fn = lambda x: sorted(
- modules,
- key=lambda module: module.sort_order
- if hasattr(module, "sort_order")
- else module.__name__,
- )
- else:
- module_collection_fn = lambda x: x
-
- for module in module_collection_fn(modules):
- if skip_module_doc(module, modules_seen):
- continue
- title, text = get_module_doc(module)
- chapter = DocChapter(builtin_part, title, XMLDoc(text, title, None))
- builtins = builtins_by_module[module.__name__]
- sections = [builtin for builtin in builtins]
- if module.__file__.endswith("__init__.py"):
- # We have a Guide Section.
- name = get_doc_name_from_module(module)
- guide_section = self.add_section(
- chapter, name, module, operator=None, is_guide=True
- )
- submodules = [
- value
- for value in module.__dict__.values()
- if isinstance(value, ModuleType)
- ]
-
- # Add sections in the guide section...
- for submodule in submodules:
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
- if submodule.__doc__ is None:
- continue
- elif IS_PYPY and submodule.__name__ == "builtins":
- # PyPy seems to add this module on its own,
- # but it is not something that can be importable
- continue
-
- if submodule in modules_seen:
- continue
-
- section = self.add_section(
- chapter,
- get_doc_name_from_module(submodule),
- submodule,
- operator=None,
- is_guide=False,
- in_guide=True,
- )
- modules_seen.add(submodule)
- guide_section.subsections.append(section)
- builtins = builtins_by_module[submodule.__name__]
-
- subsections = [
- builtin
- for builtin in builtins
- if not builtin.__class__.__name__.endswith("Box")
- ]
- for instance in subsections:
- if hasattr(instance, "no_doc") and instance.no_doc:
- continue
-
- modules_seen.add(instance)
- name = instance.get_name(short=True)
- self.add_subsection(
- chapter,
- section,
- instance.get_name(short=True),
- instance,
- instance.get_operator(),
- in_guide=True,
- )
- else:
- for instance in sections:
- if instance not in modules_seen and (
- not hasattr(instance, "no_doc") or not instance.no_doc
- ):
- name = instance.get_name(short=True)
- self.add_section(
- chapter,
- instance.get_name(short=True),
- instance,
- instance.get_operator(),
- is_guide=False,
- in_guide=False,
- )
- modules_seen.add(instance)
- pass
- pass
- pass
- builtin_part.chapters.append(chapter)
- self.parts.append(builtin_part)
-
- for part in appendix:
- self.parts.append(part)
-
- # set keys of tests
- for tests in self.get_tests(want_sorting=want_sorting):
- for test in tests.tests:
- test.key = (tests.part, tests.chapter, tests.section, test.index)
-
- def add_section(
- self,
- chapter,
- section_name: str,
- section_object,
- operator,
- is_guide: bool = False,
- in_guide: bool = False,
- ):
- """
- Adds a DocSection or DocGuideSection
- object to the chapter, a DocChapter object.
- "section_object" is either a Python module or a Class object instance.
- """
- installed = check_requires_list(getattr(section_object, "requires", []))
-
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
- if not section_object.__doc__:
- return
- if is_guide:
- section = DocGuideSection(
- chapter,
- section_name,
- section_object.__doc__,
- section_object,
- installed=installed,
- )
- chapter.guide_sections.append(section)
- else:
- section = DocSection(
- chapter,
- section_name,
- section_object.__doc__,
- operator=operator,
- installed=installed,
- in_guide=in_guide,
- )
- chapter.sections.append(section)
-
- return section
-
- def add_subsection(
- self,
- chapter,
- section,
- subsection_name: str,
- instance,
- operator=None,
- in_guide=False,
- ):
- installed = check_requires_list(getattr(instance, "requires", []))
-
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
-
- if not instance.__doc__:
- return
- subsection = DocSubsection(
- chapter,
- section,
- subsection_name,
- instance.__doc__,
- operator=operator,
- installed=installed,
- in_guide=in_guide,
- )
- section.subsections.append(subsection)
-
- def load_pymathics_doc(self):
- # This has always been broken. Revisit after revising Pymathics.
- return
class XMLDoc:
@@ -1019,6 +1128,7 @@ def test_indices(self):
class DocTests:
def __init__(self):
self.tests = []
+ self.text = ""
def get_tests(self):
return self.tests
diff --git a/mathics/doc/latex/doc2latex.py b/mathics/doc/latex/doc2latex.py
index f49b2e262..7d392060b 100755
--- a/mathics/doc/latex/doc2latex.py
+++ b/mathics/doc/latex/doc2latex.py
@@ -17,7 +17,7 @@
import mathics
from mathics import __version__, settings, version_string
-from mathics.doc.latex_doc import LaTeXMathicsMainDocumentation
+from mathics.doc.latex_doc import LaTeXMathicsDocumentation
# Global variables
logfile = None
@@ -95,7 +95,7 @@ def try_cmd(cmd_list: tuple, stdout_or_stderr: str) -> str:
def write_latex(
doc_data, quiet=False, filter_parts=None, filter_chapters=None, filter_sections=None
):
- documentation = LaTeXMathicsMainDocumentation()
+ documentation = LaTeXMathicsDocumentation()
if not quiet:
print(f"Writing LaTeX document to {DOC_LATEX_FILE}")
with open_ensure_dir(DOC_LATEX_FILE, "wb") as doc:
diff --git a/mathics/doc/latex_doc.py b/mathics/doc/latex_doc.py
index 75a656ae3..e852d05c9 100644
--- a/mathics/doc/latex_doc.py
+++ b/mathics/doc/latex_doc.py
@@ -3,17 +3,12 @@
FIXME: Ditch this and hook into sphinx.
"""
-import os.path as osp
import re
-from os import getenv, listdir
-from types import ModuleType
+from os import getenv
-from mathics import builtin, settings
-from mathics.builtin.base import check_requires_list
+from mathics import settings
from mathics.core.evaluation import Message, Print
-from mathics.core.util import IS_PYPY
from mathics.doc.common_doc import (
- CHAPTER_RE,
CONSOLE_RE,
DL_ITEM_RE,
DL_RE,
@@ -28,7 +23,6 @@
PYTHON_RE,
QUOTATIONS_RE,
REF_RE,
- SECTION_RE,
SPECIAL_COMMANDS,
SUBSECTION_END_RE,
SUBSECTION_RE,
@@ -40,17 +34,12 @@
DocTests,
DocText,
Documentation,
- MathicsMainDocumentation,
XMLDoc,
_replace_all,
- filter_comments,
gather_tests,
- get_doc_name_from_module,
- get_module_doc,
get_results_by_test,
post_sub,
pre_sub,
- skip_module_doc,
sorted_chapters,
)
from mathics.doc.utils import slugify
@@ -666,258 +655,22 @@ def latex(self, doc_data: dict):
)
-class LaTeXMathicsMainDocumentation(MathicsMainDocumentation):
+class LaTeXMathicsDocumentation(Documentation):
def __init__(self, want_sorting=False):
+ self.doc_chapter_fn = LaTeXDocChapter
self.doc_dir = settings.DOC_DIR
+ self.doc_fn = LaTeXDoc
+ self.doc_data_file = settings.get_doc_latex_data_path(should_be_readable=True)
+ self.doc_guide_section_fn = LaTeXDocGuideSection
+ self.doc_part_fn = LaTeXDocPart
+ self.doc_section_fn = LaTeXDocSection
+ self.doc_subsection_fn = LaTeXDocSubsection
self.latex_pcl_path = settings.DOC_LATEX_DATA_PCL
self.parts = []
self.parts_by_slug = {}
- self.pymathics_doc_loaded = False
- self.doc_data_file = settings.get_doc_latex_data_path(should_be_readable=True)
self.title = "Overview"
- files = listdir(self.doc_dir)
- files.sort()
- appendix = []
-
- for file in files:
- part_title = file[2:]
- if part_title.endswith(".mdoc"):
- part_title = part_title[: -len(".mdoc")]
- part = LaTeXDocPart(self, part_title)
- text = open(osp.join(self.doc_dir, file), "rb").read().decode("utf8")
- text = filter_comments(text)
- chapters = CHAPTER_RE.findall(text)
- for title, text in chapters:
- chapter = LaTeXDocChapter(part, title)
- text += ''
- sections = SECTION_RE.findall(text)
- for pre_text, title, text in sections:
- if title:
- section = LaTeXDocSection(
- chapter, title, text, operator=None, installed=True
- )
- chapter.sections.append(section)
- subsections = SUBSECTION_RE.findall(text)
- for subsection_title in subsections:
- subsection = LaTeXDocSubsection(
- chapter,
- section,
- subsection_title,
- text,
- )
- section.subsections.append(subsection)
- pass
- pass
- else:
- section = None
- if not chapter.doc:
- chapter.doc = LaTeXDoc(pre_text, title, section)
-
- part.chapters.append(chapter)
- if file[0].isdigit():
- self.parts.append(part)
- else:
- part.is_appendix = True
- appendix.append(part)
-
- for title, modules, builtins_by_module, start in [
- (
- "Reference of Built-in Symbols",
- builtin.modules,
- builtin.builtins_by_module,
- True,
- )
- ]: # nopep8
- # ("Reference of optional symbols", optional.modules,
- # optional.optional_builtins_by_module, False)]:
-
- builtin_part = LaTeXDocPart(self, title, is_reference=start)
- modules_seen = set()
- if want_sorting:
- module_collection_fn = lambda x: sorted(
- modules,
- key=lambda module: module.sort_order
- if hasattr(module, "sort_order")
- else module.__name__,
- )
- else:
- module_collection_fn = lambda x: x
- for module in module_collection_fn(modules):
- if skip_module_doc(module, modules_seen):
- continue
- title, text = get_module_doc(module)
- chapter = LaTeXDocChapter(
- builtin_part, title, LaTeXDoc(text, title, None)
- )
- builtins = builtins_by_module[module.__name__]
- # FIXME: some Box routines, like RowBox *are*
- # documented
- sections = [
- builtin
- for builtin in builtins
- if not builtin.__class__.__name__.endswith("Box")
- ]
- if module.__file__.endswith("__init__.py"):
- # We have a Guide Section.
- name = get_doc_name_from_module(module)
- guide_section = self.add_section(
- chapter, name, module, operator=None, is_guide=True
- )
- submodules = [
- value
- for value in module.__dict__.values()
- if isinstance(value, ModuleType)
- ]
-
- sorted_submodule = lambda x: sorted(
- submodules,
- key=lambda submodule: submodule.sort_order
- if hasattr(submodule, "sort_order")
- else submodule.__name__,
- )
-
- # Add sections in the guide section...
- for submodule in sorted_submodule(submodules):
-
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
- if submodule.__doc__ is None:
- continue
- elif IS_PYPY and submodule.__name__ == "builtins":
- # PyPy seems to add this module on its own,
- # but it is not something that can be importable
- continue
-
- if submodule in modules_seen:
- continue
-
- section = self.add_section(
- chapter,
- get_doc_name_from_module(submodule),
- submodule,
- operator=None,
- is_guide=False,
- in_guide=True,
- )
- modules_seen.add(submodule)
- guide_section.subsections.append(section)
- builtins = builtins_by_module[submodule.__name__]
-
- subsections = [
- builtin
- for builtin in builtins
- if not builtin.__class__.__name__.endswith("Box")
- ]
- for instance in subsections:
- modules_seen.add(instance)
- name = instance.get_name(short=True)
- self.add_subsection(
- chapter,
- section,
- instance.get_name(short=True),
- instance,
- instance.get_operator(),
- in_guide=True,
- )
- else:
- for instance in sections:
- if instance not in modules_seen:
- name = instance.get_name(short=True)
- self.add_section(
- chapter,
- instance.get_name(short=True),
- instance,
- instance.get_operator(),
- is_guide=False,
- in_guide=False,
- )
- modules_seen.add(instance)
- pass
- pass
- pass
- builtin_part.chapters.append(chapter)
- self.parts.append(builtin_part)
-
- for part in appendix:
- self.parts.append(part)
-
- # set keys of tests
- for tests in self.get_tests(want_sorting=want_sorting):
- for test in tests.tests:
- test.key = (tests.part, tests.chapter, tests.section, test.index)
-
- def add_section(
- self,
- chapter,
- section_name: str,
- section_object,
- operator,
- is_guide: bool = False,
- in_guide: bool = False,
- ):
- """
- Adds a DocSection or DocGuideSection
- object to the chapter, a DocChapter object.
- "section_object" is either a Python module or a Class object instance.
- """
- installed = check_requires_list(getattr(section_object, "requires", []))
-
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
- if not section_object.__doc__:
- return
- if is_guide:
- section = LaTeXDocGuideSection(
- chapter,
- section_name,
- section_object.__doc__,
- section_object,
- installed=installed,
- )
- chapter.guide_sections.append(section)
- else:
- section = LaTeXDocSection(
- chapter,
- section_name,
- section_object.__doc__,
- operator=operator,
- installed=installed,
- in_guide=in_guide,
- )
- chapter.sections.append(section)
-
- return section
-
- def add_subsection(
- self,
- chapter,
- section,
- subsection_name: str,
- instance,
- operator=None,
- in_guide=False,
- ):
- installed = check_requires_list(getattr(instance, "requires", []))
-
- # FIXME add an additional mechanism in the module
- # to allow a docstring and indicate it is not to go in the
- # user manual
-
- if not instance.__doc__:
- return
- subsection = LaTeXDocSubsection(
- chapter,
- section,
- subsection_name,
- instance.__doc__,
- operator=operator,
- installed=installed,
- in_guide=in_guide,
- )
- section.subsections.append(subsection)
+ self.gather_doc_data()
def latex(
self,
diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py
index de1c46a93..63234b066 100644
--- a/mathics/docpipeline.py
+++ b/mathics/docpipeline.py
@@ -25,8 +25,7 @@
from mathics.core.evaluation import Evaluation, Output
from mathics.core.parser import MathicsSingleLineFeeder
from mathics.doc.common_doc import MathicsMainDocumentation
-
-# from mathics.eval.pymathics import eval_LoadModule
+from mathics.eval.pymathics import PyMathicsLoadException, eval_LoadModule
from mathics.timing import show_lru_cache_statistics
builtins = builtins_dict()
@@ -486,11 +485,13 @@ def main():
help="stores the output in [logfilename]. ",
)
parser.add_argument(
- "--pymathics",
+ "--load-module",
"-l",
dest="pymathics",
- action="store_true",
- help="also checks pymathics modules.",
+ metavar="MATHIC3-MODULES",
+ help="load Mathics3 module MATHICS3-MODULES. "
+ "You can list multiple Mathics3 Modules by adding a comma (and no space) in between "
+ "module names.",
)
parser.add_argument(
"--time-each",
@@ -554,11 +555,12 @@ def main():
action="store_true",
help="print cache statistics",
)
- # FIXME: there is some weird interacting going on with
- # mathics when tests in sorted order. Some of the Plot
- # show a noticeable 2 minute delay in processing.
- # I think the problem is in Mathics itself rather than
- # sorting, but until we figure that out, use
+ # FIXME: historically was weird interacting going on with
+ # mathics when tests in sorted order. Possibly a
+ # mpmath precsion reset bug.
+ # We see a noticeable 2 minute delay in processing.
+ # WHile the problem is in Mathics itself rather than
+ # sorting, until we get this fixed, use
# sort as an option only. For normal testing we don't
# want it for speed. But for document building which is
# rarely done, we do want sorting of the sections and chapters.
@@ -581,10 +583,24 @@ def main():
global documentation
documentation = MathicsMainDocumentation(want_sorting=args.want_sorting)
+
+ # LoadModule Mathics3 modules
+ if args.pymathics:
+ for module_name in args.pymathics.split(","):
+ try:
+ eval_LoadModule(module_name, definitions)
+ except PyMathicsLoadException:
+ print(f"Python module {module_name} is not a Mathics3 module.")
+
+ except Exception as e:
+ print(f"Python import errors with: {e}.")
+ else:
+ print(f"Mathics3 Module {module_name} loaded")
+
+ documentation.gather_doc_data()
+
if args.sections:
sections = set(args.sections.split(","))
- if args.pymathics: # in case the section is in a pymathics module...
- documentation.load_pymathics_doc()
test_sections(
sections,
@@ -594,18 +610,12 @@ def main():
)
elif args.chapters:
chapters = set(args.chapters.split(","))
- if args.pymathics: # in case the section is in a pymathics module...
- documentation.load_pymathics_doc()
test_chapters(
chapters, stop_on_failure=args.stop_on_failure, reload=args.reload
)
else:
- # if we want to check also the pymathics modules
- if args.pymathics:
- print("Building pymathics documentation object")
- documentation.load_pymathics_doc()
- elif args.doc_only:
+ if args.doc_only:
extract_doc_from_source(
quiet=args.quiet,
reload=args.reload,