Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate TUI documentation #450

Merged
merged 14 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions codegen/data/fluent_gui_help.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35711,8 +35711,7 @@ the periodic repeat.</p>
</sect2>
<sect2 id="flu_meshing_file_start_transcript">
<h3>file/start-transcript</h3>
<p>Starts recording input and output in a file. A transcript file contains a complete record of all standard input to and output from Fluent (usually all keyboard and user interface input and all screen output).Start the transcription process with the <systemitem moreinfo="none">file/start-transcript</systemitem> command, and end it with the <systemitem moreinfo="none">file/stop-</systemitem>
<systemitem moreinfo="none">transcript</systemitem> command (or by exiting the program). <indexterm significance="normal">
<p>Starts recording input and output in a file. A transcript file contains a complete record of all standard input to and output from Fluent (usually all keyboard and user interface input and all screen output).Start the transcription process with the <systemitem moreinfo="none">file/start-transcript</systemitem> command, and end it with the <systemitem moreinfo="none">file/stop-transcript</systemitem> command (or by exiting the program). <indexterm significance="normal">
Copy link
Collaborator

@dnwillia-work dnwillia-work Jun 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not read this content from the Fluent install used to generate the TUI doc? No need to change it, just wondering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should copy this file from the docker image instead of checking it in. For now, I'll create an issue for tracking.

<primary>file/start-transcript</primary>
</indexterm>
<indexterm significance="normal">
Expand Down
110 changes: 107 additions & 3 deletions codegen/tuigen.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import os
from pathlib import Path
import string
from typing import Iterable
import xml.etree.ElementTree as ET

Expand Down Expand Up @@ -53,6 +54,48 @@
)
_INDENT_STEP = 4

_MESHING_TUI_DOC_DIR = os.path.normpath(
os.path.join(
_THIS_DIRNAME,
"..",
"doc",
"source",
"api",
"core",
"meshing",
"tui",
)
)
_SOLVER_TUI_DOC_DIR = os.path.normpath(
os.path.join(
_THIS_DIRNAME,
"..",
"doc",
"source",
"api",
"core",
"solver",
"tui",
)
)

menu_descriptions = {
"solver.tui": """The PyFluent solver text user interface (TUI) API is provided to command the
Fluent solver using commands that are Pythonic versions of the TUI commands used
in the Fluent console. Much like Fluent's TUI the API provides a hierarchical
interface to the underlying procedural interface of the program.

The solver TUI API does not support Fluent TUI features such as aliases or
command abbreviation. As an alternative, using this API in an interactive
session is easier if you install a tool such as
`pyreadline3 <https://github.com/pyreadline3/pyreadline3>`_ which provides
both command line completion and history. You can also use Python standard
`help` and `dir` commands on any object in the API to inspect it further.

The TUI based examples in our gallery provide a guide for how to use this API.
"""
}

_XML_HELP_FILE = os.path.normpath(
os.path.join(_THIS_DIRNAME, "data", "fluent_gui_help.xml")
)
Expand Down Expand Up @@ -113,11 +156,18 @@ def __init__(
self,
meshing_tui_file: str = _MESHING_TUI_FILE,
solver_tui_file: str = _SOLVER_TUI_FILE,
meshing_tui_doc_dir: str = _MESHING_TUI_DOC_DIR,
solver_tui_doc_dir: str = _SOLVER_TUI_DOC_DIR,
meshing: bool = False,
):
self._tui_file = meshing_tui_file if meshing else solver_tui_file
if Path(self._tui_file).exists():
Path(self._tui_file).unlink()
self._tui_doc_dir = meshing_tui_doc_dir if meshing else solver_tui_doc_dir
self._tui_heading = ("meshing" if meshing else "solver") + ".tui"
self._tui_module = "ansys.fluent.core." + self._tui_heading
if Path(self._tui_doc_dir).exists():
Path(self._tui_doc_dir).unlink()
self.session = pyfluent.launch_fluent(meshing_mode=meshing)
self._service = self.session._datamodel_service_tui
self._main_menu = _TUIMenu([])
Expand All @@ -127,10 +177,14 @@ def _populate_menu(self, menu: _TUIMenu):
if not menu.doc:
menu.doc = menugen.get_doc_string()
menu.doc = menu.doc.replace("\\*", "*")
menu.doc = menu.doc.replace("*", "\*")
menu.doc = menu.doc.strip()
if not menu.doc.endswith("."):
menu.doc = menu.doc + "."
child_names = menugen.get_child_names()
if child_names:
for child_name in child_names:
if child_name:
if child_name and not all(x in string.punctuation for x in child_name):
child_menu = _TUIMenu(menu.path + [child_name])
menu.children[child_menu.name] = child_menu
self._populate_menu(child_menu)
Expand All @@ -147,7 +201,9 @@ def _write_menu_to_tui_file(self, menu: _TUIMenu, indent: int = 0):
self._write_code_to_tui_file('"""\n', indent)
doc_lines = menu.doc.splitlines()
for line in doc_lines:
self._write_code_to_tui_file(f"{line}\n", indent)
line = line.strip()
if line:
self._write_code_to_tui_file(f"{line}\n", indent)
self._write_code_to_tui_file('"""\n', indent)
self._write_code_to_tui_file("def __init__(self, path, service):\n", indent)
indent += 1
Expand All @@ -173,7 +229,9 @@ def _write_menu_to_tui_file(self, menu: _TUIMenu, indent: int = 0):
self._write_code_to_tui_file('"""\n', indent)
doc_lines = menu.children[command].doc.splitlines()
for line in doc_lines:
self._write_code_to_tui_file(f"{line}\n", indent)
line = line.strip()
if line:
self._write_code_to_tui_file(f"{line}\n", indent)
self._write_code_to_tui_file('"""\n', indent)
self._write_code_to_tui_file(
f"return PyMenu(self.service, "
Expand All @@ -186,6 +244,46 @@ def _write_menu_to_tui_file(self, menu: _TUIMenu, indent: int = 0):
if not v.is_command:
self._write_menu_to_tui_file(v, indent)

def _write_doc_for_menu(self, menu, doc_dir: Path, heading, class_name) -> None:
doc_dir.mkdir(exist_ok=True)
index_file = doc_dir / "index.rst"
with open(index_file, "w", encoding="utf8") as f:
ref = "_ref_" + "_".join([x.strip("_") for x in heading.split(".")])
f.write(f".. {ref}:\n\n")
heading_ = heading.replace("_", "\_")
f.write(f"{heading_}\n")
f.write(f"{'=' * len(heading_)}\n")
desc = menu_descriptions.get(heading)
if desc:
f.write(desc)
f.write("\n")
f.write(f".. currentmodule:: {self._tui_module}\n\n")
f.write(".. autosummary::\n")
f.write(" :toctree: _autosummary\n\n")

command_names = [v.name for _, v in menu.children.items() if v.is_command]
child_menu_names = [
v.name for _, v in menu.children.items() if not v.is_command
]

f.write(f".. autoclass:: {self._tui_module}::{class_name}\n")
if command_names:
f.write(f" :members: {', '.join(command_names)}\n\n")

if child_menu_names:
f.write(".. toctree::\n")
f.write(" :hidden:\n\n")

for _, v in menu.children.items():
if not v.is_command:
f.write(f" {v.name}/index\n")
self._write_doc_for_menu(
v,
doc_dir / v.name,
heading + "." + v.name,
class_name + "." + v.name,
)

def generate(self) -> None:
Path(self._tui_file).parent.mkdir(exist_ok=True)
with open(self._tui_file, "w", encoding="utf8") as self.__writer:
Expand All @@ -207,6 +305,12 @@ def generate(self) -> None:
)
self._main_menu.name = "main_menu"
self._write_menu_to_tui_file(self._main_menu)
self._write_doc_for_menu(
self._main_menu,
Path(self._tui_doc_dir),
self._tui_heading,
self._main_menu.name,
)


def generate():
Expand Down
2 changes: 1 addition & 1 deletion doc/source/api/core/meshing/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ TUI Commands Example
:maxdepth: 2
:hidden:

tui
tui/index
29 changes: 0 additions & 29 deletions doc/source/api/core/meshing/tui.rst

This file was deleted.

2 changes: 1 addition & 1 deletion doc/source/api/core/solver/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ Solver
:hidden:

settings
tui
tui/index
44 changes: 0 additions & 44 deletions doc/source/api/core/solver/tui.rst

This file was deleted.

1 change: 1 addition & 0 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def _stop_fluent_container(gallery_conf, fname):
"additional_breadcrumbs": [
("PyAnsys", "https://docs.pyansys.com/"),
],
"navigation_depth": -1,
}

# -- Options for HTMLHelp output ---------------------------------------------
Expand Down