├── .eslintignore ├── .npmrc ├── boilerplate ├── proposal-copyright.html ├── address.html ├── software-license.html ├── standard-copyright.html └── alternative-copyright.html ├── test ├── boilerplate-copyright.fixture ├── baselines │ ├── sources │ │ ├── malformed.bad.html │ │ ├── charset-absent.html │ │ ├── imports │ │ │ ├── import2.html │ │ │ ├── sub │ │ │ │ └── import3.html │ │ │ └── import1.html │ │ ├── charset-present.html │ │ ├── html-element-attributes.html │ │ ├── algorithmsBiblio.json │ │ ├── date.html │ │ ├── toc.html │ │ ├── proposal-copyright.html │ │ ├── xrefTestBiblio.json │ │ ├── copyright.html │ │ ├── ins-nonterminal.html │ │ ├── shortname.html │ │ ├── title.html │ │ ├── assets-inline.html │ │ ├── ecmarkdown.html │ │ ├── imports.html │ │ ├── boilerplate-address.html │ │ ├── boilerplate-license.html │ │ ├── boilerplate-copyright.html │ │ ├── duplicate-productions.html │ │ ├── boilerplate-all.html │ │ ├── escaping.html │ │ ├── oldids.html │ │ ├── nonterminal-used-before-definition.html │ │ ├── step-xrefs.html │ │ ├── notes.html │ │ ├── emd-in-grammar.html │ │ ├── namespaces-productions.html │ │ ├── multipage.html │ │ ├── example.html │ │ ├── max-clause-depth.html │ │ ├── eqn.html │ │ ├── code.html │ │ ├── grammar.html │ │ ├── algorithms.html │ │ ├── optional-parts.html │ │ ├── autolinking.html │ │ ├── dfn.html │ │ ├── algorithm-replacements.html │ │ ├── duplicate-ids.html │ │ ├── clauses.html │ │ ├── figure.html │ │ └── namespaces.html │ └── generated-reference │ │ ├── charset-absent.html │ │ ├── charset-present.html │ │ ├── html-element-attributes.html │ │ ├── date.html │ │ ├── ecmarkdown.html │ │ ├── title.html │ │ ├── shortname.html │ │ ├── ins-nonterminal.html │ │ ├── escaping.html │ │ ├── notes.html │ │ ├── oldids.html │ │ ├── step-xrefs.html │ │ ├── imports.html │ │ ├── duplicate-productions.html │ │ ├── nonterminal-used-before-definition.html │ │ ├── example.html │ │ ├── toc.html │ │ ├── emd-in-grammar.html │ │ ├── multipage.html │ │ ├── multipage │ │ │ ├── index.html │ │ │ ├── second.html │ │ │ └── third.html │ │ └── index.html │ │ ├── code.html │ │ ├── algorithm-replacements.html │ │ ├── eqn.html │ │ ├── boilerplate-all.html │ │ ├── duplicate-ids.html │ │ ├── optional-parts.html │ │ ├── namespaces-productions.html │ │ ├── figure.html │ │ ├── dfn.html │ │ ├── autolinking.html │ │ ├── proposal-copyright.html │ │ ├── max-clause-depth.html │ │ ├── boilerplate-copyright.html │ │ └── algorithms.html ├── boilerplate-address.fixture ├── format-good.html ├── format-bad.html ├── build.js ├── boilerplate-license.fixture ├── clauseIds.js ├── lint-tags.js └── cli.js ├── .prettierignore ├── ecma-logo.png ├── bin ├── ecmarkup.js └── emu-format.js ├── img └── ecma-header.png ├── fonts ├── IBMPlexMono-Bold-SlashedZero.woff2 ├── IBMPlexMono-Italic-SlashedZero.woff2 ├── IBMPlexSans-Bold-SlashedZero.woff2 ├── IBMPlexSans-Italic-SlashedZero.woff2 ├── IBMPlexSerif-Bold-SlashedZero.woff2 ├── IBMPlexMono-Regular-SlashedZero.woff2 ├── IBMPlexSans-Regular-SlashedZero.woff2 ├── IBMPlexSerif-Italic-SlashedZero.woff2 ├── IBMPlexSerif-Regular-SlashedZero.woff2 ├── IBMPlexMono-BoldItalic-SlashedZero.woff2 ├── IBMPlexSans-BoldItalic-SlashedZero.woff2 └── IBMPlexSerif-BoldItalic-SlashedZero.woff2 ├── .gitignore ├── .editorconfig ├── tsconfig.test.json ├── src ├── lint │ ├── algorithm-error-reporter-type.ts │ ├── rules │ │ ├── algorithm-step-numbering.ts │ │ ├── algorithm-step-labels.ts │ │ ├── enum-casing.ts │ │ ├── for-each-element.ts │ │ ├── step-attributes.ts │ │ └── if-else-consistency.ts │ ├── collect-tag-diagnostics.ts │ └── lint.ts ├── external.d.ts ├── Context.ts ├── Terminal.ts ├── GrammarAnnotation.ts ├── .eslintrc.json ├── H1.ts ├── Builder.ts ├── Dfn.ts ├── ecmarkup.ts ├── Toc.ts ├── Example.ts ├── Meta.ts ├── Figure.ts ├── Import.ts ├── NonTerminal.ts ├── Eqn.ts ├── formatter │ ├── header.ts │ └── text.ts ├── Note.ts ├── ProdRef.ts ├── RHS.ts ├── args.ts └── arg-parser.ts ├── spec └── biblio.json ├── tsconfig.json ├── README.md ├── scripts └── auto-deploy.sh ├── .github └── workflows │ ├── publish.yml │ ├── update-docs.yml │ ├── enforce-format.yml │ └── check.yml ├── js ├── multipage.js ├── sdoMap.js ├── superscripts.js └── print.js ├── filter-entities.js ├── LICENSE ├── PUBLISHING.md ├── .eslintrc.json └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | docs 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | allow-same-version=true 2 | message=v%s 3 | -------------------------------------------------------------------------------- /boilerplate/proposal-copyright.html: -------------------------------------------------------------------------------- 1 |
© !YEAR! !CONTRIBUTORS!
2 | -------------------------------------------------------------------------------- /test/boilerplate-copyright.fixture: -------------------------------------------------------------------------------- 1 |© !YEAR! !CONTRIBUTORS!
2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.md 3 | *.json 4 | *.yml 5 | lib/ 6 | docs/ 7 | -------------------------------------------------------------------------------- /ecma-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/ecma-logo.png -------------------------------------------------------------------------------- /bin/ecmarkup.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | require('../lib/cli'); 4 | -------------------------------------------------------------------------------- /img/ecma-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/img/ecma-header.png -------------------------------------------------------------------------------- /bin/emu-format.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | require('../lib/formatter/cli'); 4 | -------------------------------------------------------------------------------- /test/baselines/sources/malformed.bad.html: -------------------------------------------------------------------------------- 1 | 2 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | -------------------------------------------------------------------------------- /fonts/IBMPlexMono-Regular-SlashedZero.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/fonts/IBMPlexMono-Regular-SlashedZero.woff2 -------------------------------------------------------------------------------- /fonts/IBMPlexSans-Regular-SlashedZero.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/fonts/IBMPlexSans-Regular-SlashedZero.woff2 -------------------------------------------------------------------------------- /fonts/IBMPlexSerif-Italic-SlashedZero.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/fonts/IBMPlexSerif-Italic-SlashedZero.woff2 -------------------------------------------------------------------------------- /fonts/IBMPlexSerif-Regular-SlashedZero.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tc39/ecmarkup/HEAD/fonts/IBMPlexSerif-Regular-SlashedZero.woff2 -------------------------------------------------------------------------------- /test/baselines/sources/imports/import2.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | toc: false 4 | copyright: false 5 | assets: none 6 |7 | 8 | -------------------------------------------------------------------------------- /test/baselines/sources/html-element-attributes.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | toc: false 4 | copyright: false 5 | assets: none 6 |7 | Content 8 | 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /test/baselines/sources/imports/sub/import3.html: -------------------------------------------------------------------------------- 1 | 2 |
2 | title: test title! 3 | date: 2014-07-01 4 | status: standard 5 | toc: false 6 | copyright: false 7 | assets: none 8 |9 | 10 |
Some body content
11 | 12 | -------------------------------------------------------------------------------- /test/baselines/sources/toc.html: -------------------------------------------------------------------------------- 1 |2 | copyright: false 3 | assets: none 4 |5 | 6 |
Example clause contents.
9 |text
5 ||nonterminal| `code` *value*.
6 | 7 |2 | title: test title! 3 | toc: false 4 | date: 2014-09-26 5 | assets: none 6 | stage: 0 7 | contributors: Brian Terlson, Ecma International 8 |9 | 10 | -------------------------------------------------------------------------------- /src/lint/algorithm-error-reporter-type.ts: -------------------------------------------------------------------------------- 1 | export type Reporter = (lintingError: LintingError) => void; 2 | 3 | // TODO rename 4 | export type LintingError = { 5 | ruleId: string; 6 | message: string; 7 | line: number; 8 | column: number; 9 | }; 10 | -------------------------------------------------------------------------------- /test/baselines/sources/xrefTestBiblio.json: -------------------------------------------------------------------------------- 1 | { 2 | "location": "http://example.com/fooSite.html", 3 | "entries": [ 4 | { 5 | "type": "clause", 6 | "title": "Foo Section", 7 | "number": "1", 8 | "id": "sec-foo" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /test/baselines/sources/copyright.html: -------------------------------------------------------------------------------- 1 |
2 | title: test title! 3 | status: draft 4 | version: Draft 1 5 | toc: false 6 | date: 2014-09-26 7 | assets: none 8 |9 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
2 | title: test title! 3 | shortname: ECMA-000 4 | status: draft 5 | version: Draft 1 6 | toc: false 7 | date: 2015-09-26 8 | copyright: false 9 | assets: none 10 |11 | 12 |
Some body content
13 | -------------------------------------------------------------------------------- /test/baselines/sources/title.html: -------------------------------------------------------------------------------- 1 |2 | title: test title! 3 | description: a test document 4 | status: draft 5 | version: Draft 1 6 | toc: false 7 | copyright: false 8 | date: 2015-09-26 9 | assets: none 10 |11 | 12 |
Some body content
13 | -------------------------------------------------------------------------------- /test/baselines/sources/assets-inline.html: -------------------------------------------------------------------------------- 1 |2 | toc: true 3 | date: 1997-06-01 4 | copyright: true 5 | contributors: Ecma 6 | assets: inline 7 |8 |
This is a section.
11 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
ecmarkdown like _v_ works before and after comments _v_.
9 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
2 | title: test title! 3 | toc: false 4 | date: 2018-04-02 5 | assets: none 6 | stage: 0 7 | status: draft 8 | contributors: Rick Waldron, Mid-World 9 | copyright: true 10 | boilerplate: 11 | address: test/boilerplate-address.fixture 12 |13 | 14 | -------------------------------------------------------------------------------- /test/baselines/sources/boilerplate-license.html: -------------------------------------------------------------------------------- 1 |
2 | title: test title! 3 | toc: false 4 | date: 2018-04-02 5 | assets: none 6 | stage: 0 7 | status: draft 8 | contributors: Rick Waldron, Mid-World 9 | copyright: true 10 | boilerplate: 11 | license: test/boilerplate-license.fixture 12 |13 | 14 | -------------------------------------------------------------------------------- /test/baselines/sources/boilerplate-copyright.html: -------------------------------------------------------------------------------- 1 |
2 | title: test title! 3 | toc: false 4 | date: 2018-04-02 5 | assets: none 6 | stage: 0 7 | status: draft 8 | contributors: Rick Waldron, Mid-World 9 | copyright: true 10 | boilerplate: 11 | copyright: test/boilerplate-copyright.fixture 12 |13 | 14 | -------------------------------------------------------------------------------- /boilerplate/address.html: -------------------------------------------------------------------------------- 1 |
Ecma International
2 |Rue du Rhone 114
3 |CH-1204 Geneva
4 |Tel: +41 22 849 6000
5 |Fax: +41 22 849 6001
6 |Web: https://ecma-international.org/
7 | -------------------------------------------------------------------------------- /test/boilerplate-address.fixture: -------------------------------------------------------------------------------- 1 |Tet Corporation
2 |2 Hammarskjöld Plaza
3 |New York City, New York
4 |Tel: 123-456-7890
5 |Fax: 123-456-7890
6 |Web: http://www.tet-corporation.com/
7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "target": "es2019", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "declaration": true, 9 | "stripInternal": true, 10 | "outDir": "lib", 11 | "lib": ["es2020", "dom", "dom.iterable"], 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/baselines/sources/duplicate-productions.html: -------------------------------------------------------------------------------- 1 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
2 | title: test title! 3 | toc: false 4 | date: 2018-04-02 5 | assets: none 6 | stage: 0 7 | status: draft 8 | contributors: Rick Waldron, Mid-World 9 | copyright: true 10 | boilerplate: 11 | address: test/boilerplate-address.fixture 12 | copyright: test/boilerplate-copyright.fixture 13 | license: test/boilerplate-license.fixture 14 |15 | 16 | -------------------------------------------------------------------------------- /test/baselines/sources/escaping.html: -------------------------------------------------------------------------------- 1 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
U+200C (ZERO WIDTH NON-JOINER) is abbreviated "<ZWNJ>"
9 |<b>also doesn't escape when *emd* and autolinks to ReturnIfAbrupt are present.
10 |Escpaing inside xref is preserved:
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
This is some content and such.
9 |This is a note!
18 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
You can refer to a step before it occurs in text, like step
You can refer to it after as well, like step
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
6 | copyright: false 7 | assets: none 8 | multipage: true 9 |10 | 11 |
Some text.
14 |A cross-section reference: Alg.
19 |A relative image:
.
Some text.
25 |Pretend there's an algorithm here.
28 |?u/p1-90`?u/p1-90`2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
Examples outside of clauses aren't processed specially.
7 |?u/p1-90`?u/p1-90`Some body content
15 | 16 |toc: false\ncopyright: false\nassets: none
6 | copyright: false 7 | assets: none 8 | maxClauseDepth: 2 9 |10 | 11 |
?u/p1-90`ecmarkdown like v works before and after comments v.
16 |3 | toc: false 4 | copyright: false 5 | assets: none 6 |7 |
Can refer to eqns inside paragraph text via autolinking: DateValue.
10 |Inline eqns are a thing, for example
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
Increases indentaion level.
10 |
11 | global1.Zone.current; // succeeds
12 | global2.Zone.current; // throws: currentRealm = realm1; thisRealm = functionRealm = realm2
13 |
14 | const getter1 = Object.getOwnPropertyDescriptor(global1.Zone, "current").get;
15 | const getter2 = Object.getOwnPropertyDescriptor(global2.Zone, "current").get;
16 |
17 | getter1.call(global2.Zone); // throws: currentRealm = functionRealm = realm1; thisRealm = realm2
18 | getter2.call(global1.Zone); // throws: currentRealm = thisRealm = realm1; functionRealm = realm2
19 |
20 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2 | 3 |The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
4 | 5 |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6 | -------------------------------------------------------------------------------- /test/clauseIds.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const sectionNums = require('../lib/clauseNums').default; 5 | 6 | describe('clause id generation', () => { 7 | let iter; 8 | 9 | beforeEach(() => { 10 | iter = sectionNums({ opts: {} }); 11 | }); 12 | 13 | specify('generating clause ids', () => { 14 | const CLAUSE = { nodeName: 'EMU-CLAUSE', hasAttribute: () => false }; 15 | const ANNEX = { nodeName: 'EMU-ANNEX', hasAttribute: () => false }; 16 | assert.strictEqual(iter.next([], CLAUSE), '1'); 17 | assert.strictEqual(iter.next([{}], CLAUSE), '1.1'); 18 | assert.strictEqual(iter.next([{}], CLAUSE), '1.2'); 19 | assert.strictEqual(iter.next([{}, {}], CLAUSE), '1.2.1'); 20 | assert.strictEqual(iter.next([], CLAUSE), '2'); 21 | assert.strictEqual(iter.next([], ANNEX), 'A'); 22 | assert.strictEqual(iter.next([{}], ANNEX), 'A.1'); 23 | assert.strictEqual(iter.next([{}], ANNEX), 'A.2'); 24 | assert.strictEqual(iter.next([{}, {}], ANNEX), 'A.2.1'); 25 | assert.strictEqual(iter.next([], ANNEX), 'B'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/baselines/generated-reference/title.html: -------------------------------------------------------------------------------- 1 | 2 |?u/p1-90`Some body content
15 |?u/p1-90`Some body content
15 |3 | toc: false 4 | copyright: false 5 | assets: none 6 |7 | 8 |
Can also have inline productions like
?u/p1-90`2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
Can refer to functions in prose, eg. Internal.
27 |Internal works if Internal is in the middle of the prose.
28 |Don't autolink references inside square brackets, eg: [[Internal]]. 29 | Likewise, percent things: %%Internal%%. 30 | Likewise, mentions of Internal.foo.
31 |?u/p1-90`U+200C (ZERO WIDTH NON-JOINER) is abbreviated "<ZWNJ>"
16 |<b>also doesn't escape when
Escpaing inside xref is preserved:
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
Normative Optional is a defined term, as is Legacy. For comparison, "Deprecated" is not.
11 |This clause is normative optional.
16 |This clause is legacy.
21 |?u/p1-90`2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
Type, type, Type(), type()
9 |%Array% and %ArrayPrototype% from ES6 should link (but not %Arrayprototype%).
10 | 11 |Lowercase
12 |strict mode
13 |%Percent%
14 |extra spaces
15 |Await
16 |Variants
17 |lowercase should not autolink. But Lowercase should. But not LowerCase.
22 |Strict mode shoud link. But Strict Mode should not. Also, strict 23 | mode can be wrapped across lines and contain extra whitespace.
24 |extra spaces in a dfn should be narrowed to one space.
25 |%Percent% should autolink.
26 |Vars to dfns should be vars not dfns: _Lowercase_.
27 |Also, no autolinks in anchors: Lowercase.
28 |Similarly, no autolinks for [Await].
29 |Variants like vOne and vTwo should autolink, including when capitalized as in VOne.
30 |%Array% and %ArrayPrototype% outside of clauses is ok.
35 | -------------------------------------------------------------------------------- /test/baselines/generated-reference/oldids.html: -------------------------------------------------------------------------------- 1 | 2 |?u/p1-90`This is some content and such.
16 |This is a note!
25 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
Forward references to dfn work.
9 |Also terms from ES6 are auto-linked: Lexical Environment, Completion, etc.
10 |The term dfn means the dfn tag. Other mentions of dfn in this clause should not be auto-linked.
15 | 16 |Terms with ids are called id dfns. Since this dfn has an id, other occurences 17 | of id dfns may autolink.
18 | 19 |Dfn should be auto-linked here as well. The linking of dfn is case insensitive. But the header shouldn't auto-link.
23 |Id dfns should link to #identifiers.
24 |Also terms are auto-linked in algorithms. But not naked abstract ops!
27 | 28 | 29 |?u/p1-90`You can refer to a step before it occurs in text, like step
You can refer to it after as well, like step
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
You can refer to a step in a replacement algorithm before it occurs in text, like step
You can similarly refer to a step in a replacement algorithm which itself which replaces a step in a replacement algorithm, like step
An algorithm can come before the step it replaces.
15 | 16 |This is our sample algorithm.
24 |An algorithm can also come after the step it replaces.
31 | 32 |You can even replace steps in replacement algorithms.
40 | 41 |?u/p1-90`text
16 |code
?u/p1-90`?u/p1-90`some text 40 |
some other text
41 | is missing its closing tag',
47 | },
48 | );
49 | });
50 |
51 | it('negative', async () => {
52 | await assertLintFree(`
53 | some text some other textExample
55 |
57 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
?u/p1-90`Examples outside of clauses aren't processed specially.
14 |?u/p1-90`Example clause contents.
20 |2 | printable: true 3 | title: Test Doc 4 | shortname: Test 5 | copyright: false 6 | assets: none 7 |8 |
2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 | 7 |
| Column 1 | Column 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
?u/p1-90`All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
2 | 3 |Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 | 5 |THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 | -------------------------------------------------------------------------------- /test/cli.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const execSync = require('child_process').execSync; 5 | const execPath = process.execPath.includes(' ') ? `"${process.execPath}"` : process.execPath; 6 | 7 | describe('ecmarkup#cli', function () { 8 | this.timeout(4000); // Increase timeout for CLI tests as startup time can be variable. 9 | 10 | it('exits cleanly on success', () => { 11 | execSync(`${execPath} ./bin/ecmarkup.js test/baselines/sources/example.html`, { 12 | encoding: 'utf8', 13 | }); 14 | }); 15 | 16 | it('exits cleanly on warning', () => { 17 | execSync(`${execPath} ./bin/ecmarkup.js test/baselines/sources/duplicate-ids.html`, { 18 | encoding: 'utf8', 19 | stdio: 'ignore', 20 | }); 21 | }); 22 | 23 | it('exits with an error on error', () => { 24 | assert.throws(() => { 25 | execSync(`${execPath} ./bin/ecmarkup.js test/baselines/sources/malformed.bad.html`, { 26 | encoding: 'utf8', 27 | stdio: 'ignore', 28 | }); 29 | }); 30 | }); 31 | 32 | it('exits with an error on warning when using --strict', () => { 33 | assert.throws(() => { 34 | execSync(`${execPath} ./bin/ecmarkup.js --strict test/baselines/sources/duplicate-ids.html`, { 35 | encoding: 'utf8', 36 | stdio: 'ignore', 37 | }); 38 | }); 39 | }); 40 | }); 41 | 42 | describe('emu-format --check', function () { 43 | this.timeout(4000); 44 | 45 | it('exits cleanly if the file needs no formatting', () => { 46 | execSync(`${execPath} ./bin/emu-format.js --check test/format-good.html`, { 47 | encoding: 'utf8', 48 | }); 49 | }); 50 | 51 | it('exits with an error if the file needs formatting', () => { 52 | assert.throws(() => { 53 | execSync(`${execPath} ./bin/emu-format.js --check test/format-bad.html`, { 54 | encoding: 'utf8', 55 | }); 56 | }); 57 | }); 58 | 59 | it('exits with an error if any files in the list need formatting', () => { 60 | assert.throws(() => { 61 | execSync( 62 | `${execPath} ./bin/emu-format.js --check test/format-good.html test/format-bad.html`, 63 | { 64 | encoding: 'utf8', 65 | }, 66 | ); 67 | }); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /src/Import.ts: -------------------------------------------------------------------------------- 1 | import type Spec from './Spec'; 2 | 3 | import * as utils from './utils'; 4 | import * as path from 'path'; 5 | import type { JSDOM } from 'jsdom'; 6 | 7 | export type Import = { 8 | importLocation: string; 9 | relativeRoot: string; 10 | source: string; 11 | }; 12 | 13 | export async function buildImports(spec: Spec, importNode: EmuImportElement, root: string) { 14 | const href = importNode.getAttribute('href'); 15 | if (!href) throw new Error('Import missing href attribute.'); 16 | const importPath = path.join(root, href); 17 | const relativeRoot = path.dirname(importPath); 18 | 19 | const html = await spec.fetch(importPath); 20 | 21 | spec.imports.push({ importLocation: importPath, relativeRoot, source: html }); 22 | 23 | const importDom = utils.htmlToDom(html); 24 | importNode.dom = importDom; 25 | importNode.source = html; 26 | importNode.importPath = importPath; 27 | 28 | const importDoc = importDom.window.document; 29 | 30 | // clone this list so we can walk it after the replaceWith call 31 | const importedNodes = [...importDoc.body.childNodes]; 32 | const frag = spec.doc.createDocumentFragment(); 33 | 34 | for (let i = 0; i < importedNodes.length; i++) { 35 | const importedNode = spec.doc.adoptNode(importedNodes[i]); 36 | importedNodes[i] = importedNode; 37 | frag.appendChild(importedNode); 38 | 39 | spec.topLevelImportedNodes.set(importedNode, importNode); 40 | } 41 | 42 | importNode.replaceWith(frag); 43 | 44 | for (let i = 0; i < importedNodes.length; i++) { 45 | const importedNode = importedNodes[i]; 46 | if (importedNode.nodeType === 1 /* Node.ELEMENT_NODE */) { 47 | const importedImports = [ 48 | ...(importedNode as HTMLElement).querySelectorAll('emu-import'), 49 | // we have to do this because querySelectorAll can't return its `this` 50 | ...((importedNode as HTMLElement).tagName === 'EMU-IMPORT' ? [importedNode] : []), 51 | ]; 52 | for (const childImport of importedImports) { 53 | await buildImports(spec, childImport as EmuImportElement, relativeRoot); 54 | } 55 | } 56 | } 57 | } 58 | 59 | export interface EmuImportElement extends HTMLElement { 60 | href: string; 61 | dom: JSDOM; 62 | source?: string; 63 | importPath?: string; 64 | } 65 | -------------------------------------------------------------------------------- /src/NonTerminal.ts: -------------------------------------------------------------------------------- 1 | import type Spec from './Spec'; 2 | import type { Context } from './Context'; 3 | import type { BiblioEntry } from './Biblio'; 4 | 5 | import Builder from './Builder'; 6 | 7 | export default class NonTerminal extends Builder { 8 | /** @internal */ params: string | null; 9 | /** @internal */ optional: boolean; 10 | /** @internal */ namespace: string; 11 | /** @internal */ entry?: BiblioEntry; 12 | 13 | static readonly elements = ['EMU-NT'] as const; 14 | 15 | constructor(spec: Spec, node: HTMLElement, namespace: string) { 16 | super(spec, node); 17 | 18 | this.params = node.getAttribute('params'); 19 | this.optional = node.hasAttribute('optional'); 20 | this.namespace = namespace; 21 | } 22 | 23 | static async enter({ spec, node, clauseStack }: Context) { 24 | const clause = clauseStack[clauseStack.length - 1]; 25 | const namespace = clause ? clause.namespace : spec.namespace; 26 | const nt = new NonTerminal(spec, node, namespace); 27 | spec._ntRefs.push(nt); 28 | 29 | if (spec.opts.lintSpec && spec.locate(node) != null && !node.hasAttribute('example')) { 30 | const clause = clauseStack[clauseStack.length - 1]; 31 | const namespace = clause ? clause.namespace : spec.namespace; 32 | spec._ntStringRefs = spec._ntStringRefs.concat({ 33 | name: node.textContent!, 34 | loc: { line: 1, column: 1 }, 35 | node, 36 | namespace, 37 | }); 38 | } 39 | } 40 | 41 | build() { 42 | const name = this.node.textContent!; 43 | // const id = 'prod-' + name; 44 | const entry = this.spec.biblio.byProductionName(name, this.namespace); 45 | 46 | if (entry) { 47 | this.node.innerHTML = '' + name + ''; 48 | this.entry = entry; 49 | } else { 50 | this.node.innerHTML = name; 51 | } 52 | let modifiers = ''; 53 | 54 | if (this.params) { 55 | modifiers += 'COPYRIGHT NOTICE
2 | 3 |© !YEAR! Ecma International
4 | 5 |By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions.
6 | 7 |This document may be copied, published and distributed to others, and certain derivative works of it may be prepared, copied, published, and distributed, in whole or in part, provided that the above copyright notice and this Copyright License and Disclaimer are included on all such copies and derivative works. The only derivative works that are permissible under this Copyright License and Disclaimer are:
8 | 9 |(i) works which incorporate all or portion of this document for the purpose of providing commentary or explanation (such as an annotated version of the document),
10 | 11 |(ii) works which incorporate all or portion of this document for the purpose of incorporating features that provide accessibility,
12 | 13 |(iii) translations of this document into languages other than English and into different formats and
14 | 15 |(iv) works by making use of this specification in standard conformant products by implementing (e.g. by copy and paste wholly or partly) the functionality therein.
16 | 17 |However, the content of this document itself may not be modified in any way, including by removing the copyright notice or references to Ecma International, except as required to translate it into languages other than English or into a different format.
18 | 19 |The official version of an Ecma International document is the English language version on the Ecma International website. In the event of discrepancies between a translated version and the official version, the official version shall govern.
20 | 21 |The limited permissions granted above are perpetual and will not be revoked by Ecma International or its successors or assigns.
22 | 23 |This document and the information contained herein is provided on an “AS IS” basis and ECMA INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
24 | -------------------------------------------------------------------------------- /boilerplate/alternative-copyright.html: -------------------------------------------------------------------------------- 1 |ALTERNATIVE COPYRIGHT NOTICE AND COPYRIGHT LICENSE
3 | 4 |© !YEAR! Ecma International
5 | 6 |7 | By obtaining and/or copying this work, you (the licensee) agree that you 8 | have read, understood, and will comply with the following terms and 9 | conditions. 10 |
11 | 12 |13 | Permission under Ecma’s copyright to copy, modify, prepare derivative works 14 | of, and distribute this work, with or without modification, for any purpose 15 | and without fee or royalty is hereby granted, provided that you include the 16 | following on ALL copies of the work or portions thereof, including 17 | modifications: 18 |
19 | 20 |21 | (i) The full text of this COPYRIGHT NOTICE AND COPYRIGHT LICENSE in a location 22 | viewable to users of the redistributed or derivative work. 23 |
24 |25 | (ii) Any pre-existing intellectual property disclaimers, notices, or terms and 26 | conditions. If none exist, the Ecma alternative copyright notice should be 27 | included. 28 |
29 |
30 | (iii) Notice of any changes or modifications, through a copyright statement on
31 | the document such as “This document includes material copied from or
32 | derived from !DOCUMENT!.
33 | Copyright © Ecma International.”
34 |
Disclaimers
37 | 38 |39 | THIS WORK IS PROVIDED “AS IS,” AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS 40 | OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES 41 | OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF 42 | THE DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, 43 | TRADEMARKS OR OTHER RIGHTS. 44 |
45 | 46 |47 | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR 48 | CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT. 49 |
50 | 51 |52 | The name and trademarks of copyright holders may NOT be used in advertising 53 | or publicity pertaining to the work without specific, written prior 54 | permission. Title to copyright in this work will at all times remain with 55 | copyright holders. 56 |
57 |?um/p1-90`Some text.
24 |?u/p1-90`Increases indentaion level.
17 |global1.Zone.current; // succeeds
18 | global2.Zone.current; // throws: currentRealm = realm1; thisRealm = functionRealm = realm2
19 |
20 | const getter1 = Object.getOwnPropertyDescriptor(global1.Zone, "current").get;
21 | const getter2 = Object.getOwnPropertyDescriptor(global2.Zone, "current").get;
22 |
23 | getter1.call(global2.Zone); // throws: currentRealm = functionRealm = realm1; thisRealm = realm2
24 | getter2.call(global1.Zone); // throws: currentRealm = thisRealm = realm1; functionRealm = realm2
25 | ?u/p1-90`You can refer to a step in a replacement algorithm before it occurs in text, like step
You can similarly refer to a step in a replacement algorithm which itself which replaces a step in a replacement algorithm, like step
An algorithm can come before the step it replaces.
22 | 23 |This is our sample algorithm.
26 |An algorithm can also come after the step it replaces.
29 | 30 |You can even replace steps in replacement algorithms.
33 | 34 |?u/p1-90`Can refer to eqns inside paragraph text via autolinking:
Inline eqns are a thing, for example
?um/p1-90`A cross-section reference:
A relative image:
.
?um/p1-90`Some text.
24 |Pretend there's an algorithm here.
27 |?u/p1-90`Tet Corporation
17 |2 Hammarskjöld Plaza
18 |New York City, New York
19 |Tel: 123-456-7890
20 |Fax: 123-456-7890
21 |Web: http://www.tet-corporation.com/
22 | 23 |© 2018 Rick Waldron, Mid-World
25 |Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
28 | 29 |The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
30 | 31 |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | 33 |2 | toc: false 3 | copyright: false 4 | assets: none 5 |6 |
SomeAlg does things.
37 |Can still xref clauses inside of namespaces:
Can xref prods in namespaces:
SomeAlg should link to #annex12. |Foo| should link to the production in #annex1.
58 |SomeAlg does things.
61 |SomeAlg does things.
77 |?u/p1-90`| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
?um/p1-90`Some text.
24 |A cross-section reference:
A relative image:
.
Some text.
35 |Pretend there's an algorithm here.
38 |?u/p1-90`Normative Optional is a defined term, as is Legacy. For comparison, "Deprecated" is not.
18 |This clause is normative optional.
23 |This clause is legacy.
28 |?u/p1-90`?u/p1-90`| Column 1 | Column 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Column 1 | Column 2 |
|---|---|
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
| Value | Value 2 |
?u/p1-90`Forward references to
Also terms from ES6 are auto-linked: Lexical Environment,
The term dfn means the dfn tag. Other mentions of dfn in this clause should not be auto-linked.
22 | 23 |Terms with ids are called id dfns. Since this dfn has an id, other occurences
24 | of
Also terms are auto-linked in algorithms. But not naked abstract ops!
34 | 35 | 36 |?u/p1-90`Type, type,
Lowercase
19 |strict mode
20 |%Percent%
21 |extra spaces
22 |Await
23 |Variants
24 |lowercase should not autolink. But
Vars to dfns should be vars not dfns: Lowercase.
34 |Also, no autolinks in anchors: Lowercase.
35 |Similarly, no autolinks for [Await].
36 |?u/p1-90`© 2014 Brian Terlson, Ecma International
19 |All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
22 | 23 |Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
24 | 25 |THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | 33 |?u/p1-90`?u/p1-90`Ecma International
17 |Rue du Rhone 114
18 |CH-1204 Geneva
19 |Tel: +41 22 849 6000
20 |Fax: +41 22 849 6001
21 |Web: https://ecma-international.org/
22 | 23 |© 2018 Rick Waldron, Mid-World
25 |All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
28 | 29 |Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
30 | 31 |THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 | 39 |?u/p1-90`Can refer to functions in prose, eg.
Don't autolink references inside square brackets, eg: [[Internal]]. 24 | Likewise, percent things: %%Internal%%. 25 | Likewise, mentions of Internal.foo.
26 |