Last active
December 20, 2015 04:08
-
-
Save fractaledmind/6068139 to your computer and use it in GitHub Desktop.
This script allows you to handle, one-by-one, changes in your text document put in CriticMarkup format. All 5 forms of CriticMarkup syntax are supported: Add, Delete, Substitute, Comment, Highlight. For each instance of an Addition or Deletion, you can either Accept or Reject the proposed option. For each instance of Substitutions, you can chose…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* ACCEPT/REJECT CRITICMARKUP CHANGES | |
--Stephen Margheim | |
--23 July 2013 | |
--open source | |
VERSION 1.1 | |
--added if, then, else blocks for all prompts, allowing for script to function even if not all markup forms are present | |
--added try block to getContext Handler, allowing script to function when context range exceeds beginning or end of doc | |
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 TextMate. If you use another text editor, you will need to change the output portion of the script. | |
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 "Enter" 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 contains Context for you to see, without returning to the text, where the Markup is and how it relates to the sentences around it. | |
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. | |
*) | |
(* PART ONE: | |
Get the CriticMarkup Information | |
*) | |
--get text as list divided by character | |
set tid to AppleScript's text item delimiters | |
set inputText to the clipboard | |
set AppleScript's text item delimiters to "" | |
set inputList to text items of inputText | |
set AppleScript's text item delimiters to tid | |
--get all CriticMarkup info | |
set theAdditions to my extractBetween(inputText, "{++", "++}") | |
set theDeletions to my extractBetween(inputText, "{--", "--}") | |
set theSubstitutions to my extractBetween(inputText, "{~~", "~~}") | |
set theComments to my extractBetween(inputText, "{^^", "^^}") | |
set theHighlights to my extractBetween(inputText, "{==", "<<}") | |
set theHighlightText to my extractBetween(inputText, "{==", "==}") | |
set theHighlightComment to my extractBetween(inputText, "==}{>>", "<<}") | |
--prepare CriticMarkdup info for Find and Replace | |
set AddsList to my rebindList(theAdditions, "{++", "++}") | |
set DelsList to my rebindList(theDeletions, "{--", "--}") | |
set SubsList to my rebindList(theSubstitutions, "{~~", "~~}") | |
set CommsList to my rebindList(theComments, "{^^", "^^}") | |
set HighlightList to my rebindList(theHighlights, "{==", "<<}") | |
--get text as new list divided by words | |
set AppleScript's text item delimiters to " " | |
set theText_list to text items of inputText | |
set AppleScript's text item delimiters to tid | |
--prepare lists for items below | |
set MatchedItems_adds to {} | |
set MatchedItems_dels to {} | |
set MatchedItems_subs to {} | |
set MatchedItems_comms to {} | |
set MatchedItems_highs to {} | |
--get all instances of CriticMarkup in text, divided by kind | |
repeat with i from 1 to count of theText_list | |
if item i of theText_list contains "{++" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_adds | |
else if item i of theText_list contains "{--" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_dels | |
else if item i of theText_list contains "{~~" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_subs | |
else if item i of theText_list contains "{^^" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_comms | |
else if item i of theText_list contains "^^}" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_comms | |
else if item i of theText_list contains "{==" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_highs | |
else if item i of theText_list contains "<<}" then | |
set MatchedItem to item i of theText_list | |
copy MatchedItem to end of MatchedItems_highs | |
end if | |
end repeat | |
--get index of CriticMarkup in text, divided by kind | |
set AddsIndex to my getIndex(MatchedItems_adds, theText_list) | |
set DelsIndex to my getIndex(MatchedItems_dels, theText_list) | |
set SubsIndex to my getIndex(MatchedItems_subs, theText_list) | |
set CommsIndex to my getIndex(MatchedItems_comms, theText_list) | |
set HighsIndex to my getIndex(MatchedItems_highs, theText_list) | |
(* PART TWO: | |
Get contextual data for all CriticMarkup | |
*) | |
--get contextual text of CriticMarkup in text, divided by kind | |
set AddsContext to my getContext(AddsIndex, theText_list) | |
set DelsContext to my getContext(DelsIndex, theText_list) | |
set SubsContext to my getContext(SubsIndex, theText_list) | |
set CommsContext to my getContext_HighsorComms(CommsIndex, theText_list) | |
set HighsContext to my getContext_HighsorComms(HighsIndex, theText_list) | |
(* PART THREE | |
Accept or Reject Additions, Deletions, Substitutions, Comments, and Highlights | |
*) | |
if (not (AddsContext is {})) then | |
set AddsPrompt to my promptUser(AddsContext, AddsIndex, theText_list, AddsList, theAdditions, inputText) | |
else | |
set AddsPrompt to inputText | |
end if | |
if (not (DelsContext is {})) then | |
set DelsPrompt to my promptUser_dels(DelsContext, DelsIndex, theText_list, DelsList, theDeletions, AddsPrompt) | |
else | |
set DelsPrompt to AddsPrompt | |
end if | |
if (not (SubsContext is {})) then | |
set theSubs to my getSubs_list(theSubstitutions) | |
set theDeSubs to my getDeSubs_list(theSubstitutions) | |
set theSubsPrompt to my promptUser_sub(SubsContext, SubsIndex, theText_list, SubsList, theSubs, theDeSubs, DelsPrompt) | |
else | |
set theSubsPrompt to DelsPrompt | |
end if | |
if (not (CommsContext is {})) then | |
set theCommsPrompt to my promptUser_Comms(CommsContext, CommsList, theSubsPrompt) | |
else | |
set theCommsPrompt to theSubsPrompt | |
end if | |
if (not (HighsContext is {})) then | |
set theHighsPrompt to my promptUser_Highs(HighsContext, HighlightList, theHighlightText, theCommsPrompt) | |
else | |
set theHighsPrompt to theCommsPrompt | |
end if | |
(* PART FOUR | |
Insert new text into TextMate | |
*) | |
set FinalText to theHighsPrompt | |
set the clipboard to FinalText | |
delay 0.1 | |
tell application "TextMate" | |
activate | |
tell application "System Events" | |
delay 0.1 | |
keystroke "v" using {command down} | |
end tell | |
end tell | |
(* HANDLERS *) | |
to extractBetween(SearchText, startText, endText) | |
set tid to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to startText | |
set liste to text items of SearchText | |
set AppleScript's text item delimiters to endText | |
set extracts to {} | |
repeat with subText in liste | |
if subText contains endText then | |
copy text item 1 of subText to end of extracts | |
end if | |
end repeat | |
set AppleScript's text item delimiters to tid | |
return extracts | |
end extractBetween | |
on getSubs_list(theSubstitutions) | |
set theSubs to {} | |
set theDeSubs to {} | |
repeat with i from 1 to count of theSubstitutions | |
set theSub to item i of theSubstitutions as string | |
set theDeSub to my getDeSubs(theSub) | |
set theSub to my getSubs(theSub) | |
copy theDeSub to end of theDeSubs | |
copy theSub to end of theSubs | |
end repeat | |
return theSubs | |
end getSubs_list | |
on getDeSubs_list(theSubstitutions) | |
set theSubs to {} | |
set theDeSubs to {} | |
repeat with i from 1 to count of theSubstitutions | |
set theSub to item i of theSubstitutions as string | |
set theDeSub to my getDeSubs(theSub) | |
set theSub to my getSubs(theSub) | |
copy theDeSub to end of theDeSubs | |
copy theSub to end of theSubs | |
end repeat | |
return theDeSubs | |
end getDeSubs_list | |
on rebindList(theExtracts, front_chars, end_chars) | |
set theboundList to {} | |
repeat with i from 1 to count of theExtracts | |
set theExtract to item i of theExtracts | |
set boundText to front_chars & theExtract & end_chars | |
copy boundText to the end of theboundList | |
end repeat | |
return theboundList | |
end rebindList | |
on getIndex(MatchedItems, theText_list) | |
set MatchedItems_index to {} | |
repeat with i from 1 to count of MatchedItems | |
set theItem to item i of MatchedItems | |
set matchedIndex to my list_position(theItem, theText_list) | |
if matchedIndex is not equal to 0 then | |
copy matchedIndex to end of MatchedItems_index | |
end if | |
end repeat | |
return MatchedItems_index | |
end getIndex | |
on getContext(indexes, theList) | |
set tid to AppleScript's text item delimiters | |
set contextTexts to {} | |
repeat with i from 1 to count of indexes | |
set thisIndex to item i of indexes | |
set priorWords to {} | |
set afterWords to {} | |
repeat with i from 1 to 15 | |
try | |
set priorWord to item (thisIndex + -i) of theList | |
copy priorWord to beginning of priorWords | |
set afterWord to item (thisIndex + i) of theList | |
copy afterWord to end of afterWords | |
end try | |
end repeat | |
set AppleScript's text item delimiters to " " | |
set priorWords to priorWords as string | |
set afterWords to afterWords as string | |
set AppleScript's text item delimiters to tid | |
set theWord to item thisIndex of theList | |
set contextText to priorWords & " " & theWord & " " & afterWords | |
copy contextText to end of contextTexts | |
end repeat | |
return contextTexts | |
end getContext | |
on getContext_HighsorComms(indexes, theList) | |
set tid to AppleScript's text item delimiters | |
set Index_grouped to my groupList(indexes, 2) | |
set contextTexts to {} | |
repeat with i from 1 to count of Index_grouped | |
set theIndexes to item i of Index_grouped | |
set thisIndex_front to item 1 of theIndexes | |
set thisIndex_back to item 2 of theIndexes | |
set priorWords to {} | |
set afterWords to {} | |
repeat with i from 1 to 10 | |
set priorWord to item (thisIndex_front + -i) of theList | |
copy priorWord to beginning of priorWords | |
set afterWord to item (thisIndex_back + i) of theList | |
copy afterWord to end of afterWords | |
end repeat | |
set AppleScript's text item delimiters to " " | |
set priorWords to priorWords as string | |
set afterWords to afterWords as string | |
set theComm_list to items thisIndex_front thru thisIndex_back of theList | |
set theComm to theComm_list as string | |
set tid to AppleScript's text item delimiters | |
set contextText to priorWords & " " & theComm & " " & afterWords | |
copy contextText to end of contextTexts | |
end repeat | |
return contextTexts | |
end getContext_HighsorComms | |
on promptUser(theContext, theIndex, theList, findList, replaceList, inputText) | |
repeat with i from 1 to count of theContext | |
set context to item i of theContext | |
set thisIndex to item i of theIndex | |
set theWord to item thisIndex of theList | |
display dialog "Accept or Reject this change:" & return & tab & theWord & return & return & "Context: " & return & "\"" & context & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"} | |
if result = {button returned:"Accept"} then | |
set theFind to item i of findList | |
set theReplace to item i of replaceList | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
else if result = {button returned:"Reject"} then | |
set theFind to item i of findList | |
set inputText to my find_replace(inputText, theFind, "") | |
end if | |
end repeat | |
return inputText | |
end promptUser | |
on promptUser_dels(theContext, theIndex, theList, findList, replaceList, inputText) | |
repeat with i from 1 to count of theContext | |
set context to item i of theContext | |
set theWord to item i of findList | |
display dialog "Accept or Reject this change:" & return & tab & theWord & return & return & "Context: " & return & "\"" & context & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"} | |
if result = {button returned:"Accept"} then | |
set theFind to item i of findList | |
set theReplace to "" | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
else if result = {button returned:"Reject"} then | |
set theFind to item i of findList | |
set theReplace to item i of replaceList | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
end if | |
end repeat | |
return inputText | |
end promptUser_dels | |
on promptUser_sub(theContext, theIndex, theList, findList, replaceList_acc, replaceList_rej, inputText) | |
repeat with i from 1 to count of theContext | |
set context to item i of theContext | |
set thisIndex to item i of theIndex | |
set theWord to item thisIndex of theList | |
display dialog "Accept or Reject this change:" & return & tab & theWord & return & return & "Context: " & return & "\"" & context & "\"" buttons {"Accept", "Reject"} with title {"Accept or Reject CriticMarkup Changes"} default button {"Accept"} | |
if result = {button returned:"Accept"} then | |
set theFind to item i of findList | |
set theReplace to item i of replaceList_acc | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
else if result = {button returned:"Reject"} then | |
set theFind to item i of findList | |
set theReplace to item i of replaceList_rej | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
end if | |
end repeat | |
return inputText | |
end promptUser_sub | |
on promptUser_Comms(theContext, findList, inputText) | |
repeat with i from 1 to count of theContext | |
set theComm to item i of findList | |
set context to item i of theContext | |
set thePrompt to display dialog "Note this Comment:" & return & tab & theComm & return & return & "Context: " & return & "\"" & context & "\"" & return & return & "What do you wish to insert?" & return default answer "" | |
set theReplace to text returned of thePrompt | |
set theFind to item i of findList | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
end repeat | |
end promptUser_Comms | |
on promptUser_Highs(theContext, findList, replaceList_rej, inputText) | |
repeat with i from 1 to count of theContext | |
set theComm to item i of findList | |
set context to item i of theContext | |
set thePrompt to display dialog "Note this Highlighted Comment:" & return & tab & theComm & return & return & "Context: " & return & "\"" & context & "\"" & return & return & "What do you wish to insert?" & return default answer "" | |
set theReplace to text returned of thePrompt | |
if theReplace is not "" then | |
set theFind to item i of findList | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
else if theReplace is "" then | |
set theFind to item i of findList | |
set theReplace to item i of replaceList_rej | |
set inputText to my find_replace(inputText, theFind, theReplace) | |
end if | |
end repeat | |
end promptUser_Highs | |
(* SUB-ROUTINES *) | |
to getSubs(theText) | |
set tid to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to "~>" | |
set theDelItem to text item 1 of theText | |
set theSubItem to text item 2 of theText | |
set AppleScript's text item delimiters to tid | |
return theSubItem as list | |
end getSubs | |
on getDeSubs(theText) | |
set tid to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to "~>" | |
set theDelItem to text item 1 of theText | |
set theSubItem to text item 2 of theText | |
set AppleScript's text item delimiters to tid | |
return theDelItem as list | |
end getDeSubs | |
on list_position(this_item, this_list) | |
repeat with i from 1 to the count of this_list | |
if item i of this_list is this_item then return i | |
end repeat | |
return 0 | |
end list_position | |
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 | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment