Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fractaledmind/6337035 to your computer and use it in GitHub Desktop.
Save fractaledmind/6337035 to your computer and use it in GitHub Desktop.
I rewrote the entire script from the ground up. Changes: --Script moves sentence by sentence and alters text each time, so that Contextual views become less and less cluttered. --Added Contextual View to see the whole paragraph containing Markup in question. This script takes as input a text with CriticMarkup in it and allows the user to either …
(* ACCEPT/REJECT CRITICMARKUP CHANGES
--Stephen Margheim
--23 July 2013
--open source
--VERSION 2.0
I rewrote the entire script from the ground up.
Changes:
--Script moves sentence by sentence and alters text each time, so that Contextual views become less and less cluttered.
--Added Contextual View to see the whole paragraph containing Markup in question.
This script takes as input a text with CriticMarkup in it and allows the user to either Accept or Reject those changes. To begin, select your text and copy it to the clipboard by cutting it. Then run the script.
This script runs with any text editor, as it simply takes text from the clipboard and returns text to the clipboard.
For Additions, Deletions, and Substitutions, the script asks if you want to Accept or Reject. Based on what you choose, it will replace the commented text with regular text.
For Comments and Highlights, the script asks you what you want to insert given that comment. If you simply press "Insert" without typing anything, the script will delete the comment without adding anything. If you type something in, it will replace the comment with that text.
Every dialog box offers you the single sentence containing the Markup under consideration. If you wish to have More Context (to see where the Markup is and how it relates to the sentences around it), simply press that button.
NOTE: I have changed the syntax for Comments for ease of use. Now, Comments use {^^…^^}, while Highlights use {==…==}{**…**}. In the original CriticMarkup syntax both use {<<…>>} for the Comment sections. This made distinguishing Comments from Highlights too difficult, however. Also, the change in character type in Comments made geting the intervening text more difficult.
*)
set theText to the clipboard
--Part 1
set theParagraphs to paragraphs of theText
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
set theCharacters to text items of theText
set AppleScript's text item delimiters to tid
set theSentences to my get_sentences(theCharacters)
--Part 1.1
set theSentences_clean to {}
repeat with i from 1 to count of theSentences
set cleanSentence to my trimStart(item i of theSentences)
copy cleanSentence to end of theSentences_clean
end repeat
--Part 2
repeat with i from 1 to count of theSentences_clean
set thisSentence to item i of theSentences_clean
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
set theCharacters to text items of thisSentence
set AppleScript's text item delimiters to tid
--Part 2.1
try
set theAdds_markup to my get_text("+", theCharacters)
end try
try
set theDels_markup to my get_text("-", theCharacters)
end try
try
set theSubs_markup to my get_text("~", theCharacters)
end try
--Part 2.2
if (count of theAdds_markup) is greater than 0 then
set theAdds_simple to my extract_between(theAdds_markup, "{++", "++}")
else
set theAdds_simple to {}
end if
if (count of theDels_markup) is greater than 0 then
set theDels_simple to my extract_between(theDels_markup, "{--", "--}")
else
set theDels_simple to {}
end if
if (count of theSubs_markup) is greater than 0 then
set theSubs_full to my extract_between(theSubs_markup, "{~~", "~~}")
set theSubs_simple to my get_Subs(theSubs_full)
else
set theSubs_simple to {}
end if
--Part 2.3.1
repeat with i from 1 to count of theAdds_markup
set thisAdd_markup to item i of theAdds_markup
set thisAdd_simple to item i of theAdds_simple
if thisSentence contains thisAdd_markup then
display dialog "Accept or Reject this change:" & return & tab & thisAdd_markup & return & return & "Context: " & return & "\"" & thisSentence & "\"" buttons {"Accept", "Reject", "More Context"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theText to my find_replace(theText, thisAdd_markup, thisAdd_simple)
else if result = {button returned:"Reject"} then
set theText to my find_replace(theText, thisAdd_markup, "")
else if result = {button returned:"More Context"} then
set theParagraphs to paragraphs of theText
repeat with i from 1 to count of theParagraphs
set thisParagraph to item i of theParagraphs
if thisParagraph contains thisSentence then
display dialog "Accept or Reject this change:" & return & tab & thisAdd_markup & return & return & "Context: " & return & "\"" & thisParagraph & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theText to my find_replace(theText, thisAdd_markup, thisAdd_simple)
else if result = {button returned:"Reject"} then
set theText to my find_replace(theText, thisAdd_markup, "")
end if
end if
end repeat
end if
else
exit repeat
end if
end repeat
set theParagraphs to paragraphs of theText
--Part 2.3.2
repeat with i from 1 to count of theDels_markup
set thisDel_markup to item i of theDels_markup
set thisDel_simple to item i of theDels_simple
if thisSentence contains thisDel_markup then
display dialog "Accept or Reject this change:" & return & tab & thisDel_markup & return & return & "Context: " & return & "\"" & thisSentence & "\"" buttons {"Accept", "Reject", "More Context"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theText to my find_replace(theText, thisDel_markup, "")
else if result = {button returned:"Reject"} then
set theText to my find_replace(theText, thisDel_markup, thisDel_simple)
else if result = {button returned:"More Context"} then
set theParagraphs to paragraphs of theText
repeat with i from 1 to count of theParagraphs
set thisParagraph to item i of theParagraphs
if thisParagraph contains thisSentence then
display dialog "Accept or Reject this change:" & return & tab & thisDel_markup & return & return & "Context: " & return & "\"" & thisParagraph & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theText to my find_replace(theText, thisDel_markup, "")
else if result = {button returned:"Reject"} then
set theText to my find_replace(theText, thisDel_markup, thisDel_simple)
end if
end if
end repeat
end if
end if
end repeat
--Part 2.3.3
repeat with i from 1 to count of theSubs_markup
set thisSub_markup to item i of theSubs_markup
set thisSub_simple to item i of theSubs_simple
if thisSentence contains theSubs_markup then
display dialog "Accept or Reject this change:" & return & tab & thisSub_markup & return & return & "Context: " & return & "\"" & thisSentence & "\"" buttons {"Accept", "Reject", "More Context"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theReplace to item 2 of thisSub_simple
set theText to my find_replace(theText, thisSub_markup, theReplace)
else if result = {button returned:"Reject"} then
set theReplace to item 1 of thisSub_simple
set theText to my find_replace(theText, thisSub_markup, theReplace)
else if result = {button returned:"More Context"} then
set theParagraphs to paragraphs of theText
repeat with i from 1 to count of theParagraphs
set thisParagraph to item i of theParagraphs
if thisParagraph contains thisSentence then
display dialog "Accept or Reject this change:" & return & tab & thisSub_markup & return & return & "Context: " & return & "\"" & thisParagraph & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"}
if result = {button returned:"Accept"} then
set theReplace to item 2 of thisSub_simple
set theText to my find_replace(theText, thisSub_markup, theReplace)
else if result = {button returned:"Reject"} then
set theReplace to item 1 of thisSub_simple
set theText to my find_replace(theText, thisSub_markup, theReplace)
end if
end if
end repeat
end if
end if
end repeat
end repeat
--Part 3
set theParagraphs to paragraphs of theText
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
set theCharacters to text items of theText
set AppleScript's text item delimiters to tid
--Part 3.1
try
set theComms_markup to my get_text("^", theCharacters)
end try
try
set theHighs_markup to my get_text("=", theCharacters)
set theHighComms_markup to my get_text("*", theCharacters)
end try
--Part 3.2
if (count of theHighs_markup) is greater than 0 then
set theHighs_simple to my extract_between(theHighs_markup, "{==", "==}")
else
set theHighs_simple to {}
end if
--Part 3.3
repeat with i from 1 to count of theParagraphs
set thisParagraph to item i of theParagraphs
--Part 3.3.1
repeat with i from 1 to count of theComms_markup
set thisComm_markup to item i of theComms_markup
if thisParagraph contains thisComm_markup then
set thePrompt to display dialog "Note this Comment:" & return & tab & thisComm_markup & return & return & "Context: " & return & "\"" & thisParagraph & "\"" & return & return & "What do you wish to insert?" & return default answer "" buttons {"Insert"} default button {"Insert"} with title {"Accept or Reject CriticMarkup Changes"}
set theButton to button returned of thePrompt
if theButton is "Insert" then
set theReplace to text returned of thePrompt
set theText to my find_replace(theText, thisComm_markup, theReplace)
end if
end if
end repeat
--Part 3.3.2
repeat with i from 1 to count of theHighs_markup
set thisHigh_markup to item i of theHighs_markup
set thisHighComm_markup to item i of theHighComms_markup
set thisHighNote_markup to thisHigh_markup & thisHighComm_markup
set thisHigh_simple to item i of theHighs_simple
if thisParagraph contains thisHigh_markup then
set thePrompt to display dialog "Note this Highlight:" & return & tab & thisHighNote_markup & return & return & "Context: " & return & "\"" & thisParagraph & "\"" & return & return & "What do you wish to insert?" & return default answer "" buttons {"Insert"} default button {"Insert"} with title {"Accept or Reject CriticMarkup Changes"}
set theButton to button returned of thePrompt
if theButton is "Insert" then
set theText to my find_replace(theText, thisHighNote_markup, thisHigh_simple)
end if
end if
end repeat
end repeat
--Part 4
set the clipboard to theText
(* HANDLERS *)
on get_text(theMarker, this_list)
set indexList to {}
repeat with i from 1 to the count of this_list
if item i of this_list is "{" then
if item (i + 1) of this_list is theMarker then
copy i to end of indexList
end if
end if
if item i of this_list is "}" then
if item (i - 1) of this_list is theMarker then
copy i to end of indexList
end if
end if
end repeat
set indexList to my groupList(indexList, 2)
set text_list to {}
repeat with i from 1 to count of indexList
set theFront to item 1 of item i of indexList
set theBack to item 2 of item i of indexList
set theText to items theFront thru theBack of this_list as string
copy theText to end of text_list
end repeat
return text_list
end get_text
on get_sentences(this_list)
set indexList to {}
repeat with i from 1 to the count of this_list
if item i of this_list is "." then
copy i to end of indexList
else if item i of this_list is "!" then
copy i to end of indexList
else if item i of this_list is "?" then
copy i to end of indexList
end if
end repeat
copy (0 as number) to the beginning of indexList
set text_list to {}
repeat with i from 1 to count of indexList
set theBack to item -i of indexList
if item -i of indexList is not 0 then
set theFront to item (-i - 1) of indexList
set theText to items (theFront + 1) thru theBack of this_list as string
copy theText to beginning of text_list
end if
end repeat
return text_list
end get_sentences
on get_Subs(theSubstitutions)
set theSubs to {}
repeat with i from 1 to count of theSubstitutions
set theSub to item i of theSubstitutions as string
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "~>"
set theDelItem to text item 1 of theSub
set theSubItem to text item 2 of theSub
set AppleScript's text item delimiters to tid
copy theDelItem to end of theSubs
copy theSubItem to end of theSubs
end repeat
set theSubs to my groupList(theSubs, 2)
return theSubs
end get_Subs
on extract_between(theList, frontChar, backChar)
if (count of theList) is greater than 1 then
set theList_raw to {}
repeat with i from 1 to count of theList
set theRaw to my RemoveListFromString(item i of theList, {frontChar, backChar})
copy theRaw to end of theList_raw
end repeat
else if (count of theList) is 1 then
set theList_raw to my RemoveListFromString(theList as string, {frontChar, backChar})
else if (count of theList) is 0 then
set theList_raw to {}
end if
return theList_raw as list
end extract_between
on find_replace(the_string, search_strings, replace_strings)
set ListNumber to the (count of search_strings) as number
set OldDelims to AppleScript's text item delimiters
considering case
set AppleScript's text item delimiters to search_strings
set newText to text items of the_string
set AppleScript's text item delimiters to replace_strings
set the_string to newText as text
set AppleScript's text item delimiters to OldDelims
end considering
return the_string
end find_replace
(* SUB-ROUTINES *)
on groupList(lst, groupLen)
-- HAS (http://applemods.sourceforge.net/mods/Data/List.php)
local lst, tailLen, groupLen, idx
try
if lst's class is not list then error "not a list." number -1704
script k
property l : lst
property res : {}
end script
set tailLen to (count of k's l) mod groupLen
repeat with idx from 1 to ((count of k's l) - tailLen) by groupLen
set k's res's end to k's l's items idx thru (idx + groupLen - 1)
end repeat
if tailLen is not 0 then
set k's res's end to k's l's items -tailLen thru -1
end if
return k's res
on error eMsg number eNum
error "Can't groupList: " & eMsg number eNum
end try
end groupList
on RemoveListFromString(theText, listOfCharsOrStrings)
-- ljr (http://applescript.bratis-lover.net/library/string/)
local ASTID, theText, CharOrString, lst
try
script k
property l : listOfCharsOrStrings
end script
set len to count k's l
repeat with i from 1 to len
set cur_ to k's l's item i
set theText to my RemoveFromString(theText, cur_)
end repeat
return theText
on error eMsg number eNum
error "Can't RemoveListFromString: " & eMsg number eNum
end try
end RemoveListFromString
on RemoveFromString(theText, CharOrString)
-- ljr (http://applescript.bratis-lover.net/library/string/)
local ASTID, theText, CharOrString, lst
set ASTID to AppleScript's text item delimiters
try
considering case
if theText does not contain CharOrString then ¬
return theText
set AppleScript's text item delimiters to CharOrString
set lst to theText's text items
end considering
set AppleScript's text item delimiters to ASTID
return lst as text
on error eMsg number eNum
set AppleScript's text item delimiters to ASTID
error "Can't RemoveFromString: " & eMsg number eNum
end try
end RemoveFromString
on trimStart(str)
-- HAS (http://applemods.sourceforge.net/mods/Data/String.php)
local str, whiteSpace
try
set str to str as string
set whiteSpace to {character id 10, return, space, tab}
try
repeat while str's first character is in whiteSpace
set str to str's text 2 thru -1
end repeat
return str
on error number -1728
return ""
end try
on error eMsg number eNum
error "Can't trimStart: " & eMsg number eNum
end try
end trimStart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment