cara/caimira/docs/style_docs.py
Nicola Tarocco a34efcac88 Project documentation and CI/CD improvements:
- Added docs folder with MkDocs and Sphinx integration for documentation.
- Updated GitLab CI/CD configuration to include documentation jobs.
- Improved Dockerfile for streamlined builds.
- Added JavaScript file to support MathJax for equations in MkDocs.
- Created and included a UML diagram for architectural overview.
- Removed unused files to clean up the repository.
- Updated project and package README files for consistency.
- Revised diameter-dependent documentation for clarity.
- Added detailed REST API documentation.
- Updated project version for release tracking.
- Included open-source acknowledgments in the documentation.
- Added repository details and UI instructions to the user guide.
- Integrated CO2 fitting algorithm into the project.
- Included logo on the main documentation page and added CI/CD prod job.
2024-11-20 15:23:46 +01:00

219 lines
7.8 KiB
Python

""" Changes the .md files to contain desired styling """
import re
import os
import subprocess
import matplotlib.pyplot as plt
from collections import Counter
def get_package_info():
"""
Retrieves package details (name, version, license, and homepage) for each installed package.
Uses pip show to get detailed information.
"""
# Get the list of installed packages using pip freeze
packages = subprocess.check_output(["pip", "freeze"]).decode().splitlines()
package_details = []
for package in packages:
package_name = package.split("==")[0]
try:
# Get detailed info about each package
info = subprocess.check_output(["pip", "show", package_name]).decode().splitlines()
details = {
"name": package_name,
"version": "",
"license": "",
"homepage": ""
}
for line in info:
if line.startswith("Version:"):
details["version"] = line.split(":", 1)[1].strip()
elif line.startswith("License:"):
details["license"] = line.split(":", 1)[1].strip()
elif line.startswith("Home-page:"):
details["homepage"] = line.split(":", 1)[1].strip()
# Append the details for the current package
package_details.append(details)
except subprocess.CalledProcessError:
print(f"Error retrieving details for package: {package_name}")
return package_details
def update_markdown_references(md_file_path):
"""
Updates the code markdown file by adding headers for class definitions and modifying internal links.
"""
# Read the original Markdown file
with open(md_file_path, 'r') as file:
md_content = file.read()
# Regular expression to find all class definitions, including those without parameters
class_pattern = re.compile(r'### \*class\* (\w+)(\(.*\))?')
# Find all matches for class definitions
class_matches = class_pattern.findall(md_content)
# For each found class definition
for match in class_matches:
# Class name (e.g., 'Interval' or 'ConcentrationModel')
class_name = match[0]
# Create the header for this class
header = f"## {class_name} Class\n"
# Check if the header already exists in the file
if header not in md_content:
# If the header does not exist, insert it before the class definition
md_content = md_content.replace(
f"### *class* {class_name}", header + f"### *class* {class_name}")
# Replace references like #models.models.ClassName with #className-class
md_content = md_content.replace(
f"#models.models.{class_name}", f"#{class_name.lower()}-class")
# Write the updated content back to the file
with open(md_file_path, 'w') as file:
file.write(md_content)
print(f"Markdown file '{md_file_path}' updated successfully.")
def unify_license(license_str):
"""
Returns an unified license version.
"""
license_map = {
'MIT': 'MIT',
'MIT License': 'MIT',
'MIT license': 'MIT',
'MIT-CMU': 'MIT',
'http://www.opensource.org/licenses/mit-license.php': 'MIT',
'BSD': 'BSD-3-Clause',
'BSD-3-Clause': 'BSD-3-Clause',
'BSD 3-Clause License': 'BSD-3-Clause',
'BSD 3-Clause': 'BSD-3-Clause',
'BSD-2-Clause': 'BSD-2-Clause',
'BSD License': 'BSD-3-Clause',
'new BSD License': 'BSD-3-Clause',
'Modified BSD License': 'BSD-3-Clause',
'BSD 2-Clause License': 'BSD-2-Clause',
'Apache 2.0': 'Apache-2.0',
'Apache Software License': 'Apache-2.0',
'Apache 2.0 License': 'Apache-2.0',
'Apache License, Version 2.0': 'Apache-2.0',
'Apache 2.0 license': 'Apache-2.0',
'Apache-2.0': 'Apache-2.0',
'Apache Software License 2.0': 'Apache-2.0',
'MPL-2.0': 'MPL-2.0',
'MPL 2.0': 'MPL-2.0',
'GPL-2.0-or-later': 'GPL-2.0-or-later',
'LGPL-2.1-or-later': 'LGPL-2.1-or-later',
'ISC license': 'ISC',
'Expat license': 'Expat',
'MIT OR Apache-2.0': 'Dual License',
'Dual License': 'Dual License',
'UNKNOWN': 'Unknown'
}
return license_map.get(license_str, 'Custom')
def add_python_dependencies_section(md_file_path, package_details):
"""
Adds the Python package dependencies section to the Open Source Acknowledgments Markdown file.
"""
# Section header for Python dependencies
dependencies_section = '\n\n'
for package in package_details:
package_url = f"https://pypi.org/project/{package['name']}/{package['version']}/"
package_title = f" #### [{package['name']} {package['version']}]({package_url})"
if package["license"]:
license_text = f" - License: {unify_license(package['license'])}"
else:
license_text = " - License: Unknown"
dependencies_section += f"{package_title}\n\n{license_text}\n\n"
# Read the current content of the Markdown file
with open(md_file_path, 'r') as file:
md_content = file.read()
# Regex to find the "Back-end (Python) Dependencies" section
section_pattern = re.compile(
r'(?<=\?\?\? "Back-end \(Python\) Dependencies")(.*?)(?=\n\?\?\?|\Z)', re.DOTALL)
match = section_pattern.search(md_content)
if match:
updated_content = md_content[:match.start(1)] + dependencies_section + md_content[match.end(1):]
else:
raise ValueError("Error: '??? \"Back-end (Python) Dependencies\"' section not found in the file.")
with open(md_file_path, 'w') as file:
file.write(updated_content)
print(f"Markdown file '{md_file_path}' updated with Python dependencies section.")
def generate_license_distribution_pie_chart(package_details, output_image_path):
"""
Generates a pie chart showing the distribution of licenses from the package details.
The chart is saved to the specified output image path.
"""
try:
licenses = [unify_license(pkg["license"]) for pkg in package_details if pkg["license"]]
license_counts = Counter(licenses)
# Create labels and sizes for the pie chart
labels = list(license_counts.keys())
sizes = list(license_counts.values())
# Create the pie chart
plt.figure(figsize=(8, 8), dpi=300)
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)
plt.axis('equal')
# Save and show the pie chart
plt.savefig(output_image_path, dpi=300)
plt.close()
print(f"License distribution pie chart saved to {output_image_path}")
except Exception as e:
print(f"Error generating license distribution chart: {e}")
def main():
# Path to the index.md markdown file to be updated
index_file_path = 'sphinx/_build/markdown/index.md'
if os.path.isfile(index_file_path):
update_markdown_references(index_file_path)
else:
print(f"File '{index_file_path}' does not exist, skipping update.")
# Path to the open source acknowledgements markdown file to be updated
acknowledgements_file_path = 'mkdocs/docs/root/open_source_acknowledgments.md'
if os.path.isfile(acknowledgements_file_path):
# Retrieve package details
package_details = get_package_info()
# Write the dependencies in the file
add_python_dependencies_section(acknowledgements_file_path, package_details)
# Generate the pie chart
output_image_path = 'mkdocs/docs/root/license_distribution.png'
generate_license_distribution_pie_chart(package_details, output_image_path)
else:
print(f"File '{acknowledgements_file_path}' does not exist, skipping update.")
if __name__ == "__main__":
main()