Skip to content

Commit 78e8db8

Browse files
authored
Merge pull request #173 from Dyalog/chm-toplevel-pages
Allow for top-level file elements in the monorepo nav
2 parents 20247e7 + 29e669c commit 78e8db8

File tree

2 files changed

+54
-27
lines changed

2 files changed

+54
-27
lines changed

chm/mkdocs2chm.py

+41-23
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def purge_css(css: str, html_content: str) -> str:
369369
# Serialise the new stylesheet
370370
return new_stylesheet.cssText.decode('utf-8')
371371

372-
def convert_to_html(filenames: List[str], css: str, macros: dict, transforms: List[Callable[[str], str]], project) -> List[str]:
372+
def convert_to_html(filenames: List[str], css: str, macros: dict, transforms: List[Callable[[str], str]], project: str, top_level_files: List[str]) -> List[str]:
373373
"""
374374
Convert each Markdown file and convert to HTML, using the same rendering library as
375375
mkdocs, with the same set of extensions. We expand the mkdocs-macro {{ templates }}
@@ -392,14 +392,18 @@ def convert_to_html(filenames: List[str], css: str, macros: dict, transforms: Li
392392
converted: List[str] = []
393393

394394
for file in filenames:
395-
# Handle both root-level files and files in docs subdirectories
396-
if '/docs/' in file:
395+
if file in top_level_files:
396+
# Top-level files go directly in project/
397+
newname = os.path.basename(file).replace('.md', '.htm')
398+
elif '/docs/' in file:
399+
# Sub-site files go in project/sub-site/
397400
path, oldname = file.split('/docs/', maxsplit=1)
398-
newname = str(os.path.join(os.path.basename(path), oldname.replace('.md', '.htm')))
401+
sub_site = os.path.basename(path)
402+
newname = os.path.join(sub_site, oldname.replace('.md', '.htm'))
399403
else:
400-
# For root-level files, just use the basename
404+
# Fallback for files without /docs/
401405
newname = os.path.basename(file).replace('.md', '.htm')
402-
406+
403407
realpath_newname = str(os.path.join(project, newname))
404408
os.makedirs(os.path.dirname(realpath_newname), exist_ok=True)
405409

@@ -581,22 +585,31 @@ def write_index_data(entries: List[Tuple[str, str]], filename: str) -> None:
581585
idxfh.write("</body></html>\n")
582586

583587

584-
def find_toplevel_dirs(filename: str, remove: List[str]) -> List[str]:
588+
def find_nav_files_and_dirs(filename: str, remove: List[str]) -> Tuple[List[str], List[str]]:
585589
"""
586-
Find the toplevel document dirs -- these are the ones that are
587-
pulled into the main mkdocs.yml file via !include
590+
Extract both top-level directories (from !include directives) and standalone Markdown files
591+
directly listed in the nav section of the mkdocs.yml file.
592+
593+
Returns:
594+
Tuple[List[str], List[str]]: (included_dirs, standalone_files)
588595
"""
589596
yaml = YAML()
590-
with (open(filename, 'r', encoding='utf-8')) as f:
597+
with open(filename, 'r', encoding='utf-8') as f:
591598
data = yaml.load(f)
592-
tlds = []
599+
600+
included_dirs = []
601+
standalone_files = []
602+
593603
for d in data['nav']:
594604
key, value = next(iter(d.items()))
595605
if key not in remove:
596-
if m := re.match(r'!include\s+([^"]+)', value):
597-
tlds.append(m.group(1))
598-
599-
return tlds
606+
if isinstance(value, str):
607+
if m := re.match(r'!include\s+([^"]+)', value):
608+
included_dirs.append(m.group(1)) # Path from !include
609+
elif value.endswith('.md'):
610+
standalone_files.append(os.path.join('docs', value)) # Direct .md file reference
611+
612+
return included_dirs, standalone_files
600613

601614

602615
def generate_hfp(project: str, chmfile: str, files: List[str], images: List[str], assets: List[str], title: str) -> None:
@@ -878,9 +891,7 @@ def filter_unused_images(md_files: List[str], css_files: List[str], image_files:
878891

879892
os.makedirs(args.project_dir, exist_ok=True)
880893

881-
# Parse the nav section. If this is a monorepo (in 99% of the cases it will be),
882-
# macro-expand any !include directives
883-
894+
# Parse config for excludes
884895
excludes = []
885896
if args.config:
886897
try:
@@ -890,15 +901,22 @@ def filter_unused_images(md_files: List[str], css_files: List[str], image_files:
890901
except (json.JSONDecodeError, FileNotFoundError) as e:
891902
sys.exit(f'--> Error reading config file: {e}')
892903

904+
# Parse mkdocs.yml
893905
yml_data = parse_mkdocs_yml(args.mkdocs_yml, remove=excludes)
894-
includes = find_toplevel_dirs(args.mkdocs_yml, remove=excludes)
906+
907+
# Find top-level dirs and standalone files from nav
908+
included_dirs, standalone_files = find_nav_files_and_dirs(args.mkdocs_yml, remove=excludes)
895909

896910
version = yml_data["extra"].get("version_majmin")
897911
if not version:
898912
sys.exit(f'--> source mkdocs.yml has no Dyalog version set')
899913

900-
# Find all source Markdown files and images
901-
md_files, image_files = find_source_files(os.path.dirname(args.mkdocs_yml), includes)
914+
# Find all source Markdown files from included directories
915+
md_files_from_dirs, image_files = find_source_files(os.path.dirname(args.mkdocs_yml), included_dirs)
916+
917+
# Add standalone Markdown files from nav, with absolute paths
918+
standalone_files_abs = [os.path.abspath(os.path.join(os.path.dirname(args.mkdocs_yml), f)) for f in standalone_files]
919+
md_files = md_files_from_dirs + standalone_files_abs
902920

903921
# Add welcome.md to the start of the files list
904922
md_files.insert(0, os.path.abspath(args.welcome))
@@ -928,7 +946,8 @@ def filter_unused_images(md_files: List[str], css_files: List[str], image_files:
928946
transforms=[
929947
table_captions
930948
],
931-
project=args.project_dir
949+
project=args.project_dir,
950+
top_level_files=standalone_files_abs
932951
)
933952

934953
# Generate the CHM ToC
@@ -942,7 +961,6 @@ def filter_unused_images(md_files: List[str], css_files: List[str], image_files:
942961

943962
# Generate the CHM project config file
944963
chm_name = "dyalog.chm"
945-
946964
generate_hfp(args.project_dir, chm_name, html_files, copied_images, assets, title=f'Dyalog version {version}')
947965

948966
# Run the compiler

pdf/mkdocs2pdf.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -821,14 +821,23 @@ def toc_friendly_headings(soup: BeautifulSoup) -> None:
821821
# Replace the old heading with the new structure
822822
heading.replace_with(heading_container)
823823

824-
825824
def toplevel_docs(nav: List[Dict[str, str]]) -> Dict[str, str]:
826825
result = {}
827826
for entry in nav:
828827
for doc_name, include_path in entry.items():
829-
path = include_path.split(' ')[1]
830-
first_component = path.split('/')[1]
831-
result[first_component] = doc_name
828+
if "!include" in include_path:
829+
# This is a directory include
830+
path = include_path.split(' ')[1]
831+
first_component = path.split('/')[1]
832+
result[first_component] = doc_name
833+
else:
834+
# This is a direct file reference
835+
path_parts = include_path.split('/')
836+
# Use the filename without extension as the key
837+
if len(path_parts) > 0:
838+
filename = path_parts[-1]
839+
file_base = os.path.splitext(filename)[0]
840+
result[file_base] = doc_name
832841
return result
833842

834843
def process_document(document_path):

0 commit comments

Comments
 (0)