in scripts/convert_ipynb_to_mdx.py [0:0]
def transform_notebook(path: Union[str, PathLike]) -> Tuple[str, str]:
"""Transform the given Jupyter notebook into strings suitable for mdx and jsx files.
Args:
path (Union[str, PathLike]): Path to the Jupyter notebook.
Returns:
Tuple[str, str]: mdx string, jsx string
"""
# Ensure the given path is a pathlib.PosixPath object.
path = Path(path).resolve()
# Load all metadata for notebooks that should be included in the documentation.
nb_metadata = load_nbs_to_convert()
# Create the assets folder for the given tutorial.
tutorial_folder_name = path.stem
filename = "".join([token.title() for token in tutorial_folder_name.split("_")])
tutorial_folder = TUTORIALS_DIR.joinpath(tutorial_folder_name)
assets_folder = tutorial_folder.joinpath("assets")
img_folder = assets_folder.joinpath("img")
plot_data_folder = assets_folder.joinpath("plot_data")
if not tutorial_folder.exists():
tutorial_folder.mkdir(parents=True, exist_ok=True)
if not img_folder.exists():
img_folder.mkdir(parents=True, exist_ok=True)
if not plot_data_folder.exists():
plot_data_folder.mkdir(parents=True, exist_ok=True)
# Load the notebook.
nb = load_notebook(path)
# Begin to build the mdx string.
mdx = ""
# Add the frontmatter to the mdx string. This is the part between the `---` lines
# that define the tutorial sidebar_label information.
frontmatter = "\n".join(
["---"]
+ [
f"{key}: {value}"
for key, value in nb_metadata.get(
tutorial_folder_name,
{
"title": "",
"sidebar_label": "",
"path": "",
"nb_path": "",
"github": "",
"colab": "",
},
).items()
]
+ ["---"]
)
frontmatter_line = len(frontmatter.splitlines())
mdx += f"{frontmatter}\n"
# Create the JSX and components strings.
jsx = ""
components = set()
# Cycle through each cell in the notebook.
bokeh_flags = []
plotly_flags = []
for cell in nb["cells"]:
cell_type = cell["cell_type"]
# Handle markdown cell objects.
if cell_type == "markdown":
mdx += transform_markdown_cell(cell, img_folder)
# Handle code cell objects.
if cell_type == "code":
tx = transform_code_cell(cell, plot_data_folder, filename)
mdx += str(tx["mdx"])
jsx += str(tx["jsx"])
bokeh_flags.append(tx["bokeh"])
plotly_flags.append(tx["plotly"])
for component in str(tx["components"]).splitlines():
components.add(component)
# Add the JSX template object to the jsx string. Only include the plotting component
# that is needed.
bokeh_flag = any(bokeh_flags)
plotly_flag = any(plotly_flags)
plotting_fp = "../../../../website/src/components/Plotting.jsx"
JSX_TEMPLATE = ["import React from 'react';"]
if bokeh_flag:
JSX_TEMPLATE.append(f"import {{ BokehFigure }} from '{plotting_fp}';")
if plotly_flag:
JSX_TEMPLATE.append(f"import {{ PlotlyFigure }} from '{plotting_fp}';")
jsx = "\n".join([item for item in JSX_TEMPLATE if item]) + "\n\n" + jsx
# Remove the last line since it is blank.
jsx = "\n".join(jsx.splitlines()[:-1])
# Add the react components needed to display bokeh objects in the mdx string.
mdx = mdx.splitlines()
mdx[frontmatter_line:frontmatter_line] = list(components) + [""]
# Add the react components needed to display links to GitHub and Colab.
idx = frontmatter_line + len(components) + 1
glk = nb_metadata[tutorial_folder_name]["github"]
clk = nb_metadata[tutorial_folder_name]["colab"]
mdx[idx:idx] = (
f'<LinkButtons\n githubUrl="{glk}"\n colabUrl="{clk}"\n/>\n\n'
).splitlines()
mdx = "\n".join(mdx)
# Write the mdx file to disk.
mdx_filename = str(tutorial_folder.joinpath(f"{filename}.mdx"))
with open(mdx_filename, "w") as f:
f.write(mdx)
# Write the jsx file to disk.
jsx_filename = str(tutorial_folder.joinpath(f"{filename}.jsx"))
with open(jsx_filename, "w") as f:
f.write(jsx)
# Return the mdx and jsx strings for debugging purposes.
return mdx, jsx