{
   "description" : "tag system sketch",
   "ancestor_list" : [],
   "author" : "vividsnow",
   "name" : "tagger",
   "code" : "( // create tagger\r\n~t = {\r\n\tvar lib = Dictionary();\r\n\t{ |w,k,op='|'|\r\n\t\tif(w.isNil.not and: w.isMemberOf(Association).not, {\r\n\t\t\t[k,w] do: {|t|\r\n\t\t\t\t[t].flatten do: {|i| lib.includesKey(i).not.if({ lib[i] = Set() })} };\r\n\t\t\tk.isNil.not.if({ [k].flatten do: {|i|\r\n\t\t\t\t[w].flatten do: {|j|\r\n\t\t\t\t\tlib[i] = [lib[i],j].reduce(op);\r\n\t\t\t\t\tlib[j] = [lib[j],i].reduce(op); }} }) });\r\n\t\tw.isNil.if({lib}, { var op = '&';\r\n\t\t\tw.isMemberOf(Association).if({ op = w.value; w = w.key });\r\n\t\t\t[w].flatten.collect(lib[_]).reduce(op) }) } }.();\r\n);\r\n\r\n// usage\r\n// add ops\r\nNdef(\\kick) !? ~t.(\\kikin,_); // add tag for ndef\r\nNdef(\\kick) !? ~t.([\\bassy,\\perc],_); // add tags for ndef\r\n~t.([\\bassy,\\perc], Ndef(\\kick)); // same\r\n~t.(Ndef(\\kick), [\\bassy,\\perc]); // same\r\nNdef(\\bass) !? ~t.([\\bassy,\\perc,\\fav],_); // same\r\n[Ndef(\\kick), Ndef(\\bass)] !? ~t.([\\some,\\thing],_); // many-to-many\r\n~t.([Ndef(\\kick), Ndef(\\bass)], [\\some,\\thing]); // same\r\n\r\n// get ops\r\n~t.(Ndef(\\bass)); // get tags by ndef\r\n~t.(\\perc); // get ndefs by tag\r\n~t.([\\perc,\\fav]); // get ndefs by tag list - matching all\r\n~t.([\\perc,\\fav]->'&'); // same\r\n~t.([\\perc,\\fav]->'|'); // get ndefs by tag list - matching any\r\n~t.([\\perc,\\fav]->'-'); // get ndefs by tag list - matching first but not second\r\n~t.([Ndef(\\kick),Ndef(\\bass)]); // get tags by ndefs - matching all\r\n~t.([Ndef(\\kick),Ndef(\\bass)]->'|'); // get tags by ndefs - matching any\r\n~t.() // get underlying structure\r\n\r\n// remove ops\r\nNdef(\\kick) !? ~t.(\\kikin,_,'-'); // remove tag\r\nNdef(\\kick) !? ~t.([\\some,\\thing],_,'-'); // remove tags\r\n\r\n// nb: Ndef can be substituted with any other class,\r\n//     but collisions may occur in case of usage of same class \r\n//     both for tags and tagged objects (e.g. Symbol to Symbol)",
   "id" : "1-51F",
   "is_private" : null,
   "labels" : [
      "shortcut",
      "tag"
   ]
}
