Sorting with Clippings

Page 1 of 1 (9 items)
This post has 8 Replies | 2 Followers

Posts 3
Seth Wallace | Forum Activity | Posted: Tue, Oct 31 2017 12:21 PM

I haven't been able to find an answer to this by searching the forums.

As I study, I read through several resources about the passage I'm working on. I grab quotes and drag them to a clipping (or right-click and add to the clipping). Unfortunately, it sorts them by the order I added them or by where I drop them (random). Since all these resources are tagged to texts, I would like the sorting to be done by textual order. That way, when I go back to all my notes they are in order of the text, not in order of the way I read the resources. Is this possible? Maybe not with clippings but with another way? So far, I've been sorting everything by hand. 

Posts 6
Bede | Forum Activity | Replied: Fri, Nov 10 2017 8:44 AM

Me Too!

I realised yesterday I want this.I've been reading several commentaries on a large part of a book, and now have a large clippings file. Most of the clippings are automatically tagged with the verse or passage to which they are related.

Although you can drag and drop, if you've got several pages of clippings this can be a bit tedious. I'm trying to sort out a Word macro to do this, based on the tags that are automatically put in. If I get it to work, I'll post it up.

Posts 3
Seth Wallace | Forum Activity | Replied: Fri, Nov 10 2017 10:02 AM

That would be great! But it'd be even GREATER if Logos could just work this into the clippings menu (sort by reference, or by order added, etc...). That way, you could add clippings from any work that was tagged with a reference and when you were done it would all be in order.

Posts 24442
Forum MVP
Dave Hooton | Forum Activity | Replied: Fri, Nov 10 2017 11:17 AM

Seth Wallace:
if Logos could just work this into the clippings menu (sort by reference, or by order added, etc...)

Clippings can come from any source and not have a 'reference'. Sorting by Tag (e.g. first tag then second tag) would likely work as long as the first tag is blank for non-versified resources.

Dave
===

Windows & Android

Posts 6
Bede | Forum Activity | Replied: Sat, Nov 11 2017 2:09 AM

I agree it would be much better if Logos would add sorting to the Clippings menu, but this seems to have been requested several times over a few years, so might not be as straightforward as it might seem.

I don't think it's possible to leave the first tag blank, if the engine works the way I would expect, then whatever gets put in as the first tag automatically becomes tag number one. A way around that would be to create a separate field for Scripture reference.

In the meantime I'm trying to make something that works for me because: (a) a workaround that does most of what I want is probable better than nothing; (b) it could be a while before Logos does this and patience never was one of my strongpoints Smile; and (c) I don't often get to play with programming or scripting so it's good to get some practice.

If I can get something to work, I'll make it available.

Posts 6
Bede | Forum Activity | Replied: Wed, Nov 15 2017 12:33 PM

I've got a working macro, although it's very slow if you've got lots of clippings (up to a few dozen should be OK, 370 takes about 10 minutes). Since I only have one computer, that's all it's been tested on: Word 2016 on Windows 10.

When you run it, first it'll tell you how many clippings it's found, then it'll ask for a default tag, in case some clippings don't have a tag. When the clipping has tags, it'll use the first tag. Each tag of a particular verse is given a number in the order it comes up, so you could have Ro #1, Ro #2, Ro #3, Ro 1:2#1, Ro 1:3#1, Ro 1:3-8#1, Ro 1:4#1, Ro 1:4#2, etc. (Note that Ro 1-3 comes after Ro 1:3; if I can work out how to change it I will.)

The code has several subroutines; the one to run is sortClippingsByReference.

'
' Set up array to store tags and counter for count of current tag
    Dim allTags() As String
    Dim countTagUsed As Integer
    Dim defaultTag As String
    Dim atEnd As Boolean
    Dim noOfClippings As Integer
    Dim totalTagsUsed As Integer


Sub sortClippingsByReference()
'
' First declare global variables and initialise
'
    countTagsUsed = 0
    totalTagsUsed = 0
    atEnd = False
'
' Get number of clippings in document
    MyDoc = ActiveDocument.Range.Text
    txt = "Clipped: "
    t = Replace(MyDoc, txt, "")
    MsgBox ((Len(MyDoc) - Len(t)) / Len(txt) & " clippings in document ")
    noOfClippings = (Len(MyDoc) - Len(t)) / Len(txt)
    ReDim allTags(noOfClippings) As String
 '
' Get default tag name
    getDefaultTag
    defaultTag = defaultTag & " "
    MsgBox ("The deault tag is " & defaultTag)
'
' Get rid of blank paragraphs at end of document NB this also deletes last section line
    KillEndBlanks
' Go to the start of the document and make the first paragraph Title text
    goToStart
    makeTitle
    insertContinuousBreak
'
'
'
' Now for the meat of the routine
' This needs to be looped until the end of the document
'
    Do
        getTags
    Loop Until ((Selection.Type = wdSelectionNormal_) And (Selection.End = ActiveDocument.Content.End)) Or ((Selection.Type = wdSelectionIP) And (Selection.End = ActiveDocument.Content.End - 1))
'
' Now sort out the tags
    sortTags
'
' Now move the clippings into the correct order
    moveSections
'
' Finally, tidy up by removing marker, etc.
    findMarker
    Selection.Delete
    Selection.Delete
'
End Sub

Sub goToStart()
'
' goToStart Macro
' Go to start of document
'
    Selection.HomeKey Unit:=wdStory
End Sub

Sub makeTitle()
'
' makeTitle Macro
' Makes the current paragraph a Title paragraph
'
    Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend
    Selection.Style = ActiveDocument.Styles("Title")
'
' Need to move cursor off title before section break is added
    Selection.EndKey Unit:=wdLine
    Selection.Move Unit:=wdCharacter, Count:=1 ' Otherwise section break is before paragraph break
'
' Now we can put in a marker to refer to when we insert sections in order. This should be at the end of the sorted document, and then be deleted.
    insertContinuousBreak
    Selection.TypeText Text:="#! Marker !#"
    Selection.InsertParagraph
'
End Sub
Sub insertContinuousBreak()
'
' insertContinuousBreak Macro
' Inserts a continuous section break
'
    Selection.InsertBreak Type:=wdSectionBreakContinuous
End Sub
Sub getTags()
'
' getTags Macro
' Finds Tags in document by going to clippings and going back one paragraph
' Then ensures the tag is unique by adding a suffix
' Then uses the tag for a section header
'
' First create variables for the tag, number of occurrences of the tag, and the section title
    Dim tag As String
    Dim noOfTags As Integer
    noOfTags = 0
    Dim sectionTitle As String
    Dim pos As Integer ' for position of : in tag
    Dim hyphen As Integer ' for hyphen (ie range) in tag
'
' Now increase the count for total tags to give the array element
    totalTagsUsed = totalTagsUsed + 1
'    MsgBox ("Tags used = " & totalTagsUsed)
'
' NB This will fail if "Clipped: " occurs inside the clipped text but this is unlikely to occur.
'
'
    With Selection.Find
        .Forward = True
        .Wrap = wdFindStop
        .Text = "Clipped: "
        .Execute
    End With
'
'
' Now deselect the word and move to the previous paragraph
    Selection.MoveLeft Unit:=wdCharacter, Count:=1
    Selection.MoveUp Unit:=wdParagraph, Count:=1
'
' Select the next word
    Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
    tag = Selection.Text
'    MsgBox ("Word is" + tag)
'
' See if the selected word is "Tags"; if so, select the first tag
    If tag = "Tags" Then
        Dim flag As Boolean
        flag = True
        While flag = True
            Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
' checks the last character to see if its a semicolon (more than one tag) or end of paragraph (only one tag).
            If Strings.Right(Selection.Range.Text, 1) = ";" Or Strings.Right(Selection.Range.Text, 1) = Chr(13) Then
'if it was a space the loop flag will end
                flag = False
            End If
        Wend
'
'
' Now need to get first tag.
'
' When searching array will need to allow for the difference between e.g. Ro 1:2 and Rom 1:2-3:4. Need also to check for digit.
        tag = Left(Selection.Text, Len(Selection.Text) - 1)
' This is including the word "Tags: " so need to remove and this method is faster to think about but needs tidying up
        tag = Right(tag, Len(tag) - 6)
' Need to check that tag is not just book name; if it is, add a space
        If Right(tag, 1) < "0" Or Right(tag, 1) > "9" Then
            tag = tag & " "
        End If
' Add a space after the chapter number if verse is less than 10
        pos = InStr(tag, ":")
        hyphen = InStr(tag, "-")
        If Mid(tag, pos + 3) <> "-" Then ' do not want space if range starting at verse greater than 9
            If (Mid(tag, pos + 2, 1) < "0" Or Mid(tag, pos + 2, 1) > 9) Then
                tag = Replace(tag, ":", ": ")
            End If
        End If
'
    Else   ' Tag is not used so need to use default tag
        tag = defaultTag
    End If
'
' Now search for use of tag already
        For i = LBound(allTags) To UBound(allTags)
            If Left(allTags(i), Len(tag)) = tag And Mid(allTags(i), Len(tag) + 1, 1) = "#" Then
                noOfTags = noOfTags + 1
            End If
        Next
'
' Now make the name of the tag as will be used, by adding the number of occurrences to its name
        tag = tag & "#" & CStr(noOfTags + 1)
'
' Need to select tag and make it the section heading
'
' Now add the tag to the array and make as title of section.
    allTags(totalTagsUsed) = tag
'
' Will need to move to end of clipping and insert a section break
' Go to clipped then end of paragraph
'
    With Selection.Find
        .Forward = True
        .Wrap = wdFindStop
        .Text = "Clipped: "
        .Execute
    End With
    Selection.MoveRight Unit:=wdCharacter, Count:=1
    Selection.MoveDown Unit:=wdParagraph, Count:=2
    insertContinuousBreak
'
' Now select the current section, goes to the start, and insert the tag to act as a marker for sorting
    Selection.MoveLeft Unit:=wdCharacter, Count:=2
    Selection.Range.Sections.First.Range.Select
    Selection.MoveLeft Unit:=wdCharacter, Count:=1
    Selection.TypeText Text:=tag
    Selection.Style = ActiveDocument.Styles("Heading 2")
    Selection.InsertParagraph
    Selection.Range.Sections.First.Range.Select
    Selection.MoveRight Unit:=wdCharacter, Count:=1
'
'
End Sub

Sub deselect()
'
' deselect Macro
' move cursor off paragraph
'
    Selection.MoveLeft Unit:=wdCharacter, Count:=1
End Sub
Sub selectCurrentWord()
'
' selectCurrentWord Macro
' Selects the current word (for use later)
'
    Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
End Sub

Sub getDefaultTag()
' Get default tag name
'
    Dim noTag As Boolean
    noTag = True
    Do
        defaultTag = InputBox("Please enter a bible reference for a default tag")
        noTag = False
        If Len(defaultTag) = 0 Or Len(defaultTag) > 15 Then
            MsgBox ("Enter a bible reference of up to 15 characters for use as a default tag")
            noTag = True
        End If
    Loop Until Not (noTag)
'
End Sub

Sub goToStartOfSection()
'
' Move to the start of the current section
    Selection.MoveUp Unit:=wdSection, Count:=1
    Selection.TypeText Text:="MyText"
    Selection.InsertParagraph

'
End Sub


Sub goToStartOfSectionAndInsert()
'
'
' Now select the current section, goes to the start, and insert the tag to act as a marker for sorting
'PUTS IN TWO TAGS AND CHANGES STYLE FOR WHOLE SECTION!
    Selection.Range.Sections.First.Range.Select
    Selection.MoveLeft Unit:=wdCharacter, Count:=1
    Selection.TypeText Text:=tag
    Selection.Style = ActiveDocument.Styles("Heading 2")
    Selection.InsertParagraph
'
End Sub

Sub KillEndBlanks()
'
'
' Go to the end of the file
    Selection.EndKey Unit:=wdStory
' Select the last character
    Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
' As long as the last character is a carriage return [CHR(13)]...
    While Selection.Text = vbCr
        ' ... Delete the character, and select the new last character
        Selection.Delete Unit:=wdCharacter, Count:=1
        Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
    Wend
' Go to the end of the file again to not leave a character selected
    Selection.EndKey Unit:=wdStory
End Sub

Sub sortTags()
'
' Sorts the tags array, using a simple bubble sort
    Dim i, j As Integer
    Dim t As String
    For i = LBound(allTags) To (UBound(allTags) - 1)
        For j = i + 1 To UBound(allTags)
            If allTags(i) > allTags(j) Then
                t = allTags(i)
                allTags(i) = allTags(j)
                allTags(j) = t
            End If
        Next j
    Next i
'
End Sub

Sub moveSections()
'
' This will move the clippings into the correct sequence
    Dim currentTag As String
    For i = LBound(allTags) To UBound(allTags)
        currentTag = allTags(i)
        With Selection.Find
        .Forward = True
        .Wrap = wdFindStop
        .Text = currentTag
        .Execute
        End With
        Selection.Range.Sections.First.Range.Select
        Selection.Range.Sections.First.Range.Cut
' Need to move to start of docuemnt first
        findMarker
        Selection.MoveLeft Unit:=wdCharacter, Count:=1
        Selection.Paste
'        Selection.MoveRight Unit:=wdCharacter, Count:=1
'        Selection.TypeParagraph
    Next
'
End Sub

Sub findMarker()
'
' Finds the marker for inserting sections, etc
    goToStart
    With Selection.Find
        .Forward = True
        .Wrap = wdFindStop
        .Text = "#! Marker !#"
        .Execute
    End With
'
End Sub

Posts 6
Bede | Forum Activity | Replied: Wed, Nov 15 2017 12:42 PM

For people who aren't familiar with macros in MS Office:

In order to run this, you'll need to save your clippings in a macro-enabled document, which has the .docm extension instead of .docx. (This doesn't apply to Word before (I think) 2007.) You'll also need to enable macros when the yellow bar appears at the top of the document.

To put the code into a word file, Press Alt and F11 (function key) simultaneously. This opens the VBA editor. On the left-hand side, in the Project pane, you should see "This Document". If there isn't already a blank file in the main screen, double-click "This Document". Then you can paste the code in.

To run the code, click on the View tab in Word, and click on Macros on the ribbon. Choose View Macros, click on sortClippingsByReference, and click Run.

Hope this helps,

Bede

Posts 3
Seth Wallace | Forum Activity | Replied: Wed, Jan 3 2018 10:51 AM

Never said, "Thanks!" I apologize. But thank you for taking the time to do this and share it. I used it today and it worked well, sorting all my clippings by verse so I can now work through my text in order. Still wish Logos would build it in!

Posts 6
Bede | Forum Activity | Replied: Sat, Jan 6 2018 9:03 AM

I'm glad it helped. I also think it would be better if Logos were to build it in. Apart from anything else, then it should be possible to sort on multiple tags as well, assuming all clippings are filed in a database. Plus, not everyone uses Word, and I don't think it'll work "as is" in LibreOffice, and I'm not sure how long it'd take to convert.

Page 1 of 1 (9 items) | RSS