AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1019791
Accepted
user423047
user423047
Asked: 2018-03-28 14:29:35 +0800 CST2018-03-28 14:29:35 +0800 CST 2018-03-28 14:29:35 +0800 CST

更改 2 个或更多 LibreOffice 文档以具有完全相同的样式/格式

  • 772

假设我有一个目录,其中包含.rtf我使用 LibreOffice Writer 编辑的大约 100 个文件。

我希望该目录中的所有文件都具有完全相同的基本富文本样式指令,例如:

* font-family: Ubuntu             # All text in all files is now Ubuntu;
* font-size: 12px                 # All text in all files is now 12px big;
h1: 28px                          # All h1's are now 28px big;
if font-size: 18px {make it 22px} # All text with font-size 18px is now 22px;

等等......所以,基本上我想一次更改所有文件。这样的“散装造型”可能吗?

也许有可能以某种方式使用 CLI?

style libreoffice
  • 3 3 个回答
  • 660 Views

3 个回答

  • Voted
  1. Best Answer
    WinEunuuchs2Unix
    2018-04-02T12:56:11+08:002018-04-02T12:56:11+08:00

    使用 LibreOffice 工具而不是命令行

    当你只有命令行工具时,一切看起来都像是一个命令行问题。我决定使用 LibreOffice 宏来写这个答案:

    1. 使用命令行循环在“无头”环境中处理每个 Writer 文档。
    2. 运行宏以更改.rtf(富文本格式)Writer 文档文件。
    3. 宏保存文件并退出
    4. 循环回到 1。

    创建测试数据

    创建两个或多个文件,其中包含:

    富文本2.png

    创建包含以下内容的脚本~/Downloads/copy-rtf.sh:

    cp ~/Documents/*.rtf ~/Downloads
    

    使用标记为可执行文件

    chmod a+x ~/Downloads/copy-rtf.sh
    
    • 在开发和测试期间,修改*.rtf文件的宏将针对~/Downloads目录运行。
    • 在每个测试类型cd ~/Downloads和运行之前./copy-rtf.sh
    • 输出完美后,将它们复制回实时目录。

    使用该Downloads目录是因为:

    • 每个人都有一个~/Downloads
    • 它会定期添加并定期手动清空
    • /tmp/它比在重新启动后可能不会持续存在的目录更永久。

    在无头环境中运行宏

    使用这个Stack Exchange answer,从命令行运行 Libreoffice Writer 并传递一个全局宏名称来执行:

    soffice -headless -invisible "vnd.sun.star.script:Standard.Module1.MySubroutine? language=Basic&location=application"
    

    如果上述方法不起作用,可以尝试另一种方法:

    soffice "macro:///Standard.SaveCSV.Main" $1
    

    安装 Java 运行时环境

    要运行宏,您需要安装 Java 运行时环境 (JRE)。开发者的网页上有手动下载和安装的说明。

    然而,这个 AU 问答:https ://askubuntu.com/a/728153/307523表明它很简单:

    sudo apt-add-repository ppa:webupd8team/java
    sudo apt-get update
    sudo apt-get install oracle-java8-installer oracle-java8-set-default
    

    我尝试了 AU Q&A 方法,在添加 PPA 的第一步之后,会出现一个带有附加信息的初始屏幕。最有用的是在 Debian 系统上设置 JRE 8的链接。

    安装 JRE 8 的第三步要求您使用Tab并Enter接受许可协议。在安装程序最繁重的部分,您的机器将暂停几分钟。

    现在打开 LibreOffice 并选择工具->选项-> LibreOffice ->高级并设置此屏幕:

    LO JRE8 高级设置.png

    单击以下选项:

    • 使用 Java 运行时环境
    • 甲骨文公司 1.8.0_161
    • 启用宏录制(实验性)
    • 点击确定
    • 系统会要求您重新启动,单击“立即重新启动”。

    LibreOffice Writer 宏

    该宏将通读整个文档并:

    • 将字体名称更改为 Ubuntu。
    • 如果标题 1 将字体大小设置为 28
    • 否则如果字体大小为 18 设置为 22
    • 否则将字体大小设置为 12

    该宏将保存文档并退出 LibreOffice Writer。

    关闭对话框

    保存文件并出现此对话框:

    LO Writer 关闭 RTF 对话框.png

    关闭此消息,如屏幕所示。如果启用此选项,宏可能无法正常运行。

    宏内容

    我花了几天时间尝试使用“工具”->“宏”->“录制宏”->“基本”来录制宏。起初它看起来很有希望,但录制的宏有不一致的行为,不得不放弃手写的基本宏。在 Stack Overflow 中为那里的专家找到了帮助,以帮助我进行基本的基本编码。结果如下:

    Sub ChangeAllFonts
        rem - Change all font names to Ubuntu.
        rem - If heading 1 set font size to 28
        rem - else if font size is 18 set to 22
        rem - else set font size to 12
        rem - The macro will save document and exit LibreOffice Writer.
        Dim oDoc As Object
        Dim oParEnum As Object, oPar As Object, oSecEnum As Object, oSec As Object
        Dim oFamilies As Object, oParaStyles As Object, oStyle As Object
        oDoc = ThisComponent
        oParEnum = oDoc.Text.createEnumeration()
        Do While oParEnum.hasMoreElements()
          oPar = oParEnum.nextElement()
          If oPar.supportsService("com.sun.star.text.Paragraph") Then
            oSecEnum = oPar.createEnumeration()
            Do While oSecEnum.hasMoreElements()
              oSec = oSecEnum.nextElement()
              If oSec.TextPortionType = "Text" Then
                If oSec.ParaStyleName = "Heading 1" Then
                    rem ignore for now
                ElseIf oSec.CharHeight = 18 Then
                    oSec.CharHeight = 22.0
                Else
                    oSec.CharHeight = 12.0
                End If
              End If
            Loop
          End If
        Loop
        oFamilies = oDoc.getStyleFamilies()
        oParaStyles = oFamilies.getByName("ParagraphStyles")
        oStyle = oParaStyles.getByName("Heading 1")
        oStyle.setPropertyValue("CharHeight", 28.0)
        FileSave
        StarDesktop.terminate()
    End Sub
    
    rem Above subroutine is missing call to UbuntuFontName ()
    rem also it is calling oStyle.setPropertyValue("CharHeight", 28.0)
    rem which may cause problems. Will test. Also StarDesktop.terminate ()
    rem is known to cause problems and will likely be reworked with a
    rem a dialog box telling operator the program is finished and maybe
    rem to press <Alt>+<F4>.
    
    rem ========= Original code below for possible recycling ===========
    
    Sub AllFonts
    rem - change all font names to Ubuntu.
    rem - If heading 1 set font size to 28
    rem - else if font size is 18 set to 22
    rem - else set font size to 12
    
    rem The macro will save document and exit LibreOffice Writer.
    
    Dim CharHeight As Long, oSel as Object, oTC as Object
    Dim CharStyleName As String
    Dim oParEnum as Object, oPar as Object, oSecEnum as Object, oSec as Object
    Dim oVC as Object, oText As Object
    Dim oParSection        'Current Section
          
    oText = ThisComponent.Text
    oSel = ThisComponent.CurrentSelection.getByIndex(0) 'get the current selection
    oTC = oText.createTextCursorByRange(oSel)           ' and span it with a cursor
    
    rem Scan the cursor range for chunks of given text size.
    rem (Doesn't work - affects the whole document)
    
    oParEnum = oTC.Text.createEnumeration()
    Do While oParEnum.hasMoreElements()
      oPar = oParEnum.nextElement()
      If oPar.supportsService("com.sun.star.text.Paragraph") Then
        oSecEnum = oPar.createEnumeration()
        oParSection = oSecEnum.nextElement()
        Do While oSecEnum.hasMoreElements()
          oSec = oSecEnum.nextElement()
          If oSec.TextPortionType = "Text" Then
            CharStyleName = oParSection.CharStyleName
            CharHeight = oSec.CharHeight
            if CharStyleName = "Heading 1" Then
                oSec.CharHeight = 28
            elseif CharHeight = 18 Then
                oSec.CharHeight = 22
            else
                oSec.CharHeight = 12
            End If
          End If
        Loop
      End If
    
    Loop
    
    FileSave
    stardesktop.terminate()
    
    End Sub
    
    
    Sub UbuntuFontName
    rem ----------------------------------------------------------------------
    rem define variables
    dim document   as object
    dim dispatcher as object
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    
    rem ----------- Select all text ------------------------------------------
    dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
    
    rem ----------- Change all fonts to Ubuntu -------------------------------
    dim args5(4) as new com.sun.star.beans.PropertyValue
    args5(0).Name = "CharFontName.StyleName"
    args5(0).Value = ""
    args5(1).Name = "CharFontName.Pitch"
    args5(1).Value = 2
    args5(2).Name = "CharFontName.CharSet"
    args5(2).Value = -1
    args5(3).Name = "CharFontName.Family"
    args5(3).Value = 0
    args5(4).Name = "CharFontName.FamilyName"
    args5(4).Value = "Ubuntu"
    
    dispatcher.executeDispatch(document, ".uno:CharFontName", "", 0, args5())
    
    end sub
    
    
    sub FileSave
    rem ----------------------------------------------------------------------
    rem define variables
    dim document   as object
    dim dispatcher as object
    rem ----------------------------------------------------------------------
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    
    rem ----------------------------------------------------------------------
    dispatcher.executeDispatch(document, ".uno:Save", "", 0, Array())
    
    end sub
    
    • 4
  2. Elder Geek
    2018-04-01T20:02:02+08:002018-04-01T20:02:02+08:00

    这是使用 Libre Office 的一次性方法。这不是批处理,但它可能有助于激发其他答案。

    打开具有 Ubuntu 字体的 rtf 文件,H1 为 28 pt,一些文本为 12 pt,一些文本为 18 pt。

    这是一个例子:

    测试 rtf

    以下步骤将应用您的问题“if font-size: 18px {make it 22px} # All text with font-size 18px is now 22px;”中请求的更改。

    单击菜单上的编辑→查找和替换或CtrlH单击其他选项单击搜索框然后属性按钮字体大小复选框然后格式按钮从最右侧的滚动框中选择 18 磅替换为框然后格式按钮并从最右边的滚动框

    查找替换

    点击全部替换

    更改的适用行是:

    \par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf1\kerning1\dbch\af7\langfe1081\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\ql\widctlpar\hyppar0\ltrpar {\rtlch \ltrch\loch\fs36\loch\f6

    fs36 改为 fs44

    唯一更改的其他字段是您可能想要或不想更新的 revtime 字段:

    {\revtim\yr2018\mo3\dy31\hr22\min19}

    了解发生了什么变化为我们提供了开发批处理方法的模型。可能会在打开文档时录制一个执行此操作的宏,或者开发一个根据需要进行更改的脚本。

    • 2
  3. Elder Geek
    2018-04-01T08:49:04+08:002018-04-01T08:49:04+08:00

    在RTF 规范中有一些很好的线索来说明如何处理这个问题。

    以下是我对这个问题的分析。

    正如您所猜测的那样,使用 CLI 完成此操作似乎是最简单的方法,因为我还没有看到任何基于 GUI 的应用程序可以处理这种批量转换。看来您可以简单地修改标题:

    标头具有以下语法:

    <header>
        \rtf <charset> \deff? <fonttbl> <filetbl>? <colortbl>? <stylesheet>? <listtables>? <revtbl>?
    
    Each of the various header tables should appear, if they exist, in the above order. Document properties can occur before and between the header tables. A property must be defined before being referenced. Specifically:
    
    * The style sheet must occur before any style usage.
    
    * The font table must precede any reference to a font.
    
    * The \deff keyword must precede any text without an explicit reference to a font, because it specifies the font to use in such cases.
    

    就个人而言,在查看此信息后,我发现您尝试做的所有事情看起来都在标题中得到支持,从字体选择到样式。

    有一些工具可以帮助您完成此过程,我将在下面概述,因为我没有您拥有的文档样式的示例,也没有您想要的文档样式的示例,并且更通用的答案可能比社区更有用一个针对您的确切情况。

    grep将有助于解析要转换的现有文件以及现有<fonttbl>和
    <stylesheet>选择的目标样式示例。在确定了您实际拥有的内容后,您应该能够编写一个简单的脚本sed,用于将现有的标题内容替换为所需的标题内容。如果您不熟悉这些概念,有许多示例说明如何在 bash 脚本中迭代文件(示例)以及如何免费使用 sed(示例)。

    还有一行选项可以替换文件中的字符串。根据您的用例,有些可能比其他更好。根据您文件的内容,简单地用您使用的哪个 shell 替换每个实例可能有意义,也可能没有意义,fs36这fs44也可能与如何最好地编写您的表达式有关。根据文档的复杂性和内容,您可能最好使用sed,perl或者grep甚至是它们的组合。由于这已成为一个编程问题,最好将您推荐给https://stackoverflow.com/questions/15402770/how-to-grep-and-replace,您可以轻松找到 1/2 打不同的方法,其中之一这很可能完全适合您的需求。

    例如,如果您希望在系统范围内应用这些更改,

    find /path/to/files -type f -exec sed -i 's/oldstring/newstring/g' {} \;rezizter提供的可能是最好的。

    如果您希望将更改包含在单个目录中,

    grep -rl matchstring somedir/ | xargs sed -i 's/fs36/fs44/g'由billtian提供是一个很好的选择。

    为了安全起见,您应该对文件进行预处理,以确保您所做的任何更改都不会产生意外后果。例如:

    <!-- language: lang-bash -->
    
        #!/bin/bash
        for f in *.rtf 
            do
            echo $f
            grep fs36
            done
    

    上面将显示包含目录中每个 .rtf 文件的搜索字符串 fs36 的行。

    编辑:

    最新的规范可以在这里获得。我没有看到任何会影响这种方法的变化。

    • 1

相关问题

  • 您在终端上使用什么背景图片?[关闭]

  • 如何安装 LibreOffice?(替换 OpenOffice.org)

  • OpenOffice 和新创建的 LibreOffice 有什么区别?

  • 如何强制面板不在顶部?

  • 如何使以 root 权限启动的非 kde/非 qt 应用程序看起来集成到我的 KDE 桌面中?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve