Plug-In: Character Attributes Apple Vision Pro

A plug-in for setting and restoring the character attributes of the note of the selected project or task.

(NOTE: This plug-in requires OmniFocus 4.x)

Character Attributes Dialog

(above) Each of the specified character attributes has its own menu of settings and options. By default, the initial setting for each property is: “No Change”

All but the alignment property menus offer these two options:

NOTE: Immediately following each attribute title, placed within parens, is the current value of that attribute in the note.

IMPORTANT: Attribute changes are applied to all of the note text, not just a selection.

Here is a description of each of the character attributes:

Return to: OmniFocus Plug-In Collection

Character Attributes
   

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automator", "identifier": "com.omni-automation.of.character-attributes", "version": "1.5", "description": "This plug-in will display and apply the character attribute settings of the note of the selected project or task.", "label": "Note Style Character Attributes", "shortLabel": "Character Attributes", "paletteLabel": "Character Attributes", "image": "textformat.abc.dottedunderline" }*/ (() => { var action = new PlugIn.Action(async function(selection, sender){ try { var shouldLog = true if(shouldLog){console.clear()} var item = selection.databaseObjects[0] // CREATE VIRTUAL TEXT OBJECT CONTAING CURRENT NOTE var noteObj = new Text("", baseStyle) noteObj.replace(noteObj.range, item.noteText) var nStyle = noteObj.style // GET ATTRIBUTES RANGES var runRanges = noteObj.ranges(TextComponent.AttributeRuns) // CREATE FORM AND FORM ELEMENTS fontFamilyTitles = ["Default", "Avenir Next", "Baskerville", "Bodoni 72", "Bradley Hand", "Chalkboard SE", "Cochin", "Courier New", "Damascus", "Georgia", "Gill Sans", "Helvetica Neue", "Hoefler Text", "Menlo", "Noteworthy", "Optima", "Palatino", "Rockwell", "Savoye LET", "Snell Roundhand", "Times New Roman", "Trebuchet MS", "Verdana"] fontFamilyIndexes = fontFamilyTitles.map((title, index) => index) var fontFamCurVal = nStyle.get(Style.Attribute.FontFamily) fontFamCurVal = (fontFamCurVal === ".AppleSystemUIFont") ? "System Font":fontFamCurVal fontFamilyMenu = new Form.Field.Option( "fontFamily", `Font Family (${fontFamCurVal})`, fontFamilyIndexes, fontFamilyTitles, null ) fontFamilyMenu.allowsNull = true fontFamilyMenu.nullOptionTitle = "No Change" fntWghtCurVal = nStyle.get(Style.Attribute.FontWeight) fntWghtValueStrings = ["Default", "1", "2", "3", "4", "5", "6", "7", "8", "9"] fntWghtValues = fntWghtValueStrings.map((title, index) => index) fontWeightMenu = new Form.Field.Option( "fontWeight", `Font Weight (${fntWghtCurVal})`, fntWghtValues, fntWghtValueStrings, null ) fontWeightMenu.allowsNull = true fontWeightMenu.nullOptionTitle = "No Change" var fntSzeCurVal = nStyle.get(Style.Attribute.FontSize) fntSzeValueStrings = ["Default", "9", "10", "11", "12", "13", "14", "15", "16", "18", "24"] fntSzeValues = fntSzeValueStrings.map((title, index) => index) fontSizeMenu = new Form.Field.Option( "fontSize", `Font Size (${fntSzeCurVal})`, fntSzeValues, fntSzeValueStrings, null ) fontSizeMenu.allowsNull = true fontSizeMenu.nullOptionTitle = "No Change" fntKrnCurVal = nStyle.get(Style.Attribute.KerningAdjustment) fntKrnCurVal = fntKrnCurVal.toString() fntKrnCurVal = (fntKrnCurVal === "NaN") ? "0":fntKrnCurVal fntKrnValueStrings = ["Default", "+3", "+2", "+1", " 0", "-1", "-2", "-3"] fntKrnValues = fntKrnValueStrings.map((title, index) => index) fontKerningMenu = new Form.Field.Option( "kerningAdjustment", `Kerning Adjustment (${fntKrnCurVal})`, fntKrnValues, fntKrnValueStrings, null ) fontKerningMenu.allowsNull = true fontKerningMenu.nullOptionTitle = "No Change" fntFilClrCurVal = nStyle.get(Style.Attribute.FontFillColor) fntFilClrCurVal = String(100 - (fntFilClrCurVal.white * 100)) fntFilClrValStrings = ["Default", "100", "95", "90", "85", "80", "75", "70"] fntFilClrIndexes = fntFilClrValStrings.map((title, index) => index) fontFillColorMenu = new Form.Field.Option( "fontFillColor", `Color Shade Pct (${fntFilClrCurVal})`, fntFilClrIndexes, fntFilClrValStrings, null ) fontFillColorMenu.allowsNull = true fontFillColorMenu.nullOptionTitle = "No Change" // CONSTRUCT FORM inputForm = new Form() inputForm.addField(fontFamilyMenu) inputForm.addField(fontWeightMenu) inputForm.addField(fontSizeMenu) inputForm.addField(fontKerningMenu) inputForm.addField(fontFillColorMenu) formPrompt = "Note Character Attributes:" buttonTitle = "Continue" formObject = await inputForm.show(formPrompt, buttonTitle) // retrieve attribute settings if(shouldLog){console.log(">>> RETRIEVING FORM SETTINGS <<<")} fontFamilyIndex = formObject.values["fontFamily"] fontFamily = fontFamilyTitles[fontFamilyIndex] console.log("fontFamily", fontFamily) fontWeightIndex = formObject.values["fontWeight"] fontWeight = fntWghtValueStrings[fontWeightIndex] console.log("fontWeight", fontWeight) fontSizeIndex = formObject.values["fontSize"] fontSize = fntSzeValueStrings[fontSizeIndex] console.log("fontSize", fontSize) fontKerningIndex = formObject.values["kerningAdjustment"] fontKerning = fntKrnValueStrings[fontKerningIndex] console.log("fontKerning", fontKerning) fontFillColorIndex = formObject.values["fontFillColor"] fontFillColor = fntFilClrValStrings[fontFillColorIndex] console.log("fontFillColor", fontFillColor) // SET ATTRIBUTE VALUES if(shouldLog){console.log(">>> ORGANIZING VALUES <<<")} var attsToModify = [] var valuesToApply = [] if(fontFamily){ if(shouldLog){console.log("fontFamily", fontFamily)} if(fontFamily === "Default"){ var valueToSet = Style.Attribute.FontFamily.defaultValue } else { var valueToSet = fontFamily } attsToModify.push(Style.Attribute.FontFamily) valuesToApply.push(valueToSet) } if(fontWeight){ if(shouldLog){console.log("fontWeight", fontWeight)} if(fontWeight === "Default"){ var valueToSet = Style.Attribute.FontWeight.defaultValue } else { var valueToSet = parseInt(fontWeight) } attsToModify.push(Style.Attribute.FontWeight) valuesToApply.push(valueToSet) } if(fontSize){ if(shouldLog){console.log("fontSize", fontSize)} if(fontSize === "Default"){ var valueToSet = Style.Attribute.FontSize.defaultValue } else { var valueToSet = parseInt(fontSize) } attsToModify.push(Style.Attribute.FontSize) valuesToApply.push(valueToSet) } if(fontKerning){ if(shouldLog){console.log("fontKerning", fontKerning)} if(fontKerning === "Default"){ var valueToSet = Style.Attribute.KerningAdjustment.defaultValue } else { var valueToSet = parseInt(fontKerning) } attsToModify.push(Style.Attribute.KerningAdjustment) valuesToApply.push(valueToSet) } if(fontFillColor){ if(shouldLog){console.log("fontFillColor", fontFillColor)} if(fontFillColor === "Default"){ var valueToSet = Style.Attribute.FontFillColor.defaultValue } else { var shadePct = parseInt(fontFillColor) shadePct = shadePct * 0.01 shadeValue = 1 - shadePct valueToSet = Color.White(shadeValue, 1) } attsToModify.push(Style.Attribute.FontFillColor) valuesToApply.push(valueToSet) attsToModify.push(Style.Attribute.FontStrokeColor) valuesToApply.push(valueToSet) } // APPLY THE SPECIFIED ATTRIBUTE SETTINGS if(shouldLog){console.log(">>> APPLYING VALUES TO NOTEOBJ <<<")} runRanges.forEach(range => { runStyle = noteObj.styleForRange(range) attsToModify.forEach((att, index) => { valueToSet = valuesToApply[index] if(shouldLog){console.log("Range:", noteObj.textInRange(range).string)} if(shouldLog){console.log("Attribute:", att.key)} if(shouldLog){console.log("Value:", valueToSet)} runStyle.set(att, valueToSet) }) }) // REPLACE NOTE WITH VIRTUAL OBJECT if(shouldLog){console.log(">>> REPLACING TEXT WITH NOTEOBJ <<<")} item.noteText.replace(item.noteText.range, noteObj) // reveal note //if(shouldLog){console.log("SHOW NOTE")} tree = document.windows[0].content tree.nodeForObject(item).expandNote(false) } catch(err){ if(!err.causedByUserCancelling){ console.log(err.name, err.message) } } }); action.validate = function(selection, sender){ // validation code // selection options: tasks, projects, folders, tags, allObjects return (selection.tasks.length === 1 || selection.projects.length === 1 ) }; return action; })();