1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- """
- Fix glyph anchors for Roboto VF.
- Script uses lxml since ufoLib rearranges data.
- The script will do the following:
- 1. Deletes anchors used for design puposes e.g making glyphs built with
- components
- 2. Renames anchors so no custom MarkWriterFeature is needed for fontmake
- 3. Ensures each mark glyph only has 1 anchor which starts with an '_'
- """
- from __future__ import print_function
- import sys
- from lxml import etree
- import copy
- import os
- from glob import glob
- DUPLICATE_ANCHOR_GLYPHS = [
- "A",
- "A",
- "A.smcp",
- "A.smcp",
- "A.unic",
- "A.unic",
- "AE",
- "AE",
- "AE.smcp",
- "AE.smcp",
- "B",
- "B",
- "B.smcp",
- "B.smcp",
- "C",
- "C",
- "C.smcp",
- "C.smcp",
- "D",
- "D",
- "D.smcp",
- "D.smcp",
- "E",
- "E",
- "E.smcp",
- "E.smcp",
- "E.unic",
- "E.unic",
- "Eng",
- "Eng",
- "Eng.smcp",
- "Eng.smcp",
- "Epsilon1",
- "Epsilon1",
- "Esh",
- "Esh",
- "F",
- "F",
- "F.smcp",
- "F.smcp",
- "G",
- "G",
- "G.smcp",
- "G.smcp",
- "Gamma",
- "Gamma",
- "Gamma.smcp",
- "Gamma.smcp",
- "Gbar",
- "Gbar",
- "Gsmallcap",
- "Gsmallcap",
- "Gsmallcaphook",
- "Gsmallcaphook",
- "H",
- "H",
- "H.smcp",
- "H.smcp",
- "Hbar",
- "Hbar",
- "Hbar.smcp",
- "Hbar.smcp",
- "I",
- "I",
- "I.smcp",
- "I.smcp",
- "Ibar",
- "Ibar",
- "Ismallcap",
- "Ismallcap",
- "J",
- "J",
- "J.smcp",
- "J.smcp",
- "K",
- "K",
- "K.smcp",
- "K.smcp",
- "L",
- "L",
- "L.smcp",
- "L.smcp",
- "Lslash",
- "Lslash",
- "Lslash.smcp",
- "Lslash.smcp",
- "Lsmallcap",
- "Lsmallcap",
- "M",
- "M",
- "M.smcp",
- "M.smcp",
- "M.unic",
- "M.unic",
- "N",
- "N",
- "N.smcp",
- "N.smcp",
- "N.unic",
- "N.unic",
- "Nsmallcap",
- "Nsmallcap",
- "O",
- "O",
- "O.smcp",
- "O.smcp",
- "OE",
- "OE",
- "OEsmallcap",
- "OEsmallcap",
- "Ohorn",
- "Ohorn",
- "Oslash",
- "Oslash",
- "Oslash.smcp",
- "Oslash.smcp",
- "P",
- "P",
- "P.smcp",
- "P.smcp",
- "Q",
- "Q",
- "Q.smcp",
- "Q.smcp",
- "R",
- "R",
- "R.alt",
- "R.alt",
- "R.smcp",
- "R.smcp",
- "Rsmallcap",
- "Rsmallcap",
- "Rsmallcapinv",
- "Rsmallcapinv",
- "S",
- "S",
- "S.smcp",
- "S.smcp",
- "Schwa",
- "Schwa",
- "T",
- "T",
- "T.smcp",
- "T.smcp",
- "Thorn.smcp",
- "Thorn.smcp",
- "U",
- "U",
- "U.smcp",
- "U.smcp",
- "U.unic",
- "U.unic",
- "Uhorn",
- "Uhorn",
- "V",
- "V",
- "V.smcp",
- "V.smcp",
- "W",
- "W",
- "W.smcp",
- "W.smcp",
- "X",
- "X",
- "X.smcp",
- "X.smcp",
- "Y",
- "Y",
- "Y.smcp",
- "Y.smcp",
- "Ysmallcap",
- "Ysmallcap",
- "Z",
- "Z",
- "Z.smcp",
- "Z.smcp",
- "Zbar",
- "Zbar",
- "a",
- "a",
- "a_uni02DE",
- "a_uni02DE",
- "ae",
- "ae",
- "alpha",
- "alpha",
- "ascript",
- "ascript",
- "ascriptturn",
- "ascriptturn",
- "aturn",
- "aturn",
- "b",
- "b",
- "babygamma",
- "babygamma",
- "bbar",
- "bbar",
- "bbar_uni1ABE",
- "bbar_uni1ABE",
- "bhook",
- "bhook",
- "bullseye",
- "bullseye",
- "c",
- "c",
- "ccurl",
- "ccurl",
- "cstretch",
- "cstretch",
- "d",
- "d",
- "dcroat",
- "dcroat",
- "dcroat_uni1ABE",
- "dcroat_uni1ABE",
- "dhook",
- "dhook",
- "dotlessi",
- "dotlessi",
- "drthook",
- "drthook",
- "dyogh",
- "dyogh",
- "dz",
- "dz",
- "dzcurl",
- "dzcurl",
- "e",
- "e",
- "eng",
- "eng",
- "eng_uni1ABE",
- "eng_uni1ABE",
- "epsilon",
- "epsilon",
- "epsilon1",
- "epsilon1",
- "epsilon1rev",
- "epsilon1rev",
- "epsilon1revclosed",
- "epsilon1revclosed",
- "epsilon1revhook",
- "epsilon1revhook",
- "epsilonclosed",
- "epsilonclosed",
- "erev",
- "erev",
- "esh",
- "esh",
- "eshcurl",
- "eshcurl",
- "eshshortrev",
- "eshshortrev",
- "eta",
- "eta",
- "f",
- "f",
- "finalkaf",
- "finalkaf",
- "finalmem",
- "finalmem",
- "finalnun",
- "finalnun",
- "g",
- "g",
- "gamma1",
- "gamma1",
- "gbar",
- "gbar",
- "gbar_uni1ABE",
- "gbar_uni1ABE",
- "gcursive",
- "gcursive",
- "ghook",
- "ghook",
- "glottalstop",
- "glottalstop",
- "glottalstopbar",
- "glottalstopbar",
- "glottalstopbarrev",
- "glottalstopbarrev",
- "glottalstopinv",
- "glottalstopinv",
- "glottalstoprevinv",
- "glottalstoprevinv",
- "h",
- "h",
- "henghook",
- "henghook",
- "hhook",
- "hhook",
- "hturn",
- "hturn",
- "i",
- "i",
- "ibar",
- "ibar",
- "iota",
- "iota",
- "iota1",
- "iota1",
- "j",
- "j",
- "jcrosstail",
- "jcrosstail",
- "jdotlessbar",
- "jdotlessbar",
- "jhookdblbar",
- "jhookdblbar",
- "k",
- "k",
- "k.alt",
- "k.alt",
- "kgreenlandic",
- "kgreenlandic",
- "kturn",
- "kturn",
- "l",
- "l",
- "lbar",
- "lbar",
- "lbelt",
- "lbelt",
- "lmidtilde",
- "lmidtilde",
- "longs",
- "longs",
- "lrthook",
- "lrthook",
- "lslash",
- "lslash",
- "lyogh",
- "lyogh",
- "m",
- "m",
- "mhook",
- "mhook",
- "mturn",
- "mturn",
- "mturndescend",
- "mturndescend",
- "n",
- "n",
- "nlfthook",
- "nlfthook",
- "nrthook",
- "nrthook",
- "o",
- "o",
- "oe",
- "oe",
- "ohorn",
- "ohorn",
- "omega",
- "omega",
- "omegaclosed",
- "omegaclosed",
- "oopen",
- "oopen",
- "oslash",
- "oslash",
- "p",
- "p",
- "philatin",
- "philatin",
- "psi",
- "psi",
- "q",
- "q",
- "qhook",
- "qhook",
- "r",
- "r",
- "rdescend",
- "rdescend",
- "rfishhook",
- "rfishhook",
- "rfishhookrev",
- "rfishhookrev",
- "rho",
- "rho",
- "rrthook",
- "rrthook",
- "rturn",
- "rturn",
- "rturnascend",
- "rturnascend",
- "rturnrthook",
- "rturnrthook",
- "s",
- "s",
- "schwa",
- "schwa",
- "schwahook",
- "schwahook",
- "srthook",
- "srthook",
- "t",
- "t",
- "tccurl",
- "tccurl",
- "tesh",
- "tesh",
- "trthook",
- "trthook",
- "ts",
- "ts",
- "tturn",
- "tturn",
- "u",
- "u",
- "ubar",
- "ubar",
- "uhorn",
- "uhorn",
- "uni0069.ccmp",
- "uni0069.ccmp",
- "uni006A.ccmp",
- "uni006A.ccmp",
- "uni012F.ccmp",
- "uni012F.ccmp",
- "uni0237",
- "uni0237",
- "uni023D",
- "uni023D",
- "uni0243",
- "uni0243",
- "uni0244",
- "uni0244",
- "uni0248",
- "uni0248",
- "uni0249",
- "uni0249",
- "uni0249.ccmp",
- "uni0249.ccmp",
- "uni024C",
- "uni024C",
- "uni024D",
- "uni024D",
- "uni024E",
- "uni024E",
- "uni024F",
- "uni024F",
- "uni0268.ccmp",
- "uni0268.ccmp",
- "uni0292",
- "uni0292",
- "uni0293",
- "uni0293",
- "uni029D.ccmp",
- "uni029D.ccmp",
- "uni02A9",
- "uni02A9",
- "uni02AB",
- "uni02AB",
- "uni02AC",
- "uni02AC",
- "uni02AE",
- "uni02AE",
- "uni02B2.ccmp",
- "uni02B2.ccmp",
- "uni03D2",
- "uni03D2",
- "uni03D6",
- "uni03D6",
- "uni03F3.ccmp",
- "uni03F3.ccmp",
- "uni0404",
- "uni0404",
- "uni0404.smcp",
- "uni0404.smcp",
- "uni0416",
- "uni0416",
- "uni0416.smcp",
- "uni0416.smcp",
- "uni0417",
- "uni0417",
- "uni0417.smcp",
- "uni0417.smcp",
- "uni0418",
- "uni0418",
- "uni0418.smcp",
- "uni0418.smcp",
- "uni0423",
- "uni0423",
- "uni0423.smcp",
- "uni0423.smcp",
- "uni0427",
- "uni0427",
- "uni0427.smcp",
- "uni0427.smcp",
- "uni042B",
- "uni042B",
- "uni042B.smcp",
- "uni042B.smcp",
- "uni042D",
- "uni042D",
- "uni042D.smcp",
- "uni042D.smcp",
- "uni042E",
- "uni042E",
- "uni042E.smcp",
- "uni042E.smcp",
- "uni042F",
- "uni042F",
- "uni042F.smcp",
- "uni042F.smcp",
- "uni0432",
- "uni0432",
- "uni0433",
- "uni0433",
- "uni0434",
- "uni0434",
- "uni0436",
- "uni0436",
- "uni0437",
- "uni0437",
- "uni0438",
- "uni0438",
- "uni043A",
- "uni043A",
- "uni043B",
- "uni043B",
- "uni043C",
- "uni043C",
- "uni043D",
- "uni043D",
- "uni043F",
- "uni043F",
- "uni0442",
- "uni0442",
- "uni0444",
- "uni0444",
- "uni0446",
- "uni0446",
- "uni0447",
- "uni0447",
- "uni0448",
- "uni0448",
- "uni0449",
- "uni0449",
- "uni044B",
- "uni044B",
- "uni044D",
- "uni044D",
- "uni044E",
- "uni044E",
- "uni044F",
- "uni044F",
- "uni0454",
- "uni0454",
- "uni0456.ccmp",
- "uni0456.ccmp",
- "uni0458.ccmp",
- "uni0458.ccmp",
- "uni0460",
- "uni0460",
- "uni0461",
- "uni0461",
- "uni046F",
- "uni046F",
- "uni0472",
- "uni0472",
- "uni0473",
- "uni0473",
- "uni0474",
- "uni0474",
- "uni0475",
- "uni0475",
- "uni047B",
- "uni047B",
- "uni047F",
- "uni047F",
- "uni0480",
- "uni0480",
- "uni0481",
- "uni0481",
- "uni048A",
- "uni048A",
- "uni048B",
- "uni048B",
- "uni04A8",
- "uni04A8",
- "uni04A8.smcp",
- "uni04A8.smcp",
- "uni04A9",
- "uni04A9",
- "uni04BA",
- "uni04BA",
- "uni04BA.smcp",
- "uni04BA.smcp",
- "uni04D8",
- "uni04D8",
- "uni04D8.smcp",
- "uni04D8.smcp",
- "uni04E8.smcp",
- "uni04E8.smcp",
- "uni0504",
- "uni0504",
- "uni0506",
- "uni0506",
- "uni050A",
- "uni050A",
- "uni050C",
- "uni050C",
- "uni050D",
- "uni050D",
- "uni050E",
- "uni050E",
- "uni0510",
- "uni0510",
- "uni1D00",
- "uni1D00",
- "uni1D01",
- "uni1D01",
- "uni1D02",
- "uni1D02",
- "uni1D03",
- "uni1D03",
- "uni1D04",
- "uni1D04",
- "uni1D05",
- "uni1D05",
- "uni1D06",
- "uni1D06",
- "uni1D07",
- "uni1D07",
- "uni1D08",
- "uni1D08",
- "uni1D09",
- "uni1D09",
- "uni1D0A",
- "uni1D0A",
- "uni1D0B",
- "uni1D0B",
- "uni1D0C",
- "uni1D0C",
- "uni1D0D",
- "uni1D0D",
- "uni1D0E",
- "uni1D0E",
- "uni1D0F",
- "uni1D0F",
- "uni1D10",
- "uni1D10",
- "uni1D14",
- "uni1D14",
- "uni1D15",
- "uni1D15",
- "uni1D18",
- "uni1D18",
- "uni1D19",
- "uni1D19",
- "uni1D1A",
- "uni1D1A",
- "uni1D1B",
- "uni1D1B",
- "uni1D1C",
- "uni1D1C",
- "uni1D20",
- "uni1D20",
- "uni1D21",
- "uni1D21",
- "uni1D22",
- "uni1D22",
- "uni1D23",
- "uni1D23",
- "uni1D24",
- "uni1D24",
- "uni1D25",
- "uni1D25",
- "uni1D26",
- "uni1D26",
- "uni1D27",
- "uni1D27",
- "uni1D28",
- "uni1D28",
- "uni1D29",
- "uni1D29",
- "uni1D2A",
- "uni1D2A",
- "uni1D2B",
- "uni1D2B",
- "uni1D62.ccmp",
- "uni1D62.ccmp",
- "uni1D6B",
- "uni1D6B",
- "uni1D6C",
- "uni1D6C",
- "uni1D6D",
- "uni1D6D",
- "uni1D6E",
- "uni1D6E",
- "uni1D6F",
- "uni1D6F",
- "uni1D70",
- "uni1D70",
- "uni1D71",
- "uni1D71",
- "uni1D72",
- "uni1D72",
- "uni1D73",
- "uni1D73",
- "uni1D74",
- "uni1D74",
- "uni1D75",
- "uni1D75",
- "uni1D76",
- "uni1D76",
- "uni1D77",
- "uni1D77",
- "uni1D79",
- "uni1D79",
- "uni1D7A",
- "uni1D7A",
- "uni1D7C",
- "uni1D7C",
- "uni1D7D",
- "uni1D7D",
- "uni1D7E",
- "uni1D7E",
- "uni1D7F",
- "uni1D7F",
- "uni1D80",
- "uni1D80",
- "uni1D81",
- "uni1D81",
- "uni1D82",
- "uni1D82",
- "uni1D83",
- "uni1D83",
- "uni1D84",
- "uni1D84",
- "uni1D85",
- "uni1D85",
- "uni1D86",
- "uni1D86",
- "uni1D87",
- "uni1D87",
- "uni1D88",
- "uni1D88",
- "uni1D89",
- "uni1D89",
- "uni1D8A",
- "uni1D8A",
- "uni1D8B",
- "uni1D8B",
- "uni1D8C",
- "uni1D8C",
- "uni1D8D",
- "uni1D8D",
- "uni1D8E",
- "uni1D8E",
- "uni1D8F",
- "uni1D8F",
- "uni1D90",
- "uni1D90",
- "uni1D91",
- "uni1D91",
- "uni1D92",
- "uni1D92",
- "uni1D93",
- "uni1D93",
- "uni1D94",
- "uni1D94",
- "uni1D95",
- "uni1D95",
- "uni1D96",
- "uni1D96",
- "uni1D96.ccmp",
- "uni1D96.ccmp",
- "uni1D97",
- "uni1D97",
- "uni1D98",
- "uni1D98",
- "uni1D99",
- "uni1D99",
- "uni1D9A",
- "uni1D9A",
- "uni1DA4.ccmp",
- "uni1DA4.ccmp",
- "uni1DA8.ccmp",
- "uni1DA8.ccmp",
- "uni1E2C",
- "uni1E2C",
- "uni1E2D",
- "uni1E2D",
- "uni1E2E",
- "uni1E2E",
- "uni1E2F",
- "uni1E2F",
- "uni2071.ccmp",
- "uni2071.ccmp",
- "uni2C7C.ccmp",
- "uni2C7C.ccmp",
- "upsilon",
- "upsilon",
- "upsilonlatin",
- "upsilonlatin",
- "v",
- "v",
- "vscript",
- "vscript",
- "vturn",
- "vturn",
- "w",
- "w",
- "wturn",
- "wturn",
- "x",
- "x",
- "y",
- "y",
- "yturn",
- "yturn",
- "z",
- "z",
- "zbar",
- "zbar",
- "zcurl",
- "zcurl",
- "zrthook",
- "zrthook"
- # mkmk
- "uni0351",
- "uni0350",
- "uni0357",
- "uni035B",
- "uni0343",
- "uni0342",
- "acuterightnosp",
- "graveleftnosp",
- "uni0346",
- "diaeresistonosnosp",
- "uni034A",
- "overscoredblnosp",
- "tildevertsupnosp",
- "xsupnosp",
- "anglesupnosp",
- "uni030C_uni1ABB",
- "dieresisnosp_uni1ABB",
- "uni034C",
- "tildecomb_uni1ABB",
- "uni0352",
- "uni034B",
- "macroncomb_uni1ABB",
- "tildecomb_uni1ABC",
- "tildevertsupnosp",
- "overscoredblnosp",
- "xsupnosp",
- "anglesupnosp",
- "uni0357",
- "uni0352",
- "uni0350",
- "uni0351",
- "uni035B",
- "uni0346",
- "diaeresistonosnosp",
- "acuterightnosp",
- "uni034C",
- "uni034B",
- "tildecomb_uni1ABC",
- "dieresisnosp_uni1ABB",
- "tildecomb_uni1ABB",
- "uni0342",
- "uni0343",
- "graveleftnosp",
- "uni030C_uni1ABB",
- "macroncomb_uni1ABB",
- "uni034A"
- ]
- def duplicate_anchor(glyph, src, dst):
- outline = glyph.find('outline')
- src_anc = glyph.xpath("//point[@name='{}']".format(src))[0]
- dst_anc = glyph.xpath("//point[@name='{}']".format(dst))
- if not dst_anc:
- dst_anc = copy.deepcopy(src_anc.getparent())
- dst_anc.getchildren()[0].attrib['name'] = dst
- outline.append(dst_anc)
- def rename_anchor(glyph, src, dst):
- anc = glyph.xpath("//point[@name='{}']".format(src))
- if anc:
- anc[0].attrib['name'] = dst
- def delete_anchor(glyph, anc_name):
- anc = glyph.xpath("//point[@name='{}']".format(anc_name))
- if anc:
- anc = anc[0].getparent()
- anc.getparent().remove(anc)
- def _delete_design_anchors(glyph):
- anchors_to_delete = [
- "_ogonek",
- "_rhalfring",
- "_right",
- "_tonos",
- "_top",
- "_bottom",
- "_bottomu",
- "_caron",
- "_cross",
- "_dot",
- "_left",
- "ogonek",
- "rhalfring",
- "right",
- "tonos",
- "bottomu",
- "caron",
- "cross",
- "dot",
- "left"
- ]
- for anchor in anchors_to_delete:
- delete_anchor(glyph, anchor)
- def _rename_anchors(glyph):
- anchors = [
- ("_marktop", "_top"),
- ("_markbottom", "_bottom"),
- ("_marktop_dd", "_top_dd"),
- ("_markbottom_dd", "_bottom_dd"),
- ("_markrhotichook", "_rhotichook"),
- ("_marktop0315", "_top0315"),
- ("_markparent_top", "_parent_top"),
- ("_markparenthesses.w1", "_parenthesses.w1"),
- ("_markparenthesses.w2", "_parenthesses.w2"),
- ("_markparenthesses.w3", "_parenthesses.w3"),
- ("mkmktop", "top"),
- ("mkmkbottom_acc", "bottom"),
- ]
- for before_anchor, after_anchor in anchors:
- rename_anchor(glyph, before_anchor, after_anchor)
- def _script_already_used(glyph):
- """Check if a user has already executed the script on the .ufo.
- Executing the script multiple times on the same .ufo will lead to
- unforeseen modifications."""
- prev_added_anc = glyph.xpath("//point[@name='parent_top']")
- if prev_added_anc:
- return True
- return False
- def main(ufo_path):
- if not ufo_path.endswith('ufo'):
- raise Exception('{} is not a ufo'.format(ufo_path))
- glifs = glob(os.path.join(ufo_path, 'glyphs', '*.glif'))
- # check script has not already been run on this font
- a_glyph = etree.parse(os.path.join(ufo_path, 'glyphs', 'a.glif'))
- if _script_already_used(a_glyph):
- raise Exception('Script has already been used')
- for path in glifs:
- glyph = etree.parse(path)
- glyph_name = glyph.getroot().attrib['name']
- _delete_design_anchors(glyph)
- _rename_anchors(glyph)
- if glyph_name in ['cedilla', 'commaaccent', 'ogonek']:
- delete_anchor(glyph, 'bottom')
- if glyph_name in ['uni1ABB', 'uni1ABC']:
- delete_anchor(glyph, '_top')
- if glyph_name in DUPLICATE_ANCHOR_GLYPHS:
- duplicate_anchor(glyph, "top", "parent_top")
- glyph.write(path)
- print('Fixed anchors: {}'.format(ufo_path))
- if __name__ == '__main__':
- if len(sys.argv) != 2:
- raise Exception("Include path to ufo")
- else:
- ufo_path = sys.argv[1]
- main(sys.argv[1])
|