Seite 1 von 2

[gelöst] [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Do 8. Sep 2022, 16:25
von tmp
Hallo,

ich habe einen Text mit vielen leeren Zeilen drin. Das sieht dann z.B. wie folgt aus:

(An dieser Position ist ein Bild eingefügt, das im Hintergrund liegt. Der Text ist also über dem Bild.


Lorem ipsum¶
Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.¶



Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.¶




Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.¶


(An dieser Position befindet sich ein Seitenumbruch)


Drei Absatzumbrüche hintereinander (¶¶¶) sollen nun durch zwei Absatzumbrüche hintereinander (¶¶) ersetzt werden, und zwar so lange, bis es nur noch zwei Absatzumbrüche hintereinander (¶¶) gibt. Der Text würde dann wie folgt aussehen:

(An dieser Position ist ein Bild eingefügt, das im Hintergrund liegt.)

Lorem ipsum¶
Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.¶

Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.¶

Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.¶
(An dieser Position befindet sich ein Seitenumbruch)


In Word ist das schnell erledigt, indem man einfach ^p^p^p durch ^p^p ersetzt (ersetzt drei Absatzumbrüche hintereinander durch zwei Absatzumbrüche hintereinander).

In LibreOffice geht das leider nicht so.

Mit der Erweiterung AltSearch kann ich zwar leere Absätze hintereinander durch einen leeren Absatz ersetzen, allerdings verschwindet dann auch das Bild und der Seitenumbruch.

Ich überlege daher gerade, über das Abgrasen der Absätze zu gehen:

Code: Alles auswählen

Sub test_paragraph

Dim Doc As Object
Dim Enum1 As Object
Dim Enum2 As Object
Dim TextElement As Object
Dim TextPortion As Object

Doc = ThisComponent
Enum1 = Doc.Text.createEnumeration()

'loop over all paragraphs
While Enum1.hasMoreElements
	TextElement = Enum1.nextElement
	If TextElement.supportsService("com.sun.star.text.Paragraph") Then
		Enum2 = TextElement.createEnumeration
		'loop over all sub-paragraphs
		While Enum2.hasMoreElements
			TextPortion = Enum2.nextElement
			If TextPortion.String = "" Then
				MsgBox "empty"
			Else
				MsgBox "'" & TextPortion.String & "'"
			End If
		Wend
	End If
Wend

End Sub
Allerdings weiß ich nicht, ob ich damit das Bild und den Seitenumbruch erkennen kann. Auch weiß ich nicht, wie ich den leeren Absatz dann löschen kann, da Enum2 leider keine Auflistung der gefundenen Elemente liefert.

Habt ihr Ideen, was ich noch probieren könnte?

---

edit: Code korrigiert ("a = Enum2.Element" entfernt)

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Do 8. Sep 2022, 18:06
von Freischreiber
Du mußt nach regulären Ausdrücken suchen. Ein Absatzende sucht man mit dem regulären Ausdruck: $
Einsetzen muß man Absatzenden jedoch mit dem regulären Ausdruck: \n

Ausprobiert habe ich es jetzt nicht, aber das ist das Prinzip.

Edit: Hm, mehrere Absatzmarken findet Writer so nicht. Da hilft wohl nur das hier:
https://extensions.libreoffice.org/exte ... for-writer

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Do 8. Sep 2022, 18:51
von miesepeter
@tmp
Ist es nicht möglich, ein (anonymisiertes) odt-Dokument zur Verfügung zu stellen, so dass man mit AltSearch.oxt selbst daran herumprobieren kann?

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Do 8. Sep 2022, 20:55
von tmp
Da hilft wohl nur das hier:
Wie geschrieben, habe ich AltSearch schon ausprobiert und es hat leider nicht so funktioniert wie gedacht. :-(

@miesepeter: Eine Datei zum Austoben habe ich hochgeladen. :-)

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 08:53
von miesepeter
@tmp
Ist ja ein geiles Beispiel. Mit Hilfe von AltSearch.oxt und SUCHEN&ERSETZEN konnte ich auch keine befriedigende Lösung finden.

Eine mögliche Vorgehensweise wäre, den Absatz mit dem Seitenumbruch auf eine andere Absatzvorlage umzuformatieren und mit etwas Text zu versehen (wäre automatisiert machbar). Dann wäre mein nächster Schritt, die CONTENT.XML mit SUCHEN&ERSETZEN zu bearbeiten. Habe ich aber nicht probiert, vielleicht hilft dir der Tipp aber...?

Ciao und viel Erfolg

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 15:34
von musikai
Meiner Ansicht nach erfordert es ein recht kompliziertes Macro wegen der Bilder.
Um herauszufinden, ob ein Bild an einer bestimmten Textstelle verankert ist, muss man jeden einzelnen Anker aller Bilder vergleichen, ob er innerhalb des Bereichs eines Textcursors steht.
Hier ein kleines Macro zum Testen ob in einer leeren Zeile ein Bild veranker ist und ob ein Umbruch vorhanden ist:

Code: Alles auswählen

sub Bild_oder_Umbruch_an_Cursor_Stelle
oDoc = ThisComponent
oText = oDoc.Text
oRange = oDoc.currentSelection(0)
g = oDoc.CurrentSelection(0)
  
go = oDoc.getGraphicObjects
For i = 0 to go.Count-1
	g = go.getByIndex(i)

	rem Vergleich ob der kollabierte Cursor (Länge 0) mit dem Anker eines Bildes übereinstimmt.
	if len(oRange.getstring())=0 AND oText.compareRegionStarts(g.anchor, oRange)=0 then
	  	msgbox g.name
	end if
	
	
next

rem  kein Seitenumbruch = 0
rem  Seitenumbruch "vor" = 4
rem  Seitenumbruch "danach" = 5
msgbox oRange.BreakType

end sub
Man läßt einen Textcursor durchs ganze Dokument laufen (weiss nicht ob man in einen enumerierten Absatz springen kann, glaube aber nicht) und muss sich gut überlegen wie man die Zählung und das Löschen vornimmt. Löschen eines Absatzes-Umbruchs ginge durch Einfügen von "" nachdem man den cursor um eine Stelle in den nächsten oder vorherigen Absatz erweitert hat.

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 19:13
von tmp
Danke für eure Antworten.

@miesepeter: Das behalte ich mal im Kopf, falls alle anderen Stricke reißen. :-)

@musikai: Ich habe jetzt mal folgendes zusammengebaut:

Code: Alles auswählen

Sub test_paragraph

Dim Doc As Object
Dim Enum1 As Object
Dim Enum2 As Object
Dim TextElement As Object
Dim TextPortion As Object
Dim ViewCursor As Object
Dim Document   As Object
Dim Dispatcher As Object
Dim i As Integer, j As Integer, k As Integer

Doc = ThisComponent
Enum1 = Doc.Text.createEnumeration()
Document = Doc.CurrentController.Frame
Dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
ViewCursor = ThisComponent.getCurrentController().getViewCursor()

Call replace_whitespaces

i = 0 'counts the paragraphs
j = 0 'counts the sub-paragraphs
k = 0 'counts the empty paragraphs; if k > 1, the paragraph will be deleted; if the paragraph is not empty, k will be resetted to 0

'loop over all paragraphs
While Enum1.hasMoreElements
	TextElement = Enum1.nextElement
	i = i + 1
	If TextElement.supportsService("com.sun.star.text.Paragraph") Then
		Enum2 = TextElement.createEnumeration
		'loop over all sub-paragraphs
		Do While Enum2.hasMoreElements
			TextPortion = Enum2.nextElement
			j = j + 1
			If j = 1 Then
				If TextPortion.String = "" Then
					k = k + 1
				Else
					k = 0
				End If
			ElseIf j > 1 Then	
				k = 0
				Exit Do
			End If
		Loop
		If k = 2 Then
			ViewCursor.gotoRange(TextElement, false)
			Dispatcher.executeDispatch(Document, ".uno:Delete", "", 0, Array())
		End If
		j = 0
	End If
Wend

MsgBox s

End Sub

'===========

Sub replace_whitespaces

Dim Doc As Object
Dim Replace As Object

Doc = ThisComponent
Replace = Doc.createReplaceDescriptor
Replace.SearchRegularExpression = True
Replace.SearchString = "^\s*$"
Replace.ReplaceString = ""
Doc.replaceAll(Replace)

End Sub
Funktioniert alles, nur das "Dispatcher.executeDispatch(Document, ".uno:Delete", "", 0, Array())" wird nicht ausgeführt. Ich dachte eigentlich, dass dort wo der Cursor ist, die Zeile dann gelöscht wird, aber das passiert nicht, obwohl der folgende Code funktioniert:

Code: Alles auswählen

Sub delte_paragraph

Dim Document As Object
Dim Dispatcher As Object

Document = ThisComponent.CurrentController.Frame
Dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Dispatcher.executeDispatch(document, ".uno:Delete", "", 0, Array())

End Sub
Wie kann ich dem dem Programm sagen, dass es die Zeile, in welcher der Cursor steht, löschen soll?
Löschen eines Absatzes-Umbruchs ginge durch Einfügen von "" nachdem man den cursor um eine Stelle in den nächsten oder vorherigen Absatz erweitert hat.
Wie mache ich das? Über eine Selection?

---

edit: "Document = Doc.CurrentController.Frame" ergänzt

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 19:25
von karolus
wie du am aufgezeichneten Code erkennen kannst, benötigt Dispatcher.executeDispatch als erstes Argument thisComponent.CurrentController.Frame und nicht nur thisComponent

wobei… du hast ja lediglich Document als object dimensioniert, aber sonst nirgends ein reales Object zugewiesen :roll: das solltest du nachholen:

Code: Alles auswählen

Document = doc.Current.Controller.Frame

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 19:46
von tmp
@karolus. Huch, die Zuweisung muss ich versehentlich gelöscht haben. Sorry. Ich habe sie im Code nachgetragen.

Allerdings bleibt auch damit das Problem bestehen, dass das Löschen der Zeile nicht ausgeführt wird. :-(

Re: [Writer] Absatzumbruch (¶) ersetzen

Verfasst: Fr 9. Sep 2022, 21:04
von karolus
Ups oben ist ein Punkt zuviel, das sollte lauten:

Code: Alles auswählen

Document = doc.CurrentController.Frame