동일한 스타일 / 포맷을 갖도록 2 개 이상의 LibreOffice 문서를 변경하십시오.


14

.rtfLibreOffice 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로 가능할까요?


3
이것은 내가 생각하기 쉬운 일이 아닙니다. 그것들이 모두 같은 방식으로 구성된다면, 명령 행에서 .rtf 파일의 텍스트를 대체하는 해키 솔루션을 사용할 수 있습니다. 그러나 이것은 rtf 파일의 모양과 유사성에 따라 달라집니다.
Sebastian Stark

오늘부터 처음부터 완전히 새로운 LibreOffice Writer 매크로에 대한 Stack Overflow의 도움말을 찾았습니다. 더 이상 가능한 모든 기존 글꼴 크기를 알 필요가 없습니다.
WinEunuuchs2Unix

마지막 도랑 노력에서 나는 유예 기간이 종료되기 전에 여기에 대한 답변을 게시하는 스택 오버플로 전문가를 요청했습니다 : stackoverflow.com/questions/49640951/...
WinEunuuchs2Unix

여러분은 수만 점의 평판을 가지고 있습니다. 겸손하게 500-750과 같은 것을주는 것이 좋습니다. 그냥 고려 해봐 그냥 그냥
JohnDoea

답변:


5

CLI 대신 Libreoffice 도구 사용

명령 줄 도구 만 있으면 모든 것이 명령 줄 문제처럼 보입니다. LibreOffice 매크로를 사용하여이 답변을 작성하기로 결정했습니다.

  1. "headless"환경에서 모든 Writer 문서를 처리하려면 명령 행 루프를 사용하십시오.
  2. 매크로를 실행하여 .rtf(Rich Text Format) 작성기 문서 파일 을 변경 하십시오.
  3. 매크로는 파일을 저장하고 종료합니다
  4. 1로 되돌아갑니다.

테스트 데이터 생성

다음을 포함하는 둘 이상의 파일을 작성하십시오.

richtext2.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 응답을 사용 하여 명령 줄에서 Libreoffice Writer를 호출하고 실행할 전역 매크로 이름을 전달하십시오.

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

위의 답변이 작동하지 않아 다른 방법 을 시도해 볼 수 있습니다.

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

Java Runtime Environment 설치

매크로를 실행하려면 JRE (Java Runtime Environment)가 설치되어 있어야합니다. 개발자의 웹 페이지에는 수동으로 다운로드하고 설치 하기 위한 지침 이 있습니다.

그러나이 AU Q & A : /ubuntu//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를 추가하는 첫 단계 후에 추가 정보가 포함 된 스플래시 화면이 나타납니다. 가장 유용한 것은 데비안 시스템에서 JRE 8설정 하는 링크 입니다.

JRE 8을 설치하는 세 번째 단계 에서는 라이센스 계약 을 사용 Tab하고 Enter동의 해야합니다 . 설치 루틴 중 가장 많은 시간 동안 기계가 몇 분 동안 일시 정지됩니다.

이제 LibreOffice를 열고 도구 -> 옵션 -> LibreOffice- > 고급 을 선택하고이 화면을 설정하십시오.

LO JRE8 고급 설정 .png

다음에 대한 옵션을 클릭하십시오.

  • Java 런타임 환경 사용
  • Oracle Corporation 1.8.0_161
  • 매크로 기록 사용 (실험)
  • 확인을 클릭하십시오
  • 다시 시작하라는 메시지가 표시되면 "지금 다시 시작"을 클릭하십시오.

LibreOffice Writer 매크로

매크로는 전체 문서를 읽고 다음을 수행합니다.

  • 글꼴 이름을 Ubuntu로 변경하십시오.
  • 제목 1이 글꼴 크기를 28로 설정 한 경우
  • 글꼴 크기가 18 인 경우 22
  • 그렇지 않으면 글꼴 크기를 12로 설정하십시오.

매크로는 문서를 저장하고 Libreoffice Writer를 종료합니다.

대화 상자 끄기

파일을 저장하면이 대화 상자가 나타납니다.

LO Writer RTF 대화 상자 끄기

화면에 표시된대로이 메시지를 끄십시오. 이 옵션이 켜져 있으면 매크로가 제대로 실행되지 않을 수 있습니다.

매크로 내용

"도구"-> "매크로"-> "매크로 기록"-> "기본"을 사용하여 매크로를 기록하려고 며칠을 보냈습니다. 처음에는 유망한 것처럼 보였지만 기록 된 매크로는 일관되지 않은 동작을했으며 손으로 쓴 기본 매크로를 위해 버려 져야했습니다. 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

2

Libre Office를 사용한 일회성 접근 방식은 다음과 같습니다. 일괄 처리는 아니지만 다른 답변에 도움이 될 수 있습니다.

Ubuntu 글꼴, 28pt의 H1, 12pt의 텍스트 및 18pt의 텍스트를 가진 rtf 파일을 엽니 다.

예를 들면 다음과 같습니다.

테스트 RTF

다음 단계는 "글꼴 크기 인 경우 : 18px {make it 22px} # 글꼴 크기가 18px 인 모든 텍스트는 이제 22px입니다."라는 질문에 요청 된 변경 사항을 적용합니다.

메뉴에서 편집 → 찾기 및 바꾸기를 CtrlH클릭 하거나 기타 옵션을 클릭하십시오. 검색 상자를 클릭 한 다음 속성 버튼 글꼴 크기 확인란을 클릭 한 다음 형식 버튼 맨 오른쪽의 스크롤 상자에서 18pt를 선택하십시오. 상자로 바꾸기를 클릭 한 다음 형식 버튼에서 22pt를 선택하십시오 맨 오른쪽 스크롤 상자

찾기

모두 바꾸기를 클릭하십시오.

변경된 해당 라인은 다음과 같습니다.

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

fs36이 fs44로 변경되었습니다

변경된 유일한 다른 필드는 업데이트하거나 원하지 않는 revtime 필드입니다.

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

변경된 사항을 알면 배치 방식을 개발하기위한 모델이 제공됩니다. 문서를 열 때이를 수행하거나 원하는대로 변경하는 스크립트를 개발하는 매크로를 기록 할 수 있습니다.


1

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 ( 예제 )를 자유롭게 사용 하는 방법에 대한 많은 예가 있습니다.

파일에서 문자열을 바꾸는 한 줄 옵션도 있습니다. 사용 사례에 따라 일부는 다른 것보다 잘 작동 할 수 있습니다. 파일의 내용에 따라 그것은 나 간단한에 감각의 모든 인스턴스 대체하지 않을 수도 있습니다 fs36와 함께 fs44당신은 또한 당신의 식을 작성하는 최선의 방법에 베어링이있을 수 있습니다 사용하는 쉘 어느. 복잡성과 문서의 내용에 따라 사용하여 더 나을 수있다 sed, perl또는 grep아마 그들도 조합 또는. 이것은 프로그래밍 질문됨에 따라 그것은 당신을 참조하는 것이 가장 /programming/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
안녕하세요. CLI 솔루션을 먼저 설명해 주셔서 감사합니다. rtf제목과 텍스트를 사용하여를 변경하는 방법에 대한 코드 예제를 공유 sed하여 답변을 중앙 집중화하십시오 sed.
JohnDoea

@JohnDoea 항상 도와주고 싶어합니다. 나는 당신과 미래의 사용자 모두가 유용하다고 생각합니다.
Geek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.