├── .github └── workflows │ └── auto-publish.this_should_be_yml ├── .pr-preview.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ECHIDNA ├── LICENSE.md ├── README.md ├── common ├── css │ └── common.css ├── html │ ├── ack-script │ │ ├── ack_pattern.html │ │ └── separate_acks.json │ ├── acknowledgements.html │ └── bidi-example-table.html └── js │ ├── biblio.js │ ├── idllink.js │ ├── orcid.js │ ├── parts.js │ └── wp.js ├── experiments ├── README.md ├── audiobook │ ├── flatland-canonical.json │ ├── flatland.json │ ├── index.html │ ├── player.js │ ├── polyfills │ │ ├── fetch.js │ │ └── urlsearchparams.js │ ├── toc-as-json.json │ └── toc.html ├── html-schema-org-json-ld │ └── index.html ├── manifest_script │ └── mobydick.html ├── separate_manifest │ ├── mobydick-simple.jsonld │ ├── mobydick.html │ └── mobydick.jsonld ├── toc_generator │ └── index.html └── w3c_rec │ ├── Readme.md │ ├── full_version.html │ ├── simple-canonical.jsonld │ └── simple_version.html ├── explainers ├── audio-explainer.md ├── audiopub-folder.png └── wpub-explainer.md ├── images ├── Makefile ├── WP-diagram.png ├── WP-diagram.svg ├── canonicalize_manifest.png ├── canonicalize_manifest.svg ├── clean_up_data.png ├── clean_up_data.svg ├── convert_manifest.png ├── convert_manifest.svg ├── find_manifest.png ├── find_manifest.svg ├── manifest_lifecycle.png ├── manifest_lifecycle.svg ├── orcid.gif └── originals.txt ├── index.html ├── schema ├── contributor-object.schema.json ├── contributor.schema.json ├── link.schema.json ├── localizable-map.schema.json ├── localizable.schema.json └── publication.schema.json └── w3c.json /.github/workflows/auto-publish.this_should_be_yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/pr-push.yml 2 | name: CI 3 | on: 4 | pull_request: {} 5 | push: 6 | branches: [main] 7 | jobs: 8 | main: 9 | name: Build, Validate and Deploy 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: w3c/spec-prod@v2 14 | with: 15 | W3C_ECHIDNA_TOKEN: ${{ secrets.W3C_TR_TOKEN }} 16 | W3C_WG_DECISION_URL: https://www.w3.org/publishing/groups/publ-wg/Meetings/Minutes/2017/2017-12-18-minutes#resolution2 17 | W3C_BUILD_OVERRIDE: | 18 | shortName: wpub 19 | specStatus: WG-NOTE 20 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Publishing Working Group 2 | 3 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 4 | [W3C Patent Policy](http://www.w3.org/Consortium/Patent-Policy-20040205/) and 5 | [Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). To make substantive contributions to specifications, you must either participate 6 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 7 | 8 | If you are not the sole contributor to a contribution (pull request), please identify all 9 | contributors in the pull request comment. 10 | 11 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 12 | 13 | ``` 14 | +@github_username 15 | ``` 16 | 17 | If you added a contributor by mistake, you can remove them in a comment with: 18 | 19 | ``` 20 | -@github_username 21 | ``` 22 | 23 | If you are making a pull request on behalf of someone else but you had no part in designing the 24 | feature, you can remove yourself with the above syntax. 25 | -------------------------------------------------------------------------------- /ECHIDNA: -------------------------------------------------------------------------------- 1 | # ECHIDNA configuration 2 | index.html 3 | common/css/common.css 4 | images/orcid.gif 5 | images/WP-diagram.svg 6 | images/WP-diagram.png 7 | images/canonicalize_manifest.png 8 | images/canonicalize_manifest.svg 9 | images/clean_up_data.png 10 | images/clean_up_data.svg 11 | images/convert_manifest.png 12 | images/convert_manifest.svg 13 | images/find_manifest.png 14 | images/find_manifest.svg 15 | images/manifest_lifecycle.png 16 | images/manifest_lifecycle.svg 17 | 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | All documents in this Repository are licensed by contributors under the [W3C Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![W3C Logo](https://www.w3.org/Icons/w3c_home) 3 | 4 | # Web Publications 5 | 6 | This is the repository of the W3C’s specification on Web Publications, developed by the [Publishing Working Group](https://www.w3.org/publishing/groups/publ-wg/). The editors’ draft of the specification can also be [read directly](https://w3c.github.io/wpub/). 7 | 8 | ## Experiments 9 | 10 | The Working Group is actively developing various proofs of concept of Web Publications and tools that demonstrate how they can be processed. A [list of these experiments](https://w3c.github.io/wpub/experiments/index.html) is maintained in the `experiments` directory. See the next section for more information on how to contribute. 11 | 12 | ## Contributing to the Repository 13 | 14 | Use the standard fork, branch, and pull request workflow to propose changes to the specification. Please make branch names informative—by including the issue or bug number for example. 15 | 16 | Editorial changes that improve the readability of the spec or correct spelling or grammatical mistakes are welcome. 17 | 18 | Please read [CONTRIBUTING.md](CONTRIBUTING.md), about licensing contributions. 19 | 20 | ## Code of Conduct 21 | 22 | W3C functions under a [code of conduct](https://www.w3.org/Consortium/cepc/). 23 | -------------------------------------------------------------------------------- /common/css/common.css: -------------------------------------------------------------------------------- 1 | 2 | section.part > h2 > span.secno { 3 | display: none; 4 | } 5 | 6 | a.suppress { 7 | display: inline-block !important; 8 | margin-left: -4rem !important; 9 | margin-bottom: 0.5rem !important; 10 | } 11 | 12 | a.suppress > span.secno { 13 | display: none; 14 | } 15 | 16 | ul.ack > li, 17 | ul.flat > li { 18 | display: inline; 19 | } 20 | 21 | ul.ack > li:after, 22 | ul.flat > li:after { 23 | content: ', ' 24 | } 25 | 26 | ul.ack > li:last-child:after, 27 | ul.flat > li:last-child:after { 28 | content: '' 29 | } 30 | 31 | ul.flat { 32 | display: inline; 33 | padding-left: 0; 34 | } 35 | 36 | dt, dd { 37 | padding-top: 0.5em; 38 | } 39 | 40 | dfn { 41 | font-weight: bold !important; 42 | } 43 | 44 | span.orcid a { 45 | border-bottom: none !important; 46 | } 47 | 48 | 49 | /* Table zebra style... */ 50 | table.zebra { 51 | font-size:inherit; 52 | font:90%; 53 | margin:1em; 54 | } 55 | 56 | table.zebra td { 57 | padding-left: 0.3em; 58 | } 59 | 60 | table.zebra th { 61 | font-weight: bold; 62 | text-align: center; 63 | background-color: rgb(0,0,128) !important; 64 | font-size: 110%; 65 | background: hsl(180, 30%, 50%); 66 | color: #fff; 67 | } 68 | 69 | table.zebra th a:link { 70 | color: #fff; 71 | } 72 | 73 | table.zebra th a:visited { 74 | color: #aaa; 75 | } 76 | 77 | table.zebra tr:nth-child(even) { 78 | background-color: hsl(180, 30%, 93%) 79 | } 80 | 81 | table.zebra th{border-bottom:1px solid #bbb;padding:.2em 1em;} 82 | table.zebra td{border-bottom:1px solid #ddd;padding:.2em 1em;} 83 | 84 | details { 85 | background-color: rgb(245,245,245); 86 | border-left: 0.3em solid rgb(200,200,200); 87 | padding: 0.3em; 88 | } 89 | 90 | summary { 91 | font-size: small; 92 | } 93 | -------------------------------------------------------------------------------- /common/html/ack-script/ack_pattern.html: -------------------------------------------------------------------------------- 1 |
2 |

Acknowledgements

3 |

The editors would like to thank the members of the Publishing Working Group for their contributions to this specification:

4 | 5 | 8 | 9 |

10 | The Working Group would also like to thank the members of 11 | the Digital Publishing Interest Group for all the hard work 12 | they did paving the road for this specification. 13 |

14 |
15 | -------------------------------------------------------------------------------- /common/html/ack-script/separate_acks.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name" : "Matt Garrish", 3 | "editor" : true 4 | },{ 5 | "name" : "Ivan Herman", 6 | "editor": true 7 | },{ 8 | "name" : "Wendy Reid", 9 | "chair" : true, 10 | "keep": true 11 | },{ 12 | "name" : "Tzviya Siegman", 13 | "chair" : true, 14 | "keep": true 15 | },{ 16 | "name" : "Garth Conboy", 17 | "chair" : true, 18 | "keep": true 19 | }] 20 | -------------------------------------------------------------------------------- /common/html/acknowledgements.html: -------------------------------------------------------------------------------- 1 |
2 |

Acknowledgements

3 |

The editors would like to thank the members of the Publishing Working Group for their contributions to this specification:

4 | 5 | 94 | 95 |

96 | The Working Group would also like to thank the members of 97 | the Digital Publishing Interest Group for all the hard work 98 | they did paving the road for this specification. 99 |

100 |
101 | -------------------------------------------------------------------------------- /common/html/bidi-example-table.html: -------------------------------------------------------------------------------- 1 |
2 |

Examples for bidirectional texts

3 | 4 |

This section illustrates how Unicode formatting characters can be applied to bidirectional strings, where necessary, in order to help a consumer produce the expected display. In cases where the first-strong heuristics would produce the wrong result, if the string is created with a prepended formatting character, the first-strong heuristics will produce the correct base direction for the string as a whole.

5 | 6 |

A right-to-left string that begins with a Latin script character should have U+200F RIGHT-TO-LEFT MARK prepended.

7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Character order in memory: HTML היא שפת סימון.
Gives incorrect display: HTML היא שפת סימון.
Source code with formatting character: "\u200FHTML היא שפת סימון."
Gives expected display: HTML היא שפת סימון.
26 | 27 |

A left-to-right string that begins with a Arabic script character should have U+200E LEFT-TO-RIGHT MARK prepended.

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
Character order in memory: 'سلام' is hello in Persian.
Gives incorrect display: 'سلام' is hello in Persian.
Source code with formatting character: "\u200E'سلام' is hello in Persian."
Gives expected display: 'سلام' is hello in Persian.
47 |
48 | -------------------------------------------------------------------------------- /common/js/biblio.js: -------------------------------------------------------------------------------- 1 | /* 2 | * WARNING: Use this file sparingly! 3 | * 4 | * Check http://www.specref.org/ first 5 | * 6 | */ 7 | 8 | /* general entry template 9 | "short_name": { 10 | "title": "...", 11 | "href": "https://...", 12 | "authors": [ 13 | "..." 14 | ], 15 | "date": "..." 16 | } 17 | */ 18 | 19 | var localBiblio = { 20 | "link-relation": { 21 | "title": "Identifier: A Link Relation to Convey a Preferred URI for Referencing", 22 | "authors": [ 23 | "H. Van de Sompel", 24 | "M. Nelson", 25 | "G. Bilder", 26 | "J. Kunze", 27 | "S. Warner" 28 | ], 29 | "rawDate": "2017-08", 30 | "publisher": "IETF", 31 | "href": "https://tools.ietf.org/html/draft-vandesompel-identifier-00" 32 | }, 33 | "cfi": { 34 | "authors" : [ 35 | "Peter Sorotokin", 36 | "Garth Conboy", 37 | "Brady Duga", 38 | "John Rivlin", 39 | "Don Beaver", 40 | "Kevin Ballard", 41 | "Alastair Fettes", 42 | "Daniel Weck" 43 | ], 44 | title: "EPUB Canonical Fragment Identifiers 1.1", 45 | href: "http://www.idpf.org/epub/linking/cfi/epub-cfi.html", 46 | publisher: "IDPF", 47 | rawDate: "2017-01-05", 48 | status: "Recommended Specification" 49 | }, 50 | "css": { 51 | "title": "CSS Snapshot", 52 | "authors" : [ 53 | "Tab Atkins Jr.", 54 | "Elika J. Etemad", 55 | "Florian Rivoal" 56 | ], 57 | "status": "W3C Working Group Note", 58 | "href": "https://www.w3.org/TR/CSS/", 59 | "publisher": "W3C" 60 | }, 61 | "doi": { 62 | "title": "Information and documentation — Digital object identifier system", 63 | "date": "2012-05", 64 | "status": "Published", 65 | "href": "https://www.iso.org/standard/43506.html" 66 | }, 67 | "iana-link-relations": { 68 | "title": "Link Relations", 69 | "href": "https://www.iana.org/assignments/link-relations/link-relations.xhtml" 70 | }, 71 | "wpub-ann": { 72 | "title": "Web Annotation Extensions for Web Publications", 73 | "href": "https://www.w3.org/TR/wpub-ann/", 74 | "authors": [ 75 | "Timothy W. Cole", 76 | "Ivan Herman" 77 | ], 78 | "date": "2018-01-04" 79 | }, 80 | "pwpub": { 81 | "title": "Packaged Web Publications", 82 | "href": "https://www.w3.org/TR/pwpub/", 83 | "authors": [ 84 | "David Wood" 85 | ], 86 | "date": "2018-01-04" 87 | }, 88 | "wpub": { 89 | "title": "Web Publications", 90 | "href": "https://www.w3.org/TR/wpub/", 91 | "authors": [ 92 | "Matt Garrish", 93 | "Ivan Herman" 94 | ], 95 | "date": "2018-01-04" 96 | }, 97 | "string-meta": { 98 | "title": "Requirements for Language and Direction Metadata in Data Formats", 99 | "href": "https://w3c.github.io/string-meta/", 100 | "authors" : [ 101 | "Addison Phillips", 102 | "Richard Ishida" 103 | ], 104 | "date": "2017-12-01" 105 | }, 106 | "schema.org": { 107 | "title": "Schema.org", 108 | "href": "https://schema.org" 109 | }, 110 | "onix": { 111 | "title": "ONIX for Books", 112 | "href": "http://www.editeur.org/83/Overview" 113 | }, 114 | "bibtex": { 115 | "title": "BibTeX Format Description", 116 | "href" : "http://www.bibtex.org/Format/" 117 | }, 118 | "webschemas-a11y": { 119 | "title": "WebSchemas Accessibility", 120 | "href": "http://www.w3.org/wiki/WebSchemas/Accessibility" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /common/js/idllink.js: -------------------------------------------------------------------------------- 1 | 2 | function convert_dfn_to_link() { 3 | 4 | var defs = document.querySelectorAll("*[data-dfn-for='PublicationManifest']"); 5 | 6 | if (defs) { 7 | defs.forEach( function(elem) { 8 | var dfns = elem.querySelectorAll('dfn'); 9 | 10 | if (dfns) { 11 | dfns.forEach( function(dfn) { 12 | var link = document.createElement('a'); 13 | link.setAttribute('href', '#idl-def-publicationmanifest-' + dfn.textContent.toLowerCase()); 14 | link.appendChild(dfn.cloneNode(true)); 15 | 16 | dfn.parentNode.replaceChild(link,dfn); 17 | }); 18 | } 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/js/orcid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Add an orcid image linked to the authors' and editors' ORCID ID-s (when applicable) 3 | * 4 | * The trigger is an additional "orcid" key in the person's object in the respec config. The "w3cid" key is also necessary (to be used anyway...) 5 | */ 6 | function show_orcid(config) { 7 | let orcidmaps = { 8 | }; 9 | 10 | //-------------------------------------------------------------------------------- 11 | // 1st step: find the authors/editors who have set their ORCID number as part of the persons' structure 12 | // This can be extracted from the configuration set by the user (and extended by respec) 13 | let personKeys = ["editors", "authors"]; 14 | personKeys.forEach( key => { 15 | if( config[key] ) { 16 | config[key].forEach( (editor) => { 17 | if(editor.orcid && editor.w3cid) { 18 | orcidmaps[editor.w3cid] = editor.orcid 19 | } 20 | }); 21 | } 22 | }); 23 | 24 | //--------------------------------------------------------------------------------- 25 | // 2nd step: find the persons in the header, see if their id is listed in orcidmap and, if yes 26 | // add the additional image reference. 27 | // 28 | // 29 | // Persons are in a dd element with the class set to p-author (and some others) 30 | document.querySelectorAll("dd.p-author").forEach( (element) => { 31 | // Look at the data-editor-id value to see if it is relevant. 32 | if( element.dataset.editorId ) { 33 | // Get the possible ordicId from the orcid mapping 34 | orcidId = orcidmaps[element.dataset.editorId] 35 | if(orcidId) { 36 | // Bingo; add a span with the image linked to the orcid web site 37 | let span = document.createElement('span'); 38 | let a = document.createElement('a'); 39 | let img = document.createElement('img'); 40 | 41 | img.setAttribute('src','images/orcid.gif'); 42 | img.setAttribute('alt','orcid logo'); 43 | 44 | a.setAttribute('href', `https://orcid.org/${orcidId}`); 45 | a.appendChild(img); 46 | 47 | span.setAttribute('class', 'orcid'); 48 | span.appendChild(a); 49 | 50 | element.innerHTML += " "; 51 | element.appendChild(span); 52 | } 53 | } 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /common/js/parts.js: -------------------------------------------------------------------------------- 1 | 2 | function denumber_parts() { 3 | 4 | var toc_entries = document.querySelectorAll('nav#toc > ol.toc > li.tocline'); 5 | 6 | for (var i = 0; i < toc_entries.length; i++) { 7 | toc_label = toc_entries[i].querySelector('a.tocxref'); 8 | 9 | if (toc_label.textContent.match(/part i+:/i)) { 10 | toc_label.classList.add('suppress'); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/js/wp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Create a Web Publication manifest for the publication. 3 | * 4 | * @param config: the respec configuration object 5 | */ 6 | function create_wp(config) { 7 | // It is currently unclear whether the WP manifest should include all possible resources (like in EPUB) 8 | // if it wants the publication to be properly cached/packaged, or not. At this moment, 9 | // it seems to be not true. 10 | // This flag controls on what should happen if the full boundary is supposed to be included in the manifest... 11 | const FULL_BOUNDARY = false; 12 | 13 | // ----------------------------------------------------------------------------------- // 14 | // Rudimentary check whether the URL is relative or not. Surely not ideal, but I did not want to include a full URI library... 15 | // (Why, oh why is not URL management part of the default JS environment?) 16 | const is_relative = (url) => { 17 | //alert(url); 18 | return (url[0] === '#' || url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:")) ? false : true; 19 | }; 20 | 21 | const image_type = (img) => { 22 | if( img.endsWith(".gif") ) { 23 | return "image/gif"; 24 | } else if( img.endsWith(".png") ) { 25 | return "image/png"; 26 | } else if( img.endsWith(".bmp") ) { 27 | return "image/bmp"; 28 | } else if( img.endsWith(".jpg") || img.endsWith(".jpeg") ) { 29 | return "image/jpeg"; 30 | } else if( img.endsWith(".svg") ) { 31 | return "image/svg+xml"; 32 | } else if( img.endsWith(".pdf") ) { 33 | return "application/pdf"; 34 | } else { 35 | return null; 36 | } 37 | }; 38 | 39 | const uniq = (arr) => { 40 | let buffer = []; 41 | return arr.filter( (entry) => { 42 | let key = entry.url; 43 | if( buffer.indexOf(key) !== -1 ) { 44 | // that url has already been seen 45 | return false; 46 | } else { 47 | buffer.push(key); 48 | return true; 49 | } 50 | }) 51 | }; 52 | 53 | // There are minor differences between the terms used in the respec config file and the ones in schema.org... 54 | let person_keys_mapping = { 55 | "editors" : "editor", 56 | "authors" : "author", 57 | "creators" : "creator" 58 | }; 59 | 60 | // The id attribute value for the 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /experiments/audiobook/player.js: -------------------------------------------------------------------------------- 1 | /* Simple prototype for an Audiobook Player based on