diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08e5a0b2..e48fbdcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,17 +19,9 @@ jobs: specs-ietf: runs-on: ubuntu-latest steps: + - name: Install docker-compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - run: pip install --requirement requirements.txt - - run: xml2rfc --version - - run: make all - - uses: actions/upload-artifact@v4 - with: - name: specification-docs - path: | - *.html - *.txt - !requirements.txt + - run: npm run build-ietf diff --git a/.gitignore b/.gitignore index 7007b640..0cb023a3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,17 +2,7 @@ web/ # IETF builds -json-schema-use-cases.html -json-schema-use-cases.pdf -json-schema-use-cases.txt -relative-json-pointer.html -relative-json-pointer.pdf -relative-json-pointer.txt - -# For the Python enviornment -.venv +.refcache/ # For the node-based build tools node_modules/ - -.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a11bba8d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM fedora + +RUN dnf install -y ruby python3-pip +RUN gem install kramdown-rfc +RUN pip install xml2rfc + +WORKDIR /app + +COPY . . + +# First covert md to xml. Then convert xml to html +CMD sh -c "xml2rfc --version \ + && ls ietf/*.md | xargs -n1 sh -c 'kramdown-rfc \"\$0\" > \"\${0%.md}.xml\"' \ + && ls ietf/*.xml | xargs -n1 sh -c 'xml2rfc --html \"\$0\" -p web'" diff --git a/Makefile b/Makefile deleted file mode 100644 index f5b21217..00000000 --- a/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -XML2RFC ?= xml2rfc -VENV ?= .venv - -OUT = \ - relative-json-pointer.html relative-json-pointer.txt - -all: $(VENV) $(OUT) - -%.txt: specs/%.xml - $(XML2RFC) --text $< -o $@ - -%.pdf: specs/%.xml - $(XML2RFC) --pdf $< -o $@ - -%.html: specs/%.xml - $(XML2RFC) --html $< -o $@ - -json-schema.tar.gz: $(OUT) - test ! -e json-schema - mkdir json-schema - git clone . json-schema - (cd json-schema && make) - tar -czf json-schema.tar.gz --exclude '.*' json-schema - rm -rf json-schema - -$(VENV): requirements.txt - python -m venv $@ - $@/bin/python -m pip install --upgrade pip - $@/bin/python -m pip install -r $< - -spec-clean: - rm -f $(OUT) json-schema.tar.gz - -clean: spec-clean - rm -rf $(VENV) - -.PHONY: spec-clean clean all diff --git a/README.md b/README.md index 0f2c950d..4efe7236 100644 --- a/README.md +++ b/README.md @@ -113,17 +113,7 @@ features they make available to you. ### Internet-Drafts To build components that are being maintained as IETF Internet-Drafts, run -`make`. The Makefile will create the necessary Python venv for you as part of -the regular make target. - -`make clean` will remove all output including the venv. To clean just the spec -output and keep the venv, use `make spec-clean`. - -If you want to run `xml2rfc` manually after running make for the first time, you -will need to activate the virtual environment: `source .venv/bin/activate`. - -The version of "xml2rfc" that this project uses is updated by modifying -`requirements.in` and running `pip-compile requirements.in`. +`npm run build-ietf`. Descriptions of the xml2rfc, I-D documents, and RFC processes: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..8b7d8f42 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +services: + build: + build: + context: . + working_dir: /app + volumes: + - .:/app:Z diff --git a/ietf/.remarkrc.js b/ietf/.remarkrc.js new file mode 100644 index 00000000..39d52a3b --- /dev/null +++ b/ietf/.remarkrc.js @@ -0,0 +1,12 @@ +import lintPreset from "../.remarkrc-lint.js"; +import remarkLintNoMultipleToplevelHeadings from "remark-lint-no-multiple-toplevel-headings"; +import remarkLintFencedCodeMarker from "remark-lint-fenced-code-marker"; + + +export default { + plugins: [ + lintPreset, + [remarkLintNoMultipleToplevelHeadings, false], + [remarkLintFencedCodeMarker, "~"] + ] +}; diff --git a/ietf/example.md b/ietf/example.md new file mode 100644 index 00000000..9615bdc4 --- /dev/null +++ b/ietf/example.md @@ -0,0 +1,32 @@ +--- + +stand_alone: true +ipr: trust200902 +submissiontype: independent +category: info + +author: +- name: Jason Desrosiers + email: jdesrosi@gmail.com + role: editor + +title: Example + +--- abstract + +An example of an I-D in markdown + +--- middle + +# Introduction + +## Notational Conventions + +{::boilerplate bcp14+} + +# Security Considerations + +TODO: Required section + +--- back + diff --git a/specs/jsonschema-use-cases.xml b/ietf/jsonschema-use-cases.xml similarity index 100% rename from specs/jsonschema-use-cases.xml rename to ietf/jsonschema-use-cases.xml diff --git a/specs/relative-json-pointer.xml b/ietf/relative-json-pointer.xml similarity index 100% rename from specs/relative-json-pointer.xml rename to ietf/relative-json-pointer.xml diff --git a/package.json b/package.json index b7a625b6..6e358b31 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "main": "index.js", "scripts": { "lint": "eslint . ; remark --no-stdout --frail .", - "build": "remark --rc-path specs/.remarkrc-build.js --output web/" + "build": "remark --rc-path specs/.remarkrc-build.js --output web/", + "build-ietf": "docker-compose run --rm build" }, "license": "MIT", "devDependencies": { diff --git a/remark/rehype-link-transformer.js b/remark/rehype-link-transformer.js index 224667d1..458bfe9f 100644 --- a/remark/rehype-link-transformer.js +++ b/remark/rehype-link-transformer.js @@ -1,6 +1,7 @@ -import { existsSync } from "fs"; +import { existsSync } from "node:fs"; +import { basename } from "node:path"; +import url from "node:url"; import { visit } from "unist-util-visit"; -import url from "url"; const rehypeLinkTransformer = () => (tree, vfile) => { @@ -8,7 +9,7 @@ const rehypeLinkTransformer = () => (tree, vfile) => { if (node.tagName === "a") { const href = url.parse(node.properties.href); if (href.hostname === null && href.pathname?.endsWith(".md") && existsSync(vfile.history[0])) { - href.pathname = href.pathname.replace(/.md$/, ".html"); + href.pathname = basename(href.pathname).replace(/.md$/, ".html"); node.properties.href = url.format(href); } } diff --git a/requirements.in b/requirements.in deleted file mode 100644 index f5cf3e08..00000000 --- a/requirements.in +++ /dev/null @@ -1 +0,0 @@ -xml2rfc>=3.12.0 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5e4410da..00000000 --- a/requirements.txt +++ /dev/null @@ -1,45 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile requirements.in -# -certifi==2025.7.14 - # via requests -charset-normalizer==3.4.2 - # via requests -configargparse==1.7.1 - # via xml2rfc -google-i18n-address==3.1.1 - # via xml2rfc -idna==3.10 - # via requests -intervaltree==3.1.0 - # via xml2rfc -jinja2==3.1.6 - # via xml2rfc -lxml==6.0.0 - # via xml2rfc -markupsafe==3.0.2 - # via jinja2 -platformdirs==4.3.8 - # via xml2rfc -pycountry==24.6.1 - # via xml2rfc -pyyaml==6.0.2 - # via xml2rfc -requests==2.32.4 - # via - # google-i18n-address - # xml2rfc -sortedcontainers==2.4.0 - # via intervaltree -urllib3==2.5.0 - # via requests -wcwidth==0.2.13 - # via xml2rfc -xml2rfc==3.30.2 - # via -r requirements.in - -# The following packages are considered to be unsafe in a requirements file: -# setuptools