Skip to content

Instantly share code, notes, and snippets.

@cboulanger
cboulanger / README.md
Last active November 2, 2025 11:58
crossref_to_ris.py

Crossref to RIS Converter

This Python script converts Crossref API bibliographic data into RIS format, specifically designed to handle books with chapters. It enriches chapter records with complete book information (title, editors, ISBN) that is typically missing in the Crossref API response.

Features

  • Fetches bibliographic data from Crossref API using ISBN
  • Generates complete RIS records for both the book and all chapters
  • Includes full book metadata (title, editors, publisher, ISBNs) in each chapter entry
  • Can work with pre-downloaded JSON files when API access is restricted
@cboulanger
cboulanger / grobid.training.segmentation.rng
Created September 23, 2025 10:59
RNG Schema for Grobid's *.training.segmentation files with an optional TEI header
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://relaxng.org/relaxng.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<!--
To validate TEI documents against this schema, add this processing instruction
to the beginning of your TEI document (after the XML declaration):
<?xml-model href="http://localhost:3001/api/files/872ab" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
-->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
ns="http://www.tei-c.org/ns/1.0"
@cboulanger
cboulanger / js-plugin.mjs
Created July 14, 2025 07:47
js-plugin as an ESM module
/**
* patched version of https://www.npmjs.com/package/js-plugin
*/
var _plugins = [];
var _byName = {};
var _cache = {};
// Only support debug mode on browser and node, not web workers.
var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
@cboulanger
cboulanger / counter.css
Created May 26, 2025 14:45
A CSS-only counter widget
/**
* Displays Countdown clock
* Usage: <div class="countdown" style="--duration-seconds: 15;"></div>
*/
@property --total-seconds-remaining {
syntax: "<number>";
initial-value: 0;
inherits: true;
}
@cboulanger
cboulanger / hedgedoc-slide-quadrant.md
Last active March 19, 2025 07:59
Hedgedoc/Reveal.js Slide Template: Quadrant layout

Lorem ipsum dolor sit amet

Lorem

  • dolor sit amet
  • consectetur adipiscing
  • sed do eiusmod tempor
@cboulanger
cboulanger / reference-extraction-experiment-text-davinci-003.md
Created December 19, 2024 09:50
OpenAI reference extraction via API (text-davinci-003): Code/Result

OpenAI reference extraction via API: Code/Result

December 2022

Code

import openai
import json
import time
@cboulanger
cboulanger / 10.1111_1467-6478.00057.xml
Last active August 17, 2024 20:51
TEI file as auto-generated from AnyStyle XML
<?xml version="1.0" ?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title>10.1111_1467-6478.00057</title>
</titleStmt>
<publicationStmt>
<publisher>mpilhlt</publisher>
</publicationStmt>
@cboulanger
cboulanger / download-hedgedoc-presentation.py
Last active May 28, 2024 16:52
Download a pad.gwdg.de presentation for local offline viewing. Script written with the help of ChatGPT4
import os
import re
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import argparse
def download_resource(session, url, base_dir, level=0):
try:
response = session.get(url, stream=True)
@cboulanger
cboulanger / hedgedoc-background.css
Last active May 17, 2024 06:07
Hedgedoc CSS to specify a common background image in CSS instead of manually and set an opacity to the background except for the title page
/* set the background image for all pages which have an (empty) <!-- .slide: data-background="" --> marker */
/* create overlay with background image */
.slide-background-content::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url("image-url");
@cboulanger
cboulanger / parse-easychair-program.py
Created November 9, 2023 10:13
Parse an EasyChair conference programme to create a separate track overview. This requires a consistent naming scheme for the sessions. Cannot be used as-is.
import dateparser
import re
import requests
from bs4 import BeautifulSoup
import csv
from collections import defaultdict
url = "https://easychair.org/smart-program/<conference_name>/program.html"
track_url = "https://easychair.org/smart-program/<conference_name>/de_tracks.html"
css_url = "https://easychair.org/smart-program/<conference_name>/program.css"