Preventing / finding broken internal links to chapter headings

asked 2016-06-01 12:05:35 +0100

Júlio Reis gravatar image

updated 2016-06-10 13:14:49 +0100

Hello all. I see that when linking to chapter headings in LO Write, it sometimes loses track of which chapter heading it’s supposed to link to. I only found out about this yesterday, but it apparently cannot keep up with much messing around with headings, e.g. moving and renaming headings around the document. I’ll see if I can replicate the issue, but right now I’m a little worried about fixing my own document (+150 pages, hundreds of links).

So:

  1. How may I prevent breaking more links? Is there some behaviour I should be avoiding?
  2. How may I find broken internal links? An extension, a script in any language… please! Alex Kemp is onto something – https://ask.libreoffice.org/en/question/51794/utilities-to-fix-broken-hyperlinks/ – but it’s not working well for me. Also, it’d be better if this were a LO add-on, which could take me to where the broken links are; or the next broken link, starting from the current cursor position.

EDIT: I started writing a macro. When generating the list of anchors, I need to access the outline numbering for headings. And I need to open the hyperlink editor on the current text portion.

Option Explicit

' PrintArray displays a MsgBox with the whole array
' for DEBUG purposes only
Sub PrintArray(sTitle as String, theArray() as String)
    Dim sArray, i, iStart, iStop
    sArray = sTitle & ":"
    iStart = LBound(theArray)
    iStop = UBound(theArray)
    If iStart<=iStop then
        For i = iStart to iStop
            sArray = sArray & Chr(13) & theArray(i)
        Next
    End if
    MsgBox(sArray, 64, "***DEBUG")
End sub

' auxiliary sub for BuildAnchorList
Sub AddItemToAnchorList (oAnchors() as String, sTheAnchor as String, sType as String)
    Dim sAnchor
    Select Case sType
        Case "Heading":
            sAnchor = "#" + sTheAnchor + "|outline"
        Case "Table":
            sAnchor = "#" + sTheAnchor + "|table"
        Case "Text Frame":
            sAnchor = "#" + sTheAnchor + "|frame"
        Case "Image":
            sAnchor = "#" + sTheAnchor + "|graphic"
        Case "Object":
            sAnchor = "#" + sTheAnchor + "|ole"
        Case "Section":
            sAnchor = "#" + sTheAnchor + "|region"
        Case "Bookmark":
            sAnchor = "#" + sTheAnchor
    End Select
    ReDim Preserve oAnchors(UBound(oAnchors)+1) as String
    oAnchors(UBound(oAnchors)) = sAnchor
End Sub

' auxiliary sub for BuildAnchorList
Sub AddArrayToAnchorList (oAnchors() as String, oNewAnchors() as String, sType as String)
    Dim i, iStart, iStop
    iStart = LBound(oNewAnchors)
    iStop = UBound(oNewAnchors)
    If iStop < iStart then Exit Sub ' empty array, nothing to do
    For i = iStart to iStop
        AddItemToAnchorList (oAnchors, oNewAnchors(i), sType)
    Next
End Sub

Function BuildAnchorList()
    Dim oDoc as Object, oAnchors() as String
    oDoc = ThisComponent

    ' get the whole document outline
    Dim oParagraphs, thisPara, oTextPortions, thisPortion
    oParagraphs = oDoc.Text.createEnumeration ' all the paragraphs
    Do While oParagraphs.hasMoreElements
        thisPara = oParagraphs.nextElement
        If thisPara.ImplementationName = "SwXParagraph" then ' is a paragraph
            If thisPara.OutlineLevel>0 Then ' is a heading
                ' ***
                ' *** TO DO: How do we get the numbering for each heading?
                ' For example, if the first level 1 heading text is “Introduction”,
                ' the correct anchor is `#1.Introduction|outline`
                ' and we are recording `Introduction|outline`
                ' ***
                AddItemToAnchorList (oAnchors, thisPara.String, "Heading")
            End if
        End if
    Loop
    ' text tables, text frames, images, objects, bookmarks and text sections
    AddArrayToAnchorList(oAnchors, oDoc.getTextTables().ElementNames, "Table")
    AddArrayToAnchorList(oAnchors, oDoc.getTextFrames().ElementNames, "Text ...
(more)
edit retag flag offensive close merge delete