spec-up-t 1.3.0-beta → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/compiled/body.js +1 -1
- package/assets/compiled/head.css +1 -0
- package/assets/css/counter.css +104 -0
- package/assets/js/collapse-definitions.js +0 -3
- package/assets/js/custom-elements.js +25 -27
- package/assets/js/highlight-heading-plus-sibling-nodes.test.js +120 -0
- package/config/asset-map.json +1 -0
- package/package.json +3 -2
- package/sonar-project.properties +7 -6
- package/src/create-docx.js +1 -1
- package/src/html-dom-processor.js +15 -15
- package/src/install-from-boilerplate/boilerplate/.github/workflows/menu.yml +52 -28
- package/test-default-definitions.js +0 -55
- package/test-edge-cases.md +0 -20
- package/test-fix-markdown.js +0 -11
- package/test-no-def.md +0 -22
package/assets/compiled/body.js
CHANGED
|
@@ -109,7 +109,7 @@ function showModal(e){const n=document.createElement("div");n.className="spec-up
|
|
|
109
109
|
function tokenInput(){document.querySelector(".button-token-input").addEventListener("click",(()=>{const t=prompt("Please enter your GitHub token:");t?(localStorage.setItem("githubToken",t),console.log("GitHub token is set.")):alert("GitHub token is not set.")}))}document.addEventListener("DOMContentLoaded",(function(){tokenInput()}));
|
|
110
110
|
function pdfDownload(){fetch("./index.pdf",{method:"HEAD"}).then((e=>{if(e.ok){let e=document.createElement("a");e.classList.add("button-pdf-download"),e.classList.add("btn","d-block","btn-sm","btn-outline-secondary"),e.target="_blank",e.rel="noopener noreferrer",e.href="./index.pdf",e.title="Download this page as a PDF",e.innerHTML='\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" class="me-1" viewBox="0 0 16 16">\n <path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0H4zm0 1h5v4h4v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm7 4h-1V2l3 3h-2z"/>\n <path d="M6.5 10.5a.5.5 0 0 1-.5-.5V7.5a.5.5 0 0 1 .5-.5H8a.5.5 0 0 1 .5.5V10a.5.5 0 0 1-.5.5H6.5z"/>\n </svg>\n ',e.style.display="inline-flex",e.style.alignItems="center",e.style.justifyContent="center",document.querySelector(".service-menu").prepend(e)}else console.log("PDF file does not exist. No PDF download button will be added.")})).catch((e=>{console.error("Error checking PDF file:",e)}))}document.addEventListener("DOMContentLoaded",(function(){pdfDownload()}));
|
|
111
111
|
function insertTrefs(e){!function(e){const n=[];document.querySelectorAll("dl.terms-and-definitions-list dt span.transcluded-xref-term").forEach((e=>{const t=e.textContent.trim(),r=e.closest("dt");if(r){const e=r.nextElementSibling;if(e?.classList.contains("transcluded-xref-term")&&e.classList.contains("meta-info-content-wrapper"))return}n.push({element:e,textContent:t,dt:r,parent:r?.parentNode})}));const t=n.map((n=>{const{textContent:t,dt:r,parent:d}=n;if(!r||!d)return null;const o=e.xtrefs.find((e=>e.term===t)),s=document.createDocumentFragment(),i=document.createElement("dd");if(i.classList.add("transcluded-xref-term","meta-info-content-wrapper","collapsed"),o){const e=`\n| Property | Value |\n| -------- | ----- |\n| Owner | ${o.avatarUrl?``:""} ${o.owner||"Unknown"} |\n| Repo | ${o.repo&&o.repoUrl?`[${o.repo}](${o.repoUrl})`:"Unknown"} |\n| Commit hash | ${o.commitHash||"Unknown"} |\n `;i.innerHTML=md.render(e),s.appendChild(i);let n=o.content.split("\n").map((e=>e.replace(/^\s*~\s*/,""))).join("\n").replace(/\]\]/g,"");const t=document.createElement("div");t.innerHTML=md.render(n),t.querySelectorAll("a").forEach((e=>e.replaceWith(...e.childNodes))),n=t.innerHTML;const r=document.createElement("div");r.innerHTML=md.render(n);const d=r.querySelectorAll("dd");if(d.length>0)Array.from(d).forEach((e=>{const n=e.cloneNode(!0);n.classList.add("transcluded-xref-term","transcluded-xref-term-embedded"),s.appendChild(n)}));else{const e=document.createElement("dd");e.classList.add("transcluded-xref-term","transcluded-xref-term-embedded"),e.innerHTML=r.innerHTML,s.appendChild(e)}}else{i.innerHTML=md.render("\n| Property | Value |\n| -------- | ----- |\n| Owner | Unknown |\n| Repo | Unknown |\n| Commit hash | not found |\n "),s.appendChild(i);const e=document.createElement("dd");e.innerHTML="<p>This term was not found in the external repository.</p>",s.appendChild(e)}return{dt:r,parent:d,fragment:s}})).filter(Boolean);requestAnimationFrame((()=>{t.forEach((e=>{const{dt:n,parent:t,fragment:r}=e;t.insertBefore(r,n.nextSibling)})),document.dispatchEvent(new CustomEvent("trefs-inserted",{detail:{count:t.length}}))}))}(e)}function initializeOnTrefsInserted(e){let n=!1;document.addEventListener("trefs-inserted",(function(t){n||(n=!0,e(),t.detail&&console.log(`Collapsible definitions initialized after ${t.detail.count} xrefs were inserted`))})),setTimeout((()=>{n||(console.warn("trefs-inserted event was not received, initializing collapsible definitions anyway"),e(),n=!0)}),1e3)}document.addEventListener("DOMContentLoaded",(()=>{"undefined"!=typeof allXTrefs&&allXTrefs?.xtrefs?insertTrefs(allXTrefs):(console.error("allXTrefs is undefined or missing xtrefs property"),document.dispatchEvent(new CustomEvent("trefs-inserted",{detail:{count:0,error:"Missing xtrefs data"}})))}));
|
|
112
|
-
function collapseDefinitions(){let{dds:t,dts:e,regularDds:s,specialDds:a}=function(){const t=document.querySelectorAll("#content dl.terms-and-definitions-list > dd");return{dds:t,dts:document.querySelectorAll("#content dl.terms-and-definitions-list > dt"),regularDds:Array.from(t).filter((t=>!i(t.textContent.trim()))),specialDds:Array.from(t).filter((t=>i(t.textContent.trim())))}}();function i(t){return["Source","See also","More in","Also see","See:","See also","See more","See more in","See more about","See more on","See more at","More:","Supporting definitions:"].some((e=>t.startsWith(e)))}a.forEach((t=>{t.classList.add("terms-def-extra-info")})),e.forEach((t=>{if(t.querySelector(".collapse-all-defs-button"))return;const e=document.createElement("button");e.classList.add("collapse-all-defs-button","btn-outline-secondary","d-print-none","btn","p-0","fs-5","d-flex","align-items-center","justify-content-center"),e.innerHTML='<span class="state-indicator" data-state="0">①</span><span class="state-indicator" data-state="1">②</span><span class="state-indicator" data-state="2">③</span>',e.setAttribute("id","toggleButton"),e.setAttribute("title","Change how much info is shown"),e.setAttribute("data-state","2"),e.querySelector('.state-indicator[data-state="2"]').classList.add("active"),t.appendChild(e)})),document.addEventListener("click",(e=>{if(e.target.classList.contains("collapse-all-defs-button")||e.target.classList.contains("state-indicator")){const i=e.target.classList.contains("collapse-all-defs-button")?e.target:e.target.closest(".collapse-all-defs-button"),n=
|
|
112
|
+
function collapseDefinitions(){let{dds:t,dts:e,regularDds:s,specialDds:a}=function(){const t=document.querySelectorAll("#content dl.terms-and-definitions-list > dd");return{dds:t,dts:document.querySelectorAll("#content dl.terms-and-definitions-list > dt"),regularDds:Array.from(t).filter((t=>!i(t.textContent.trim()))),specialDds:Array.from(t).filter((t=>i(t.textContent.trim())))}}();function i(t){return["Source","See also","More in","Also see","See:","See also","See more","See more in","See more about","See more on","See more at","More:","Supporting definitions:"].some((e=>t.startsWith(e)))}a.forEach((t=>{t.classList.add("terms-def-extra-info")})),e.forEach((t=>{if(t.querySelector(".collapse-all-defs-button"))return;const e=document.createElement("button");e.classList.add("collapse-all-defs-button","btn-outline-secondary","d-print-none","btn","p-0","fs-5","d-flex","align-items-center","justify-content-center"),e.innerHTML='<span class="state-indicator" data-state="0">①</span><span class="state-indicator" data-state="1">②</span><span class="state-indicator" data-state="2">③</span>',e.setAttribute("id","toggleButton"),e.setAttribute("title","Change how much info is shown"),e.setAttribute("data-state","2"),e.querySelector('.state-indicator[data-state="2"]').classList.add("active"),t.appendChild(e)})),document.addEventListener("click",(e=>{if(e.target.classList.contains("collapse-all-defs-button")||e.target.classList.contains("state-indicator")){const i=e.target.classList.contains("collapse-all-defs-button")?e.target:e.target.closest(".collapse-all-defs-button"),n=i.getBoundingClientRect();document.documentElement.classList.add("definitions-transitioning"),i.style.position="fixed",i.style.top=`${n.top}px`,i.style.right=window.innerWidth-n.right+"px",i.style.zIndex="1000",function(){const e=document.querySelectorAll(".collapse-all-defs-button");switch((parseInt(e[0].dataset.state||0)+1)%3){case 0:t.forEach((t=>{t.classList.add("hidden"),t.classList.remove("visible")})),e.forEach((t=>{t.dataset.state=0,t.title="Show basic definitions",t.querySelectorAll(".state-indicator").forEach((t=>{0===parseInt(t.dataset.state)?t.classList.add("active"):t.classList.remove("active")}))})),document.querySelector("html").classList.add("defs-hidden");break;case 1:s.forEach((t=>{t.classList.remove("hidden"),t.classList.add("visible")})),a.forEach((t=>{t.classList.add("hidden"),t.classList.remove("visible")})),e.forEach((t=>{t.dataset.state=1,t.title="Show all definitions",t.querySelectorAll(".state-indicator").forEach((t=>{1===parseInt(t.dataset.state)?t.classList.add("active"):t.classList.remove("active")}))})),document.querySelector("html").classList.remove("defs-hidden");break;case 2:t.forEach((t=>{t.classList.remove("hidden"),t.classList.add("visible")})),a.forEach((t=>{t.classList.add("terms-def-extra-info")})),e.forEach((t=>{t.dataset.state=2,t.title="Hide all definitions",t.querySelectorAll(".state-indicator").forEach((t=>{2===parseInt(t.dataset.state)?t.classList.add("active"):t.classList.remove("active")}))})),document.querySelector("html").classList.remove("defs-hidden")}}(),requestAnimationFrame((()=>{i.style.position="",i.style.top="",i.style.right="",i.style.zIndex="",document.documentElement.classList.remove("definitions-transitioning");const t=i.getBoundingClientRect();window.scrollTo({top:window.scrollY+(t.top-n.top),behavior:"instant"})}))}}))}document.addEventListener("DOMContentLoaded",(function(){initializeOnTrefsInserted(collapseDefinitions)}));
|
|
113
113
|
function createTermFilter(){const e=document.querySelector(".terms-and-definitions-list");if(0===(e?e.querySelectorAll("dt"):[]).length)return;const c=document.getElementById("terminology-section-utility-container"),t=document.createElement("div");t.className="d-flex mt-0";const n=document.createElement("div");n.className="form-check me-3",n.innerHTML='\n <input class="form-check-input" type="checkbox" id="showLocalTermsCheckbox" checked>\n <label class="form-check-label" for="showLocalTermsCheckbox">\n Show local terms\n </label>\n ';const o=document.createElement("div");o.className="form-check ms-3",o.innerHTML='\n <input class="form-check-input" type="checkbox" id="showExternalTermsCheckbox" checked>\n <label class="form-check-label" for="showExternalTermsCheckbox">\n Show external terms\n </label>\n ',t.appendChild(n),t.appendChild(o),t.addEventListener("change",(function(e){e.target.matches('input[type="checkbox"]')&&function(e){const c=t.querySelectorAll('input[type="checkbox"]'),n=Array.from(c).filter((e=>e.checked));e.target.checked||0===n.length&&c.forEach((c=>{c!==e.target&&(c.checked=!0)})),c.forEach((e=>{const c=document.querySelector("html");"showLocalTermsCheckbox"===e.id?c.classList.toggle("hide-local-terms",!e.checked):"showExternalTermsCheckbox"===e.id&&c.classList.toggle("hide-external-terms",!e.checked)}))}(e)})),c.appendChild(t)}document.addEventListener("DOMContentLoaded",(function(){createTermFilter()}));
|
|
114
114
|
function createToggleButton(e){const t=document.createElement("button");t.classList.add("meta-info-toggle-button","btn"),t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;"><path fill-rule="evenodd" d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588z"/><path d="M9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/></svg>',t.title="Meta info",t.addEventListener("click",(function(t){t.preventDefault(),t.stopPropagation();e.classList.contains("collapsed")?(e.classList.remove("collapsed"),e.getBoundingClientRect()):e.classList.add("collapsed")}));let n=e.previousElementSibling;for(;n&&"DT"!==n.tagName;)n=n.previousElementSibling;n?n.appendChild(t):e.insertBefore(t,e.firstChild)}function collapseMetaInfo(){document.querySelectorAll("dl > dd:has(table)").forEach((function(e){e.classList.add("meta-info-content-wrapper");const t=document.createElement("div");for(t.classList.add("meta-info-inner-wrapper");e.firstChild&&e.firstChild!==e.querySelector(".meta-info-toggle-button");)t.appendChild(e.firstChild);e.querySelector(".meta-info-toggle-button")||createToggleButton(e),e.appendChild(t),e.classList.add("collapsed")}))}document.addEventListener("DOMContentLoaded",(function(){initializeOnTrefsInserted(collapseMetaInfo)}));
|
|
115
115
|
function fixLastDd(){document.querySelectorAll("dl.terms-and-definitions-list").forEach((t=>{t.querySelectorAll(":scope > dd").forEach(((t,e)=>{t.classList.remove("last-dd");let s=t.nextElementSibling;s&&"DT"!==s.tagName||t.classList.contains("last-dd")||t.classList.add("last-dd")}))}))}document.addEventListener("trefs-inserted",(function(){fixLastDd()}));
|
package/assets/compiled/head.css
CHANGED
|
@@ -28,4 +28,5 @@ article a[href^="https://"]:not(.btn)::after,article a[href^=http]:not(.btn)::af
|
|
|
28
28
|
#content .figure{width:100%;margin-bottom:1.5rem}#content .figure img{transition:all .3s ease}#content .figure img:hover{transform:scale(1.01);cursor:pointer}#content img.img-fluid{max-width:100%;height:auto}#content .figure-caption{margin-top:.5rem;font-style:italic;color:#6c757d}
|
|
29
29
|
#content .figure:has(.scrollHintImage){padding:0;margin:0;width:auto;height:auto}
|
|
30
30
|
.highlight2{padding-left:1em;padding-right:1em;border:1px dashed #71bbe6;background:#a9dde03b}
|
|
31
|
+
#toc ul.toc{counter-reset:toc-section}#toc ul.toc>li{counter-reset:toc-subsection}#toc ul.toc>li>ul>li{counter-reset:toc-subsubsection}#toc ul.toc>li>a::before{counter-increment:toc-section;content:counter(toc-section) ". ";font-weight:700;margin-right:.5em}#toc ul.toc>li>ul>li>a::before{counter-increment:toc-subsection;content:counter(toc-section) "." counter(toc-subsection) " ";font-weight:700;margin-right:.5em}#toc ul.toc>li>ul>li>ul>li>a::before{counter-increment:toc-subsubsection;content:counter(toc-section) "." counter(toc-subsection) "." counter(toc-subsubsection) " ";font-weight:700;margin-right:.5em}main article{counter-reset:main-section}main article h2{counter-reset:main-subsection}main article h3{counter-reset:main-subsubsection}main article h2::before{counter-increment:main-section;content:counter(main-section) ". ";font-weight:700;margin-right:.5em;color:#007bff}main article h3::before{counter-increment:main-subsection;content:counter(main-section) "." counter(main-subsection) " ";font-weight:700;margin-right:.5em;color:#007bff}main article h4::before{counter-increment:main-subsubsection;content:counter(main-section) "." counter(main-subsection) "." counter(main-subsubsection) " ";font-weight:700;margin-right:.5em;color:#007bff}main article h5::before,main article h6::before{font-weight:700;margin-right:.5em;color:#6c757d}.toc-anchor{margin-left:.5em}@media print{#toc ul.toc>li>a::before,#toc ul.toc>li>ul>li>a::before,#toc ul.toc>li>ul>li>ul>li>a::before,main article h2::before,main article h3::before,main article h4::before{color:#000!important}}
|
|
31
32
|
:target{scroll-margin-top:calc(50vh)}body:not([hashscroll]) :target{animation:highlight-target 3.5s .25s ease}body:not([hashscroll]) dt:has(:target){animation:highlight-target-parent-dt 3.5s .25s ease}dl.terms-and-definitions-list>.highlight{background-color:#ff0!important;transition:background-color .3s ease-in-out}svg[icon]{width:1.25em;height:1.25em;vertical-align:text-top}@keyframes highlight-target{50%{background-color:#ff0}}@keyframes highlight-target-parent-dt{50%{background-color:#ff0;border:1px solid #00c8ff}}#svg{display:none}main *{overflow-wrap:anywhere;word-break:normal}.table-responsive{overflow-x:auto!important;-webkit-overflow-scrolling:touch;width:100%;max-width:100%}.table-responsive *{overflow-wrap:normal!important;word-break:normal!important;white-space:nowrap!important}dd td img{max-width:30px}.notice{margin:1em 0;padding:.5em .9em .55em .65em;border-left:.5em solid}.notice p{margin:.4em 0 0}.note{background:#e9fbe9;border-color:#52e052}.note .notice-link{display:block;color:#178217}.issue{background:#e9f0fb;border-color:#527fe0}.issue .notice-link:before{display:block;color:#1e4cae}.warning{background:#fbe9e9;border-color:#e05252}.warning .notice-link{display:block;color:#ae1e1e}.example{color:#cebe00;background:#1a1e23;border-left:.5em solid}.example .notice-link{display:block;color:inherit;font-size:1.1em;font-family:Heebo,sans-serif}.example pre[class*=language-]{padding:0;border-radius:0}.todo{background:#fbe4ff;border-color:#9700e2}.todo .notice-link{display:block;color:#6d00a2}.alert-primary{background-color:#f9fcff;border-color:#b2ebf2;color:#00838f}.alert-secondary{background-color:#f5f5f5;border-color:#e0e0e0;color:#616161}.alert-success{background-color:#e8f5e9;border-color:#c8e6c9;color:#388e3c}.alert-danger{background-color:#ffebee;border-color:#ef9a9a;color:#d32f2f}.alert-warning{background-color:#fffde7;border-color:#fff9c4;color:#f9a825}.alert-info{background-color:#e1f5fe;border-color:#b3e5fc;color:#0288d1}.alert-light{background-color:#f9f9f9;border-color:#eee;color:#424242}.alert-dark{background-color:#e0e0e0;border-color:#bdbdbd;color:#212121}.alert a{color:inherit;font-weight:700}.alert-primary a{color:#006064}.alert-success a{color:#2e7d32}.alert-danger a{color:#b71c1c}.alert-warning a{color:#f57f17}.alert-info a{color:#01579b}.alert-dark a{color:#000}[data-bs-theme=dark] .alert-primary{background-color:#004d40;border-color:#00695c;color:#b2dfdb}[data-bs-theme=dark] .alert-secondary{background-color:#424242;border-color:#616161;color:#e0e0e0}[data-bs-theme=dark] .alert-success{background-color:#1b5e20;border-color:#2e7d32;color:#a5d6a7}[data-bs-theme=dark] .alert-danger{background-color:#b71c1c;border-color:#c62828;color:#ef9a9a}[data-bs-theme=dark] .alert-warning{background-color:#f57f17;border-color:#ffb300;color:#ffe082}[data-bs-theme=dark] .alert-info{background-color:#01579b;border-color:#0277bd;color:#81d4fa}[data-bs-theme=dark] .alert-light{background-color:#303030;border-color:#424242;color:#e0e0e0}[data-bs-theme=dark] .alert-dark{background-color:#212121;border-color:#424242;color:#bdbdbd}[data-bs-theme=dark] .alert a{color:inherit;font-weight:700}[data-bs-theme=dark] .alert-primary a{color:#80cbc4}[data-bs-theme=dark] .alert-success a{color:#81c784}[data-bs-theme=dark] .alert-danger a{color:#ef5350}[data-bs-theme=dark] .alert-warning a{color:#ffca28}[data-bs-theme=dark] .alert-info a{color:#4fc3f7}[data-bs-theme=dark] .alert-dark a{color:#9e9e9e}#offcanvasSettings .btn-menu-item{border-radius:unset;width:100%;text-align:left;border:1px solid #dee2e6;background-color:var(--card-bg);color:var(--card-text);padding:10px 15px;margin-bottom:5px;transition:background-color .2s ease}#offcanvasSettings .btn-menu-item:hover{background-color:#e9ecef}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CSS Counters for Navigation Menu Items and Content Headings
|
|
3
|
+
* Description: Adds incremental numbering to TOC menu items and corresponding content headings
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Reset and initialize counters for the table of contents */
|
|
7
|
+
#toc ul.toc {
|
|
8
|
+
counter-reset: toc-section;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#toc ul.toc > li {
|
|
12
|
+
counter-reset: toc-subsection;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#toc ul.toc > li > ul > li {
|
|
16
|
+
counter-reset: toc-subsubsection;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Add numbering to first-level TOC items (h2 equivalent) */
|
|
20
|
+
#toc ul.toc > li > a::before {
|
|
21
|
+
counter-increment: toc-section;
|
|
22
|
+
content: counter(toc-section) ". ";
|
|
23
|
+
font-weight: bold;
|
|
24
|
+
margin-right: 0.5em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Add numbering to second-level TOC items (h3 equivalent) */
|
|
28
|
+
#toc ul.toc > li > ul > li > a::before {
|
|
29
|
+
counter-increment: toc-subsection;
|
|
30
|
+
content: counter(toc-section) "." counter(toc-subsection) " ";
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
margin-right: 0.5em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Add numbering to third-level TOC items (h4 equivalent) */
|
|
36
|
+
#toc ul.toc > li > ul > li > ul > li > a::before {
|
|
37
|
+
counter-increment: toc-subsubsection;
|
|
38
|
+
content: counter(toc-section) "." counter(toc-subsection) "." counter(toc-subsubsection) " ";
|
|
39
|
+
font-weight: bold;
|
|
40
|
+
margin-right: 0.5em;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Initialize counters for main content headings */
|
|
44
|
+
main article {
|
|
45
|
+
counter-reset: main-section;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
main article h2 {
|
|
49
|
+
counter-reset: main-subsection;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
main article h3 {
|
|
53
|
+
counter-reset: main-subsubsection;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Add numbering to main content headings */
|
|
57
|
+
main article h2::before {
|
|
58
|
+
counter-increment: main-section;
|
|
59
|
+
content: counter(main-section) ". ";
|
|
60
|
+
font-weight: bold;
|
|
61
|
+
margin-right: 0.5em;
|
|
62
|
+
color: #007bff;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
main article h3::before {
|
|
66
|
+
counter-increment: main-subsection;
|
|
67
|
+
content: counter(main-section) "." counter(main-subsection) " ";
|
|
68
|
+
font-weight: bold;
|
|
69
|
+
margin-right: 0.5em;
|
|
70
|
+
color: #007bff;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main article h4::before {
|
|
74
|
+
counter-increment: main-subsubsection;
|
|
75
|
+
content: counter(main-section) "." counter(main-subsection) "." counter(main-subsubsection) " ";
|
|
76
|
+
font-weight: bold;
|
|
77
|
+
margin-right: 0.5em;
|
|
78
|
+
color: #007bff;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Optional: Style for h5 and h6 if needed */
|
|
82
|
+
main article h5::before,
|
|
83
|
+
main article h6::before {
|
|
84
|
+
font-weight: bold;
|
|
85
|
+
margin-right: 0.5em;
|
|
86
|
+
color: #6c757d;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Ensure numbering doesn't interfere with existing anchor links */
|
|
90
|
+
.toc-anchor {
|
|
91
|
+
margin-left: 0.5em;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Print-friendly styles */
|
|
95
|
+
@media print {
|
|
96
|
+
#toc ul.toc > li > a::before,
|
|
97
|
+
#toc ul.toc > li > ul > li > a::before,
|
|
98
|
+
#toc ul.toc > li > ul > li > ul > li > a::before,
|
|
99
|
+
main article h2::before,
|
|
100
|
+
main article h3::before,
|
|
101
|
+
main article h4::before {
|
|
102
|
+
color: #000 !important;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -206,9 +206,6 @@ function collapseDefinitions() {
|
|
|
206
206
|
event.target :
|
|
207
207
|
event.target.closest('.collapse-all-defs-button');
|
|
208
208
|
|
|
209
|
-
// Find the parent dt and dl elements
|
|
210
|
-
const dtElement = button.closest('dt');
|
|
211
|
-
|
|
212
209
|
// Get button's position in viewport and page
|
|
213
210
|
const buttonRect = button.getBoundingClientRect();
|
|
214
211
|
|
|
@@ -7,21 +7,21 @@ customElements.define('slide-panels', class SidePanels extends HTMLElement {
|
|
|
7
7
|
}
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
this.addEventListener('pointerup', e => {
|
|
12
12
|
if (e.target === this) this.close();
|
|
13
13
|
})
|
|
14
14
|
}
|
|
15
|
-
get active
|
|
15
|
+
get active() {
|
|
16
16
|
return this.getAttribute('open');
|
|
17
17
|
}
|
|
18
|
-
toggle(panel){
|
|
18
|
+
toggle(panel) {
|
|
19
19
|
this.active === panel ? this.close() : this.open(panel)
|
|
20
20
|
}
|
|
21
|
-
open
|
|
21
|
+
open(panel) {
|
|
22
22
|
this.setAttribute('open', panel);
|
|
23
23
|
}
|
|
24
|
-
close
|
|
24
|
+
close() {
|
|
25
25
|
this.removeAttribute('open');
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -39,12 +39,12 @@ customElements.define('detail-box', class DetailBox extends HTMLElement {
|
|
|
39
39
|
return ['open'];
|
|
40
40
|
}
|
|
41
41
|
constructor() {
|
|
42
|
-
super();
|
|
43
|
-
|
|
42
|
+
super();
|
|
43
|
+
|
|
44
44
|
this.addEventListener('pointerup', e => {
|
|
45
45
|
if (e.target.hasAttribute('detail-box-toggle')) {
|
|
46
46
|
e.stopPropagation();
|
|
47
|
-
this.toggle();
|
|
47
|
+
this.toggle();
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -55,7 +55,7 @@ customElements.define('detail-box', class DetailBox extends HTMLElement {
|
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
-
toggle(){
|
|
58
|
+
toggle() {
|
|
59
59
|
this.toggleAttribute('open');
|
|
60
60
|
}
|
|
61
61
|
attributeChangedCallback(attr, last, current) {
|
|
@@ -91,24 +91,22 @@ customElements.define('tab-panels', class TabPanels extends HTMLElement {
|
|
|
91
91
|
}
|
|
92
92
|
attributeChangedCallback(attr, last, current) {
|
|
93
93
|
domReady.then(() => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
94
|
+
if (attr === 'selected-index') {
|
|
95
|
+
let index = current || 0;
|
|
96
|
+
let nav = this.querySelector('nav');
|
|
97
|
+
if (nav.parentElement === this) {
|
|
98
|
+
let tabs = nav.children;
|
|
99
|
+
let selected = tabs[index];
|
|
100
|
+
for (let tab of tabs) tab.removeAttribute('selected');
|
|
101
|
+
if (selected) selected.setAttribute('selected', '');
|
|
102
|
+
let panel = Array.prototype.filter.call(this.children, node => {
|
|
103
|
+
if (node.tagName === 'SECTION') {
|
|
104
|
+
node.removeAttribute('selected');
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
})[index];
|
|
108
|
+
if (panel) panel.setAttribute('selected', '');
|
|
109
|
+
}
|
|
112
110
|
}
|
|
113
111
|
});
|
|
114
112
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview Unit tests for highlight-heading-plus-sibling-nodes.js
|
|
6
|
+
* Covers all exported functions to satisfy SonarQube coverage requirements.
|
|
7
|
+
*/
|
|
8
|
+
const {
|
|
9
|
+
highlightHeadingSection,
|
|
10
|
+
getHeadingLevel,
|
|
11
|
+
collectHeadingSiblings,
|
|
12
|
+
wrapNodesWithHighlight,
|
|
13
|
+
removeExistingHighlights,
|
|
14
|
+
initializeAnchorHighlighting
|
|
15
|
+
} = require('./highlight-heading-plus-sibling-nodes');
|
|
16
|
+
|
|
17
|
+
describe('highlight-heading-plus-sibling-nodes', () => {
|
|
18
|
+
let container;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
// Set up a DOM structure for testing
|
|
22
|
+
document.body.innerHTML = '';
|
|
23
|
+
container = document.createElement('div');
|
|
24
|
+
container.innerHTML = `
|
|
25
|
+
<h2 id="h2-1">Heading 2</h2>
|
|
26
|
+
<p id="p1">Paragraph 1</p>
|
|
27
|
+
<ul id="ul1"><li>Item</li></ul>
|
|
28
|
+
<h3 id="h3-1">Heading 3</h3>
|
|
29
|
+
<p id="p2">Paragraph 2</p>
|
|
30
|
+
<h2 id="h2-2">Heading 2b</h2>
|
|
31
|
+
`;
|
|
32
|
+
document.body.appendChild(container);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
document.body.innerHTML = '';
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('getHeadingLevel', () => {
|
|
40
|
+
it('returns correct level for h2-h6', () => {
|
|
41
|
+
expect(getHeadingLevel(document.getElementById('h2-1'))).toBe(2);
|
|
42
|
+
expect(getHeadingLevel(document.getElementById('h3-1'))).toBe(3);
|
|
43
|
+
});
|
|
44
|
+
it('returns null for h1 or non-heading', () => {
|
|
45
|
+
const h1 = document.createElement('h1');
|
|
46
|
+
expect(getHeadingLevel(h1)).toBeNull();
|
|
47
|
+
expect(getHeadingLevel(document.getElementById('p1'))).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('collectHeadingSiblings', () => {
|
|
52
|
+
it('collects heading and following siblings until next heading of same or higher level', () => {
|
|
53
|
+
const h2 = document.getElementById('h2-1');
|
|
54
|
+
const siblings = collectHeadingSiblings(h2, 2);
|
|
55
|
+
expect(siblings.map(n => n.id)).toEqual(['h2-1', 'p1', 'ul1', 'h3-1', 'p2']);
|
|
56
|
+
});
|
|
57
|
+
it('stops at next heading of same or higher level', () => {
|
|
58
|
+
const h3 = document.getElementById('h3-1');
|
|
59
|
+
const siblings = collectHeadingSiblings(h3, 3);
|
|
60
|
+
expect(siblings.map(n => n.id)).toEqual(['h3-1', 'p2']);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('wrapNodesWithHighlight', () => {
|
|
65
|
+
it('wraps nodes in a div.highlight2', () => {
|
|
66
|
+
const nodes = [document.getElementById('h2-1'), document.getElementById('p1')];
|
|
67
|
+
const wrapper = wrapNodesWithHighlight(nodes);
|
|
68
|
+
expect(wrapper).not.toBeNull();
|
|
69
|
+
expect(wrapper.className).toBe('highlight2');
|
|
70
|
+
expect(wrapper.contains(nodes[0])).toBe(true);
|
|
71
|
+
expect(wrapper.contains(nodes[1])).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
it('returns null if nodes is empty', () => {
|
|
74
|
+
expect(wrapNodesWithHighlight([])).toBeNull();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('removeExistingHighlights', () => {
|
|
79
|
+
it('removes all .highlight2 wrappers and restores children', () => {
|
|
80
|
+
const nodes = [document.getElementById('h2-1'), document.getElementById('p1')];
|
|
81
|
+
wrapNodesWithHighlight(nodes);
|
|
82
|
+
expect(document.querySelectorAll('.highlight2').length).toBe(1);
|
|
83
|
+
const removed = removeExistingHighlights();
|
|
84
|
+
expect(removed).toBe(1);
|
|
85
|
+
expect(document.querySelectorAll('.highlight2').length).toBe(0);
|
|
86
|
+
// Children are restored to parent
|
|
87
|
+
expect(container.contains(nodes[0])).toBe(true);
|
|
88
|
+
expect(container.contains(nodes[1])).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('highlightHeadingSection', () => {
|
|
93
|
+
it('highlights section for valid anchor', () => {
|
|
94
|
+
expect(highlightHeadingSection('#h2-1')).toBe(true);
|
|
95
|
+
const highlight = document.querySelector('.highlight2');
|
|
96
|
+
expect(highlight).not.toBeNull();
|
|
97
|
+
expect(highlight.contains(document.getElementById('h2-1'))).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
it('returns false for invalid anchor', () => {
|
|
100
|
+
expect(highlightHeadingSection('#does-not-exist')).toBe(false);
|
|
101
|
+
expect(highlightHeadingSection('not-a-hash')).toBe(false);
|
|
102
|
+
expect(highlightHeadingSection('#')).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
it('returns false for non-heading element', () => {
|
|
105
|
+
expect(highlightHeadingSection('#p1')).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('initializeAnchorHighlighting', () => {
|
|
110
|
+
it('sets up event listeners and highlights on hash', () => {
|
|
111
|
+
window.location.hash = '#h2-1';
|
|
112
|
+
// Remove highlights if any
|
|
113
|
+
removeExistingHighlights();
|
|
114
|
+
initializeAnchorHighlighting();
|
|
115
|
+
// Simulate hashchange
|
|
116
|
+
window.dispatchEvent(new HashChangeEvent('hashchange'));
|
|
117
|
+
expect(document.querySelector('.highlight2')).not.toBeNull();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
package/config/asset-map.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-up-t",
|
|
3
|
-
"version": "1.3.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Technical specification drafting tool that generates rich specification documents from markdown. Forked from https://github.com/decentralized-identity/spec-up by Daniel Buchner (https://github.com/csuwildcat)",
|
|
5
5
|
"main": "./index",
|
|
6
6
|
"repository": {
|
|
@@ -68,7 +68,8 @@
|
|
|
68
68
|
"braces": ">=3.0.3"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"jest": "^29.7.0"
|
|
71
|
+
"jest": "^29.7.0",
|
|
72
|
+
"jest-environment-jsdom": "^30.0.5"
|
|
72
73
|
},
|
|
73
74
|
"scripts": {
|
|
74
75
|
"test": "jest",
|
package/sonar-project.properties
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
sonar.
|
|
3
|
-
sonar.
|
|
4
|
-
sonar.
|
|
5
|
-
sonar.
|
|
6
|
-
sonar.
|
|
1
|
+
# Temporarily disabled for Automatic Analysis
|
|
2
|
+
# sonar.projectKey=blockchainbird_spec-up-t
|
|
3
|
+
# sonar.organization=blockchainbird
|
|
4
|
+
# sonar.host.url=https://sonarcloud.io
|
|
5
|
+
# sonar.token=SONAR_TOKEN
|
|
6
|
+
# sonar.exclusions=assets/compiled/refs.json
|
|
7
|
+
# sonar.cpd.exclusions=**/*.test.js
|
package/src/create-docx.js
CHANGED
|
@@ -145,18 +145,18 @@ function fixDefinitionListStructure(html) {
|
|
|
145
145
|
function collectDtDdGroup(startNode) {
|
|
146
146
|
const group = [];
|
|
147
147
|
let currentNode = startNode;
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
// Collect the dt and all following dd elements
|
|
150
150
|
while (currentNode && (currentNode.tagName === 'DT' || currentNode.tagName === 'DD')) {
|
|
151
151
|
group.push(currentNode);
|
|
152
152
|
currentNode = currentNode.nextSibling;
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
// Skip text nodes (whitespace) between elements
|
|
155
155
|
while (currentNode && currentNode.nodeType === 3 && !currentNode.textContent.trim()) {
|
|
156
156
|
currentNode = currentNode.nextSibling;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
|
|
159
|
+
|
|
160
160
|
return group;
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -166,7 +166,7 @@ function fixDefinitionListStructure(html) {
|
|
|
166
166
|
if (dt.parentElement !== mainDl) {
|
|
167
167
|
// Collect the dt and its associated dd elements
|
|
168
168
|
const group = collectDtDdGroup(dt);
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
// Move all elements in the group to the main dl
|
|
171
171
|
group.forEach(element => {
|
|
172
172
|
if (element.parentNode) {
|
|
@@ -190,15 +190,15 @@ function fixDefinitionListStructure(html) {
|
|
|
190
190
|
// Process all subsequent content
|
|
191
191
|
while (currentNode) {
|
|
192
192
|
// Save the next node before potentially modifying the DOM
|
|
193
|
-
|
|
193
|
+
let nextNode = currentNode.nextSibling;
|
|
194
194
|
|
|
195
195
|
// Handle different node types
|
|
196
196
|
if (currentNode.nodeType === 1) { // 1 = Element node
|
|
197
197
|
if (currentNode.tagName === 'DL') {
|
|
198
198
|
// Check if this is a reference list (contains dt elements with id="ref:...")
|
|
199
|
-
const hasRefIds = currentNode.innerHTML.includes('id="ref:') ||
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
const hasRefIds = currentNode.innerHTML.includes('id="ref:') ||
|
|
200
|
+
currentNode.classList.contains('reference-list');
|
|
201
|
+
|
|
202
202
|
if (!hasRefIds) {
|
|
203
203
|
// Only move non-reference definition lists - move all its children to the main dl
|
|
204
204
|
while (currentNode.firstChild) {
|
|
@@ -212,11 +212,11 @@ function fixDefinitionListStructure(html) {
|
|
|
212
212
|
else if (currentNode.tagName === 'DT') {
|
|
213
213
|
// Check if this dt has a ref: id (spec reference)
|
|
214
214
|
const hasRefId = currentNode.id?.startsWith('ref:');
|
|
215
|
-
|
|
215
|
+
|
|
216
216
|
if (!hasRefId) {
|
|
217
217
|
// Collect the dt and its associated dd elements
|
|
218
218
|
const group = collectDtDdGroup(currentNode);
|
|
219
|
-
|
|
219
|
+
|
|
220
220
|
// Move all elements in the group to the main dl
|
|
221
221
|
group.forEach(element => {
|
|
222
222
|
if (element.parentNode) {
|
|
@@ -225,7 +225,7 @@ function fixDefinitionListStructure(html) {
|
|
|
225
225
|
element.parentNode.removeChild(element);
|
|
226
226
|
}
|
|
227
227
|
});
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
// Skip the nodes we just processed
|
|
230
230
|
let skipNodes = group.length - 1; // -1 because currentNode will be advanced anyway
|
|
231
231
|
while (skipNodes > 0 && nextNode) {
|
|
@@ -241,7 +241,7 @@ function fixDefinitionListStructure(html) {
|
|
|
241
241
|
// Handle orphaned dd elements - move them to the main dl if they don't belong to a reference
|
|
242
242
|
const dtBefore = currentNode.previousSibling;
|
|
243
243
|
let hasAssociatedDt = false;
|
|
244
|
-
|
|
244
|
+
|
|
245
245
|
// Check if there's a dt before this dd (walking backwards through siblings)
|
|
246
246
|
let checkNode = currentNode.previousSibling;
|
|
247
247
|
while (checkNode) {
|
|
@@ -250,7 +250,7 @@ function fixDefinitionListStructure(html) {
|
|
|
250
250
|
checkNode = checkNode.previousSibling;
|
|
251
251
|
continue;
|
|
252
252
|
}
|
|
253
|
-
|
|
253
|
+
|
|
254
254
|
if (checkNode.tagName === 'DT') {
|
|
255
255
|
hasAssociatedDt = true;
|
|
256
256
|
break;
|
|
@@ -258,10 +258,10 @@ function fixDefinitionListStructure(html) {
|
|
|
258
258
|
// Found a non-dt, non-dd element, so this dd is orphaned
|
|
259
259
|
break;
|
|
260
260
|
}
|
|
261
|
-
|
|
261
|
+
|
|
262
262
|
checkNode = checkNode.previousSibling;
|
|
263
263
|
}
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
// If this dd doesn't have an associated dt in the same context, move it to main dl
|
|
266
266
|
if (!hasAssociatedDt) {
|
|
267
267
|
const ddClone = currentNode.cloneNode(true);
|
|
@@ -9,16 +9,16 @@ on:
|
|
|
9
9
|
required: true
|
|
10
10
|
default: 'Render specification'
|
|
11
11
|
options:
|
|
12
|
-
|
|
12
|
+
- Add content
|
|
13
13
|
- Render specification
|
|
14
|
-
|
|
14
|
+
- Export to PDF
|
|
15
|
+
- Export to DOCX
|
|
15
16
|
- Collect external references
|
|
16
|
-
-
|
|
17
|
+
- Add, remove or view xref source
|
|
18
|
+
- Configure
|
|
19
|
+
- Run health check
|
|
20
|
+
- Open documentation website
|
|
17
21
|
- Freeze specification
|
|
18
|
-
# - List references
|
|
19
|
-
# - Show help
|
|
20
|
-
# - Add/remove xref source
|
|
21
|
-
# - Configure specification
|
|
22
22
|
- Custom update
|
|
23
23
|
|
|
24
24
|
jobs:
|
|
@@ -59,9 +59,11 @@ jobs:
|
|
|
59
59
|
MY_PAT: ${{ secrets.MY_PAT }} # Make the secret available as an env var
|
|
60
60
|
run: |
|
|
61
61
|
case "${{ github.event.inputs.script }}" in
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
"Add content")
|
|
63
|
+
echo "You can start adding your content to the markdown files in the 'spec' directory."
|
|
64
|
+
echo "You can do this by editing local files in an editor or by going to your repository on GitHub."
|
|
65
|
+
echo "More info: https://blockchainbird.github.io/spec-up-t-website/docs/various-roles/content-authors-guide/introduction"
|
|
66
|
+
;;
|
|
65
67
|
"Render specification")
|
|
66
68
|
node --no-warnings -e "require('spec-up-t/index.js')({ nowatch: true })"
|
|
67
69
|
git config --global user.email "actions@github.com"
|
|
@@ -70,9 +72,15 @@ jobs:
|
|
|
70
72
|
git commit -m "Render specification: Update files" || echo "No changes to commit"
|
|
71
73
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
72
74
|
;;
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
# ...existing code...
|
|
76
|
+
"Export to DOCX")
|
|
77
|
+
node -e "require('spec-up-t/src/create-docx.js')"
|
|
78
|
+
git config --global user.email "actions@github.com"
|
|
79
|
+
git config --global user.name "GitHub Actions"
|
|
80
|
+
git add .
|
|
81
|
+
git commit -m "Export to DOCX" || echo "No changes to commit"
|
|
82
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
83
|
+
;;
|
|
76
84
|
"Collect external references")
|
|
77
85
|
node --no-warnings -e "require('spec-up-t/src/collect-external-references.js').collectExternalReferences({ pat: process.env.MY_PAT })"
|
|
78
86
|
git config --global user.email "actions@github.com"
|
|
@@ -81,12 +89,12 @@ jobs:
|
|
|
81
89
|
git commit -m "Collect external references" || echo "No changes to commit"
|
|
82
90
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
83
91
|
;;
|
|
84
|
-
"
|
|
92
|
+
"Export to PDF")
|
|
85
93
|
node -e "require('spec-up-t/src/create-pdf.js')"
|
|
86
94
|
git config --global user.email "actions@github.com"
|
|
87
95
|
git config --global user.name "GitHub Actions"
|
|
88
96
|
git add .
|
|
89
|
-
git commit -m "
|
|
97
|
+
git commit -m "Export to PDF" || echo "No changes to commit"
|
|
90
98
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
91
99
|
;;
|
|
92
100
|
"Freeze specification")
|
|
@@ -97,18 +105,34 @@ jobs:
|
|
|
97
105
|
git commit -m "Freeze specification" || echo "No changes to commit"
|
|
98
106
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
99
107
|
;;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
"Add, remove or view xref source")
|
|
109
|
+
node --no-warnings -e "require('spec-up-t/src/add-remove-xref-source.js')"
|
|
110
|
+
git config --global user.email "actions@github.com"
|
|
111
|
+
git config --global user.name "GitHub Actions"
|
|
112
|
+
git add .
|
|
113
|
+
git commit -m "Add, remove or view xref source" || echo "No changes to commit"
|
|
114
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
115
|
+
;;
|
|
116
|
+
"Configure")
|
|
117
|
+
node --no-warnings -e "require('spec-up-t/src/configure.js')"
|
|
118
|
+
git config --global user.email "actions@github.com"
|
|
119
|
+
git config --global user.name "GitHub Actions"
|
|
120
|
+
git add .
|
|
121
|
+
git commit -m "Configure" || echo "No changes to commit"
|
|
122
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
123
|
+
;;
|
|
124
|
+
"Run health check")
|
|
125
|
+
node --no-warnings -e "require('spec-up-t/src/health-check.js')"
|
|
126
|
+
git config --global user.email "actions@github.com"
|
|
127
|
+
git config --global user.name "GitHub Actions"
|
|
128
|
+
git add .
|
|
129
|
+
git commit -m "Run health check" || echo "No changes to commit"
|
|
130
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
131
|
+
;;
|
|
132
|
+
"Open documentation website")
|
|
133
|
+
echo "Opening documentation website: https://blockchainbird.github.io/spec-up-t-website/"
|
|
134
|
+
echo "Please visit the URL manually: https://blockchainbird.github.io/spec-up-t-website/"
|
|
135
|
+
;;
|
|
112
136
|
"Custom update")
|
|
113
137
|
npm update && node -e "require('spec-up-t/src/install-from-boilerplate/custom-update.js')"
|
|
114
138
|
git config --global user.email "actions@github.com"
|
|
@@ -124,7 +148,7 @@ jobs:
|
|
|
124
148
|
esac
|
|
125
149
|
|
|
126
150
|
- name: Deploy to GitHub Pages
|
|
127
|
-
if: success() && github.event.inputs.script != '
|
|
151
|
+
if: success() && github.event.inputs.script != 'Add content' && github.event.inputs.script != 'Open documentation website' && github.event.inputs.script != 'Configure' && github.event.inputs.script != 'Run health check'
|
|
128
152
|
uses: peaceiris/actions-gh-pages@v3.7.3
|
|
129
153
|
with:
|
|
130
154
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
const { fixMarkdownFiles } = require('./src/fix-markdown-files');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
// Test cases for the default definition functionality
|
|
6
|
-
function testDefaultDefinitions() {
|
|
7
|
-
console.log('Running tests for default definition functionality...');
|
|
8
|
-
|
|
9
|
-
const testContent = [
|
|
10
|
-
'[[def: test-term, test-term]]',
|
|
11
|
-
'',
|
|
12
|
-
'[[tref: another-term, another-term]]',
|
|
13
|
-
'',
|
|
14
|
-
'[[def: term-with-def, term-with-def]]',
|
|
15
|
-
'',
|
|
16
|
-
'~ This term already has a definition',
|
|
17
|
-
'',
|
|
18
|
-
'[[tref: final-term, final-term]]'
|
|
19
|
-
].join('\n');
|
|
20
|
-
|
|
21
|
-
// Write test content to a temp file
|
|
22
|
-
const tempFile = './temp-test.md';
|
|
23
|
-
fs.writeFileSync(tempFile, testContent, 'utf8');
|
|
24
|
-
|
|
25
|
-
// Process the file
|
|
26
|
-
fixMarkdownFiles('.');
|
|
27
|
-
|
|
28
|
-
// Read and verify results
|
|
29
|
-
const result = fs.readFileSync(tempFile, 'utf8');
|
|
30
|
-
console.log('Test result:');
|
|
31
|
-
console.log(result);
|
|
32
|
-
|
|
33
|
-
// Clean up
|
|
34
|
-
fs.unlinkSync(tempFile);
|
|
35
|
-
|
|
36
|
-
// Verify expected content
|
|
37
|
-
const lines = result.split('\n');
|
|
38
|
-
let hasDefaultDefs = 0;
|
|
39
|
-
|
|
40
|
-
for (let i = 0; i < lines.length; i++) {
|
|
41
|
-
if (lines[i] === '~ No local definition found.') {
|
|
42
|
-
hasDefaultDefs++;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(`Found ${hasDefaultDefs} default definitions`);
|
|
47
|
-
|
|
48
|
-
if (hasDefaultDefs === 3) { // Should be 3: test-term, another-term, final-term
|
|
49
|
-
console.log('✅ Test passed: All terms without definitions got default definitions');
|
|
50
|
-
} else {
|
|
51
|
-
console.log('❌ Test failed: Expected 3 default definitions');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
testDefaultDefinitions();
|
package/test-edge-cases.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
[[def: term1, term1]]
|
|
2
|
-
|
|
3
|
-
~ No local definition found.
|
|
4
|
-
|
|
5
|
-
[[def: term2, term2]]
|
|
6
|
-
|
|
7
|
-
~ This term has a definition
|
|
8
|
-
|
|
9
|
-
[[tref: term3, term3]]
|
|
10
|
-
|
|
11
|
-
~ No local definition found.
|
|
12
|
-
|
|
13
|
-
[[def: term4, term4]]
|
|
14
|
-
|
|
15
|
-
~ This term also has a definition
|
|
16
|
-
~ With multiple lines
|
|
17
|
-
|
|
18
|
-
[[tref: term5, term5]]
|
|
19
|
-
|
|
20
|
-
~ No local definition found.
|
package/test-fix-markdown.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const { fixMarkdownFiles } = require('./src/fix-markdown-files');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
// Test the functionality on our test files
|
|
6
|
-
console.log('Testing fix-markdown-files functionality...');
|
|
7
|
-
|
|
8
|
-
// Process test files directly by calling fixMarkdownFiles on the current directory
|
|
9
|
-
fixMarkdownFiles('.');
|
|
10
|
-
|
|
11
|
-
console.log('Processing complete. Check the test files for results.');
|
package/test-no-def.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# Test File for Terms Without Definitions
|
|
2
|
-
|
|
3
|
-
This file contains terms that have no definitions to test the default definition functionality.
|
|
4
|
-
|
|
5
|
-
[[def: xip, xip]]
|
|
6
|
-
|
|
7
|
-
~ No local definition found.
|
|
8
|
-
|
|
9
|
-
[[tref:toip1, SSI]]
|
|
10
|
-
|
|
11
|
-
~ No local definition found.
|
|
12
|
-
|
|
13
|
-
Some other content here.
|
|
14
|
-
|
|
15
|
-
[[def: weight, weight]]
|
|
16
|
-
|
|
17
|
-
~ an optional field map in the Edge section that provides edge weight property that enables directed weighted edges and operators that use weights.
|
|
18
|
-
~ Source: Dr. S.Smith
|
|
19
|
-
|
|
20
|
-
[[def: another-term, another-term]]
|
|
21
|
-
|
|
22
|
-
~ No local definition found.
|