Files
gitea/templates/html/base.js
jiantw83andClaude Opus 5 a0c13f807a feat(gitea): 新增 HTML 匯出與範本風格設定
What:新增 html-export 與 html-style 兩支技能、tools/html-render.sh 與 tools/html-style.sh 兩支工具,以及六種版型乘五種風格的 HTML 範本。

Why:wiki 頁與議題要拿給 Gitea 以外的人看時,只能複製 markdown;不同類型的文件也該有各自的版面,不是每份都長一樣。

How:版型(report、slide、dashboard、spec、timeline、onepager)決定內容怎麼排,風格(minimal、corporate、dark、print、vivid)決定看起來長怎樣,兩者自由搭配。哪一種頁面套哪一組由設定決定:專案的 .jsc/html-styles 優先,其次 $JSC_HOME/html-styles.conf,對不到退 DEFAULT,再對不到才用內建的 report/minimal。產出是單一 HTML 檔,CSS 與腳本全部內嵌。

Who:需要把 wiki 頁或議題寄給客戶、主管或跨團隊同事的人。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 09:19:25 +08:00

64 lines
2.1 KiB
JavaScript

// 共用行為:表格加捲動外框、依 h2 切段、產生目錄。各版型自己決定要用哪幾個。
(function (w) {
'use strict';
// 寬表格包一層可橫捲的外框,整頁就不會被撐開。
function wrapTables(root) {
root.querySelectorAll('table').forEach(function (t) {
if (t.parentElement && t.parentElement.classList.contains('table-wrap')) return;
var box = document.createElement('div');
box.className = 'table-wrap';
t.parentNode.insertBefore(box, t);
box.appendChild(t);
});
}
// 依 h2 把內容切成一段一段。h2 之前的內容自成第一段(前言)。
function splitBySection(root) {
var nodes = Array.prototype.slice.call(root.childNodes);
var sections = [];
var current = null;
function open(headingText) {
current = document.createElement('section');
current.className = 'jsc-section';
current.dataset.title = headingText || '';
sections.push(current);
}
nodes.forEach(function (node) {
if (node.nodeType === 1 && node.tagName === 'H2') {
open(node.textContent.trim());
} else if (!current) {
if (node.nodeType === 3 && !node.textContent.trim()) return;
open('');
}
current.appendChild(node);
});
root.innerHTML = '';
sections.forEach(function (s) { root.appendChild(s); });
return sections;
}
// 依 h2、h3 產生目錄,塞進指定容器。標題沒有 id 就補一個。
function buildToc(root, target) {
var heads = root.querySelectorAll('h2, h3');
if (!heads.length) { target.remove(); return; }
var list = document.createElement('ul');
heads.forEach(function (h, i) {
if (!h.id) h.id = 'sec-' + (i + 1);
var li = document.createElement('li');
li.className = 'toc-' + h.tagName.toLowerCase();
var a = document.createElement('a');
a.href = '#' + h.id;
a.textContent = h.textContent.trim();
li.appendChild(a);
list.appendChild(li);
});
target.appendChild(list);
}
w.jsc = { wrapTables: wrapTables, splitBySection: splitBySection, buildToc: buildToc };
})(window);