Skip to content

Commit

Permalink
Feature/50 Index page to be compatible with html projects (#60)
Browse files Browse the repository at this point in the history
* Index page is compatible with html projects (mdoc viewer).
  • Loading branch information
MobiTikula authored Nov 4, 2024
1 parent a17b3b9 commit 77d7078
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 42 deletions.
123 changes: 104 additions & 19 deletions living_documentation_generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,18 @@ class LivingDocumentationGenerator:
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

ISSUE_PAGE_TEMPLATE_FILE = os.path.join(PROJECT_ROOT, os.pardir, "templates", "issue_detail_page_template.md")
INDEX_PAGE_TEMPLATE_FILE = os.path.join(PROJECT_ROOT, os.pardir, "templates", "_index_page_template.md")
INDEX_NO_STRUCT_TEMPLATE_FILE = os.path.join(
PROJECT_ROOT, os.pardir, "templates", "_index_no_struct_page_template.md"
)
INDEX_ROOT_LEVEL_TEMPLATE_FILE = os.path.join(
PROJECT_ROOT, os.pardir, "templates", "_index_root_level_page_template.md"
)
INDEX_ORG_LEVEL_TEMPLATE_FILE = os.path.join(
PROJECT_ROOT, os.pardir, "templates", "_index_org_level_page_template.md"
)
INDEX_REPO_LEVEL_TEMPLATE_FILE = os.path.join(
PROJECT_ROOT, os.pardir, "templates", "_index_repo_level_page_template.md"
)

def __init__(self):
github_token = ActionInputs.get_github_token()
Expand Down Expand Up @@ -280,7 +291,10 @@ def _generate_markdown_pages(self, issues: dict[str, ConsolidatedIssue]) -> None
@param issues: A dictionary containing all consolidated issues.
"""
issue_page_detail_template = None
issue_index_page_template = None
index_page_template = None
index_root_level_page = None
index_org_level_template = None
index_repo_level_template = None

# Load the template files for generating the Markdown pages
try:
Expand All @@ -290,22 +304,50 @@ def _generate_markdown_pages(self, issues: dict[str, ConsolidatedIssue]) -> None
logger.error("Issue page template file was not successfully loaded.", exc_info=True)

try:
with open(LivingDocumentationGenerator.INDEX_PAGE_TEMPLATE_FILE, "r", encoding="utf-8") as f:
issue_index_page_template = f.read()
with open(LivingDocumentationGenerator.INDEX_NO_STRUCT_TEMPLATE_FILE, "r", encoding="utf-8") as f:
index_page_template = f.read()
except IOError:
logger.error("Index page template file was not successfully loaded.", exc_info=True)

try:
with open(LivingDocumentationGenerator.INDEX_ROOT_LEVEL_TEMPLATE_FILE, "r", encoding="utf-8") as f:
index_root_level_page = f.read()
except IOError:
logger.error(
"Structured index page template file for root level was not successfully loaded.", exc_info=True
)

try:
with open(LivingDocumentationGenerator.INDEX_ORG_LEVEL_TEMPLATE_FILE, "r", encoding="utf-8") as f:
index_org_level_template = f.read()
except IOError:
logger.error(
"Structured index page template file for organization level was not successfully loaded.", exc_info=True
)

try:
with open(LivingDocumentationGenerator.INDEX_REPO_LEVEL_TEMPLATE_FILE, "r", encoding="utf-8") as f:
index_repo_level_template = f.read()
except IOError:
logger.error(
"Structured index page template file for repository level was not successfully loaded.", exc_info=True
)

# Generate a markdown page for every issue
for consolidated_issue in issues.values():
self._generate_md_issue_page(issue_page_detail_template, consolidated_issue)
logger.info("Markdown page generation - generated `%s` issue pages.", len(issues))

# Generate an index page with a summary table about all issues
if ActionInputs.get_is_structured_output_enabled():
self._generate_structured_index_page(issue_index_page_template, issues)
self._generate_structured_index_pages(index_repo_level_template, index_org_level_template, issues)

output_path = ActionInputs.get_output_directory()
with open(os.path.join(output_path, "_index.md"), "w", encoding="utf-8") as f:
f.write(index_root_level_page)
else:
issues = list(issues.values())
self._generate_index_page(issue_index_page_template, issues)
self._generate_index_page(index_page_template, issues)
logger.info("Markdown page generation - generated `_index.md`")

def _generate_md_issue_page(self, issue_page_template: str, consolidated_issue: ConsolidatedIssue) -> None:
Expand Down Expand Up @@ -347,13 +389,17 @@ def _generate_md_issue_page(self, issue_page_template: str, consolidated_issue:

logger.debug("Generated Markdown page: %s.", page_filename)

def _generate_structured_index_page(
self, issue_index_page_template: str, consolidated_issues: dict[str, ConsolidatedIssue]
def _generate_structured_index_pages(
self,
index_repo_level_template: str,
index_org_level_template: str,
consolidated_issues: dict[str, ConsolidatedIssue],
) -> None:
"""
Generates a structured index page with a summary of one repository issues.
Generates a set of index pages due to a structured output feature.
@param issue_index_page_template: The template string for generating the index markdown page.
@param index_repo_level_template: The template string for generating the repository level index markdown page.
@param index_org_level_template: The template string for generating the organization level index markdown page.
@param consolidated_issues: A dictionary containing all consolidated issues.
@return: None
"""
Expand All @@ -367,8 +413,20 @@ def _generate_structured_index_page(

# Generate an index page for each repository
for repository_id, issues in issues_by_repository.items():
self._generate_index_page(issue_index_page_template, issues, repository_id)
logger.info("Markdown page generation - generated `_index.md` for %s.", repository_id)
organization_name, _ = repository_id.split("/")

self._generate_org_level_index_page(index_org_level_template, organization_name)
logger.debug(
"Generated organization level `_index.md` for %s as a cause of structured output feature.",
organization_name,
)

self._generate_index_page(index_repo_level_template, issues, repository_id)
logger.debug(
"Generated repository level `_index.md` for %s as a cause of structured output feature.", repository_id
)

logger.info("Markdown page generation - generated `_index.md` pages for %s.", repository_id)

def _generate_index_page(
self, issue_index_page_template: str, consolidated_issues: list[ConsolidatedIssue], repository_id: str = None
Expand All @@ -395,9 +453,12 @@ def _generate_index_page(
# Prepare issues replacement for the index page
replacement = {
"date": datetime.now().strftime("%Y-%m-%d"),
"issues": issue_table,
"issue-overview-table": issue_table,
}

if ActionInputs.get_is_structured_output_enabled():
replacement["repository_name"] = repository_id.split("/")[1]

# Replace the issue placeholders in the index template
index_page = issue_index_page_template.format(**replacement)

Expand All @@ -409,6 +470,29 @@ def _generate_index_page(
with open(os.path.join(index_directory_path, "_index.md"), "w", encoding="utf-8") as f:
f.write(index_page)

@staticmethod
def _generate_org_level_index_page(index_org_level_template: str, organization_name: str) -> None:
"""
Generates an organization level index page and save it.
@param index_org_level_template: The template string for generating the organization level index markdown page.
@param organization_name: The name of the organization.
@return: None
"""
# Prepare issues replacement for the index page
replacement = {
"date": datetime.now().strftime("%Y-%m-%d"),
"organization_name": organization_name,
}

# Replace the issue placeholders in the index template
org_level_index_page = index_org_level_template.format(**replacement)

# Create a sub index page file
output_path = os.path.join(ActionInputs.get_output_directory(), organization_name)
with open(os.path.join(output_path, "_index.md"), "w", encoding="utf-8") as f:
f.write(org_level_index_page)

@staticmethod
def _generate_markdown_line(consolidated_issue: ConsolidatedIssue) -> str:
"""
Expand All @@ -422,7 +506,8 @@ def _generate_markdown_line(consolidated_issue: ConsolidatedIssue) -> str:
number = consolidated_issue.number
title = consolidated_issue.title
title = title.replace("|", " _ ")
page_filename = consolidated_issue.generate_page_filename()
issue_link_base = consolidated_issue.title.replace(" ", "-").lower()
issue_mdoc_link = f"features#{issue_link_base}"
url = consolidated_issue.html_url
state = consolidated_issue.state

Expand All @@ -438,14 +523,14 @@ def _generate_markdown_line(consolidated_issue: ConsolidatedIssue) -> str:

# Generate the Markdown issue line WITH extra project data
md_issue_line = (
f"| {organization_name} | {repository_name} | [#{number} - {title}]({page_filename}) |"
f" {linked_to_project} | {status} |[GitHub link]({url}) |\n"
f"| {organization_name} | {repository_name} | [#{number} - {title}]({issue_mdoc_link}) |"
f" {linked_to_project} | {status} |<a href='{url}' target='_blank'>GitHub link</a> |\n"
)
else:
# Generate the Markdown issue line WITHOUT project data
md_issue_line = (
f"| {organization_name} | {repository_name} | [#{number} - {title}]({page_filename}) |"
f" {state} |[GitHub link]({url}) |\n"
f"| {organization_name} | {repository_name} | [#{number} - {title}]({issue_mdoc_link}) |"
f" {state} |<a href='{url}' target='_blank'>GitHub link</a> |\n"
)

return md_issue_line
Expand All @@ -464,7 +549,7 @@ def _generate_issue_summary_table(consolidated_issue: ConsolidatedIssue) -> str:

# Format issue URL as a Markdown link
issue_url = consolidated_issue.html_url
issue_url = f"[GitHub link]({issue_url})" if issue_url else None
issue_url = f"<a href='{issue_url}' target='_blank'>GitHub link</a> " if issue_url else None

# Define the header for the issue summary table
headers = [
Expand Down
2 changes: 1 addition & 1 deletion living_documentation_generator/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def sanitize_filename(filename: str) -> str:
@return: The sanitized filename
"""
# Remove invalid characters for Windows filenames
sanitized_name = re.sub(r'[<>:"/|?*`]', "", filename)
sanitized_name = re.sub(r'[<>:"/|?*#{}()`]', "", filename)
# Reduce consecutive periods
sanitized_name = re.sub(r"\.{2,}", ".", sanitized_name)
# Reduce consecutive spaces to a single space
Expand Down
21 changes: 21 additions & 0 deletions templates/_index_no_struct_page_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Features
toolbar_title: Features
description_title: Living Documentation
description: >
This is a comprehensive list and brief overview of all mined features.
date: {date}
weight: 0
---

<h1>Feature Summary page</h1>

Our project is designed with a myriad of features to ensure seamless user experience, top-tier functionality, and efficient operations. Here, you'll find a summarized list of all these features, their brief descriptions, and links to their detailed documentation.

<h2>Feature Overview</h2>

<div class="cps-table sortable searchable filterableByColumns paginator">

{issue-overview-table}

</div>
7 changes: 7 additions & 0 deletions templates/_index_org_level_page_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: "{organization_name}"
date: {date}
weight: 0
---

This section displays the living documentation for all repositories within the organization: {organization_name} in a structured output.
16 changes: 0 additions & 16 deletions templates/_index_page_template.md

This file was deleted.

19 changes: 19 additions & 0 deletions templates/_index_repo_level_page_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: "{repository_name}"
date: {date}
weight: 0
---

This section displays all the information about mined features for the repository: {repository_name}.

<h3>Feature Summary page</h3>

Our project is designed with a myriad of features to ensure seamless user experience, top-tier functionality, and efficient operations. Here, you'll find a summarized list of all these features, their brief descriptions, and links to their detailed documentation.

<h4>Feature Overview</h4>

<div class="cps-table sortable searchable filterableByColumns paginator">

{issue-overview-table}

</div>
9 changes: 9 additions & 0 deletions templates/_index_root_level_page_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Liv Doc
toolbar_title: Features
description_title: Living Documentation
description: >
This is a comprehensive list and brief overview of all mined features.
date: {date}
weight: 0
---
8 changes: 3 additions & 5 deletions templates/issue_detail_page_template.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
---
title: "{title}"
date: "{date}"
date: {date}
weight: 1
---

# {page_issue_title}

{issue_summary_table}

## Issue Content
<h3>Issue Content</h3>

{issue_content}
2 changes: 1 addition & 1 deletion tests/utils/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_make_issue_key():
@pytest.mark.parametrize(
"filename_example, expected_filename",
[
("in<>va::lid//.fi|le?na*me.txt", "invalid.filename.txt"), # Remove invalid characters for Windows filenames
("in<>va::l#(){}id//.fi|le?*.txt", "invalid.file.txt"), # Remove invalid characters for Windows filenames
("another..invalid...filename.txt", "another.invalid.filename.txt"), # Reduce consecutive periods
(
"filename with spaces.txt",
Expand Down

0 comments on commit 77d7078

Please sign in to comment.