From be401128ca3cd84eb1a9324fa1d27ca097ec2d2f Mon Sep 17 00:00:00 2001 From: JiayingL Date: Wed, 29 Mar 2023 15:47:38 +0800 Subject: [PATCH] Add Copyright exception config (#1720) * add json and test * add test * remove test * move copyright exceptions under lib/ and add missing exceptions * remove copyright exceptions as they are now being checked * update checks * fix copyright rule * fix tests --------- Co-authored-by: Denis Ah-Kang --- .cspell.json | 3 ++ README.md | 2 +- lib/copyright-exceptions.json | 31 ++++++++++++++++++ lib/exceptions.json | 15 --------- lib/l10n-en_GB.js | 2 ++ lib/rules.json | 2 +- lib/rules/headers/copyright.js | 45 +++++++++++++++++++++++--- test/doc-views/TR/Recommendation/WD.js | 4 ++- test/doc-views/layout/spec.handlebars | 3 ++ test/doc-views/specBase.js | 5 ++- 10 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 lib/copyright-exceptions.json diff --git a/.cspell.json b/.cspell.json index ddbbf1fbb..fda53233b 100644 --- a/.cspell.json +++ b/.cspell.json @@ -19,6 +19,8 @@ "doasync", "doctypes", "dvcs", + "epub", + "epubcfi", "ERCIM", "exphbs", "extractmetadataoptions", @@ -29,6 +31,7 @@ "hellip", "hilite", "historyuri", + "Hickson", "howto", "Imple", "implelink", diff --git a/README.md b/README.md index 9cdc42380..86d02ef51 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ $ W3C_API_KEY="" npm start 3001 Set the environment variable `DEBUG` to run in _debug mode_ instead: ```bash -$ DEBUG=true W3C_API_KEY="" npm start +$ DEBUG=true W3C_API_KEY="" npm run start ``` This modifies the behaviour of certain parts of the application to facilitate debugging. diff --git a/lib/copyright-exceptions.json b/lib/copyright-exceptions.json new file mode 100644 index 000000000..6930b2ea3 --- /dev/null +++ b/lib/copyright-exceptions.json @@ -0,0 +1,31 @@ +[ + { + "specShortnames": [ + "epub-overview-33", + "epub-33", + "epub-rs-33", + "epub-multi-rend-11", + "epub-tts-10", + "epub-ssv-11", + "epub-a11y-11", + "epub-a11y-tech-11", + "epub-aria-authoring-11", + "epub-fxl-a11y", + "epubcfi", + "epubcfi-11" + ], + "copyright": "Copyright © 1999-@YEAR International Digital Publishing Forum and World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply." + }, + { + "specShortnames": ["webrtc"], + "copyright": "Initial Author of this Specification was Ian Hickson, Google Inc., with the following copyright statement:
© Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document. All subsequent changes since 26 July 2011 done by the W3C WebRTC Working Group are under the following Copyright:
Copyright © 2011-@YEAR World Wide Web Consortium. W3C® liability, trademark and document use rules apply." + }, + { + "specShortnames": ["security-privacy-questionnaire"], + "copyright": "\"CC0\" To the extent possible under law, the editors have waived all copyright and related or neighboring rights to this work. This document is also made available under the W3C Software and Document License." + }, + { + "specShortnames": ["mediacapture-streams"], + "copyright": "Initial Author of this Specification was Ian Hickson, Google Inc., with the following copyright statement:
© Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document." + } +] diff --git a/lib/exceptions.json b/lib/exceptions.json index ede95b9f9..0c4ea4dd4 100644 --- a/lib/exceptions.json +++ b/lib/exceptions.json @@ -10,21 +10,6 @@ "message": "Bad value “publication” for attribute “rel” on element “link”: The string “publication” is not a registered keyword." } ], - "^webrtc$": [ - { - "rule": "headers.copyright" - } - ], - "^security-privacy-questionnaire$": [ - { - "rule": "headers.copyright" - } - ], - "^mediacapture-streams$": [ - { - "rule": "headers.copyright" - } - ], "^audiobooks$": [ { "rule": "sotd.candidate-review-end" diff --git a/lib/l10n-en_GB.js b/lib/l10n-en_GB.js index 4786fae89..409f19e2a 100644 --- a/lib/l10n-en_GB.js +++ b/lib/l10n-en_GB.js @@ -118,6 +118,8 @@ export const messages = { "This document is published by multiple groups, but these groups don't use the same document license. Please ask the team contact for help.", 'headers.copyright.no-license-found': 'Pubrules fails to find the document license in the group charter. Please ask the team contact for help.', + 'headers.copyright.exception-no-html': + 'The copyright used in this document
${copyright}
does not match the requirements. The expected copyright is
${expected}
', 'headers.memsub-copyright.not-found': 'Missing link to the W3C document notice (https://www.w3.org/Consortium/Legal/copyright-documents).', // headers/github-repo diff --git a/lib/rules.json b/lib/rules.json index 655046c9b..7398a8bf9 100644 --- a/lib/rules.json +++ b/lib/rules.json @@ -1587,7 +1587,7 @@ "editorSection": "The editors'/authors' names must be listed, with attribute data-editor-id=\"@@\". Affiliations and email addresses are optional; email addresses are not recommended. If an editor/author is acknowledged in an earlier version of this document and the individual's affiliation has since changed, list the individual using the notation \"<name>, <affiliation> (until DD Month YYYY)\". If the list of authors is very long (e.g., the entire Working Group), identify the authors in the acknowledgments section, linked from the head of the document. Distinguish any contributors from authors in the acknowledgments section.", "altRepresentations": "Authors may provide links to alternative (non-normative) representations or packages for the document. For instance:

<p>This document is also available in these non-normative formats: <a href=\"@{param1}-shortname-20180101.html\">single HTML file</a>, <a href=\"@{param1}-shortname-20180101.tgz\">gzipped tar file of HTML</a>.</p>

", "implReport": "It must include either:
  • a link to an interoperability or implementation report if the Director used such a report as part of the decision to advance the specification, or
  • a statement that the Director's decision did not involve such a report.
", - "copyright": "Starting from 01 February 2023, the copyright must follow the following markup (fill in with the appropriate year, years, or year range). The type of license the document is using can be found in the group's charter.
  1. For documents using W3C Document License:
    Copyright © @{year} World Wide Web Consortium. W3C® liability, trademark and document use rules apply.
    Include this source code:
    <p class="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © @{year} <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href=\"https://www.w3.org/Consortium/Legal/copyright-documents\">document use</a> rules apply.</p>
  2. For documents using W3C Software and Document License:
    Copyright © @{year} World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
    Include this source code:
    <p class="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © @{year} <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/Consortium/Legal/copyright-software">permissive document license</a> rules apply.</p>
", + "copyright": "Starting from 01 February 2023, the copyright must follow the following markup (fill in with the appropriate year, years, or year range). The type of license the document is using can be found in the group's charter.
  1. For documents using W3C Document License:
    Copyright © @{year} World Wide Web Consortium. W3C® liability, trademark and document use rules apply.
    Include this source code:
    <p class="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © @{year} <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href=\"https://www.w3.org/Consortium/Legal/copyright-documents\">document use</a> rules apply.</p>
  2. For documents using W3C Software and Document License:
    Copyright © @{year} World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
    Include this source code:
    <p class="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © @{year} <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/Consortium/Legal/copyright-software">permissive document license</a> rules apply.</p>

Note: Exceptions are listed in this json file.", "hrAfterCopyright": "A horizontal rule (hr) must follow the copyright." } }, diff --git a/lib/rules/headers/copyright.js b/lib/rules/headers/copyright.js index 91ef1e240..a705e8d63 100644 --- a/lib/rules/headers/copyright.js +++ b/lib/rules/headers/copyright.js @@ -7,7 +7,7 @@ * 4. For "copyright-software", the url is https://www.w3.org/Consortium/Legal/copyright-software, the dated url is https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document, they are both allowed. The name in the API is "W3C Software and Document License", but the document would use text "permissive document license". * 5. For "copyright-documents", the url is https://www.w3.org/Consortium/Legal/copyright-documents. The name in the API is "W3C Document License", but the document would use text "document use". */ -import { AB, TAG } from '../../util.js'; +import { AB, TAG, importJSON } from '../../util.js'; const self = { name: 'headers.copyright', @@ -43,6 +43,11 @@ const latestBaseLinks = { trademark: 'https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks', }; +const copyrightExceptions = importJSON( + '../../copyright-exceptions.json', + import.meta.url +); + export const { name } = self; async function isOnlyPublishedByTagOrAb(sr) { @@ -60,12 +65,17 @@ function getCommonLicenseUri(data) { .map(charter => charter['doc-licenses'].map(license => license.uri)) .reduce((first, cur) => first.filter(uri => cur.includes(uri))); } + // The date can be 19xx-2023, or 2023. function getLatestCopyrightMatchRegex(sr, licenseTexts) { const licenseRex = licenseTexts.join('|'); const year = (sr.getDocumentDate() || new Date()).getFullYear(); - const startRex = `^Copyright [©|©] (?:(?:199\\d|20\\d\\d)-)?${year} *World Wide Web Consortium`; + const startRex = + '^Copyright [©|©] (?:(?:199\\d|20\\d\\d)-)?@YEAR *World Wide Web Consortium'.replace( + '@YEAR', + year + ); const endRex = `\\. W3C[®|®] liability, trademark,? and (${licenseRex}) rules apply\\.$`; return new RegExp(startRex + endRex); } @@ -112,8 +122,26 @@ function checkCopyright(sr, copyright, licenseTexts, baseLinks, matchRegex) { }); } +// Some documents like epub-33 uses special copyrights listed in copyright-exception.json +function checkSpecialCopyright(sr, copyright, specialCopyright, shortname) { + const year = (sr.getDocumentDate() || new Date()).getFullYear(); + + const domHtml = sr.norm(copyright.innerHTML); + const specHtml = sr.norm( + specialCopyright.copyright.replace(/@YEAR/g, year) + ); + if (domHtml !== specHtml) { + sr.error(self, 'exception-no-html', { + copyright: domHtml, + expected: specHtml, + shortname, + }); + } +} + function checkLatestCopyright(sr, copyright, licenseTexts) { const matchRegex = getLatestCopyrightMatchRegex(sr, licenseTexts); + checkCopyright(sr, copyright, licenseTexts, latestBaseLinks, matchRegex); } @@ -128,7 +156,6 @@ export async function check(sr, done) { sr.error(self, 'not-found'); return done(); } - if (await isOnlyPublishedByTagOrAb(sr)) { return done(); } @@ -154,7 +181,17 @@ export async function check(sr, done) { .filter(v => [LICENSE_CD_URL, LICENSE_CS_URL].includes(v)) .map(v => LICENSE_URL_TEXT_MAP[v]); - checkLatestCopyright(sr, copyright, licenseTexts); + // get exception rule for certain shortnames + const shortname = await sr.getShortname(); + const specialCopyright = copyrightExceptions.find(({ specShortnames }) => + specShortnames.includes(shortname) + ); + + if (specialCopyright) { + checkSpecialCopyright(sr, copyright, specialCopyright, shortname); + } else { + checkLatestCopyright(sr, copyright, licenseTexts); + } return done(); } diff --git a/test/doc-views/TR/Recommendation/WD.js b/test/doc-views/TR/Recommendation/WD.js index 97937a09f..31bc2a4c7 100644 --- a/test/doc-views/TR/Recommendation/WD.js +++ b/test/doc-views/TR/Recommendation/WD.js @@ -18,9 +18,11 @@ const customData = { // Used in http://localhost:8001/doc-views/TR/Recommendation/WD?type=good const good = { ...data, ...customData }; +const commonData = buildCommonViewData(good); + export default { good, - ...buildCommonViewData(good), + ...commonData, 'draft-stability': buildDraftStability(good), 'security-privacy': buildSecurityPrivacy(good), }; diff --git a/test/doc-views/layout/spec.handlebars b/test/doc-views/layout/spec.handlebars index ba276290b..035d19d31 100644 --- a/test/doc-views/layout/spec.handlebars +++ b/test/doc-views/layout/spec.handlebars @@ -134,6 +134,9 @@ {{copyright.startText}} © {{nowYear}} World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.

{{/if}} + {{#if copyrightHtmlContent.show}} + {{{copyrightHtmlContent.html}}} + {{/if}} {{#if header.hr.show}}
diff --git a/test/doc-views/specBase.js b/test/doc-views/specBase.js index fb2adbfe1..5e45bc056 100644 --- a/test/doc-views/specBase.js +++ b/test/doc-views/specBase.js @@ -98,7 +98,10 @@ export const data = { startText: 'Copyright', W3CLink: 'https://www.w3.org/', licenseHTML: - 'W3C® liability, trademark and permissive document license rules apply.', + 'W3C® liability, trademark and permissive document license rules apply', + }, + copyrightHtmlContent: { + show: false, }, abstract: { abstractText: 'Abstract',