diff --git a/build.py b/build.py index cd9815a..d5093fc 100644 --- a/build.py +++ b/build.py @@ -21,6 +21,7 @@ from __future__ import annotations import argparse +import hashlib import html import re import sys @@ -94,9 +95,7 @@ def _parse_entries(text: str) -> list[dict]: entries.append(current) for e in entries: - e["body"] = " ".join( - l.strip() for l in e.pop("_body_lines") if l.strip() - ) + e["body"] = "\n".join(e.pop("_body_lines")).strip() return entries @@ -218,21 +217,82 @@ def render_projects(projects: list[Project]) -> str: return "\n".join(cards) +def _render_inline(text: str) -> str: + """Render inline markdown (links, bold) within an already-plaintext string.""" + result = "" + last_end = 0 + for m in re.finditer(r'\[([^\]]*)\]\(([^)]*)\)', text): + result += re.sub(r'\*\*([^*]+)\*\*', r'\1', + html.escape(text[last_end:m.start()])) + result += ( + f'' + f'{html.escape(m.group(1))}' + ) + last_end = m.end() + result += re.sub(r'\*\*([^*]+)\*\*', r'\1', + html.escape(text[last_end:])) + return result + + +def _render_bio(text: str) -> str: + """Convert plain text / simple markdown (bullets, links, bold) to HTML.""" + if not text.strip(): + return "" + lines = text.splitlines() + parts: list[str] = [] + in_list = False + para_lines: list[str] = [] + + def flush_para() -> None: + if para_lines: + parts.append(f'
{_render_inline(" ".join(para_lines))}
') + para_lines.clear() + + for line in lines: + stripped = line.strip() + is_bullet = stripped.startswith("- ") or stripped.startswith("* ") + if is_bullet: + flush_para() + if not in_list: + parts.append('No collaborators found.
" cards = [] for c in collaborators: - # Avatar: photo if available, otherwise coloured initials + # Avatar: explicit photo > Gravatar (if email) > coloured initials + initials = "".join(w[0].upper() for w in c.name.split()[:2]) if c.picture: - initials = "".join(w[0].upper() for w in c.name.split()[:2]) avatar = ( f'{html.escape(c.bio)}
' if c.bio else "" + bio = _render_bio(c.bio) cards.append(f"""\European research project investigating how large language models and AI agents can assist and automate software engineering tasks, from requirements analysis and code generation to testing and maintenance. SIMLab contributes expertise in hybrid modelling and uncertainty quantification for AI-assisted development pipelines.
+European research project investigating how large language models and AI agents can +assist and automate software engineering tasks, from requirements analysis and code +generation to testing and maintenance. SIMLab contributes expertise in hybrid modelling +and uncertainty quantification for AI-assisted development pipelines.
Project website →Contrôle Autonome de la Précision des outils de coupe par Intelligence Artificielle. Innosuisse project with Eskenazi SA developing real-time machine-learning models for in-process monitoring and automatic correction of cutting-tool precision, reducing scrap rates and improving surface quality in high-precision machining.
+Contrôle Autonome de la Précision des outils de coupe par Intelligence Artificielle. +Innosuisse project with Eskenazi SA developing real-time machine-learning models for +in-process monitoring and automatic correction of cutting-tool precision, reducing scrap +rates and improving surface quality in high-precision machining.
Project website →A JAX-based framework for 5-day groundwater level prediction from meteorological and weather forecast data. Uses differentiable hybrid models combining physics-based priors with data-driven components, enabling uncertainty-aware forecasts at regional scale.
+A JAX-based framework for 5-day groundwater level prediction from meteorological and +weather forecast data. Uses differentiable hybrid models combining physics-based priors +with data-driven components, enabling uncertainty-aware forecasts at regional scale.
GitHub →Domain-informed machine learning for the simulation of hydroelectric turbines. The project develops physics-constrained surrogate models that accurately replicate high-fidelity CFD simulations at a fraction of the computational cost, enabling rapid turbine optimisation and digital-twin applications for Swiss hydropower operators.
+Domain-informed machine learning for the simulation of hydroelectric turbines. The +project develops physics-constrained surrogate models that accurately replicate +high-fidelity CFD simulations at a fraction of the computational cost, enabling rapid +turbine optimisation and digital-twin applications for Swiss hydropower operators.
Innosuisse project with Infomaniak developing a sovereign, open-source solution for automated spearphishing detection. The system combines large language models with behavioural analysis to identify highly targeted email attacks without relying on third-party cloud infrastructure, addressing privacy and data-sovereignty requirements for Swiss organisations.
+Innosuisse project with Infomaniak developing a sovereign, open-source solution for +automated spearphishing detection. The system combines large language models with +behavioural analysis to identify highly targeted email attacks without relying on +third-party cloud infrastructure, addressing privacy and data-sovereignty requirements +for Swiss organisations.
SNSF Spark project developing domain-informed system-dynamics models of tree growth and mortality under changing climatic conditions. Combines differentiable mechanistic representations of carbon allocation and hydraulic failure with observational data to produce interpretable, uncertainty-aware forecasts of forest dynamics.
+SNSF Spark project developing domain-informed system-dynamics models of tree growth and +mortality under changing climatic conditions. Combines differentiable mechanistic +representations of carbon allocation and hydraulic failure with observational data to +produce interpretable, uncertainty-aware forecasts of forest dynamics.
GitHub → @@ -608,8 +649,8 @@Gregory Mermoud is a professor at HES-SO Valais-Wallis and director of SIMLab. His research focuses on the intersection of physics-based modeling and machine learning, with an emphasis on developing interpretable and uncertainty-aware models for real-world engineering problems.
Cedric Travelletti is a senior scientist at SIMLab specialising in probabilistic machine learning and spatial statistics. His work addresses inverse problems in geosciences, with a focus on scalable Gaussian process methods and uncertainty quantification for large-scale environmental applications.
Marc is currently working on projects related to hydroelectric power production, in particular applying data analysis and machine learning techniques to: - predict strain and fatigue for variable-speed turbines, - detect anomalies in operational data for better maintenance planning. At the HES-SO, Marc has also worked on problems related to power systems, such as power flow optimization through topological changes, modelling of hydroelectric production and high-voltage grids, and network reconstruction using Smart Meter data. Marc's background is in high-energy physics, with a stint in software engineering.
+Marc is currently working on projects related to hydroelectric power production, in particular applying data analysis and machine learning techniques to:
+At the HES-SO, Marc has also worked on problems related to power systems, such as power flow optimization through topological changes, modelling of hydroelectric production and high-voltage grids, and network reconstruction using Smart Meter data.
+Marc's background is in high-energy physics, with a stint in software engineering.