How to paste deleting the lines

Hi. I often paste text from papers into my LibreOffice Writer documents. It’s all good and nice, however I want to become more efficient doing this. My only problem is that when I paste text like
obraz

It’ll paste exactly how it looks (15 new lines). I always remove them manually. Is there any possibility to just paste it without the “enter” line?

I assume that you are copying from PDF so let’s use your sample but in a pdf, excuse the OCR errors.
HowToPasteDeletingTheLines.pdf (50.1 KB)
So copy and paste the text from the PDF and find that each line ends in a paragraph mark. Some paragraph marks might represent real paragraphs, they would end with a full stop before the paragraph mark. Sometimes it is a co-incidence but that is what a human editor has to spot.

  1. Click Edit > Find & Replace (Ctrl+H)
    1. Tick the box Regular expressions
    2. In the Find field enter \.$ This will find the full stop; the \ lets LibreOffice know that the stop is an actual character, the $ says find only full stops at the end of a paragraph.
    3. In the Replace field enter a character that will not appear in the text, e.g. ¿ for English text. This character will be replaced later
    4. Click Replace All
  2. With the Find and Replace box still open and Regular Expressions still ticked
    1. In the Find field enter $ This will find paragraph breaks
    2. In the Replace field enter a space. This will replace the paragraph marks with a space
    3. Click Replace All
  3. With the Find and Replace box still open
    1. In the Find field enter ¿
    2. In the Replace field enter .\n That is a full stop followed by a paragraph mark
    3. Click Replace All
  4. Check for incorrect paragraph breaks, etc.
2 Likes

Hi. Thanks - excellent solution, works exactly how I wanted it to.

I’ve got one last question, if you don’t mind. Obviously, the approach still takes some time. While with long fragments it is significantly faster, with short pastes it would be not worthwile anymore.
Could you tell me how to automate this process, if this is at all possible? I don’t know much about macros, but I believe they may be the answer?

As a workaround, Draw has a tool that combine text lines: menu Shape - Consolidate Text, and it works pretty well.

1 Like

There could be also Exclamation mark or Question mark (or maybe also Quotation marks) at the end of sentence. So for 1. point → Find ([.!?])$ (or add the Quotation mark to the square brackets) and Replace by $1¿; and for 3. point \n (space + Enter).
The macro is here, I beleive you will find alone how to run a macros :-).

Sub replaceEnters
	dim oDoc as object, oDesc as object
	oDoc=ThisComponent
	oDesc=oDoc.createReplaceDescriptor()
	with oDesc
		.SearchString="([.!?])$" '. or ? or ! and Enter
		.ReplaceString="$1¿" 'end mark and special character for next use
		.SearchRegularExpression=true
	end with
	oDoc.replaceAll(oDesc)
	
	with oDesc
		.SearchString="$" 'Enter
		.ReplaceString=" " 'space
	end with
	oDoc.replaceAll(oDesc)
	
	with oDesc
		.SearchString="¿" 'special character
		.ReplaceString=" \n" 'space + Enter
	end with
	oDoc.replaceAll(oDesc)
End Sub
3 Likes

Thank you. Works perfectly :slight_smile:

Hi there. It’s me once again.

I have one problem with this code. I’d like it to work on selected text, not the entire document. Would you be so kind to fix it? Sorry for the trouble

Unfortunately it is not so easy but test this macro. It is only for one selection, no multiselection via Ctrl.

Sub findReplaceInSelection
	on local error goto bug
	dim oDoc as object, oSel as object, oDesc as object, p(), oFound as object, s$, i&, a&, undoMgr as object, pp()
	const cUndo="F&R in Selection"
	
	const special="¿" 'special character, it is needful also for test at the end vith oVCur !!!
	'arrays with replacements: array(Find, Replace)
	p=array( array("([.!?])$", "$1" & special), array("$", " "), array(special, " " & chr(13)) ) '!!! use only $1, $2 etc. for regex replacement in Replace part !!!
	
	oDoc=ThisComponent
	undoMgr=oDoc.UndoManager 'undo manager
	undoMgr.enterUndoContext(cUndo) 'only one step in Undo
	
	oDesc=oDoc.createReplaceDescriptor()
	with oDesc
		.SearchCaseSensitive=true
		.SearchRegularExpression=true
	end with

	oSel=oDoc.CurrentController.Selection.getByIndex(0) 'current selection (only for one selection, no multiselection via holding by Ctrl)
	
	rem Find&Replace
	for i=lbound(p) to ubound(p)
		with oDesc
			.SearchString=p(i)(0)
			.ReplaceString=p(i)(1)
		end with		
		oFound=oDoc.findNext(oSel.Start, oDesc) 'find 1st occurence in selection
		do while not isNull(oFound)
			a=oDoc.Text.compareRegionEnds(oFound, oSel) 'compare the Ends
			if a<>-1 then 'the occurence is in selection
				pp=getSubreg(oFound.String, p(i)(0))
				if isNull(pp) then 'static replacing
					oFound.string=p(i)(1)
				else 'replace via regular sub-expressions
					oFound.String=replRegString( pp(), p(i)(1) )
				end if
			else
				exit do
			end if
			oFound=oDoc.findNext(oFound.End, oDesc)
		loop
	next i
	
	rem delete special character if it is left at the end of selection
	dim oStart as object, oVCur as object
	oVCur=oDoc.CurrentController.ViewCursor
	oStart=oVCur.Start 'remember the start position of visible cursor	
	oVCur.collapseToEnd
	oVCur.goLeft(Len(special), true)
	if oVCur.String=special then oVCur.String="" else oVCur.goRight(1, false)
	oVCur.goToRange(oStart, true)
	
	undoMgr.leaveUndoContext(cUndo)
	exit sub
bug:
	msgbox(sErr & ": " & sError & chr(13) & "Line: " & sErl & chr(13), 16, "findReplaceInSelection")
End Sub

Function replRegString(p(), sreg$) as string 'replace the $1 in string for found characters; p() is array from function getSubreg
	dim i%
	for i=lbound(p) to ubound(p)
		sreg=replace(sreg, "$" & i+1, p(i))
	next i
	replRegString=sreg
End Function

Function getSubreg(optional s$, optional sreg$) as array 'get all sub-expressions from brackets (aa)(bb)
	dim pole(2), oHledani, oHledaniParam, oNalez, oStart, oEnd, pocet%, i%, a()
	oHledani=CreateUnoService("com.sun.star.util.TextSearch") 
	oHledaniParam=CreateUnoStruct("com.sun.star.util.SearchOptions")
	With oHledaniParam
	  .algorithmType=com.sun.star.util.SearchAlgorithms.REGEXP
	  .searchString=sreg 'regular expression
	End With
	oHledani.setOptions(oHledaniParam)
	oNalez=oHledani.searchForward(s,0,len(s)) 'search string from start to end
	oStart=oNalez.startOffset() 'array with starts of sub-expressions
	oEnd=oNalez.endOffset() 'array with ends of sub-expressions
	rem get sub-expressions
	pocet=oNalez.subRegExpressions()-1
	if pocet<1 then exit function '-1= no found; 0=no subexpressions
	redim a(pocet-1) 'output array
	for i=1 to pocet
		a(i-1)=Mid(s,oStart(i)+1,oEnd(i)-oStart(i)) 'the characters from sub-expression
	next i
	getSubreg=a()
End Function

The details of problems: There isn’t command for regexp F&R only in Selection :-(. It is not problem to find all occurences in Selection with regex searching, but the problem is to replace these occurences with regex replacing. It need the method com.sun.star.util.TextSearch to get sub-expressions from brackets like (aa)(bb) and put ones to replacements instead $1,$2 etc. And this procedure could be complicated, but it seems it is functional.


Safe solution is copy the selected part to new document, use replaceAll and paste it back, but it will be slower.

That’s what I’m going to probably do :wink:

The code you gave throws errors.

Thanks anyways for your effort. I appreciate that a lot, the solution with copying from the different document still works wonders and I couldn’t ask for me.

The searching via com.sun.star.util.TextSearch really isn’t easy to use. I haven’t any example ODT with your data, so I tested only some short dummy data: example.odt (13.8 kB)

Macro via Temporary file, there are replacements in array p() from: How to paste deleting the lines - #7 by KamilLanda

Sub copyPasteSelectionViaTemp 'copy the selection to the temporary file, replace the substitutions and paste it back to selection
	on local error goto bug
	dim oDoc as object, oSel as object, oDocTemp as object, oCurTemp as object, data as object
	oDoc=ThisComponent
	oSel=oDoc.CurrentController.Selection.getByIndex(0) 'current simple selection (no multiselection via Ctrl)
	rem copy Selection from original
	data=oDoc.CurrentController.getTransferableForTextRange(oSel)
	rem Paste selection to Temp
	dim prop(0) as new com.sun.star.beans.PropertyValue
		prop(0).Name="Hidden" : prop(0).Value=True 'open as hidden
	oDocTemp=StarDesktop.LoadComponentFromUrl("private:factory/swriter", "_blank", 0, prop()) 'temporary file
	oCurTemp=oDocTemp.Text.createTextCursor
	oDocTemp.CurrentController.insertTransferable(data)
	
	rem Temp
	dim oDesc as object, i%, p()
	p=array( array("([.!?])$", "$1¿"), array("$", " "), array("¿", " \n") ) 'replacements
	rem replace in Temp
	oDesc=oDoc.createReplaceDescriptor()
	with oDesc
		.SearchRegularExpression=True
		.SearchCaseSensitive=True
	end with
	rem replacing in Temp
	for i=lbound(p) to ubound(p)
		with oDesc
			.SearchString=p(i)(0)
			.ReplaceString=p(i)(1)
		end with
		oDocTemp.replaceAll(oDesc)	
	next i
	rem select all in Temp
	oCurTemp.goToStart(false)
	oCurTemp.goToEnd(true)
	oDocTemp.CurrentController.Select(oCurTemp)
	oSel=oDocTemp.CurrentController.Selection.getByIndex(0) 'current simple selection (no multiselection via Ctrl)
	data=oDocTemp.CurrentController.getTransferableForTextRange(oSel)
	
	rem Paste to original
	oDoc.CurrentController.insertTransferable(data)
bug:
	if NOT isNull(oDocTemp) then oDocTemp.close(true)
End Sub

Try the options under Edit > Paste Special > Paste Special …

I always paste using this approach. It’ll remove many issues with font ambiguity, but does nothing on the “new lines” issue.