小插件 Sheets Basic:合并 Markdown 表格单元格

@Arsery 那没必要用这个插件,可以用 AnyBlock。

请问下如果需要多行合并,如下这样,为什么在阅读视图和导出时候只有内容1下面一行(第2行生效)能与内容1合并,然后再往下的几行(3、4、5行都不行)都不会合并呢,而且会有最后一列在3、4、5行缺失的情况出现

|表头1 | 表头2 | 表头3 | 表头4 |
|--- | --- | --- | ---|
|内容1 | 内容2 | 内容3 | |
|^ | 内容2-1 | 内容3-1 | |
|^ | 内容2-2 | 内容3-2 | |
|^ | 内容2-3 | 内容3-3 | |
| |  |  | |

阅读模式:

image

编辑模式(也是我的本意):

image

@aybinz 后续如有问题在其他线程继续。

很有用,感谢大佬

:partying_face:谢谢大佬,之前没有登录就没看到消息,收到邮件才看到回复,我试了一下确实问题已经修复好了,大佬厉害b( ̄▽ ̄)d

我不知道为什么,也许我下载插件的方式有问题,总之我下载了插件之后并不能实现表格合并,就算用源码模式也不行:sob::sob:

这个插件很方便,只是和strange new world插件有一点冲突,当表格中有链接时,在阅读视图中,链接被链入的数量标记无法被激活弹窗(编辑视图是正常的)。
让AI对 k 模块 做下面的修改后才正常。

// ========== 只修改这个 k 模块 前面原碼中的assgin似拼写錯误==========
var k = g((se, T) => {
    var { tableId: Q, merge: X } = b();
    T.exports = (t, s) => class extends s.MarkdownRenderChild {
        constructor(e, r) {
            super(e);
            this.buildContGrid(r);
            this.footMgr.retain(e);
            let i = e;
            i.id = Q;
            this.domGrid = Array.from(i.rows).map((o, l) => Array.from(o.cells).map((a, u) => ({
                el: a,
                row: l,
                col: u,
                text: this.contGrid[l]?.[u] ?? ""
            })));
            this.buildDomTable();
        }
        onload() { }
        onunload() { }
        cellBorderRE = /(?<!\\)\|/;
        headerRE = /^\s*?(\:)?(?:-+)(\:)?\s*/;
        buildContGrid(e) {
            this.contGrid = e.split("\n").filter(r => r).map(r => r.split(this.cellBorderRE).slice(1, -1).map(i => i?.trim() ?? ""));
            this.headerRow = this.contGrid.findIndex(r => r.every(i => this.headerRE.test(i)));
            if (this.headerRow !== -1) {
                this.contGrid.splice(this.headerRow, 1);
            }
        }
        buildDomTable() {
            let e = this.domGrid.flat();
            for (let r of e) {
                X(r, e) || this.normalizeCell(r);
            }
        }
        footMgr = new class {
            retain(e) {
                let r = e.querySelectorAll(".footnote-ref");
                this.footrefs = Array.from(r).map(i => ({ cont: i.children[0]?.dataset?.footref, html: i.outerHTML }));
            }
            footRE = /(?<!\\)\[\^(.+?)\]/g;
            dummy(e) {
                return e?.replaceAll(this.footRE, "\u21BF$1\u21BF") ?? "";
            }
            restore(e) {
                return e?.replaceAll(/↿(.+?)↿/g, (r, i) => {
                    let o = this.footrefs.find(l => l.cont === i);
                    return o ? o.html : i;
                }) ?? "";
            }
        };
        
        normalizeCell({ text: e, el: r }) {
            // 保存 SNW 元素
            let savedSnw = [];
            let snwElements = r.querySelectorAll('.snw-link-preview, .snw-reference, [data-snw-type]');
            snwElements.forEach(el => {
                let prevLink = el.previousElementSibling;
                if (prevLink && prevLink.classList && prevLink.classList.contains('internal-link')) {
                    savedSnw.push({
                        href: prevLink.getAttribute('href'),
                        html: el.outerHTML
                    });
                }
            });
            
            e = e?.replaceAll("<br>", "\n") ?? "\u200B";
            e = this.footMgr.dummy(e);
            r.empty();
            
            s.MarkdownRenderer.render(t, e || "\u200B", r, "", this).then(() => {
                // 去除 <p> 标签,但保留子节点(使用 DOM 操作,不重建 HTML)
                let paragraphs = r.querySelectorAll('p');
                paragraphs.forEach(p => {
                    let parent = p.parentNode;
                    while (p.firstChild) {
                        parent.insertBefore(p.firstChild, p);
                    }
                    p.remove();
                });
                
                // 清理空段落(原版逻辑)
                let isPElement = o => o?.tagName === "P";
                let firstChild = r.firstChild;
                let lastChild = r.lastChild;
                
                if (firstChild && isPElement(firstChild) && (!firstChild.textContent || firstChild.textContent.trim() === "") && (!firstChild.children || firstChild.children.length === 0)) {
                    firstChild.remove();
                }
                
                if (lastChild && lastChild !== firstChild && isPElement(lastChild) && (!lastChild.textContent || lastChild.textContent.trim() === "") && (!lastChild.children || lastChild.children.length === 0)) {
                    lastChild.remove();
                }
                
                // 恢复 SNW 元素
                if (savedSnw.length > 0) {
                    let links = r.querySelectorAll('a.internal-link');
                    links.forEach(link => {
                        let saved = savedSnw.find(s => s.href === link.getAttribute('href'));
                        if (saved) {
                            // 检查后面是否已经有 SNW 元素
                            let next = link.nextSibling;
                            let alreadyHas = next && next.nodeType === 1 && 
                                (next.className?.includes('snw-link-preview') || 
                                 next.className?.includes('snw-reference'));
                            if (!alreadyHas) {
                                let tempDiv = document.createElement('div');
                                tempDiv.innerHTML = saved.html;
                                let restored = tempDiv.firstChild;
                                if (restored) {
                                    link.insertAdjacentElement('afterend', restored);
                                }
                            }
                        }
                    });
                }
                
                // 恢复脚注(只替换标记,不重建 HTML)
                let html = r.innerHTML;
                if (html.includes('↿')) {
                    let restoredHtml = this.footMgr.restore(html);
                    if (restoredHtml !== html) {
                        r.innerHTML = restoredHtml;
                    }
                }
            });
        }
        
        afterRender(e) {
            // 不再使用,所有逻辑已移到 normalizeCell 中
        }
    };
});
// ========== k 模块修改结束 ==========

AnyBlock 和strange new world插件的冲突更大一点,还好这个插件改起来方便一些。

虽然没懂 #36 问题描述的具体情况,但根据给出的 AI 代码,和我目前处理脚注的逻辑一致,只是处理对象换成了其他插件特殊的部分。

我会试试找个合适的方式摆放。不过少点儿看不出来,多了就拼拼乐了。用 AI 定制确实是个好法子,这对其他用户很有参考价值。只要本地用着没问题,不必追更新,现在的状态就是生产力。

strange new world 的作用是,会在链接的右上角生成一个该链接被使用的次数,这个数字可以被鼠标悬停激活弹窗。
在使用sheet basic插件后,当表格中有链接时,在阅读视图中,链接被链入的数量标记无法被激活弹窗(编辑视图是正常的)。
两个插件并存时,在表格中加入链接(其他地方也复制存放此链接),然后在阅读视图和编辑视图间切换,试着对链接右上角的数字进行悬停操作,很容易复现此问题。