From b602c300ea0b3a303a5f9ace2ad35e7243ab2d12 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Wed, 13 Nov 2019 22:24:22 +1100 Subject: [PATCH 1/5] www: add vuepress for publishing --- .gitignore | 2 ++ .vuepress/README.md | 11 ++++++++ .vuepress/config.js | 55 +++++++++++++++++++++++++++++++++++++ .vuepress/highlight.js | 36 ++++++++++++++++++++++++ .vuepress/styles/index.styl | 3 ++ package.json | 13 +++++++++ schemas/authoring-guide.md | 4 +-- schemas/schema-kinds.md | 40 ++++++++++++++++++++------- 8 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 .gitignore create mode 100644 .vuepress/README.md create mode 100644 .vuepress/config.js create mode 100644 .vuepress/highlight.js create mode 100644 .vuepress/styles/index.styl create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..19df328c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +html/ diff --git a/.vuepress/README.md b/.vuepress/README.md new file mode 100644 index 00000000..7c43bff1 --- /dev/null +++ b/.vuepress/README.md @@ -0,0 +1,11 @@ +--- +editLink: false +--- + +# IPLD Specifications + +Specifications for the Inter-planetary Linked Data (IPLD) project: + +* **[IPLD Schemas](./schemas/)** + +See more or contribute on [GitHub](https://github.com/ipld/specs/). \ No newline at end of file diff --git a/.vuepress/config.js b/.vuepress/config.js new file mode 100644 index 00000000..559ce184 --- /dev/null +++ b/.vuepress/config.js @@ -0,0 +1,55 @@ +require('./highlight') + +function linkfix (md) { + const defaultRender = md.renderer.rules.link_open + + md.renderer.rules.link_open = function (tokens, idx, options, env, self) { + const hrefIndex = tokens[idx].attrIndex('href'); + if (hrefIndex > -1) { + const href = tokens[idx].attrs[hrefIndex][1] + if (/\.(ipldsch|json)$/.test(href)) { + tokens[idx].attrs[hrefIndex][1] = `${href}.md` + } + } + + return defaultRender(tokens, idx, options, env, self) + } +} + +module.exports = { + title: 'IPLD Specifications', + description: 'Specifications for the Inter-planetary Linked Data project', + base: '/specs/', + themeConfig: { + repo: 'ipld/specs', + editLinks: true, + editLinkText: 'Edit this page on GitHub', + lastUpdated: 'Last Updated', + smoothScroll: true, + nav: [ + { text: 'Home', link: '/' }, + { text: 'IPLD Schemas', link: '/schemas/' } + ], + sidebar: { + '/schemas/': [{ + title: 'IPLD Schemas', + collapsable: false, + sidebarDepth: 2, + children: [ + ['goals', 'Goals'], + ['feature-summary', 'Feature Summary'], + ['introduction', 'Introduction'], + ['authoring-guide', 'Authoring Guide'], + 'links', + 'schema-kinds', + ['representations', 'Representations'], + ['advanced-layouts', 'Advanced Layouts'] + ] + }] + } + }, + extendMarkdown: md => { + // use more markdown-it plugins! + md.use(linkfix) + } +} diff --git a/.vuepress/highlight.js b/.vuepress/highlight.js new file mode 100644 index 00000000..75b762d9 --- /dev/null +++ b/.vuepress/highlight.js @@ -0,0 +1,36 @@ +// this require is awkward but technically the proper way to find the 'prismjs' +// that's used by vuepress -> @vuepress/markdown -> prismjs +const prism = require( + require.resolve('prismjs', + require.resolve('@vuepress/markdown', + require.resolve('vuepress')))) + +prism.languages.ipldsch = { + typedef: { + pattern: /^[ \t]*(?:type|advanced)[ \t][A-Z](_?[A-Za-z0-9])*\b/m, + inside: { + keyword: /^[ \t]*(type|advanced)/m, + 'class-name': /[\w]+$/ + } + }, + keyword: /\b(?:bool|int|float|string|bytes|null|nullable|optional)\b/, + builtin: /\b(struct|union|enum)(?=[ \t]*\{)\b/, + representation: { + pattern: /^}[ \t]representation\b/m, + inside: { + builtin: /representation/ + } + }, + operator: /=/, + number: /\b-?\d+\.?\d*(?:e[+-]?\d+)?\b/i, + punctuation: /[(){}:[\]\|&]/, + string: { + pattern: /(")(?:\\[\s\S]|(?!\1)[^\\])*\1/, + greedy: true + }, + comment: { + pattern: /(^|[^"])#.*/, + lookbehind: true, + greedy: true + } +} diff --git a/.vuepress/styles/index.styl b/.vuepress/styles/index.styl new file mode 100644 index 00000000..e2224669 --- /dev/null +++ b/.vuepress/styles/index.styl @@ -0,0 +1,3 @@ +div[class~="language-ipldsch"]::before { + content: "ipld schema"; +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..3870ea01 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "prepare:base": "rm -rf html && mkdir html && cp -a .vuepress/ html/.vuepress/ && mv html/.vuepress/README.md html/", + "prepare:content": "cp -a schemas/ html/schemas/", + "prepare:ipldsch": "cd html && find . -name \\*.ipldsch -exec sh -c \"echo '---\\neditLink: false\\n---\\n\\n\\`\\`\\`ipldsch' > {}.md && cat {} >> {}.md && echo '\\`\\`\\`' >> {}.md\" \\;", + "prepare:json": "find html/ -name \\*.json -exec sh -c \"echo '---\\neditLink: false\\n---\\n\\n\\`\\`\\`json' > {}.md && cat {} >> {}.md && echo '\\`\\`\\`' >> {}.md\" \\;", + "build:vue": "vuepress build html --no-cache", + "build": "set -e; for t in prepare:base prepare:content prepare:ipldsch prepare:json build:vue; do npm run $t; done" + }, + "dependencies": { + "vuepress": "^1.2.0" + } +} diff --git a/schemas/authoring-guide.md b/schemas/authoring-guide.md index 0f36debc..8c4dca6b 100644 --- a/schemas/authoring-guide.md +++ b/schemas/authoring-guide.md @@ -819,7 +819,7 @@ IPLD Schemas are intended to serve a documentation role as well as a programmati When embedding IPLD Schema declarations in Markdown, use code blocks with the language marker `ipldsch`, i.e.: -
+

 ```ipldsch
 type Foo struct {
   a   Int
@@ -829,7 +829,7 @@ type Foo struct {
 
 type Message string
 ```
-
+
Any such block found in a Markdown document will be extracted and stitched together to form a single Schema document. diff --git a/schemas/schema-kinds.md b/schemas/schema-kinds.md index 316a21c3..7750f2d3 100644 --- a/schemas/schema-kinds.md +++ b/schemas/schema-kinds.md @@ -233,11 +233,15 @@ expose and correctly preserve the value's presense or absence. -
+
+
+```ipldsch
 type Foo struct {
 	bar Bool
 }
-
+``` + + {"bar": true}
{"bar": false}
@@ -247,11 +251,15 @@ type Foo struct { -
+
+
+```ipldsch
 type Foo struct {
 	bar nullable Bool
 }
-
+``` + + {"bar": true}
{"bar": false}
@@ -262,11 +270,15 @@ type Foo struct { -
+
+
+```ipldsch
 type Foo struct {
 	bar optional Bool
 }
-
+``` + + {"bar": true}
{"bar": false}
@@ -277,11 +289,15 @@ type Foo struct { -
+
+
+```ipldsch
 type Foo struct {
 	bar optional nullable Bool
 }
-
+``` + + {"bar": true}
{"bar": false}
@@ -293,13 +309,17 @@ type Foo struct { -
+
+
+```ipldsch
 type Foo struct {
 	bar Bool
 } representation map {
 	field bar default "false"
 }
-
+``` + + {"bar": true}
{}
From 440129f93fb386bb7f70c18cff4ccf5fae4128ae Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 14 Nov 2019 09:24:34 +1100 Subject: [PATCH 2/5] www: add gh-pages build & publish workflow --- .github/workflows/main.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..2e3b749a --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,31 @@ +name: gh-pages + +on: + push: + branches: + - master + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Build with Node.js + uses: actions/setup-node@v1 + with: + node-version: '12.x' + - run: npm install + - run: npm run build + + - name: GitHub Pages action + uses: peaceiris/actions-gh-pages@v2.5.1 + env: + ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} + PUBLISH_BRANCH: gh-pages + PUBLISH_DIR: ./html/.vuepress/dist/ From 0afb149c0c26a83db86e4a9e875f231208f36220 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 15 Nov 2019 10:44:39 +1100 Subject: [PATCH 3/5] fixup! www: add gh-pages build & publish workflow --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3870ea01..1d0ff223 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "prepare:ipldsch": "cd html && find . -name \\*.ipldsch -exec sh -c \"echo '---\\neditLink: false\\n---\\n\\n\\`\\`\\`ipldsch' > {}.md && cat {} >> {}.md && echo '\\`\\`\\`' >> {}.md\" \\;", "prepare:json": "find html/ -name \\*.json -exec sh -c \"echo '---\\neditLink: false\\n---\\n\\n\\`\\`\\`json' > {}.md && cat {} >> {}.md && echo '\\`\\`\\`' >> {}.md\" \\;", "build:vue": "vuepress build html --no-cache", - "build": "set -e; for t in prepare:base prepare:content prepare:ipldsch prepare:json build:vue; do npm run $t; done" + "build": "set -e; for t in prepare:base prepare:content prepare:ipldsch prepare:json build:vue; do npm run $t; done", + "serve": "echo '\n\n\u001b[1mView IPLD Specs @ http://localhost:1337/specs/\u001b[22m\n\n'; npx st --dir html/.vuepress/dist --no-cache --index index.html -u /specs/" }, "dependencies": { "vuepress": "^1.2.0" From 40b7558d2233340dfc4262e09f6cf818a60d83ed Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 15 Nov 2019 11:03:06 +1100 Subject: [PATCH 4/5] www: deploy on specs.ipld.io --- .vuepress/config.js | 2 +- CNAME | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 CNAME diff --git a/.vuepress/config.js b/.vuepress/config.js index 559ce184..2239b669 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -19,7 +19,7 @@ function linkfix (md) { module.exports = { title: 'IPLD Specifications', description: 'Specifications for the Inter-planetary Linked Data project', - base: '/specs/', + base: '/', themeConfig: { repo: 'ipld/specs', editLinks: true, diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..901248c1 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +specs.ipld.io From c0c0bb594f3b39d1d5e354910f9c087aa7e7debc Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 15 Nov 2019 15:01:38 +1100 Subject: [PATCH 5/5] www: (temp) rewrite schema ../ urls to absolute because we are only publishing /schemas/ to the web for now, links outside of /schemas/ don't work. --- package.json | 2 +- schemas/authoring-guide.md | 2 +- schemas/goals.md | 2 +- schemas/introduction.md | 2 +- schemas/links.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1d0ff223..f325750b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "prepare:json": "find html/ -name \\*.json -exec sh -c \"echo '---\\neditLink: false\\n---\\n\\n\\`\\`\\`json' > {}.md && cat {} >> {}.md && echo '\\`\\`\\`' >> {}.md\" \\;", "build:vue": "vuepress build html --no-cache", "build": "set -e; for t in prepare:base prepare:content prepare:ipldsch prepare:json build:vue; do npm run $t; done", - "serve": "echo '\n\n\u001b[1mView IPLD Specs @ http://localhost:1337/specs/\u001b[22m\n\n'; npx st --dir html/.vuepress/dist --no-cache --index index.html -u /specs/" + "serve": "echo '\n\n\u001b[1mView IPLD Specs @ http://localhost:1337/\u001b[22m\n\n'; npx st --dir html/.vuepress/dist --no-cache --index index.html" }, "dependencies": { "vuepress": "^1.2.0" diff --git a/schemas/authoring-guide.md b/schemas/authoring-guide.md index 8c4dca6b..b3bcbc16 100644 --- a/schemas/authoring-guide.md +++ b/schemas/authoring-guide.md @@ -142,7 +142,7 @@ Links in IPLD Schemas are a special-case. The Data Model kind "Link" is expresse Links can be typedef'd, `type Foo &Bar` or can appear inline: `type Baz {String:&Bang}`. -Further, the type name is not a strict assertion that can be directly tested against underlying data, it is simply a hint regarding what should be found when following the link identified by the [CID](../block-layer/CID.md) at the position indicated by the Schema link. Strict assertions of this expected type may be applied at layers above the Schema validation layer when the link is resolved and the node decoded. +Further, the type name is not a strict assertion that can be directly tested against underlying data, it is simply a hint regarding what should be found when following the link identified by the [CID](https://github.com/ipld/specs/blob/master/block-layer/CID.md) at the position indicated by the Schema link. Strict assertions of this expected type may be applied at layers above the Schema validation layer when the link is resolved and the node decoded. For more information about Links in Schemas, see [Links and IPLD Schemas](./links.md). diff --git a/schemas/goals.md b/schemas/goals.md index dfd58fd8..d0cf78b2 100644 --- a/schemas/goals.md +++ b/schemas/goals.md @@ -1,7 +1,7 @@ # IPLD Schemas Goals 1. Provide a reasonable, easy to use, general type system for declaring useful properties about data. -2. Compose nicely over the [IPLD Data Model](../data-model-layer/data-model.md): Schemas should be usable with any data format you can build an [IPLD Codec](../block-layer/codecs/README.md) for. +2. Compose nicely over the [IPLD Data Model](https://github.com/ipld/specs/blob/master/data-model-layer/data-model.md): Schemas should be usable with any data format you can build an [IPLD Codec](https://github.com/ipld/specs/tree/master/block-layer/codecs) for. 3. Be efficient to verify: predictable; roughly linear in the size of the data and Schema; and absolutely not turing complete. 4. Be language-agnostic: many compatible implementations of the Schema tooling should exist, as well as bindings for many languages. 5. Assist rather than obstruct migration: we expect to be working with _existing_ data; we need to work well on this case. diff --git a/schemas/introduction.md b/schemas/introduction.md index 476096ef..8e83c331 100644 --- a/schemas/introduction.md +++ b/schemas/introduction.md @@ -4,7 +4,7 @@ IPLD concerns itself with the data layer of the distributed web. Its scope begins above the data storage and transmission layer, only interested in how data elements are encoded and decoded to a particular storage format and then presented in a consistent and usable form when above this encoding layer. -IPLD uses a [Data Model](../data-model-layer/data-model.md) to bound what form its standard data elements can take. The data model allows for standard scalar data types found across most programming languages and a large number of generic data encoding formats (JSON, CBOR, etc.), such as String and Int. It also includes two recursive types that are used to build more complex data structures upon the scalar types. These recursive types are List and Map and should be familiar to most programmers and are also common in many generic data encoding formats. The IPLD Data Model doesn’t include many of the types available in some encoding formats (such as the many Int sizing options available in CBOR). Similarly, it doesn’t support many of these same types available in some programming languages. Instead, it uses this bounded data presentation model as a way to build practical tools that can span many encoding formats and be practically usable in many programming languages. +IPLD uses a [Data Model](https://github.com/ipld/specs/blob/master/data-model-layer/data-model.md) to bound what form its standard data elements can take. The data model allows for standard scalar data types found across most programming languages and a large number of generic data encoding formats (JSON, CBOR, etc.), such as String and Int. It also includes two recursive types that are used to build more complex data structures upon the scalar types. These recursive types are List and Map and should be familiar to most programmers and are also common in many generic data encoding formats. The IPLD Data Model doesn’t include many of the types available in some encoding formats (such as the many Int sizing options available in CBOR). Similarly, it doesn’t support many of these same types available in some programming languages. Instead, it uses this bounded data presentation model as a way to build practical tools that can span many encoding formats and be practically usable in many programming languages. IPLD’s Data Model is useful for building an abstraction at the data layer. It pushes concerns about encoding and decoding to its own dedicated domain where such concerns only have to deal with a limited set of data types and how to convert to and from those data types. But it also makes room for the development of an ecosystem of libraries and tools that are able to build on top of this model and can therefore operate according to shared assumptions about how data is presented. Such an ecosystem should empower significantly more sharing of algorithms, tools, techniques and code in the distributed web community, rather than siloing these assets in codebases that are concerned entirely use-case-specific stacks. diff --git a/schemas/links.md b/schemas/links.md index 42d35332..d0310ed0 100644 --- a/schemas/links.md +++ b/schemas/links.md @@ -83,6 +83,6 @@ type Element union { # ... further definitions for `Bucket` ``` -In this example, from the [HashMap](../data-structures/hashmap.md) spec, we describe a `map`, named `HashMapNode` that contains a `data` property which is a list of `Element`s. These `Element`s may be one of three things: a `map` that contains another `HashMapNode` (an inlined child for a tree data structure), a `link` which is assumed to lead to a `HashMapNode` (a linked child) or a `Bucket` (not described here) which comprises a `list`. +In this example, from the [HashMap](https://github.com/ipld/specs/blob/master/data-structures/hashmap.md) specification, we describe a `map`, named `HashMapNode` that contains a `data` property which is a list of `Element`s. These `Element`s may be one of three things: a `map` that contains another `HashMapNode` (an inlined child for a tree data structure), a `link` which is assumed to lead to a `HashMapNode` (a linked child) or a `Bucket` (not described here) which comprises a `list`. Our validator can scan the `data` list and check that each element is one of: `map`, `link` and `list`. We make no strong assertions that the `link` actually yields a `HashMapNode` but such assertions may be built into code generated from this schema _when_ the link is loaded and validated.