关于多级笔记导出为 PDF 时目录缺失、代码高亮缺失、分页符缺失的问题

本贴最后更新于 190 天前,其中的信息可能已经时移世异

不得不说,思源的主题非常清爽,非常适合阅读《阮一峰 TypeScript 教程》这类的开源电子书!
但是,在思源笔记里阅读,没办法像 Bookxnote 这类阅读器那样,在一旁方便地标记备注。
而正文和自己的备注混在一起的感觉实在太差了,又不醒目又不方便检索。
那么最好的办法就是将 md 文件导入思源,再整本导出为 pdf。

但是我在转换时遇到了三个非常影响体验的 BUG。

目录缺失

经实测,当导出单层笔记为 PDF 时,目录是可以正常输出的。

图片.png

但是一旦导出多层笔记,比如从下面箭头所指处导出,目录就完全没有了。

图片.png

图片.png

代码高亮缺失

同样存在导出单层笔记时,代码高亮正常

图片.png

但是导出多层笔记时,代码高亮就失效的问题

图片.png

分页符缺失

这是只在导出多层笔记时才会遇到的问题。

下图可以看到第 01 章的标题紧紧贴着封面图,非常不自然。

图片.png

第 04 章也是紧紧贴着第 03 章末尾显示的

图片.png

而正常情况下,红色箭头处应该是存在分页符的,从而将两个文件,也就是两个章节隔开。

总结

如果不是反复的折腾,可能很多人都难以发现导出 PDF 时,单层笔记和多层笔记的表现竟然不一样。
这种前后不一致真的很让人难受…

于我个人而言,将多层笔记输出为 PDF 的功能还是挺常用的。
除了这种阅读电子书的场景,我还经常拿思源写一些用户操作手册、会议纪要、编程课件。
以往篇幅不长的情况下,我都是逐个转换单篇笔记为 PDF,再用其它软件合起来,再手动编辑目录。
而且 PDF 这种文件格式不像 Markdown,修改调整起来费时费力,常会因为格式不对从头返工。
而像电子书这种场景,要是没有脚本软件批量操作,一本书就能搞个把小时…

盼望 D 大 V 大能考虑一下,早日修复这几个问题,十分感谢。
也希望在修复之前,有同样需求的朋友们,能留言说一下你们是用什么小妙招克服这个问题的。

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    22390 引用 • 89648 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • didididididi

    我还观察到,有时候单篇大笔记导出 PDF 的时候,有时候也会有目录缺失的现象。
    这个时候只需要手动点一下优化排版,就恢复正常了。

    不知道导出多层笔记是不是会面临内存问题。
    我觉得宁可导出速度慢一点,也要功能完整。
    最好是能有个导出进度条,或者预估时间之类的东西,要不然不知道是导出失败了还是单纯的导出慢。

    如果受打印 PDF 的 API 限制,能否在思源内部模拟手动导出单篇笔记的脚本,最后再合并到一起呢?
    体验上类似手机上的长截图的感觉,即用户可以看到每篇笔记的操作流程,但阻塞除暂停和退出外的一切用户操作。

  • 1 操作
    JeffreyChen 在 2024-05-19 10:14:31 更新了该回帖
  • 88250
    1. 导出 PDF 的书签目录是使用标题块生成的,不对应原来的父子文档结构,导出时只能合并子文档到同一个大的文档中再导出 PDF
    2. 较大的 PDF 导出会有问题 Issue #10982 · siyuan-note/siyuan
    3. 代码块高亮的问题我这里无法重现,建议在默认主题下测试看看

    感谢反馈。

    2 回复
  • didididididi

    第一点

    可以理解,有 issue 提到,有一个自动标题自动降级的逻辑。

    但只是在 PDF 以目录的形式呈现的话,并不需要搞自动降级这么复杂。
    PDF 中的目录只以缩进来表示 Level,完全不受笔记标题 H1~H6 的限制。

    举例来说,存在如下文档结构:

    • 阮一峰 TypeScript → 点击这里导出 PDF
      • 第一章.md → 这是一篇笔记
        • H1 概述 → 这是笔记中的 H1
          • H2 历史
        • H1 理论
      • 第二章.md → 这是另一篇笔记
        • H1 语法
          • H2 变量
          • H2 常量

    那么,导出为 PDF 时,保留同样的目录结构就可以了

    • 阮一峰 TypeScrip
      • 第一章
        • 概述
          • 历史
        • 理论
      • 第二章
        • 语法
          • 变量
          • 常量

    实际上,手动导出单篇笔记,再合并的逻辑也是如此。

    确实有的人喜欢在笔记中写一个 H1 作为标题,但是用思源写笔记的话,这种作法应该相对较少。
    而且只要保证目录结构不错乱,有些目录的小细节修改起来也比较容易。

    第二点

    所以我在下面回帖补充了关于这个功能的设想:在思源笔记内部模拟用户单篇笔记导出 PDF 再合并的逻辑,然后再修改 PDF 目录
    导出时每次就导出固定页面数的 PDF,比如 100 页;

    可能会慢一点,也可能需要阻塞用户操作。
    但是只要以适当的方式显示导出进度给用户应该还算可以接受。

    当然,可以预见到,这是个大工程。

    第三点

    我以默认主题 daylight 导出,并以两种代码块配色,都可以复现。

    图片.png

    图片.png

    据观察,在打印窗口中,代码块一开始是不渲染的,是在几乎导出完成时才以黑白的方式渲染。
    不知这个信息是否有用。

    我导出 PDF 的环境是:

    • Win10x64
    • 思源 v3.0.14
    • 官方内置主题 daylight
    • 代码块主题:
      • base16/papercolor-light
      • default

    补充:目前导出用的 AHK 脚本

    #Requires AutoHotkey v2.0
    #SingleInstance Force
    CoordMode 'Mouse', 'Screen'
    
    itemH := 28 + 1 ;上下maring各1,margin塌陷=1
    loops := 32 ; 笔记个数
    looplast := loops ; 剩余笔记个数
    offitem := 0
    offH := 0
    newY := 0
    
    /*
    一次点击的示例:
    右键:433,95
    导出:599,506 → +166,+411
    PDF:779,632 → +180,+126
    */
    
    F9:: {
        global
        MouseGetPos &itemX, &itemY
        loop loops {
            looplast -= 1
            offH := itemH * offitem
            newY := itemY + offH
    
            Click itemX, newY ; 点击条目
            Sleep 1000
            MouseMove 580, 220 ; 点击文件中空白处
            Sleep 2000
            Send '{Alt Down}'
            Sleep 300
            Send '{F8}'
            Sleep 300
            Send '{Alt Up}'
    
            Sleep 4000
            Click itemX, newY ; 点击条目
            Sleep 1000
            Click itemX, newY, 'Right' ; 右键条目
            Sleep 1000
            MouseMove itemX + 166, newY + 411 ; 移动到导出 ;
            Sleep 1000
            Click ; 点击导出
            Sleep 1000
            MouseMove itemX + 166 + 180, newY + 412 + 126 ; 移动到PDF ;
            Sleep 1000
    
            ; send "{Esc}" ; 与clickPDF两者存一,send Esc为测试状态
    
            Click ; 点击PDF
    
            Sleep 4000
            MouseMove 3094, 1264 ; 点击打印的确定
            Sleep 1000
            Click ; 点击确定
            Sleep 3000
            MouseMove 2385, 885 ; 移动选择文件夹
            Sleep 3000
            Click ; 点击选择文件夹
            Sleep 5000
    
    
            offitem += 1
    
            ; 每搞7个向下滚2下
            if offitem == 7 {
                Click "325 90 wheeldown 2"
                Sleep 100 ; 滚动间隔时间,单位为毫秒,可以根据需要调整
    
                ; 滚两下的精确距离是200,因此需要手动补偿3
                ; itemH的精确高度是29,29*7=203
                ; 重置itemY并修正偏移
                itemY := itemY + 3
    
                offitem := 0
            }
        }
    }
    
    F10:: {
        global
        ; 重置脚本
        offitem := 0
        offH := 0
        newY := 0
        loops := looplast
        MsgBox "脚本已停止运行。"
        ExitApp ; 停止脚本运行
    }
    
    
    F12:: {
        ; 用于测试
        CoordMode 'Mouse', 'Screen'
        Click "325 90 wheeldown 2" ; 滚两下正好是200px
        Sleep 100 ; 滚动间隔时间,单位为毫秒,可以根据需要调整
    }
    
  • didididididi

    另外,想请教一下,目前 PDF 打印功能是如何实现的?是 Electron 提供的 API 还是像 docx 一样调用 pandoc 呢?我能不能自己写命令行参数来实现批量导出,并在导出时使用思源中的主题呢?

    1 回复
  • 88250

    Electron

请输入回帖内容 ...