How to find/replace with hyperlinks in Writer

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
leuce2
Posts: 5
Joined: Fri Jan 30, 2009 3:04 pm

How to find/replace with hyperlinks in Writer

Post by leuce2 »

G'day everyone

I have a Writer document with hyperlinks in it. I would like to add ">> " in front of every hyperlink in the document. I suspect it would have to be done using a macro. I thought that I might be able to use find/replace but there doesn't seem to be a hyperlink "style" to select. Does anyone know how to do this? I'm talking about multiple documents with many hyperlinks in them.

Please note, I don't want to add ">> " to the actual text of the hyperlink -- I want to add that to the piece of normal text before the hyperlink (or, if the hyperlink is at the start of a line/paragraphy, then create normal text before it and put the ">> " there).

Any ideas for doing this?

Thanks
Samuel
OOo 2.3.X on Ms Windows XP
leuce2
Posts: 5
Joined: Fri Jan 30, 2009 3:04 pm

Re: How to find/replace with hyperlinks in Writer

Post by leuce2 »

I forgot to say... Windows XP with OOo 3.0.
OOo 2.3.X on Ms Windows XP
leuce2
Posts: 5
Joined: Fri Jan 30, 2009 3:04 pm

Re: How to find/replace with hyperlinks in Writer

Post by leuce2 »

explanation.odt
(15.95 KiB) Downloaded 592 times
Sorry for my third post -- here is an OOo Writer file, attached, that explains it better.
OOo 2.3.X on Ms Windows XP
sqykly
Posts: 27
Joined: Mon Nov 24, 2008 8:28 am

Re: How to find/replace with hyperlinks in Writer

Post by sqykly »

I'm not 100% sure how OOo handles hyperlinks, so someone will have to fill in some blanks, or you could look at the IDL, but I'm certain that you can find the hyperlinks with a text portion "enumeration". When you create an enumeration of a whole document, you get paragraphs as elements, which isn't all that useful, but if you further enumerate a paragraphs, you get text portions. Any conceivable difference from one character to the next, including general format and appearance, as well as being part of a textfield, gets its own text portion, so the hyperlinks will be set aside from the rest of the text. Your code (in Basic) would look something like:

Code: Select all

sub markHyperlink
dim oParaEnum as object
dim oPortEnum as object
dim oPara as object
dim oPort as object

oParaEnum = thisComponent.text.createEnumeration()

do while oParaEnum.hasMoreElements()
oPara = oParaEnum.nextElement

if oPara.supportsService("com.sun.star.text.Paragraph") then
rem if you're sure you'll never use a table for whatever reason, you can get rid of this if clause
oPortEnum = oPara.createEnumeration

do while oPortEnum.hasMoreElements()
oPort = oPortEnum.nextElement()

if isHyperlink(oPort) then
rem please note that 'isHyperlink()' is a stand in for however you end up determining whether something is a hyperlink
thisComponent.text.insertString(oPort.getStart(), ">>", false)
endif

loop

loop

end sub
The best case for you, actually, would be if OOo keeps a master list of hyperlinks like it does for certain types of text content. I can't tell you offhand, but you can find out in the IDL reference, and I'll bet it's a no. The code above will work either way, but if you can get something like thisComponent.hyperlinks, it will run faster.

One more thing I'm unsure on: whether the ">>" will be included as part of the hyperlink. I'm guessing that, if OOo is treating the hyperlink as a text content object rather than a style or something over normal text, it will be separate from the link.

And that's what I know. Check the IDL reference if no one coughs up some information on how to determine which text portions are hyperlinks.
OOo 3.0.X on Ms Windows XP
sqykly
Posts: 27
Joined: Mon Nov 24, 2008 8:28 am

Re: How to find/replace with hyperlinks in Writer

Post by sqykly »

Okay, I went ahead and checked the IDL myself. Those text portions support the TextRange service, which further includes the service CharacterProperties, from which you can access a hyperlink's target, name, and url. With the code I gave you above:

Code: Select all

function isHyperlink(oTextPortion as object) as boolean
with oTextPortion
if .hyperlinkTarget = "" and .hyperlinkName = "" and .hyperlinkURL = "" then
isHyperlink = false
else
isHyperlink = true
endif
end with
end function
The only caveat here is that I haven't tried this, and that those properties are listed as optional for the CharacterProperties service. If the text portion has opted out of this property, then you'll get a runtime error (in Basic, it won't crash OOo or anything). I don't see why that would be the case, but I've seen too many screwy object organization schemes in OOo to rule it out. Can't hurt to give it a try, anyway.
OOo 3.0.X on Ms Windows XP
lyndonhood1
Posts: 1
Joined: Fri Jan 27, 2017 2:12 am

Re: How to find/replace with hyperlinks in Writer

Post by lyndonhood1 »

Hi!

I've been interested in this for some years because we convert a lot of emailed text to clean HTML formatted and it was handy to have a non-proprietary option. I was using a version of the solution above, which was useful but skips any text inside tables. There is a lot of text inside tables.

Anyway, just now, looking at some stuff for other text formatting, I realised if you use the search you can get at all the bits of text in the doc. You still have to do all the enumerations to the results as above, and getting it right was a bit trial and error, but this seems to work.

So: the below seems to find every linked piece of text and replace it with (non-linked) HTML anchor code.

Note this refers to the isHyperlink function pasted above. Apologies for the coding faux pas.

Code: Select all

Sub LinkLink

oDoc = ThisComponent
    Dim vDescriptor, vFound, vFind, vPort, vPara, vElEnum
    ' Create a descriptor from a searchable document.
    vDescriptor = oDoc.createSearchDescriptor()
    ' Set search for any text 
    With vDescriptor
      .searchString = ".*"
      .searchAll=True
      .SearchRegularExpression=True
    End With
    ' Get search results
    vFind = oDoc.findAll(vDescriptor)
    
    Dim n
    'iterate through search results
    For n = 0 to (vFind.getcount-1)
	   	vFound = vFind.getByIndex(n)
	   	vParaEnum = vFound.Text.createEnumeration()
	   	' this apparently gives an enumeration of search results as paragraphs, but one which includes paras inside tables
	   	
	   	do while vParaEnum.hasMoreElements()
			vPara = vParaEnum.nextElement()
						
			if vPara.supportsService("com.sun.star.text.Paragraph") then
				vElEnum = vPara.createEnumeration()
				' enumeration of text elements - hyperlinks will each have their own
				do while vElEnum.hasMoreElements()
					vEl = vElEnum.nextElement()
					if isHyperlink(vEl) then
						rem do link tags
						rem should check for internal links, anchors but doesn't
						theText = vEl.String
						theLink = vEl.hyperlinkURL
						theName = vEl.hyperlinkName
						if theName = "" then
							vEl.String="<a href=""" + theLink + """>" + theText + "</a>"
						else
							vEl.String="<a href=""" + theLink + " name=""" + theName + """>" + theText + "</a>"
						endif
					endif
				loop
	   		endif
	   	Loop
	   	
	next n

End Sub
Win 7 / LibreOffice 5.2.4.2
Post Reply