Reporting Writer Annotation contents

Writing a book, Automating Document Production - Discuss your special needs here
Post Reply
User avatar
RoryOF
Moderator
Posts: 35055
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Reporting Writer Annotation contents

Post by RoryOF »

I am trying to enumerate all Annotations (formerly Comments) in a Writer document. I am able to do this using the macro code listed below.

I have only one problem. No matter where in the document I invoke the macro, it returns the first Annotation of the document, then the last, second-last, third-last etc. Is there any way to make it return the Annotations either in ascending or descending order? This would obviate having to write some code to handle the "out of place" first Annotation.

For the present I display the Annotation contents using a messagebox. When (if) I have their retrieval in sequential order, either ascending or descending, I will do further processing with the contents.

Code: Select all

Sub ListAnnotes

Rem Report the content of  all Annotations in a Writer document

Dim oDoc as Object
Dim oEnum as Object
Dim oField as Object
Dim oText as String ' do not Dim as Object or Variant

oDoc = ThisComponent
oEnum = oDoc.getTextFields().createEnumeration()

If Not IsNull(oEnum) Then
    Do While oEnum.hasMoreElements()
        oField = oEnum.nextElement()
        If oField.supportsService("com.sun.star.text.TextField.Annotation") Then
            oText = oField.Content
            Msgbox "Annotation content is : " + oText
        End If
    Loop
End If

End Sub 'ListAnnotes

Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Reporting Writer Annotation contents

Post by hubert lambert »

Hi RoryOF,

Strange behavior indeed, that still exists within LibreOffice.
One way to workaround it would be to sort the field anchors before displaying their content, as in the following example.
Caveat: this only work if all annotations are in the same text object, i.e. not in frames or tables...

Code: Select all

Sub ListAnnotes

Rem Report the content of  all Annotations in a Writer document

Dim oDoc as Object
Dim oEnum as Object
Dim oField as Object
Dim oText as String ' do not Dim as Object or Variant

    oDoc = ThisComponent
    textfields = oDoc.getTextFields()
    oEnum = textfields.createEnumeration()
    
    dim anchors()

    If Not IsNull(oEnum) Then
        Do While oEnum.hasMoreElements()
            oField = oEnum.nextElement()
            If oField.supportsService("com.sun.star.text.TextField.Annotation") Then
                addanchor(anchors, oField.anchor)
            End If
        Loop
        sortanchors(anchors)
        dim notes(ubound(anchors))
        for n = 0 to ubound(anchors)
            msgbox anchors(n).TextField.Content
        next n
    End If
End Sub 'ListAnnotes

sub addanchor(anchors, anchor)
    u = ubound(anchors)+1
    redim preserve anchors(u)
    anchors(u) = anchor
end sub

sub sortanchors(sortlist())
    ' adapted from AOO Tools macro BubbleSortList
    txt = sortlist(0).Text
    i = ubound(sortlist(),1)
    for s = 1 to i - 1
        for t = 0 to i-s
            if txt.compareRegionStarts(sortlist(t+1), sortlist(t)) = 1 then                             
                displaydummy = sortlist(t)
                sortlist(t) = sortlist(t+1)
                sortlist(t+1) = displaydummy    
            end if
        next t
    next s
end sub
Regards.
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
User avatar
RoryOF
Moderator
Posts: 35055
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Reporting Writer Annotation contents

Post by RoryOF »

I will try your code later today, Hubert.

For various reasons, it would be most convenient if the Annotations were returned in document order. That would greatly simplify some of the processing I would like to do with them and avoid having to pass through the document to count the number of Annotations, before once again having to pass through to retrieve, modify, and rewrite any modified Annotations.

An Annotation does not appear to have an index or any location in the document other than its anchor. Early today I found some code by Andrew Pitonyak processing other enumerations in a Writer document which, if it is applicable to Annotations (not yet tested) might change their return order to ascending.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
User avatar
RoryOF
Moderator
Posts: 35055
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Reporting Writer Annotation contents

Post by RoryOF »

That works nicely, Hubert. Thank you. I will now have to consider how I can integrate your method with my project, but will have to pause on that for a few days because of other commitments.

If anyone else has suggestions on a direct method of retrieving the enumeration of Annotations in proper ascending or descending order, their suggestions would be welcome.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

Enumerate the paragraphs and text portions of each paragraph (as Pitonyak)

Look for TextPortionType = "Annotation" then the TextField of that Portion is the Comment.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
RoryOF
Moderator
Posts: 35055
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Reporting Writer Annotation contents

Post by RoryOF »

Thanks, JeJe. I've had to pause my project for a few days (medical tests), but I will return to it shortly.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

Writer must have a list of Comments ordered as they appear in the document internally - as it displays them this way in the Navigator. Its the same with other Navigator items like Sections - we're given access to the list of items - but not in the way we want, in the order they appear in the document.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

The exception is bookmarks. They're listed in the navigator in alphabetical order, but usefully (unless you need that) they're listed in the order they appear in the document in ThisComponent.bookmarks. That means if you want access to a list of objects as they appear in the document you can bookmark them as a workaround.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
_savage
Posts: 198
Joined: Sun Apr 21, 2013 12:55 am

Re: Reporting Writer Annotation contents

Post by _savage »

Thank you for the useful hints!

FWIW, the following works for me (pseudo code):

Code: Select all

texts = par.createEnumeration()
while texts.hasMoreElements():
    text = texts.nextElement() 
    if text.TextPortionType == 'Annotation':  # Or 'AnnotationEnd' for the span.
        # text.getString() seems always empty for 'Annotation', it's just a marker/anchor, I guess.
        field = text.TextField  # As per JeJe's comment implements the Annotation service, does not exist for 'AnnotationEnd'.
        comment = field.Content
See also the Annotation service (as per Hubert’s suggestion).

I also assume that there always must be an 'AnnotationEnd' type portion paired with an 'Annotation' type portion? That would make sense to establish the text that’s spanned by a comment (which might span multiple paragraphs, etc.)
Mac 13.7 using LO 24.8.2.1, Ubuntu Linux using LO 24.8 headless.
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

There's no AnnotationEnd if the Annotation is just at one point.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

For the text of the Annotation look at the TextRange property of the Annotation portion.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
_savage
Posts: 198
Joined: Sun Apr 21, 2013 12:55 am

Re: Reporting Writer Annotation contents

Post by _savage »

JeJe wrote: Mon Aug 12, 2024 12:02 amThere's no AnnotationEnd if the Annotation is just at one point.
I see a text portion type 'Annotation' always paired with a text portion type 'AnnotationEnd', and that 'Annotation' text portion itself is an empty string. But that’s probably because in the document, all annotations (comments) span words and phrases?
JeJe wrote: Mon Aug 12, 2024 12:05 amFor the text of the Annotation look at the TextRange property of the Annotation portion.
Hmm, I tried

Code: Select all

if text.portion == "Annotation":
    print(text.TextRange)
and it always gives me a None.
Mac 13.7 using LO 24.8.2.1, Ubuntu Linux using LO 24.8 headless.
JeJe
Volunteer
Posts: 3064
Joined: Wed Mar 09, 2016 2:40 pm

Re: Reporting Writer Annotation contents

Post by JeJe »

I should have said .TextField.TextRange of the Annotation portion. Its an interface not a string. Use MRI.

viewtopic.php?t=49294

You can create a single paragraph test document with one annotation at one point to verity that then there isn't an AnnotationEnd portion.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Lupp
Volunteer
Posts: 3693
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Reporting Writer Annotation contents

Post by Lupp »

(I probably didn't study the old thread and its revival thoroughly enough. Sorry if my hints will not be useful.)
There is viewtopic.php?t=111343 where I presented a piece of code related to this thread.
If you want to study it, please note that the

Code: Select all

Sub annotationInfoToSheet(..., ...)
is not eligible for a direct call from >>Macros>Run Macro... . It's just a helper for

Code: Select all

Sub collectWriterAnnotationsInfo(Optional pDoc)
On Windows 10: LibreOffice 25.2.2 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
_savage
Posts: 198
Joined: Sun Apr 21, 2013 12:55 am

Re: Reporting Writer Annotation contents

Post by _savage »

I think I might have been unclear: for an annotation I’d like to get access to both the annotated text and the annotation itself.

Take, for example, the attached document: it contains a paragraph

Code: Select all

A paragraph with annotated text.
and the annotation itself

Code: Select all

A text annotation.
The above code extracts the annotation via .textfield.textrange, but I can’t quite get access to the annotated text itself — other than having two special text portions Annotation and AnnotationEnd “wrapping” the annotated text itself. Furthermore, annotations can overlap for annotated text, so, hmm… :?
Attachments
comments.odt
Annotated paragraph.
(9.56 KiB) Downloaded 115 times
Mac 13.7 using LO 24.8.2.1, Ubuntu Linux using LO 24.8 headless.
_savage
Posts: 198
Joined: Sun Apr 21, 2013 12:55 am

Re: Reporting Writer Annotation contents

Post by _savage »

Ah, poking and poking around with MRI… it looks like the Anchor property of a Annotation type text portion is the gateway to the annotated text.
Mac 13.7 using LO 24.8.2.1, Ubuntu Linux using LO 24.8 headless.
User avatar
Lupp
Volunteer
Posts: 3693
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Reporting Writer Annotation contents

Post by Lupp »

Back to the roots:
JeJe wrote: Tue Jul 07, 2020 11:19 am Writer must have a list of Comments ordered as they appear in the document internally - as it displays them this way in the Navigator. ...
Can't confirm this. For my example the Navigator is showing the annotations in an arbitrary order.
@RoryOF: There is no .Annotations (and also no .Comments) property/service, and the .TextFields property/service hasn't even a .Count nor does it support XIndexAccess. We need to use the XEnumerationAccess for which no order is specified in any way.

@All:
If we want to get the annotations in a specific order we wiil need to create that order explicitly. My related suggestion was posted and exemplified in the CodeSnippets thread I linked to already in my previous post to this topic (viewtopic.php?t=111343).
_savage wrote: Sat Aug 31, 2024 11:10 pm I think I might have been unclear: for an annotation I’d like to get access to both the annotated text and the annotation itself.
Supposing "annotated text" is meant to mean the content of the .Anchor TextRange of the annotation:
In the abovementioned post I also commented on the relevant fact that AOO and old versions of LibO don't support non-empty anchors for annotations. Old documents opened with newer version will also show the empty anchors annotations got at creation.
_savage wrote: Sun Sep 01, 2024 12:21 am Ah, poking and poking around with MRI… it looks like the Anchor property of a Annotation type text portion is the gateway to the annotated text.
Actually we are talking of the .Text porperty of the .Anchor of the related TextField .
Once again: Everything exemplified in the mentioned CodeSnippets post.
On Windows 10: LibreOffice 25.2.2 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
Post Reply