MarginNote 是 Mac 和 iOS 上的一个非常强大的学习工具,知乎上有很多人推荐。可惜在多设备同步等功能上 bug 非常多,导致我一直对它爱不起来,但奈何它的功能确实比较强大,市面上并没有替代的工具。这段时间我尝试使用 MarginNote 来阅读老师的 PPT 以准备考试。MarginNote 并不能直接使用 PPT 格式的文档,而是需要先转换成其他格式,比如 PDF。

然而,PPT 在转换为 PDF 的时候会丢失动画。而有的老师很喜欢在一页 PPT 上加很多动画,使得元素会重叠,转换为 PDF 之后底层的内容被挡住。有没有办法可以让 PPT 中的重叠元素自动分页,使得底层的元素在转换为 PDF 之后也可见呢?

经过搜索,我发现我们可以使用 VBA 脚本来将 PPT 的动画进行分页,然后再导出为 PDF 的话就不会出现元素的重叠了。而且非常幸运的是,VBA 脚本并不是只有 Windows 可以使用,Mac 也可以使用。以下演示以 Office for Mac 2016 为例:

打开 PPT 的“工具->宏>Visual Basic 编辑器”

打开 PPT 的“工具->宏>Visual Basic 编辑器”,然后选择“插入->模块”。

在新打开的窗口中粘贴以下代码:

Option Explicit

Sub AddElements()
Dim shp As Shape

Dim i As Integer, n As Integer
n = ActivePresentation.Slides.Count
For i = 1 To n
    Dim s As Slide
    Set s = ActivePresentation.Slides(i)
    s.SlideShowTransition.Hidden = msoTrue
    
    Dim max As Integer: max = AnimationElements(s)
    Dim k As Integer, s2 As Slide
    For k = 1 To max
        Set s2 = s.Duplicate(1)
        s2.Name = "AutoGenerated: " & s2.SlideID
        s2.SlideShowTransition.Hidden = msoFalse
        s2.MoveTo ActivePresentation.Slides.Count
        
        Dim i2 As Integer, h As Shape
        Dim Del As New Collection
        For i2 = s2.Shapes.Count To 1 Step -1
            Set h = s2.Shapes(i2)
            If Not IsVisible(s2, h, k) Then Del.Add h
        Next
        Dim j As Integer
        For j = s.TimeLine.MainSequence.Count To 1 Step -1
            s2.TimeLine.MainSequence.Item(1).Delete
        Next
        For j = Del.Count To 1 Step -1
            Del(j).Delete
            Del.Remove j
        Next
    Next
Next
End Sub

'is the shape on this slide visible at point this time step (1..n)
Function IsVisible(s As Slide, h As Shape, i As Integer) As Boolean

'first search for a start state
Dim e As Effect
IsVisible = True
For Each e In s.TimeLine.MainSequence
    If e.Shape Is h Then
        IsVisible = Not (e.Exit = msoFalse)
        Exit For
    End If
Next

'now run forward animating it
Dim n As Integer: n = 1
For Each e In s.TimeLine.MainSequence
    If e.Timing.TriggerType = msoAnimTriggerOnPageClick Then n = n + 1
    If n > i Then Exit For
    If e.Shape Is h Then IsVisible = (e.Exit = msoFalse)
Next
End Function

'How many animation steps are there
'1 for a slide with no additional elements
Function AnimationElements(s As Slide) As Integer
AnimationElements = 1
Dim e As Effect
For Each e In s.TimeLine.MainSequence
    If e.Timing.TriggerType = msoAnimTriggerOnPageClick Then
        AnimationElements = AnimationElements + 1
    End If
Next
End Function

Sub RemElements()
Dim i As Integer, n As Integer
Dim s As Slide
n = ActivePresentation.Slides.Count
For i = n To 1 Step -1
    Set s = ActivePresentation.Slides(i)
    If s.SlideShowTransition.Hidden = msoTrue Then
        s.SlideShowTransition.Hidden = msoFalse
    ElseIf Left$(s.Name, 13) = "AutoGenerated" Then
        s.Delete
    End If
Next
End Sub

然后我们关闭这个窗口,在 Powerpoint 的主窗口中选择“工具->宏->宏”。

选择“AddElements”,然后点击“运行”。

运行之后,你原来的页面将会变成隐藏的状态(左上角有个符号),而新增的页面为动画分页后的版本。

这时候在从菜单中选择“文件->另存为”,选择 PDF 保存即可。

如果你使用的 Office 是其他版本,可以在这里查看如何使用 VBA 脚本。本文所使用的 VBA 脚本来自 Neil Mitchell’s Haskell Blog

你也许会喜欢
阅读更多

Mac 根据应用程序决定Fn键(功能键)的功能

使用键盘顶部的 Fn 键用作 macOS 功能键可以非常方便的调整亮度、控制音乐播放、以及显示“启动台”(Launchpad),但有的时候(必须写代码)我们需要临时将 Fn 键给应用程序用作标准功能键,不然的话需要多按一个 Fn 键,很不顺手,有没有办法自动切换呢?
阅读更多

我是如何管理网络书签和个人知识库的

对于网络书签和个人知识库的需求,相信很多人还是有的。只是很多人因为整理“历史遗留问题”的成本偏高、又或者是因为没有发现合适的工具,而越来越懒得去整理书签和知识库,导致要找资料的时候总是找不到。作为一个希望事情变得有条理的个人知识管理初烧者,我今天准备写一篇文章,向大家介绍一下如何妥善的建立自己的电子化知识搜寻体系。