Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit 17f6ca0

Browse files
authored
feat: use GitHub's default README as index page (#255)
* feat: use GitHub's default README as index page * feat: address review comemnts
1 parent b786611 commit 17f6ca0

4 files changed

Lines changed: 115 additions & 28 deletions

File tree

docfx_yaml/extension.py

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,33 @@ def highlight_md_codeblocks(mdfile):
14291429
mdfile_iterator.write(new_content)
14301430

14311431

1432+
def clean_image_links(mdfile_path: str) -> None:
1433+
"""Cleans extra whitespace that breaks image links in index.html file."""
1434+
image_link_pattern='\[\s*!\[image\]\(.*\)\s*\]\(.*\)'
1435+
new_lines = []
1436+
with open(mdfile_path) as mdfile:
1437+
file_content = mdfile.read()
1438+
1439+
prev_start = prev_end = 0
1440+
1441+
for matched_obj in re.finditer(image_link_pattern, file_content):
1442+
start = matched_obj.start()
1443+
end = matched_obj.end()
1444+
matched_str = file_content[start:end]
1445+
# Clean up all whitespaces for the image link.
1446+
clean_str = ''.join(matched_str.split())
1447+
1448+
new_lines.append(file_content[prev_end:start])
1449+
new_lines.append(clean_str)
1450+
prev_start, prev_end = start, end
1451+
1452+
new_lines.append(file_content[prev_end:])
1453+
1454+
with open(mdfile_path, 'w') as mdfile:
1455+
new_content = ''.join(new_lines)
1456+
mdfile.write(new_content)
1457+
1458+
14321459
def prepend_markdown_header(filename: str, mdfile: Iterable[str]):
14331460
"""Prepends the filename as a Markdown header.
14341461
@@ -1448,16 +1475,16 @@ def prepend_markdown_header(filename: str, mdfile: Iterable[str]):
14481475
def find_markdown_pages(app, outdir):
14491476
# Use this to ignore markdown files that are unnecessary.
14501477
files_to_ignore = [
1451-
"index.md", # merge index.md and README.md and index.yaml later.
1452-
# See https://github.com/googleapis/sphinx-docfx-yaml/issues/105.
1478+
"index.md", # use readme.md instead
14531479

14541480
"reference.md", # Reference docs overlap with Overview. Will try and incorporate this in later.
14551481
# See https://github.com/googleapis/sphinx-docfx-yaml/issues/106.
1456-
1457-
"readme.md", # README does not seem to work in cloud site
1458-
# See https://github.com/googleapis/sphinx-docfx-yaml/issues/107.
14591482
]
14601483

1484+
files_to_rename = {
1485+
'readme.md': 'index.md',
1486+
}
1487+
14611488
markdown_dir = Path(app.builder.outdir).parent / "markdown"
14621489
if not markdown_dir.exists():
14631490
print("There's no markdown file to move.")
@@ -1467,7 +1494,6 @@ def find_markdown_pages(app, outdir):
14671494
for mdfile in markdown_dir.iterdir():
14681495
if mdfile.is_file() and mdfile.name.lower() not in files_to_ignore:
14691496
mdfile_name = ""
1470-
highlight_md_codeblocks(markdown_dir / mdfile.name)
14711497

14721498
# Extract the header name for TOC.
14731499
with open(mdfile) as mdfile_iterator:
@@ -1482,12 +1508,30 @@ def find_markdown_pages(app, outdir):
14821508

14831509
prepend_markdown_header(name, mdfile_iterator)
14841510

1485-
shutil.copy(mdfile, f"{outdir}/{mdfile.name.lower()}")
1511+
mdfile_name_to_use = mdfile.name.lower()
1512+
if mdfile_name_to_use in files_to_rename:
1513+
mdfile_name_to_use = files_to_rename[mdfile_name_to_use]
1514+
1515+
mdfile_outdir = f"{outdir}/{mdfile_name_to_use}"
1516+
1517+
shutil.copy(mdfile, mdfile_outdir)
1518+
1519+
highlight_md_codeblocks(mdfile_outdir)
1520+
clean_image_links(mdfile_outdir)
1521+
1522+
# Use Overview as the name for index file.
1523+
if mdfile_name_to_use == 'index.md':
1524+
# Place the Overview page at the top of the list.
1525+
app.env.markdown_pages.insert(
1526+
0,
1527+
{'name':'Overview', 'href': 'index.md'}
1528+
)
1529+
continue
14861530

14871531
# Add the file to the TOC later.
14881532
app.env.markdown_pages.append({
14891533
'name': name,
1490-
'href': mdfile.name.lower(),
1534+
'href': mdfile_name_to_use,
14911535
})
14921536

14931537
def find_uid_to_convert(
@@ -1941,7 +1985,7 @@ def convert_module_to_package_if_needed(obj):
19411985
dump(
19421986
[{
19431987
'name': app.config.project,
1944-
'items': [{'name': 'Overview', 'uid': 'project-' + app.config.project}] + app.env.markdown_pages + pkg_toc_yaml
1988+
'items': app.env.markdown_pages + pkg_toc_yaml
19451989
}],
19461990
default_flow_style=False,
19471991
)
@@ -2001,25 +2045,6 @@ def convert_module_to_package_if_needed(obj):
20012045
'fullname': item.get('uidname', ''),
20022046
'isExternal': False
20032047
})
2004-
with open(index_file, 'w') as index_file_obj:
2005-
index_file_obj.write('### YamlMime:UniversalReference\n')
2006-
dump(
2007-
{
2008-
'items': [{
2009-
'uid': 'project-' + app.config.project,
2010-
'name': app.config.project,
2011-
'fullName': app.config.project,
2012-
'langs': ['python'],
2013-
'type': 'package',
2014-
'kind': 'distribution',
2015-
'summary': 'Reference API documentation for `{}`.'.format(app.config.project),
2016-
'children': index_children
2017-
}],
2018-
'references': index_references
2019-
},
2020-
index_file_obj,
2021-
default_flow_style=False
2022-
)
20232048

20242049
'''
20252050
# TODO: handle xref for other products.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Python Client for Google Cloud Storage API
2+
3+
[
4+
5+
![image](https://img.shields.io/badge/support-stable-gold.svg)
6+
7+
](https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels) [
8+
9+
![image](https://img.shields.io/pypi/v/google-cloud-storage.svg)
10+
11+
](https://pypi.org/project/google-cloud-storage/) [
12+
13+
![image](https://img.shields.io/pypi/pyversions/google-cloud-storage.svg)
14+
15+
](https://pypi.org/project/google-cloud-storage/)
16+
17+
[Google Cloud Storage API](https://cloud.google.com/storage): is a durable and highly available object storage service. Google Cloud Storage is almost infinitely scalable and guarantees consistency: when a write succeeds, the latest copy of the object will be returned to any GET, globally.
18+
19+
20+
* [Client Library Documentation](https://cloud.google.com/python/docs/reference/storage/latest)
21+
22+
23+
* [Product Documentation](https://cloud.google.com/storage)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Python Client for Google Cloud Storage API
2+
3+
[![image](https://img.shields.io/badge/support-stable-gold.svg)](https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels) [![image](https://img.shields.io/pypi/v/google-cloud-storage.svg)](https://pypi.org/project/google-cloud-storage/) [![image](https://img.shields.io/pypi/pyversions/google-cloud-storage.svg)](https://pypi.org/project/google-cloud-storage/)
4+
5+
[Google Cloud Storage API](https://cloud.google.com/storage): is a durable and highly available object storage service. Google Cloud Storage is almost infinitely scalable and guarantees consistency: when a write succeeds, the latest copy of the object will be returned to any GET, globally.
6+
7+
8+
* [Client Library Documentation](https://cloud.google.com/python/docs/reference/storage/latest)
9+
10+
11+
* [Product Documentation](https://cloud.google.com/storage)

tests/test_helpers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from docfx_yaml.extension import extract_product_name
88
from docfx_yaml.extension import highlight_md_codeblocks
99
from docfx_yaml.extension import prepend_markdown_header
10+
from docfx_yaml.extension import clean_image_links
1011

1112
import unittest
1213
from parameterized import parameterized
@@ -310,6 +311,33 @@ def test_prepend_markdown_header(self, base_filename, want_filename):
310311
self.assertEqual(test_file.read(), mdfile_want.read())
311312

312313

314+
# Filenames to test cleaning up markdown image links.
315+
test_markdown_filenames = [
316+
[
317+
"tests/markdown_example_bad_image_links.md",
318+
"tests/markdown_example_bad_image_links_want.md"
319+
],
320+
]
321+
@parameterized.expand(test_markdown_filenames)
322+
def test_clean_image_links(self, base_filename, want_filename):
323+
# Ensure image links are well formed in markdown files.
324+
325+
# Copy the base file we'll need to test.
326+
with tempfile.NamedTemporaryFile(mode='r+', delete=False) as test_file:
327+
with open(base_filename) as base_file:
328+
# Use same file name extraction as original code.
329+
file_name = base_file.name.split("/")[-1].split(".")[0].capitalize()
330+
test_file.write(base_file.read())
331+
test_file.flush()
332+
test_file.seek(0)
333+
334+
clean_image_links(test_file.name)
335+
test_file.seek(0)
336+
337+
with open(want_filename) as mdfile_want:
338+
self.assertEqual(test_file.read(), mdfile_want.read())
339+
340+
313341
test_reference_params = [
314342
[
315343
# If no reference keyword is found, check for None

0 commit comments

Comments
 (0)