Skip to content

Commit 5dc3261

Browse files
richarddushimeLukasWallrichclaude
authored
Fix FLoRA citation update to support repeated runs (#688)
* Add automated FLoRA citation update from FReD-data - Extend update_fred_citation.py to replace {{flora-ref}} placeholder in content/replication-hub/flora/_index.md with the HTML-formatted citation - Add content/replication-hub/flora/_index.md (source file with placeholder) - Update data-processing workflow to stage and commit the resolved _index.md to the build-resources branch alongside fred_citation.txt The citation update already ran weekly on Sundays; the new _index.md replacement runs on the same schedule with no additional triggers needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * flora citation update --------- Co-authored-by: Lukas Wallrich <lukas.wallrich@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ef47064 commit 5dc3261

3 files changed

Lines changed: 51 additions & 15 deletions

File tree

content/replication-hub/flora/_index.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ With this simple structure FLoRA allows for tracking of replication rates across
1919
In FLoRA, years of work from a large community of volunteers culminate. If you would like to contribute to the project or use the data for your own research, we would strongly appreciate you reaching out to us.
2020

2121
**How to cite:**
22+
<!-- flora-citation-start -->
2223

2324
{{< alert note >}}
2425
Wallrich, L.*, & Röseler, L.*, Hartmann, H., Ashcroft-Jones, S., Doetsch, C., Kaiser, L., Schüller, S. M., Aldoh, A., Behbood, H., Elsherif, M. M., Klett, N., Krapp, J., Liu, M., Pavlović, Z., Pennington, C. R., Schütz, A., Seida, C., Siziva, K., Skvortsova, A., Aczel, B., Adelina, N., Agostini, V., Al-Hoorie, A. H., Alarie, S., Albayrak-Aydemir, N., Alzahawi, S., Anvari, F., Arriaga, P., Baker, B. J., Barth, C. L., Bauer, D. J., Becker, R., Beitner, J., Belaus, A., Bhatt, H., Bhogal, J., Boyce, V., Breemer, L., Brick, C., Brohmer, H., Brummernhenrich, B., Budd, E., Butler, A., Casula, A., Chandrashekar, S. P., Chen, S., Chung, K. L., Cockcroft, J. P., Crowe, P., Cummins, J., Daniel, A., Deane, O., Deressa, T. K., Dienlin, T., Diveica, V., Draguns, A., Dumbalska, T., Efendic, E., El Halabi, M., Enright, S., Evans, T. R., Exner, A., Farrar, B. G., Feldman, G., Fillon, A., Floyd, J., Fontana Vieira, F., Frese, J., Förster, N., Gattie, M. C., Gemmecke, C., Genschow, O., Giannouli, V., Gjoneska, B., Gnambs, T., Gourdon-Kanhukamwe, A., Graham, C. J., Greshake Tzovaras, B., Guay, S., Hausenloy, J., Haviva, C., Henderson, E. L., Herderich, A., Hilbert, L., Holgado, D., Hussey, I., Höfer, L., Ilchovska, Z. G., Imada, H., Imwene, P., Izydorczak, K., Jaubert, S., Jeftić, A., Kalandadze, T., Kamermans, K., Karhulahti, V., Kasseckert, L., Kastrinogiannis, A., Klingelhöfer-Jens, M., Kocalar, H. E., Koppel, L., Koppold, A., Korbmacher, M., Kujawa, Z., Kulke, L., Kumar, P., Kuper, N., LaPlume, A. A., Lach, R., Lecuona, O., Lee, J., Leech, G., Leksina, E., Lin, C., Liu, Y., Lohkamp, F., Lou, N. M., Lynott, D., Mackinnon, S., Maier, M., Maiya, S., Makel, M. C., Manrique-Castano, D., Manríquez-Robles, D., Mathes, L., McSharry, D., Meidenbauer, K. L., Meier, M., Micheli, L., Miller, T., Montefinese, M., Moreau, D., Moser, N., Mrkva, K., Murphy, J., Muthu, J., Narkar, N., Nemcova, M., Nádvorník, J., O'Mahoney, R., O'Mahony, A., Oberholzer, Y., Oomen, D., Osano, M., Otstavnov, N., Packheiser, J., Pandey, S., Panton, H., Papenmeier, F., Parsons, S., Paruzel-Czachura, M., Pavlov, Y. G., Pittelkow, M., Plomp, W., Plonski, P. E., Pravednikov, A., Pronizius, E., Pua, A., Pypno-Blajda, K., Rausch, M., Raza, H., Reason, R., Rebholz, T. R., Resulbegoviq, H., Richert, E., Ross, R. M., Russo, S., Röer, J. P., Sandkühler, J. F., Schmidt, K., Sempere, N., Sobolak, R., Sperl, M. F., Stevens, J. R., Stogianni, M., Szekely, R., Tan, A. W., Thürmer, J. L., Tiulpakova, M., Tomczak, J., Tołopiło, A., Tunca, B., Vanpaemel, W., Vaughn, L. A., Verheyen, S., Vineyard, G. H., Weber, L., Weinberg, A., Wingen, S., Wolska, J., Yeung, S. K., Younssi, M., Zaneva, M., Zimmermann, D., Azevedo, F. (2026). FORRT Library of Replication Attempts (FLoRA) [Data set]. OSF. <a href="https://doi.org/10.17605/OSF.IO/9R62X">https://doi.org/10.17605/OSF.IO/9R62X</a>
2526

26-
\* These authors contributed equally to this work.
27+
<strong>* These authors contributed equally to this work.</strong>
2728
{{< /alert >}}
29+
30+
<!-- flora-citation-end -->

scripts/update_fred_citation.py

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
And saves it to static/data/fred_citation.txt for use in the cite_us page.
99
"""
1010

11+
import re
1112
import sys
1213
import logging
1314
from pathlib import Path
@@ -25,7 +26,6 @@
2526
CITATION_URL = "https://raw.githubusercontent.com/forrtproject/FReD-data/refs/heads/main/output/citation.txt"
2627
OUTPUT_FILE = "static/data/fred_citation.txt"
2728
FLORA_INDEX_FILE = "content/replication-hub/flora/_index.md"
28-
FLORA_PLACEHOLDER = "{{flora-ref}}"
2929

3030
def fetch_fred_citation():
3131
"""
@@ -64,7 +64,6 @@ def save_citation(citation, output_path):
6464

6565
# Post-process citation to match required format
6666
# Replace DOI URL with HTML link and append note if not present
67-
import re
6867
# Find DOI URL (assume starts with https://doi.org/)
6968
citation = citation.strip()
7069
# Remove any trailing note
@@ -80,8 +79,8 @@ def repl(match):
8079
return f'<a href="{url}">{url}</a>'
8180
citation_main = re.sub(doi_pattern, repl, citation_main)
8281

83-
# Compose final citation
84-
citation_final = citation_main + "\n\n" + note + "\n"
82+
# Compose final citation with highlighted note
83+
citation_final = citation_main + "\n\n<strong>" + note + "</strong>\n"
8584

8685
with open(output_file, 'w', encoding='utf-8') as f:
8786
f.write(citation_final)
@@ -94,13 +93,16 @@ def repl(match):
9493

9594
def update_flora_index(citation_html):
9695
"""
97-
Replace the {{flora-ref}} placeholder in the FLoRA _index.md with the citation HTML.
96+
Update the citation inside the flora-citation block in the FLoRA _index.md.
97+
98+
The function looks for <!-- flora-citation-start --> and <!-- flora-citation-end --> markers,
99+
and replaces the content between {{< alert note >}} and {{< /alert >}} with the citation.
98100
99101
Args:
100-
citation_html: The processed citation HTML string (same as saved to fred_citation.txt)
102+
citation_html: The processed citation HTML string
101103
102104
Returns:
103-
bool: True if successful or placeholder not present, False on error
105+
bool: True if successful or markers not present, False on error
104106
"""
105107
try:
106108
index_file = Path(FLORA_INDEX_FILE)
@@ -109,13 +111,45 @@ def update_flora_index(citation_html):
109111
return False
110112

111113
content = index_file.read_text(encoding='utf-8')
112-
if FLORA_PLACEHOLDER not in content:
113-
logger.info("No {{flora-ref}} placeholder found in FLoRA index, skipping")
114+
start_marker = "<!-- flora-citation-start -->"
115+
end_marker = "<!-- flora-citation-end -->"
116+
alert_start = "{{< alert note >}}"
117+
alert_end = "{{< /alert >}}"
118+
119+
if start_marker not in content or end_marker not in content:
120+
logger.info("No flora citation block markers found in FLoRA index, skipping")
121+
return True
122+
123+
# Find flora-citation block (escape markers for regex)
124+
flora_block_pattern = re.compile(
125+
rf"({re.escape(start_marker)})(.*?){re.escape(end_marker)}",
126+
re.DOTALL
127+
)
128+
flora_block_match = flora_block_pattern.search(content)
129+
if not flora_block_match:
130+
logger.info("No flora citation block found, skipping")
131+
return True
132+
133+
flora_block = flora_block_match.group(2)
134+
# Find alert note block inside flora-citation block (escape Hugo shortcode for regex)
135+
alert_pattern = re.compile(
136+
rf"({re.escape(alert_start)})(.*?){re.escape(alert_end)}",
137+
re.DOTALL
138+
)
139+
alert_match = alert_pattern.search(flora_block)
140+
if not alert_match:
141+
logger.info("No alert note block found inside flora citation block, skipping")
114142
return True
115143

116-
updated = content.replace(FLORA_PLACEHOLDER, citation_html.strip())
144+
# Replace content between alert markers
145+
new_alert_block = f"{alert_start}\n{citation_html.strip()}\n{alert_end}"
146+
new_flora_block = alert_pattern.sub(new_alert_block, flora_block)
147+
# Rebuild flora-citation block
148+
new_flora_citation = f"{start_marker}\n{new_flora_block}\n{end_marker}"
149+
# Replace in file (use lambda to avoid backreference issues)
150+
updated = flora_block_pattern.sub(lambda m: new_flora_citation, content)
117151
index_file.write_text(updated, encoding='utf-8')
118-
logger.info(f"Successfully updated {FLORA_INDEX_FILE}")
152+
logger.info(f"Successfully updated citation inside alert note in {FLORA_INDEX_FILE}")
119153
return True
120154
except Exception as e:
121155
logger.error(f"Failed to update FLoRA index: {e}")
@@ -138,7 +172,6 @@ def main():
138172
return 1
139173

140174
# Build the HTML-formatted citation string (same logic as save_citation)
141-
import re
142175
citation_stripped = citation.strip()
143176
note = "* These authors contributed equally to this work."
144177
citation_main = citation_stripped
@@ -148,7 +181,7 @@ def main():
148181
def repl(match):
149182
url = match.group(1)
150183
return f'<a href="{url}">{url}</a>'
151-
citation_html = re.sub(doi_pattern, repl, citation_main) + "\n\n" + note
184+
citation_html = re.sub(doi_pattern, repl, citation_main) + "\n\n<strong>" + note + "</strong>"
152185

153186
# Replace placeholder in FLoRA _index.md
154187
if not update_flora_index(citation_html):

static/data/fred_citation.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Wallrich, L.*, & Röseler, L.*, Hartmann, H., Ashcroft-Jones, S., Doetsch, C., Kaiser, L., Schüller, S. M., Aldoh, A., Behbood, H., Elsherif, M. M., Klett, N., Krapp, J., Liu, M., Pavlović, Z., Pennington, C. R., Schütz, A., Seida, C., Siziva, K., Skvortsova, A., Aczel, B., Adelina, N., Agostini, V., Al-Hoorie, A. H., Alarie, S., Albayrak-Aydemir, N., Alzahawi, S., Anvari, F., Arriaga, P., Baker, B. J., Barth, C. L., Bauer, D. J., Becker, R., Beitner, J., Belaus, A., Bhatt, H., Bhogal, J., Boyce, V., Breemer, L., Brick, C., Brohmer, H., Brummernhenrich, B., Budd, E., Butler, A., Casula, A., Chandrashekar, S. P., Chen, S., Chung, K. L., Cockcroft, J. P., Crowe, P., Cummins, J., Daniel, A., Deane, O., Deressa, T. K., Dienlin, T., Diveica, V., Draguns, A., Dumbalska, T., Efendic, E., El Halabi, M., Enright, S., Evans, T. R., Exner, A., Farrar, B. G., Feldman, G., Fillon, A., Floyd, J., Fontana Vieira, F., Frese, J., Förster, N., Gattie, M. C., Gemmecke, C., Genschow, O., Giannouli, V., Gjoneska, B., Gnambs, T., Gourdon-Kanhukamwe, A., Graham, C. J., Greshake Tzovaras, B., Guay, S., Hausenloy, J., Haviva, C., Henderson, E. L., Herderich, A., Hilbert, L., Holgado, D., Hussey, I., Höfer, L., Ilchovska, Z. G., Imada, H., Imwene, P., Izydorczak, K., Jaubert, S., Jeftić, A., Kalandadze, T., Kamermans, K., Karhulahti, V., Kasseckert, L., Kastrinogiannis, A., Klingelhöfer-Jens, M., Kocalar, H. E., Koppel, L., Koppold, A., Korbmacher, M., Kujawa, Z., Kulke, L., Kumar, P., Kuper, N., LaPlume, A. A., Lach, R., Lecuona, O., Lee, J., Leech, G., Leksina, E., Lin, C., Liu, Y., Lohkamp, F., Lou, N. M., Lynott, D., Mackinnon, S., Maier, M., Maiya, S., Makel, M. C., Manrique-Castano, D., Manríquez-Robles, D., Mathes, L., McSharry, D., Meidenbauer, K. L., Meier, M., Micheli, L., Miller, T., Montefinese, M., Moreau, D., Moser, N., Mrkva, K., Murphy, J., Muthu, J., Narkar, N., Nemcova, M., Nádvorník, J., O'Mahoney, R., O'Mahony, A., Oberholzer, Y., Oomen, D., Osano, M., Otstavnov, N., Packheiser, J., Pandey, S., Panton, H., Papenmeier, F., Parsons, S., Paruzel-Czachura, M., Pavlov, Y. G., Pittelkow, M., Plomp, W., Plonski, P. E., Pravednikov, A., Pronizius, E., Pua, A., Pypno-Blajda, K., Rausch, M., Raza, H., Reason, R., Rebholz, T. R., Resulbegoviq, H., Richert, E., Ross, R. M., Russo, S., Röer, J. P., Sandkühler, J. F., Schmidt, K., Sempere, N., Sobolak, R., Sperl, M. F., Stevens, J. R., Stogianni, M., Szekely, R., Tan, A. W., Thürmer, J. L., Tiulpakova, M., Tomczak, J., Tołopiło, A., Tunca, B., Vanpaemel, W., Vaughn, L. A., Verheyen, S., Vineyard, G. H., Weber, L., Weinberg, A., Wingen, S., Wolska, J., Yeung, S. K., Younssi, M., Zaneva, M., Zimmermann, D., Azevedo, F. (2026). FORRT Library of Replication Attempts (FLoRA) [Data set]. OSF. <a href="https://doi.org/10.17605/OSF.IO/9R62X">https://doi.org/10.17605/OSF.IO/9R62X</a>
22

3-
* These authors contributed equally to this work.
3+
<strong>* These authors contributed equally to this work.</strong>

0 commit comments

Comments
 (0)