Skip to content

Instantly share code, notes, and snippets.

@Marbux
Created April 14, 2017 05:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Marbux/184ed6c310739460c8c040056d7b08ce to your computer and use it in GitHub Desktop.
Save Marbux/184ed6c310739460c8c040056d7b08ce to your computer and use it in GitHub Desktop.
--[[
NoteCase Pro script
See http://www.notecasepro.com/
SCRIPT NAME: Change Case — To Title Case
v. 1.0.2
PURPOSE: The Change Case — To Title Case script converts English language selected text to Title Case, that is all words have their first character capitalized, excepting articles, conjunctions, and (particular) prepositions.
This script presently produces title case in the English language only. For other languages, edit this script's "smallwords" table.
This script's output should not be trusted without review. The script does not respect the four exceptions specified for capitalization in the MLA style rules:
* When one of these words starts a title;
* When one of these words ends a title;
* When one of these words comes after a colon, as in a subtitle; and
* When a quotation is part of a title, follow the capitalization used in the quote.
Also,
[i] the MLA list of words to be lower-cased in title case includes words used as both prepositions and nouns (only the latter should be capitalized in title case) and a complete list of English prepositions (all of which should be lower-cased in title case) is impossible to generate for that reason. See http://www.englishclub.com/download/PDF/EnglishClub-English-Prepositions-List.pdf.
[ii] the script does not correctly handle the case of punctuation within a word. Characters after such punctuation will be upper cased.
RIGHTS: Derived in large part from code by Duncan Cross licensed under the MIT license. http://punchtheair.blogspot.com/, in turn derived from javascript code by David Gouch licensed under the MIT license, https://github.com/gouch/to-title-case.
Copyright © 2015 Duncan Cross
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Adapted for use in NoteCase Pro by Paul E. Merrell, this script's author, who hereby waives all of his copyright and related or neighboring rights to this script, pursuant to the Creative Commons CC0 Universal relinquishment of rights found at http://creativecommons.org/publicdomain/zero/1.0/
CHANGE LOG:
v. 1.0.2
* Added check to see if language setting is English and if not, throw a choice message box on whether to proceed.
v. 1.0.1
* Fix: script did not work when string was all caps. Work-around is to convert string to all lower case before applying title case function.
* Fix: now aborts with error message if string includes either unordered list or A element markup.
TODO:
* find and fix bug that stops script from correctly processing strings that are all upper case. See work-around in second line of first function that converts the string to lower case before other processing
--]]
-- loads functions
local function titlecase(title)
local title = utf8ex.lower(title)
return utf8ex.gsub(title, "()([%w&`'''\".@:/{%(%[<>_]+)(-? *)()",
--return utf8ex.gsub(title, "()([%w&`'''\"".@:/{%(%[<>_]+)(-? *)()",
function(index, nonspace, space, endpos)
local low = nonspace:lower();
if (index > 1) and (title:sub(index-2,index-2) ~= ':')
and (endpos < #title) and smallwords[low] then
return low .. space;
elseif title:sub(index-1, index+1):match("['\"_{%(%[]/)") then
return nonspace:sub(1,1) .. nonspace:sub(2,2):upper()
.. nonspace:sub(3) .. space;
elseif nonspace:sub(2):match("[A-Z&]")
or nonspace:sub(2):match("%w[%._]%w") then
return nonspace .. space;
end
return nonspace:sub(1,1):upper() .. nonspace:sub(2) .. space;
end);
end -- function titlecase
local function Test_String_For_Substrings(s)
for i, v in ipairs(tQueries) do
if utf8ex.find(s, v) == nil then
return 0
else
return 1
end -- if string.find
end -- for i,
end -- function
local function Get_Selected_Note_Content(nDocID, strNoteID, nIsHtml)
local nSelFrom, nSelTo = Nc_Note_SelectionRange_Get(nDocID, strNoteID)
assert(nSelFrom ~= nSelTo, [[
ERROR: Text must be selected
in the Note Pane when using
this script. Aborting execution.]])
-- get selected content in desired format
local strContent = Nc_Note_Content_Get(nDocID, strNoteID, nIsHtml, nSelFrom, nSelTo)
return strContent, nSelFrom, nSelTo
end -- function GetSelected
-- function replaces content in note
local function Replace_Selected_Note_Content(nDocID, strNoteID, strContent, nIsHtml, nSelFrom, nSelTo)
-- makes sure nSelFrom is <= nSelTo
if nSelFrom > nSelTo then nSelFrom, nSelTo = nSelTo, nSelFrom end
-- replace the selected content in the note
Nc_Note_Content_Set(nDocID, strNoteID, strContent, nIsHtml, nSelFrom, nSelTo)
-- get the character count of the new string
local nCount = Nc_String_CharacterCount_Get(strContent)
-- calculate new cursor offset
local nCursorPos = nSelFrom + nCount
-- remove selection highlighting and set the cursor position immediately after the inserted new string
Nc_Note_SelectionRange_Set(nDocID, strNoteID, nCursorPos, nCursorPos)
return
end -- function
-- begins script
-- throws choice message box if program's current language setting is not English
local strLanguage = Nc_Config_Language_Get()
if strLanguage ~= "en" then
local strText = [[
CAUTION: This script is designed
for English text only. It will
damage text in any other language.
Proceed?]]
local nChoice = Nc_GUI_MessageBox(strText, 1, 0, "Caution")
if nChoice == 3 then
return
end
end
-- get IDs for current document/note
local nDocID = Nc_Doc_ID_GetCur()
local strNoteID = Nc_Note_ID_GetCur(nDocID)
-- gets selection
local strContent, nSelFrom, nSelTo = Get_Selected_Note_Content(nDocID, strNoteID, 1)
if strContent == "" then
Nc_GUI_InfoBox("ERROR: Text must be selected. Terminating script prematurely.", "ERROR", 1)
end
-- array of substrings function will test for
tQueries = {
"<A ",
"</A>",
"<a ",
"</a>",
"<UL>",
"</UL>",
"<LI>",
"</LI>"}
-- tests string for A and list elements
local nMatch = Test_String_For_Substrings(strContent)
assert(nMatch ~= 1, "ERROR: Selection includes hyperlink or\r\nbullet list markup. This script cannot\r\nprocess text containing those types of markup.")
-- table of lower case words
smallwords = {
["a"]=1,
["aboard"]=1,
["about"]=1,
["above"]=1,
["according to"]=1,
["across"]=1,
["after"]=1,
["against"]=1,
["ahead of"]=1,
["à la"]=1,
["along"]=1,
["alongside"]=1,
["along with"]=1,
["amid"]=1,
["amidst"]=1,
["among"]=1,
["amongst"]=1,
["and"]=1,
["anti"]=1,
["apart from"]=1,
["around"]=1,
["as"]=1,
["as for"]=1,
["as per"]=1,
["as to"]=1,
["aside from"]=1,
["astride"]=1,
["as well as"]=1,
["at"]=1,
["atop"]=1,
["away from"]=1,
["because of"]=1,
["barring"]=1,
["before"]=1,
["behind"]=1,
["beneath"]=1,
["below"]=1,
["beside"]=1,
["besides"]=1,
["between"]=1,
["betwixt"]=1,
["beyond"]=1,
["but"]=1,
["but for"]=1,
["by"]=1,
["by means of"]=1,
["circa"]=1,
["close to"]=1,
["concerning"]=1,
["considering"]=1,
["contrary to"]=1,
["counting"]=1,
["cum"]=1,
["depending on"]=1,
["despite"]=1,
["down"]=1,
["due to"]=1,
["during"]=1,
["en"]=1,
["except"]=1,
["except for"]=1,
["excepting"]=1,
["excluding"]=1,
["following"]=1,
["for"]=1,
["forward of"]=1,
["from"]=1,
["further to"]=1,
["given"]=1,
["if"]=1,
["in"]=1,
["in addition to"]=1,
["inbetween"]=1,
["in case of"]=1,
["in face of"]=1,
["in favor of"]=1,
["in favour of"]=1,
["in front of"]=1,
["including"]=1,
["in lieu of"]=1,
["in spite of"]=1,
["instead of"]=1,
["inside"]=1,
["into"]=1,
["in view of"]=1,
["irrespective of"]=1,
["like"]=1,
["minus"]=1,
["near"]=1,
["near to"]=1,
["next to"]=1,
["notwithstanding"]=1,
["of"]=1,
["off"]=1,
["on"]=1,
["on account of"]=1,
["on behalf of"]=1,
["on board"]=1,
["onto"]=1,
["on to"]=1,
["on top of"]=1,
["opposite"]=1,
["opposite to"]=1,
["other than"]=1,
["out of"]=1,
["out from"]=1,
["outside"]=1,
["outside of"]=1,
["owing to"]=1,
["over"]=1,
["past"]=1,
["pending"]=1,
["per"]=1,
["plus"]=1,
["preparatory to"]=1,
["prior to"]=1,
["re"]=1,
["regarding"]=1,
["regardless of"]=1,
["respecting"]=1,
["save for"]=1,
["since"]=1,
["than"]=1,
["thanks to"]=1,
["the"]=1,
["through"]=1,
["thru"]=1,
["throughout"]=1,
["til"]=1,
["to"]=1,
["together with"]=1,
["touching"]=1,
["toward"]=1,
["towards"]=1,
["under"]=1,
["unlike"]=1,
["until"]=1,
["up"]=1,
["up against"]=1,
["upon"]=1,
["up to"]=1,
["up until"]=1,
["versus"]=1,
["vs."]=1,
["v."]=1,
["via"]=1,
["vis-à-vis"]=1,
["with"]=1,
["within"]=1,
["without"]=1,
["with reference to"]=1,
["with regard to"]=1,
["worth"]=1
}
-- converts string to title case
local strTitleCase = titlecase(strContent)
-- replaces string in note
Replace_Selected_Note_Content(nDocID, strNoteID, strTitleCase, 1, nSelFrom, nSelTo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment