Skip to content

Commit ceb9d8d

Browse files
make plugin.py more concise
1 parent a88c214 commit ceb9d8d

File tree

2 files changed

+96
-92
lines changed

2 files changed

+96
-92
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ part of the documentation build. This mean a physical file does not have to exis
126126

127127
## Contributing
128128

129-
Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request on the [GitHub repository](#).
129+
Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request on the [GitHub repository](https://github.com/thomaszwagerman/mkdocs-authors-plugin).
130130

131131
## License
132132

src/mkdocs_authors_plugin/plugin.py

Lines changed: 95 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from mkdocs.plugins import BasePlugin, get_plugin_logger
44
from mkdocs.config import config_options as c
55
from mkdocs.structure.files import File
6-
from mkdocs.structure.pages import Page
76

87

98
log = get_plugin_logger(__name__)
@@ -22,115 +21,103 @@ class AuthorsPlugin(BasePlugin):
2221

2322
def on_pre_build(self, config):
2423
"""
25-
The 'on_pre_build' event is called once, before the documentation is built.
26-
This is where we'll generate our authors page content.
24+
Generates the authors page content from the YAML file before the build.
2725
"""
2826
authors_file_path = os.path.join(
2927
config["docs_dir"], "..", self.config["authors_file"]
3028
)
31-
3229
authors_data = []
3330
page_parameters = {}
3431

35-
if os.path.exists(authors_file_path):
36-
with open(authors_file_path, "r", encoding="utf-8") as f:
37-
try:
38-
raw_data = yaml.safe_load(f)
39-
40-
if isinstance(raw_data, dict):
41-
if self.config["page_params_key"] in raw_data and isinstance(
42-
raw_data[self.config["page_params_key"]], dict
43-
):
44-
page_parameters = raw_data[self.config["page_params_key"]]
45-
46-
if "authors" in raw_data and isinstance(
47-
raw_data["authors"], dict
48-
):
49-
for author_id, details in raw_data["authors"].items():
50-
details["id"] = author_id
51-
authors_data.append(details)
52-
else:
53-
log.warning(
54-
f"'{self.config['authors_file']}' does not contain an 'authors' key at the top level, or it's not a dictionary. No authors will be listed."
55-
)
56-
authors_data = []
57-
else:
58-
log.warning(
59-
f"'{self.config['authors_file']}' should contain a dictionary at the top level. No authors or page parameters will be loaded."
60-
)
61-
authors_data = []
62-
page_parameters = {}
63-
64-
except yaml.YAMLError as e:
65-
log.error(f"Error parsing '{self.config['authors_file']}': {e}")
66-
authors_data = []
67-
page_parameters = {}
68-
else:
32+
if not os.path.exists(authors_file_path):
6933
log.warning(
7034
f"Authors file not found at '{authors_file_path}'. No authors page will be generated."
7135
)
7236
self.authors_markdown_content = "No authors file found. Please create a '.authors.yml' file in your project root."
7337
return
7438

75-
page_title = page_parameters.get("title", "Our Amazing Authors")
76-
page_description = page_parameters.get("description")
39+
try:
40+
with open(authors_file_path, "r", encoding="utf-8") as f:
41+
raw_data = yaml.safe_load(f)
42+
43+
if isinstance(raw_data, dict):
44+
potential_page_params = raw_data.get(self.config["page_params_key"])
45+
if isinstance(potential_page_params, dict):
46+
page_parameters = potential_page_params
47+
else:
48+
log.warning(
49+
f"'{self.config['page_params_key']}' in '{self.config['authors_file']}' is not a dictionary. Page parameters will be ignored."
50+
)
51+
page_parameters = {}
52+
53+
authors_dict = raw_data.get("authors", {})
54+
55+
if isinstance(authors_dict, dict):
56+
authors_data = [
57+
{"id": aid, **details} for aid, details in authors_dict.items()
58+
]
59+
else:
60+
log.warning(
61+
f"'{self.config['authors_file']}' does not contain an 'authors' key as a dictionary. No authors will be listed."
62+
)
63+
else:
64+
log.warning(
65+
f"'{self.config['authors_file']}' should contain a dictionary at the top level. No authors or page parameters will be loaded."
66+
)
67+
except yaml.YAMLError as e:
68+
log.error(f"Error parsing '{self.config['authors_file']}': {e}")
69+
except Exception as e:
70+
log.error(f"An unexpected error occurred while loading authors data: {e}")
7771

78-
# Get avatar styling from page_parameters, with defaults
72+
self._generate_markdown_content(authors_data, page_parameters)
73+
log.info(f"Authors page content generated for '{self.config['output_page']}'.")
74+
75+
def _generate_markdown_content(self, authors_data, page_parameters):
76+
"""Helper to generate the markdown string."""
77+
page_title = page_parameters.get("title", "Our Amazing Authors")
78+
page_description = page_parameters.get("description", "")
7979
avatar_size = page_parameters.get("avatar_size", 100)
8080
avatar_shape = page_parameters.get("avatar_shape", "square")
81-
avatar_align = page_parameters.get(
82-
"avatar_align", "center"
83-
) # Default to 'center'
81+
avatar_align = page_parameters.get("avatar_align", "center")
8482

85-
markdown_content = f"# {page_title}\n\n"
83+
markdown_parts = [f"# {page_title}\n\n"]
8684
if page_description:
87-
markdown_content += f"{page_description}\n\n"
85+
markdown_parts.append(f"{page_description}\n\n")
8886

8987
if not authors_data:
90-
markdown_content += "No authors found or an error occurred while loading the authors data.\n"
88+
markdown_parts.append(
89+
"No authors found or an error occurred while loading the authors data.\n"
90+
)
9191
else:
9292
for author in authors_data:
93-
markdown_content += f"## {author.get('name', 'Unknown Author')}\n"
94-
95-
avatar_html = "" # Initialize avatar HTML for conditional placement
96-
if author.get("avatar"):
97-
avatar_url = author["avatar"]
98-
author_name = author.get("name", "Avatar")
99-
100-
style_attributes = f"width: {avatar_size}px; height: {avatar_size}px; object-fit: cover;"
101-
if avatar_shape == "circle":
102-
style_attributes += " border-radius: 50%;"
103-
else: # Default or 'square'
104-
style_attributes += " border-radius: 0;"
105-
106-
if avatar_align == "left":
107-
style_attributes += (
108-
" float: left; margin-right: 15px; margin-bottom: 10px;"
109-
)
110-
avatar_html = f'<img src="{avatar_url}" alt="{author_name} Avatar" style="{style_attributes}">'
111-
elif avatar_align == "right":
112-
style_attributes += (
113-
" float: right; margin-left: 15px; margin-bottom: 10px;"
93+
markdown_parts.append(f"## {author.get('name', 'Unknown Author')}\n")
94+
95+
avatar_html = self._get_avatar_html(
96+
author, avatar_size, avatar_shape, avatar_align
97+
)
98+
if avatar_align not in [
99+
"left",
100+
"right",
101+
]: # Center-aligned avatar needs to be handled as a block
102+
if avatar_html:
103+
markdown_parts.append(
104+
f'<p style="text-align: center;">{avatar_html}</p>\n'
114105
)
115-
avatar_html = f'<img src="{avatar_url}" alt="{author_name} Avatar" style="{style_attributes}">'
116-
else: # 'center' or default
117-
style_attributes += " display: block; margin: 0 auto 10px auto;" # Add bottom margin for spacing
118-
# For center, wrap in a paragraph for block-level centering
119-
avatar_html = f'<p style="text-align: center;"><img src="{avatar_url}" alt="{author_name} Avatar" style="{style_attributes}"></p>'
106+
avatar_html = "" # Clear for other alignments
120107

121-
# Insert avatar HTML
122-
markdown_content += avatar_html
108+
# Add avatar for left/right float and then other details
109+
if avatar_html:
110+
markdown_parts.append(avatar_html)
123111

124-
# Now add the textual details that might wrap around a floated image
125112
if author.get("affiliation"):
126-
markdown_content += f"**Affiliation:** {author['affiliation']}\n"
113+
markdown_parts.append(f"**Affiliation:** {author['affiliation']}\n")
127114

128115
if author.get("description"):
129-
markdown_content += f"\n {author['description']}\n"
116+
markdown_parts.append(f"\n{author['description']}\n")
130117

131118
if author.get("email"):
132-
markdown_content += (
133-
f"\n **Email:** [{author['email']}](mailto:{author['email']})\n"
119+
markdown_parts.append(
120+
f"\n**Email:** [{author['email']}](mailto:{author['email']})\n"
134121
)
135122

136123
social_links = []
@@ -148,26 +135,44 @@ def on_pre_build(self, config):
148135
)
149136

150137
if social_links:
151-
markdown_content += (
138+
markdown_parts.append(
152139
"\n**Connect:** " + " | ".join(social_links) + "\n"
153140
)
154141

155-
# Clear float after each author block if avatar was floated
156142
if avatar_align in ["left", "right"]:
157-
markdown_content += '<div style="clear: both;"></div>\n'
143+
markdown_parts.append('<div style="clear: both;"></div>\n')
158144

159-
markdown_content += "\n---\n\n"
145+
markdown_parts.append("\n---\n\n")
160146

161-
self.authors_markdown_content = markdown_content
162-
log.info(f"Authors page content generated for '{self.config['output_page']}'.")
147+
self.authors_markdown_content = "".join(markdown_parts)
148+
149+
def _get_avatar_html(self, author, size, shape, align):
150+
"""Generates the HTML for the author's avatar."""
151+
if not author.get("avatar"):
152+
return ""
153+
154+
avatar_url = author["avatar"]
155+
author_name = author.get("name", "Avatar")
156+
157+
style_attributes = f"width: {size}px; height: {size}px; object-fit: cover;"
158+
style_attributes += (
159+
" border-radius: 50%;" if shape == "circle" else " border-radius: 0;"
160+
)
161+
162+
if align == "left":
163+
style_attributes += " float: left; margin-right: 15px; margin-bottom: 10px;"
164+
elif align == "right":
165+
style_attributes += " float: right; margin-left: 15px; margin-bottom: 10px;"
166+
elif align == "center":
167+
style_attributes += " display: block; margin: 0 auto 10px auto;"
168+
169+
return f'<img src="{avatar_url}" alt="{author_name} Avatar" style="{style_attributes}">'
163170

164171
def on_files(self, files, config):
165172
"""
166-
The 'on_files' event is called after the files are gathered.
167-
We need to ensure our generated authors.md file is included in the build.
173+
Ensures the generated authors.md file is included in the MkDocs build.
168174
"""
169175
output_page_name = self.config["output_page"]
170-
171176
if not any(f.src_path == output_page_name for f in files):
172177
generated_file = File(
173178
path=output_page_name,
@@ -181,8 +186,7 @@ def on_files(self, files, config):
181186

182187
def on_page_read_source(self, page, config):
183188
"""
184-
The 'on_page_read_source' event is called when MkDocs reads the source
185-
for a page. We'll intercept our generated page and provide its content.
189+
Intercepts the generated page and provides its content.
186190
"""
187191
output_page_name = self.config["output_page"]
188192
if page.file.src_path == output_page_name:

0 commit comments

Comments
 (0)