From 70b916cc34b25f11f80ab3b3b4bc410b821e670e Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 5 Aug 2026 17:08:04 +0200 Subject: [PATCH] Copapy logo added to doc page and readme --- README.md | 4 +++ docs/source/conf.py | 8 ++++-- docs/source/extract_section.py | 41 ++++++++++++++++++++++------ docs/source/media/logo.svg | 49 ++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 docs/source/media/logo.svg diff --git a/README.md b/README.md index eae753b..84e9f03 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +
+Copapy logo +
+ # Copapy Copapy is a Python framework for deterministic, low-latency realtime computation with automatic differentiation support, targeting hardware applications - for example in the fields of robotics, aerospace, SDR, embedded systems and control systems in general. diff --git a/docs/source/conf.py b/docs/source/conf.py index c3defd1..ace4171 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,13 +25,17 @@ exclude_patterns = [] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# html_theme = 'alabaster' html_theme = 'pydata_sphinx_theme' html_static_path = ['_static'] +html_title = "Python framework for deterministic, low-latency realtime computation" +html_short_title = "Copapy" +html_logo = 'media/logo.svg' +html_favicon = 'media/logo.svg' html_css_files = ['custom.css'] html_theme_options = { "secondary_sidebar_items": ["page-toc"], - "footer_start": ["copyright"] + "footer_start": ["copyright"], + "logo": {"text": "Copapy"} } html_theme_options["footer_end"] = [] diff --git a/docs/source/extract_section.py b/docs/source/extract_section.py index 177a32c..6b85605 100644 --- a/docs/source/extract_section.py +++ b/docs/source/extract_section.py @@ -2,11 +2,32 @@ import re import argparse import os -def extract_sections(md_text: str) -> dict[str, str]: + +def strip_leading_html_tag(text: str) -> str: + """Remove a leading HTML element if the first non-space character is '<'.""" + trimmed = text.lstrip() + #if not trimmed.startswith('<'): + # return text + + match = re.match( + r'^\s*<\s*(?P[A-Za-z][A-Za-z0-9:-]*)(?:\s+[^<>]*)?>' + r'(?P.*?)(?:)?', + trimmed, + re.DOTALL, + ) + if not match: + return text + + return trimmed[match.end():] + + +def extract_sections(md_text: str) -> dict[str, tuple[str, str]]: """ Extracts sections based on headings (#...). Returns {heading_text: section_content} Works for simple Markdown, not fully strict. + + If strip_first_heading is True, omit the first heading/section from the output. """ # regex captures: heading marks (###...), heading text, and the following content @@ -17,13 +38,17 @@ def extract_sections(md_text: str) -> dict[str, str]: re.MULTILINE | re.DOTALL ) - sections: dict[str, str] = {} - for _, title, content in pattern.findall(md_text): + sections: dict[str, tuple[str, str]] = {} + matched = list(pattern.findall(md_text)) + + for prefix, title, content in matched: assert isinstance(content, str) - sections[title] = content.strip().replace('](docs/source/media/', '](media/') + content = strip_leading_html_tag(content) + sections[title] = (prefix + ' ' + title, content.strip().replace('](docs/source/media/', '](media/')) return sections + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Extract sections from README.md and generate documentation files') parser.add_argument('--readme', type=str, default='README.md', help='README.md path') @@ -37,9 +62,9 @@ if __name__ == '__main__': readme = extract_sections(f.read()) with open(os.path.join(build_dir, 'start.md'), 'wt') as f: - f.write('\n'.join(f"{s}\n" + readme[s.strip(' #')] for s in [ - '# Copapy', '## Current state', '## Install', '## Examples', - '### Basic example', '### Inverse kinematics', '## License'])) + f.write('\n'.join('\n'.join(readme[s]) if s != 'Copapy' else readme[s][1] for s in [ + 'Copapy', 'Current state', 'Install', 'Examples', + 'Basic example', 'Inverse kinematics', 'License'])) with open(os.path.join(build_dir, 'compiler.md'), 'wt') as f: - f.write('\n'.join(readme[s] for s in ['How it works'])) + f.write('\n'.join(readme[s][1] for s in ['How it works'])) diff --git a/docs/source/media/logo.svg b/docs/source/media/logo.svg new file mode 100644 index 0000000..a4df3f8 --- /dev/null +++ b/docs/source/media/logo.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + +