def handler(data, response, error): callback = self._callbacks[url] # if there is no data we return the original URL response_url = url if data and response: # save the URL returned after all the possible redirects post_redirect_url = response.URL() if self._cache: # always cache with the original request URL so even # if the response requires a redirect, like for raw # files on Github, we can still fulfill it offline self.setCachedData_forURL_(data, url) # but in that case, remove the cached data for the # final URL so we don’t store two copies if url != post_redirect_url: self.invalidateCacheForURL_(post_redirect_url) # if we have a response we pass the final URL after # the redirects, so a consumer can see it changed response_url = post_redirect_url # callAfter executes on the main thread callAfter(callback, response_url, data, error) del self._callbacks[url]
def buttonCallback(self, sender): """Runs when the Search button is pressed.""" kernChars = self.w.kernChars.get() #.decode("utf-8") self.w.close() myFiles = openFileDialog() literature = u"" if myFiles != None: for filepath in myFiles: f = open(filepath, mode='r') print ">>> Reading:", f.name literature += f.read().decode('utf-8') f.close() myPairList = searchForKernPairs(kernChars=kernChars, text=literature, excludeString=myExcludeString) editTabString = " ".join(myPairList) try: # try to guess the frontmost window: Doc = Glyphs.font.parent # document for current font callAfter(Doc.windowController().addTabWithString_, editTabString) except: # if that fails, take the Macro Window: Glyphs.clearLog() Glyphs.showMacroWindow() print "Copy this paragraph and paste it into an Edit tab in text mode:" print editTabString
def buttonCallback(self, sender): """Runs when the Search button is pressed.""" kernChars = self.w.kernChars.get() #.decode("utf-8") self.w.close() myFiles = openFileDialog() literature = u"" if myFiles != None: for filepath in myFiles: f = open( filepath, mode='r' ) print ">>> Reading:", f.name literature += f.read().decode('utf-8') f.close() myPairList = searchForKernPairs( kernChars=kernChars, text=literature, excludeString=myExcludeString ) editTabString = " ".join( myPairList ) try: # try to guess the frontmost window: Doc = Glyphs.font.parent # document for current font callAfter( Doc.windowController().addTabWithString_, editTabString ) except: # if that fails, take the Macro Window: Glyphs.clearLog() Glyphs.showMacroWindow() print "Copy this paragraph and paste it into an Edit tab in text mode:" print editTabString
def processMetrics(self, sender): def processProcess( thisLayer ): thisLayerKey = (str(thisLayer.leftMetricsKeyUI()), str(thisLayer.rightMetricsKeyUI())) if sender == self.w.reportManual: # This layer does not have auto aligned width and no left and right layer or glyph metrics key if not thisLayer.hasAlignedWidth() and all(x is None for x in [thisLayer.leftMetricsKey(), thisGlyph.leftMetricsKey, thisLayer.rightMetricsKey(), thisGlyph.rightMetricsKey]): thisGlyphname = thisGlyph.name elif sender == self.w.reportAuto: # This layer has auto aligned width if thisLayer.hasAlignedWidth(): thisGlyphname = thisGlyph.name elif sender == self.w.reportLinked: # This layer does not have auto aligned width and has either left or right layer or glyph metrics key if not thisLayer.hasAlignedWidth() and any(x is not None for x in [thisLayer.leftMetricsKey(), thisGlyph.leftMetricsKey, thisLayer.rightMetricsKey(), thisGlyph.rightMetricsKey]): thisGlyphname = thisGlyph.name print "%s\n %s" % (thisGlyphname, thisLayerKey) return thisGlyphname glyphList = "" # print "These glyphs have %s metrics\n" % metricsType for thisLayer in selectedLayers: thisGlyph = thisLayer.parent try: glyphList += "/" + processProcess( thisLayer ) except: pass callAfter( Doc.windowController().addTabWithString_, glyphList )
def output(self, sender): output = "" inputString = self.w.editText.get() outputList = [str(y) for y in inputString.split("/")] for glyphName in outputList: output += str(glyphName) + "/" print output for font in fonts: callAfter(font.parent.windowController().addTabWithString_, "".join(x for x in output)) self.w.close()
def fetchURL_withCallback_(self, url, callback): cachedData = self.getCachedDataForURL_(url) if cachedData: # callAfter executes on the main thread callAfter(callback, url, cachedData, None) return request = self.requestForURL_(url) handler = self.makeHandlerWithURL_(url) if url not in self._callbacks: self._callbacks[url] = callback task = self._session.\ dataTaskWithRequest_completionHandler_(request, handler) task.resume() else: logger.error(f'{url} already being fetched')
def buttonCallback(self, sender): Font = Glyphs.font selectedLayers = Font.selectedLayers numberOfMasters = len( Font.masters ) editString = u"" searchFor = self.w.searchFor.get() for g in Font.glyphs: if len( g.layers ) > numberOfMasters: for l in [ x for x in g.layers ][numberOfMasters:]: if searchFor in l.name: print "%s in %s" % (l.name, g.name) UpperGlyph = Font.glyphForName_(g.name) Char = unichr(Font.characterForGlyph_(UpperGlyph)) editString += Char # Glyphs.showMacroWindow() callAfter( Doc.windowController().addTabWithString_, editString )
def handler(data, response, error): callback = self._callbacks[url] # if there is no data we return the original URL response_url = url if data and response: # always cache with the original request URL so even # if the response requires a redirect, like for raw # files on Github, we can still fulfill it offline self.setCachedData_forURL_(data, url) # if we have a response we pass the final URL after # the redirects, so a consumer can see it changed response_url = response.URL() # callAfter executes on the main thread callAfter(callback, response_url, data, error) del self._callbacks[url]
def showAllMastersOfGlyphInCurrentTab( thisGlyphName ): try: escapedGlyphName = "/" + thisGlyphName thisDoc = Glyphs.currentDocument thisWindow = thisDoc.windowController() thisEditView = thisWindow.activeEditViewController() # current tab if thisEditView is None: # opens new Edit tab if none was open: callAfter( thisWindow.addTabWithString_, escapedGlyphName ) else: thisGraphicView = thisEditView.graphicView() # current display string thisGraphicView.setDisplayString_( escapedGlyphName ) # set the display string to this glyph thisGraphicView.setSelectedRange_( zeroPosition ) # moves the cursor to beginning thisEditView.insertAllMasters_( None ) # insert all masters return True except Exception as e: print e return False
def buttonCallback(self, sender): Font = Glyphs.font selectedLayers = Font.selectedLayers numberOfMasters = len(Font.masters) editString = u"" searchFor = self.w.searchFor.get() for g in Font.glyphs: if len(g.layers) > numberOfMasters: for l in [x for x in g.layers][numberOfMasters:]: if searchFor in l.name: print "%s in %s" % (l.name, g.name) UpperGlyph = Font.glyphForName_(g.name) Char = unichr(Font.characterForGlyph_(UpperGlyph)) editString += Char # Glyphs.showMacroWindow() callAfter(Doc.windowController().addTabWithString_, editString)
def processMetrics(self, sender): def processProcess(thisLayer): thisLayerKey = (str(thisLayer.leftMetricsKeyUI()), str(thisLayer.rightMetricsKeyUI())) if sender == self.w.reportManual: # This layer does not have auto aligned width and no left and right layer or glyph metrics key if not thisLayer.hasAlignedWidth() and all(x is None for x in [ thisLayer.leftMetricsKey(), thisGlyph.leftMetricsKey, thisLayer.rightMetricsKey(), thisGlyph.rightMetricsKey ]): thisGlyphname = thisGlyph.name elif sender == self.w.reportAuto: # This layer has auto aligned width if thisLayer.hasAlignedWidth(): thisGlyphname = thisGlyph.name elif sender == self.w.reportLinked: # This layer does not have auto aligned width and has either left or right layer or glyph metrics key if not thisLayer.hasAlignedWidth() and any( x is not None for x in [ thisLayer.leftMetricsKey(), thisGlyph.leftMetricsKey, thisLayer.rightMetricsKey(), thisGlyph.rightMetricsKey ]): thisGlyphname = thisGlyph.name print "%s\n %s" % (thisGlyphname, thisLayerKey) return thisGlyphname glyphList = "" # print "These glyphs have %s metrics\n" % metricsType for thisLayer in selectedLayers: thisGlyph = thisLayer.parent try: glyphList += "/" + processProcess(thisLayer) except: pass callAfter(Doc.windowController().addTabWithString_, glyphList)
#MenuTitle: Export All Instances # -*- coding: utf-8 -*- __doc__ = """ Exports all instances of all opened files to a chosen destination """ def exportAllInstances(): folderPath = GetFolder(allowsMultipleSelection = False) for font in Glyphs.fonts: for instance in font.instances: instance.generate(FontPath = folderPath) Message('Export All Instances', 'Export successful.') from PyObjCTools.AppHelper import callAfter # makes possible for Glyphs 1.x to run OS X UI related code callAfter(exportAllInstances, None)
# -*- coding: utf-8 -*- """ Show all glyphs in the kerning groups of the selected glyph in a new tab. """ import GlyphsApp from PyObjCTools.AppHelper import callAfter Doc = Glyphs.currentDocument Font = Glyphs.font selectedLayers = Font.selectedLayers allLeftGlyphs = "L " allRightGlyphs = "R " for l in selectedLayers: thisGlyph = l.parent leftGroup = thisGlyph.leftKerningGroup rightGroup = thisGlyph.rightKerningGroup print '\t', leftGroup, rightGroup for g in Font.glyphs: if g.leftKerningGroup and g.leftKerningGroup == leftGroup: allLeftGlyphs += "/" + g.name if g.rightKerningGroup and g.rightKerningGroup == rightGroup: allRightGlyphs += "/" + g.name print allLeftGlyphs print allRightGlyphs callAfter( Doc.windowController().addTabWithString_, allLeftGlyphs + '\n' + allRightGlyphs )
#MenuTitle: New Tab with Right Groups # -*- coding: utf-8 -*- __doc__ = """ Creates a new tab with one glyph of each right group. Useful for checking the constency of right kerning groups. """ thisFont = Glyphs.font # frontmost font thisFontMaster = thisFont.selectedFontMaster # active master listOfSelectedLayers = thisFont.selectedLayers # active layers of selected glyphs groupDict = {} for thisGlyph in thisFont.glyphs: glyphName = thisGlyph.name rGroup = thisGlyph.rightKerningGroup if rGroup in groupDict.keys(): groupDict[rGroup].append(glyphName) else: groupDict[rGroup] = [glyphName] tabString = "" for thisRightGroup in groupDict.keys(): tabString += "/%s/space\n" % "/".join(groupDict[thisRightGroup]) # opens new Edit tab: from PyObjCTools.AppHelper import callAfter callAfter(Glyphs.currentDocument.windowController().addTabWithString_, tabString)
#MenuTitle: New Tab with Selected Glyph Combinations # -*- coding: utf-8 -*- __doc__=""" Opens a new tab with all possible combinations of currently selected glyphs. """ import GlyphsApp from PyObjCTools.AppHelper import callAfter Doc = Glyphs.currentDocument Font = Glyphs.font selectedLayers = Font.selectedLayers namesOfSelectedGlyphs = [ "/%s" % l.parent.name for l in selectedLayers if hasattr(l.parent, 'name')] editString = "" for leftGlyphName in namesOfSelectedGlyphs: for rightGlyphName in namesOfSelectedGlyphs: editString += ( leftGlyphName + rightGlyphName ) editString += ( leftGlyphName + "\n" ) # in case last line fails, the text is in the macro window: Glyphs.clearLog() # clears macro window log print editString # opens new Edit tab: callAfter( Doc.windowController().addTabWithString_, editString )
def worker(): process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, encoding="utf-8", bufsize=1) readers = [process.stdout, process.stderr] while readers: readyReaders, _, _ = select.select(readers, [], [], timeout) if not readyReaders: process.kill() callAfter( stderrCallback, f"The {name} process timed out (in select.select())") callAfter(resultCallback, -1) return for reader in readyReaders: data = reader.readline() if not data: readers.remove(reader) continue if reader is process.stderr: callAfter(stderrCallback, data) else: callAfter(stdoutCallback, data) try: process.wait(timeout=timeout) except subprocess.TimeoutExpired: process.kill() callAfter(stderrCallback, f"The {name} process timed out (in process.wait())") callAfter(resultCallback, -1) return callAfter(resultCallback, process.returncode)
selectedLayers = thisFont.selectedLayers thisFontMaster = thisFont.selectedFontMaster # active master candidates = [] listOfAllComponents = [] allGlyphs = [glyph.name for glyph in thisFont.glyphs] for glyph in thisFont.glyphs: thisLayer = glyph.layers[thisFont.selectedFontMaster.id] if len(thisLayer.components) > 0: for component in thisLayer.componentNames(): listOfAllComponents.append(component) if len(thisLayer.paths) > 0: if len(thisLayer.components) == 0 and len(thisLayer.anchors) > 0: candidates.append(glyph.name) glyphNamesNotUsedAsComponents = [x for x in candidates if x not in listOfAllComponents] output = "/" output += "/".join(glyphNamesNotUsedAsComponents) callAfter(Glyphs.currentDocument.windowController().addTabWithString_, output) ### Open Tab with all Characters for g in glyphNamesNotUsedAsComponents: glyphToRemoveAnchor = thisFont.glyphs[g] if removeAnchors: layer = glyphToRemoveAnchor.layers[thisFont.selectedFontMaster.id] layer.setAnchors_( None )
from PyObjCTools.AppHelper import callAfter from random import shuffle import copy Doc = Glyphs.currentDocument Font = Glyphs.font selectedLayers = Font.selectedLayers namesOfSelectedGlyphs = ["/" + l.parent.name for l in selectedLayers] random_list = copy.copy(namesOfSelectedGlyphs) before_string = "" for GlyphName in namesOfSelectedGlyphs: before_string += GlyphName print before_string shuffle(random_list) randomized_string = "" print "Randomizing..." for GlyphName in random_list: randomized_string += GlyphName print "Output:" + randomized_string callAfter(Glyphs.currentDocument.windowController().addTabWithString_, randomized_string)
for thisPath in thisLayer.paths: numberOfNodes = len(thisPath.nodes) for i in range(numberOfNodes-1): thisNode = thisPath.nodes[i] if thisNode.type == 65: prevNodeIndex = (i-1) % numberOfNodes nextNodeIndex = (i+1) % numberOfNodes prevNode = thisPath.nodes[prevNodeIndex] nextNode = thisPath.nodes[nextNodeIndex] if thisNode.position == prevNode.position or thisNode.position == nextNode.position: return True return False listOfGlyphNames = [] for thisGlyph in thisFont.glyphs: thisLayer = thisGlyph.layers[thisFontMasterID] if process( thisLayer ): glyphName = thisGlyph.name print "Found Zero Handle in", glyphName listOfGlyphNames.append( glyphName ) if listOfGlyphNames: # opens new Edit tab: from PyObjCTools.AppHelper import callAfter callAfter( Glyphs.currentDocument.windowController().addTabWithString_, "/%s" % ("/".join(listOfGlyphNames)) ) else: # brings macro window to front and clears its log: Glyphs.clearLog() Glyphs.showMacroWindow() print "No glyphs with zero handles found."
#MenuTitle: Show this in Context # -*- coding: utf-8 -*- __doc__=""" Show selected text in spacing context in a new tab. """ import GlyphsApp from PyObjCTools.AppHelper import callAfter from kernMakerFunc import kernMaker Font = Glyphs.font Doc = Glyphs.currentDocument selectedLayers = Font.selectedLayers namesOfSelectedGlyphs = [ "/%s" % l.parent.name for l in selectedLayers ] editString = "".join(namesOfSelectedGlyphs) callAfter( Doc.windowController().addTabWithString_, kernMaker(editString) )
import GlyphsApp from PyObjCTools.AppHelper import callAfter Doc = Glyphs.currentDocument Font = Glyphs.font selectedLayers = Font.selectedLayers glyphList = "" def process( thisLayer ): disabledComps = "" thisGlyph = thisLayer.parent if thisLayer.components: for thisComp in thisLayer.components: if thisComp.disableAlignment: disabledComps += str(thisComp.componentName) + " " if disabledComps: print "%s:\n\t%s\n" % (thisGlyph.name, disabledComps) return thisGlyph.name print "These glyphs have components not automatically aligned\n" for thisLayer in selectedLayers: thisGlyph = thisLayer.parent try: glyphList += "/" + process( thisLayer ) except: pass # print glyphList callAfter( Doc.windowController().addTabWithString_, glyphList )
# -*- coding: utf-8 -*- __doc__=""" Show All Kerning Pairs for this Master in a new tab """ import GlyphsApp from PyObjCTools.AppHelper import callAfter Font = Glyphs.font Doc = Glyphs.currentDocument selectedLayers = Font.selectedLayers selectedMaster = Font.selectedFontMaster masterID = selectedMaster.id editString = u"""""" def nameMaker(kernGlyph): if kernGlyph[0] == "@": return kernGlyph[7:] else: return Font.glyphForId_(kernGlyph).name for L in Font.kerning[ masterID ]: try: for R in Font.kerning[masterID][L]: kernPair = "/%s/%s " % (nameMaker(L), nameMaker(R)) editString += kernPair except: pass callAfter( Doc.windowController().addTabWithString_, editString )
for i in range(numberOfNodes - 1): thisNode = thisPath.nodes[i] if thisNode.type == 65: prevNodeIndex = (i - 1) % numberOfNodes nextNodeIndex = (i + 1) % numberOfNodes prevNode = thisPath.nodes[prevNodeIndex] nextNode = thisPath.nodes[nextNodeIndex] if thisNode.position == prevNode.position or thisNode.position == nextNode.position: return True return False listOfGlyphNames = [] for thisGlyph in thisFont.glyphs: thisLayer = thisGlyph.layers[thisFontMasterID] if process(thisLayer): glyphName = thisGlyph.name print "Found Zero Handle in", glyphName listOfGlyphNames.append(glyphName) if listOfGlyphNames: # opens new Edit tab: from PyObjCTools.AppHelper import callAfter callAfter(Glyphs.currentDocument.windowController().addTabWithString_, "/%s" % ("/".join(listOfGlyphNames))) else: # brings macro window to front and clears its log: Glyphs.clearLog() Glyphs.showMacroWindow() print "No glyphs with zero handles found."
import GlyphsApp thisFont = Glyphs.font # frontmost font thisFontMaster = thisFont.selectedFontMaster # active master listOfSelectedLayers = thisFont.selectedLayers # active layers of selected glyphs tabString = "" if len(listOfSelectedLayers) > 1: firstGlyph = listOfSelectedLayers[0].parent firstGroup = firstGlyph.rightKerningGroup secondGlyph = listOfSelectedLayers[1].parent secondGroup = secondGlyph.leftKerningGroup firstGlyphNames = [g.name for g in thisFont.glyphs if g.rightKerningGroup == firstGroup] secondGlyphNames = [g.name for g in thisFont.glyphs if g.leftKerningGroup == secondGroup] for firstGlyphName in firstGlyphNames: for secondGlyphName in secondGlyphNames: thisPair = "/%s/%s/space" % (firstGlyphName, secondGlyphName) tabString += thisPair tabString = tabString.strip() + "\n" tabString = tabString.strip() if tabString: # opens new Edit tab: from PyObjCTools.AppHelper import callAfter callAfter(Glyphs.currentDocument.windowController().addTabWithString_, tabString)
#MenuTitle: Set New Path for Images # -*- coding: utf-8 -*- __doc__=""" Resets the path for placed images in selected glyphs. Useful if you have moved your images. """ import GlyphsApp from PyObjCTools.AppHelper import callAfter Font = Glyphs.font FontMaster = Font.selectedFontMaster selectedLayers = Font.selectedLayers #newFolder = GetFolder( message="Choose location of placed images:", allowsMultipleSelection = False ) newFolder = callAfter( GetFolder, message="Choose location of placed images:" ) Glyphs.clearLog() Glyphs.showMacroWindow() print "New image paths for selected glyphs:" print newFolder def process( thisLayer ): try: thisImage = thisLayer.backgroundImage() thisImageFileName = thisImage.imagePath().split("/")[-1] thisImageNewFullPath = "%s/%s" % ( newFolder, thisImageFileName ) thisImage.setImagePath_( thisImageNewFullPath ) except Exception as e: if "NoneType" in str(e): return "No image found." else: return "Error: %s." % e