{"id":50908073,"url":"https://github.com/ateeducacion/h5p2elpx","last_synced_at":"2026-06-16T07:03:06.393Z","repository":{"id":359828441,"uuid":"1247633510","full_name":"ateeducacion/h5p2elpx","owner":"ateeducacion","description":"Convert H5P activities into editable eXeLearning .elpx projects.","archived":false,"fork":false,"pushed_at":"2026-06-06T23:52:57.000Z","size":64856,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T01:17:24.543Z","etag":null,"topics":["elpx","exelearning","h5p"],"latest_commit_sha":null,"homepage":"https://ateeducacion.github.io/h5p2elpx/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ateeducacion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-23T15:21:06.000Z","updated_at":"2026-06-06T23:53:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ateeducacion/h5p2elpx","commit_stats":null,"previous_names":["ateeducacion/h5p2elpx"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ateeducacion/h5p2elpx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ateeducacion%2Fh5p2elpx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ateeducacion%2Fh5p2elpx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ateeducacion%2Fh5p2elpx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ateeducacion%2Fh5p2elpx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ateeducacion","download_url":"https://codeload.github.com/ateeducacion/h5p2elpx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ateeducacion%2Fh5p2elpx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34393305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elpx","exelearning","h5p"],"created_at":"2026-06-16T07:03:05.571Z","updated_at":"2026-06-16T07:03:06.388Z","avatar_url":"https://github.com/ateeducacion.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# h5p2elpx\n\nConvert H5P activities into editable eXeLearning `.elpx` projects.\n\n`h5p2elpx` is a **conservative** converter: it maps supported source content\ninto editable eXeLearning iDevices and keeps unsupported content visible with\nclear warnings instead of silently dropping it. Every conversion produces a JSON\nreport explaining what was converted, partially converted, or left as a\nfallback.\n\nSupported inputs:\n\n- **H5P** (`.h5p`) — 50+ content type adapters.\n- **ADC / Content** (`.zip`) — the legacy authoring tool used by the Aula\n  Digital Canaria platform. All six export flavours are detected\n  automatically: *native*, plain *zip*, *SCORM 1.2*, *SCORM 2004*,\n  *xAPI/Tin Can*, and *local*. Bundles that omit `project.json` are recovered\n  by deobfuscating the `ntxCafCompressed` blob in `index.html` (zlib + base64;\n  no encryption).\n\n\u003e Status: MVP. CLI + browser-only web app + 50+ H5P adapters + ADC import.\n\n## Installation\n\nInstall [Bun](https://bun.sh). The CLI is published to GitHub Packages as\n`@ateeducacion/h5p2elpx`.\n\n```bash\necho \"@ateeducacion:registry=https://npm.pkg.github.com\" \u003e\u003e .npmrc\nbunx --bun @ateeducacion/h5p2elpx convert activity.h5p -o activity.elpx\n```\n\nIf GitHub Packages asks for authentication, add a GitHub token that can read\npackages:\n\n```bash\necho \"//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN\" \u003e\u003e .npmrc\n```\n\nFor local development, clone this repository and install its dependencies:\n\n```bash\ngit clone https://github.com/ateeducacion/h5p2elpx.git\ncd h5p2elpx\nbun install\n```\n\nThe eXeLearning runtime template (`fixtures/elpx/template.elpx`) is already\ncommitted. To rebuild it from a fresh\n[eXeLearning release](https://github.com/exelearning/exelearning/releases)\n(default: `v4.0.0`, theme `base`):\n\n```bash\nbun run build-template            # latest pinned default\nbun run build-template v4.0.0 base\n```\n\nThe script downloads `exelearning-static-vX.Y.Z.zip`, unpacks\n`bundles/{idevices,libs,common,content-css}.zip` and\n`bundles/themes/\u003ctheme\u003e.zip`, and assembles them into the runtime parts of the\n`.elpx` template (`idevices/`, `libs/`, `theme/`, `html/`, `content/css/`,\n`index.html`, etc.). `h5p2elpx` always regenerates `content.xml` and\n`content.dtd` during conversion. The GitHub Pages workflow runs this on every\npush so the bundled web template stays up to date.\n\n## CLI\n\nRun the published CLI:\n\n```bash\n# Inspect an .h5p package (detects main library, lists dependencies)\nbunx --bun @ateeducacion/h5p2elpx inspect activity.h5p\n\n# Convert one .h5p file into an .elpx project\nbunx --bun @ateeducacion/h5p2elpx convert activity.h5p \\\n  -o activity.elpx \\\n  --layout preserve \\\n  --include-original-h5p \\\n  --report report.json\n\n# Convert a folder of .h5p files\nbunx --bun @ateeducacion/h5p2elpx convert ./h5p-folder -o bundle.elpx\n\n# Validate an .elpx\nbunx --bun @ateeducacion/h5p2elpx validate activity.elpx\n```\n\nFrom a cloned checkout, use `bun run cli -- \u003ccommand\u003e` instead.\n\nOptions for `convert`:\n\n| Option | Values | Default |\n| --- | --- | --- |\n| `--layout` | `blocks`, `pages`, `preserve` | `preserve` |\n| `--unsupported` | `keep`, `text`, `drop` | `keep` |\n| `--include-original-h5p` | flag | off |\n| `--title \u003cs\u003e` | string | \"Imported H5P content\" |\n| `--lang \u003ccode\u003e` | string | unset |\n| `--report \u003cfile\u003e` | path | none |\n| `--template \u003cfile\u003e` | path to a real eXe `.elpx` template | none |\n| `--strict` | flag | off (fails if anything is unsupported) |\n\n## Web app\n\nDrag-and-drop, fully client-side. No backend.\n\n```bash\nbun run --cwd packages/web dev          # local dev\nbun run --cwd packages/web build        # production build → packages/web/dist\n```\n\nDeployed automatically to GitHub Pages on every push to `main` via\n`.github/workflows/pages.yml`.\n\n## Report a broken H5P file\n\nIf an `.h5p` file does not convert correctly, open a GitHub issue with the\n`Broken H5P conversion` form. Attach the file when possible, or paste a public\nor shared download URL.\n\n## Compatibility matrix\n\n| Phase | H5P type | Mapping |\n| --- | --- | --- |\n| 1 | `H5P.Text`, `H5P.AdvancedText` | text iDevice |\n| 1 | `H5P.Image` | text iDevice with `\u003cimg\u003e` |\n| 1 | `H5P.Audio` | text iDevice with `\u003caudio\u003e` |\n| 1 | `H5P.Video` | text iDevice with `\u003cvideo\u003e` |\n| 1 | `H5P.InteractiveVideo` | `interactive-video` iDevice (text + single-choice slides preserved) |\n| 1 | `H5P.Column` | flattens children into iDevices |\n| 1 | `H5P.CoursePresentation` | one eXe page per slide (preserve mode) |\n| 1 | `H5P.InteractiveBook` | one eXe page per chapter |\n| 1 | `H5P.Table` | HTML `\u003ctable\u003e` in a text iDevice |\n| 2 | `H5P.TrueFalse` | trueorfalse iDevice |\n| 2 | `H5P.MultiChoice` | form iDevice (`activityType: \"selection\"`) |\n| 2 | `H5P.SingleChoiceSet` | one form iDevice per choice |\n| 2 | `H5P.Blanks` | form iDevice |\n| 2 | `H5P.Dialogcards`, `H5P.MemoryGame` | flipcards iDevice |\n| 2 | `H5P.Summary` | form iDevices |\n| 3 | `H5P.DragText` | form iDevice |\n| 3 | `H5P.MarkTheWords` | text fallback |\n| 3 | `H5P.DragQuestion` | structured fallback (drag list + drop zones) |\n| 3 | `H5P.ImageHotspots` | `map` iDevice (info markers with rich popups on the background image) |\n| 3 | `H5P.MultipleHotspotQuestion` | `map` iDevice (rectangle hotspots, quiz mode) |\n| 3 | `H5P.Crossword` | `crossword` iDevice (native eXe `$eXeCrucigrama`) |\n| 3 | `H5P.ImageJuxtaposition` | `beforeafter` iDevice |\n| 3 | `H5P.IFrameEmbed` | `external-website` iDevice |\n| 3 | `H5P.FindTheWords` | `word-search` iDevice (encrypted DataGame) |\n| 3 | `H5P.Flashcards`, `H5P.ImagePair` | `flipcards` iDevice |\n| 3 | `H5P.Accordion` | text iDevice with `\u003cdetails\u003e` panels |\n| 3 | `H5P.Essay` | text iDevice with `\u003ctextarea\u003e` placeholder |\n| 3 | `H5P.QuestionSet`, `H5P.Questionnaire` | flatten children into iDevices |\n| 3 | `H5P.Dictation` | form iDevice (`activityType: \"fill\"`, drops audio) |\n| 3 | `H5P.SortParagraphs`, `H5P.ImageSequencing` | ordered text iDevice (author re-scrambles in eXe) |\n| 3 | `H5P.ImageSlider`, `H5P.Collage` | text iDevice with sequential figures |\n| 3 | `H5P.ImageHotspotQuestion` | `map` iDevice (rectangle hotspots, quiz mode) |\n| 4 | `H5P.GuessTheAnswer` | `flipcards` iDevice (image+question front, solution back) |\n| 4 | `H5P.AdventCalendar` | `flipcards` iDevice (one door per card) |\n| 4 | `H5P.InformationWall` | `flipcards` iDevice (one panel per card) |\n| 4 | `H5P.MultiMediaChoice` | form iDevice (`activityType: \"selection\"`, image options) |\n| 4 | `H5P.ArithmeticQuiz` | expanded into N form (selection) iDevices with deterministic problems |\n| 4 | `H5P.AdvancedBlanks` (Complex Fill the Blanks) | form iDevice (`activityType: \"fill\"`) |\n| 4 | `H5P.Agamotto` | `beforeafter` iDevice for two frames, sequential text iDevice otherwise |\n| 4 | `H5P.GameMap` | `map` iDevice (markers parsed from `telemetry`) |\n| 4 | `H5P.Link` | text iDevice with `\u003ca href\u003e` |\n| 4 | `H5P.DocumentationTool` | one eXe page per `H5P.StandardPage` |\n| anything else | visible warning iDevice (unless `--unsupported drop`) |\n\n## Roadmap — H5P types still on the text fallback\n\nRemaining content types from\n\u003chttps://h5p.org/content-types-and-applications\u003e stay on the generic\n`text` fallback because eXeLearning has no native equivalent:\n\nChart, Timeline, Personality Quiz, KewAr Code, AR Scavenger, Audio\nRecorder, Speak the Words(+Set), Virtual Tour (360), Branching\nScenario, Cornell Notes, Structure Strip, Impressive Presentation.\n\nSample `.h5p` files for every implemented mapping live under\n`fixtures/h5p/` and are exercised by `packages/core/tests/fixtures.test.ts`.\n\n## Architecture\n\n```\n.h5p ZIP\n  → packages/core/src/h5p/read-h5p.ts          (JSZip, browser-safe)\n  → packages/core/src/normalize/adapters/*     (registry — one file per H5P lib)\n  → Normalized AST (packages/core/src/normalize/nodes.ts)\n  → packages/core/src/convert/convert.ts       (layout planner: blocks|pages|preserve)\n  → packages/core/src/exe/idevices/*           (registry — one writer per typeName)\n  → packages/core/src/exe/elpx-writer.ts       (clones a template, injects content.xml)\n  → .elpx ZIP + JSON ConversionReport\n```\n\n`packages/core` has zero Node-only imports — it works identically in the CLI\nand in the browser.\n\n## Adding a new H5P mapper\n\n1. Create `packages/core/src/normalize/adapters/\u003cyour-type\u003e.ts` exporting\n   `machineName` and `adapt(content) → NormalizedNode`.\n2. Add it to the registry in `adapters/index.ts`.\n3. Add a unit test under `packages/core/tests/`.\n\n## Adding a new eXeLearning iDevice writer\n\n1. Create `packages/core/src/exe/idevices/\u003cyour-type\u003e.ts` building an\n   `ElpxIdevice` from a normalized node.\n2. Wire it from `convert.ts` for the AST kinds it handles.\n\n## Development\n\nWe use [Bun](https://bun.sh) and [Biome](https://biomejs.dev) — verbs are\nthe same as eXeLearning's:\n\n```bash\nmake install        # bun install\nmake lint           # biome check . (read-only)\nmake fix            # biome check --write . (auto-fix lint + format)\nmake typecheck      # tsc --noEmit\nmake test           # vitest run\nmake test-watch     # vitest in watch mode\nmake up             # start the Vite dev server (web app)\nmake web-build      # build the production web bundle\nmake template       # rebuild fixtures/elpx/template.elpx from upstream\nmake ci             # the same gate CI runs\n```\n\nCI: `.github/workflows/test.yml` runs typecheck + tests on every push and PR.\n`.github/workflows/pages.yml` builds and deploys the web app to GitHub Pages.\n\n## Known limitations\n\n* The generated `content.xml` targets the real eXeLearning ODE v2.0 format.\n  `h5p2elpx` rewrites `content.xml`/`content.dtd` on every conversion while\n  preserving the runtime assets from the bundled template (or a custom one\n  passed via `--template`).\n* H5P.InteractiveVideo preserves `H5P.Text` / `H5P.AdvancedText` overlays and\n  `H5P.MultiChoice` / `H5P.SingleChoiceSet` questions as eXe interactive-video\n  slides. Other interaction types (drag, hotspots, summaries, …) are dropped\n  with a warning in the report.\n* H5P.DragQuestion loses geometric positions (becomes a descriptive list).\n* `H5P.ImageHotspots`, `H5P.MultipleHotspotQuestion` and\n  `H5P.ImageHotspotQuestion` are pinned on the native eXe `map`\n  iDevice, but informational content (links, embedded media) inside\n  H5P.ImageHotspots panels is rendered into the popup body as static\n  HTML.\n\n## License\n\nAGPL-3.0-or-later (see `LICENSE`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fateeducacion%2Fh5p2elpx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fateeducacion%2Fh5p2elpx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fateeducacion%2Fh5p2elpx/lists"}