npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mikaello/rankinglop-resultlist-generator

v0.0.3

Published

Generate old school HTML file when given an IOF v3 XML file

Readme

rankinglop-resultlist-generator

npm version license

A command-line tool and library that converts an IOF 3.0 XML result list (as exported by Otime) into a self-contained HTML page with modern, responsive styling. Built for the GeoForm Rankingløp series.

Web app

A browser-based version is available at https://mikaello.github.io/rankinglop-resultlist-generator/. Upload an IOF 3.0 XML file, fill in optional event metadata, and download the generated HTML — no installation required.

Requirements

Node.js 22.18.0 or later (runs TypeScript files natively — no compilation step needed for local development).

Installation

As a global CLI

npm install -g @mikaello/rankinglop-resultlist-generator
rankinglop --input result.xml --output result.html

In a project

npm install @mikaello/rankinglop-resultlist-generator

For local development

npm install

CLI usage

node src/cli.ts \
  --input result.xml \
  [--config event.json] \
  [--output result.html]

If --output is omitted the HTML is written to stdout, so you can pipe it:

node src/cli.ts --input result.xml > result.html

When installed globally via npm:

rankinglop --input result.xml --output result.html

Options

| Flag | Description | |------|-------------| | --input <file.xml> | IOF 3.0 XML result list (required) | | --config <file.json> | Event metadata JSON (see below) | | --output <file.html> | Output path (default: stdout) |

Event metadata (--config)

{
  "title": "Rankingløp 1 - 2024",
  "isoDate": "2024-05-08",
  "place": "Østmarksetra",
  "map": "Solbergvann",
  "organiserClub": "IL GeoForm",
  "organiserPersons": ["Ola Nordmann"],
  "rentalDevices": 8,
  "yearDistribution": {
    "adults": 80,
    "oldTeenager": 3,
    "youngTeenager": 2,
    "child": 3
  }
}

All fields are optional and fall back to sensible defaults or values from the XML itself.

Programmatic API

The package exposes a browser- and Node.js-compatible API:

import {
  parseIofXmlContent,
  createResultListHtml,
  type ResultList,
  type ResultListOptions,
} from "@mikaello/rankinglop-resultlist-generator";

// 1. Parse an IOF 3.0 XML string into a typed model
const resultList: ResultList = parseIofXmlContent(xmlString);

// 2. Generate the HTML, providing the Pico CSS string yourself
//    (load it however is right for your environment)
const html: string = createResultListHtml(resultList, options, picoCSS);

parseIofXmlContent(xmlString: string): ResultList : Parse an IOF 3.0 XML result list from a string. No file-system access — works in Node.js and browsers.

createResultListHtml(resultList, options, picoCSS): string : Generate a complete self-contained HTML document with the Rankingløp-specific header (club distribution, year distribution, kontingent, leiebrikker). picoCSS is the content of @picocss/pico/css/pico.classless.min.css as a string. In Node.js you can readFileSync it; in a Vite project use a ?inline import.

createGenericResultListHtml(resultList, options, picoCSS): string : Same signature, but emits a minimal generic event header (title, date, place, map, organiser) instead of the Rankingløp-specific one. Intended for reuse from other applications that want a clean result list preview without the GeoForm-specific reporting fields.

createGenericResultListHtmlFromXml(xmlString, options, picoCSS): string : Convenience wrapper that takes an IOF 3.0 XML string, parses it with parseIofXmlContent, and renders it via createGenericResultListHtml. Use this when your contract with the library is "IOF XML in, HTML out" — for example, an editor that wants to render its exported XML as a verification preview.

Node.js convenience wrapper

If you don't want to manage the CSS yourself, the Node.js-only createResultListDocument reads Pico CSS from the installed package automatically:

import { createResultListDocument } from "@mikaello/rankinglop-resultlist-generator/node";
// or via the full path:
import { createResultListDocument } from "@mikaello/rankinglop-resultlist-generator/src/generateResultList.ts";

npm scripts

| Script | Description | |--------|-------------| | npm start | Run the CLI (add arguments after --) | | npm run build | Compile TypeScript to dist/ with tsup | | npm run typecheck | Type-check with tsc --noEmit | | npm run lint | Lint and format with Biome | | npm test | Run all tests with node:test |

Output

The generated HTML is a single self-contained file with no external requests:

  • Pico CSS (classless flavour) is embedded inline in <style>.
  • A <nav> at the top links to each class section and its split-time table.
  • Each orienteering class gets a <section> with a results <table>.
  • Columns: Plass · Navn · Klubb · Tid · Diff · km-tid.
  • Non-finishers (DNS, DNF, DSQ, OVT, feilst, NC) are shown at the bottom of each table in a muted style.
  • A second table per class shows leg split times and accumulated times.
  • Best split per control highlighted red, second-best highlighted blue.

Development

# Type-check
npm run typecheck

# Build dist/
npm run build

# Lint / format
npm run lint

# Run tests
npm test

License

GPL-3.0 — see LICENSE.