fmod MODS2JSON is
  inc MAUDE2JSON-AUX .

***(
A modification specification (mod)  is an object of size 4
{ "stype" : "mod",
  "name" : String,      // constructed from op (and site if present)
  "shortname" : String  // for op -- md abbrev
  "op" : String,  
  "site" : String,      // constructed mod 
  "mtype" : MType, 
  "cvs" : JArray[CV],          //controlled vocab refs
  "metadata" : JObject    // omit abbrev, 
}
MType = {"AAMOD","ACT","FRAG","SMBIND","OTHER"} computed from  Maude sort.
)

op modJsonTemplate : -> String .
eq modJsonTemplate =
"\n %name:{\"stype\" : \"mod\",\n\
\t \"name\" : %name,\n\
\t \"shortname\" : %shortname,\n\
\t \"op\" : %op,\n\
\t \"site\" : %site,\n\
\t \"mtype\" : %mtype,\n\
\t \"cvs\" : %cvs,\n\
\t \"metadata\" : %metadata\n}" 
.


  vars  modname qid  : Qid .
  vars str tag val default mdstr jelts : String .
  vars mdelt db id term cvselt name cv cvs : String .
  var next : FindResult .
  var sexp? : Sexp? .

  var alist alist1 : SexpL .
  var bindings : TBinds .


op alist2cvs : SexpL  -> String .
ceq alist2cvs(alist) 
       = fillTemplate(jarrTemplate, ("%jvals" :~ cv)) 
  if db := alookupd(alist,"db","")
  /\ id := alookupd(alist,"id","")
  /\ term := alookupd(alist,"term","")
  /\ cv := (if (db == "" or id == "") 
            then "" 
            else fillTemplate(cvTemplate,
                              (("%db" :~ squote(db)),
                               ("%id" :~ squote(id)), 
                               ("%term" :~ squote(term))))
            fi) .


op cvTemplate : -> String .
eq cvTemplate =
     "{\"stype\" : \"cv\", \"db\" : %db, \"id\" : %id, \"term\" : %term}" .

op mods2json : Qid -> String .
op mods2json : OpDeclSet String -> String .
op mod2json : OpDecl -> String .

eq mods2json(modname) = mods2json(upOpDecls(modname,false),"") .

eq mods2json(none,jelts) = fillTemplate(jobjTemplate, ("%jelts" :~ jelts)) .
eq mods2json(op qid : nil -> t:Type [atts:AttrSet]. ods:OpDeclSet,jelts) 
     = (if occurs(t:Type, ('AAMOD 'ACT 'FRAG 'OTHER 'SMBIND))
        then mods2json(ods:OpDeclSet, 
							         jelts 
							         + (if jelts == "" then "" else ", " fi) 
							         + mod2json(op qid : nil -> t:Type [atts:AttrSet].) ) 
				 else  mods2json(ods:OpDeclSet, jelts)
				 fi) . 

eq mods2json(od:OpDecl ods:OpDeclSet,jelts) 
      = mods2json(ods:OpDeclSet,jelts) [owise] .

ceq mod2json(op qid : nil -> t:Type [atts:AttrSet]. )
   = fillTemplate(modJsonTemplate, bindings)
  if  mdstr := getMetaData(atts:AttrSet)
  /\ ixs(next,sexp?) := readSexp(mdstr,0,length(mdstr)) 
  /\ alist := (if sexp? :: Sexp then sexp2l(sexp?) else nil fi) 
  /\ cvselt := alist2cvs(alist)
  /\ name := string(qid)
  /\ mdelt :=  alist2json(alist,("abbrev" "db" "id" "term"),"")  
  /\ bindings := (("%name" :~ squote(name)),
                  ("%shortname" :~
                     squote(alookupd(alist,"abbrev",substr(name,0,3)))),
                  ("%op" :~ squote(name)),
                  ("%site" :~ squote("")),
                  ("%mtype" :~ squote(string(t:Type))),
                  ("%cvs" :~ cvselt),
                  ("%metadata" :~ mdelt) ) .


endfm

***(
{
"GDP":{"op":"GDP","description":"","stype":"mod","name":"GDP","shortname":"GDP","cvs":[{"id":"17552","db":"CHEBI","term":"Guanosine 5'-diphosphate"}],"mtype":"SMBIND"},
"on":{"op":"on","description":"gene transcription on","stype":"mod","name":"on","shortname":"on","mtype":"ACT"},
"cleaved":{"op":"cleaved","description":"cleaved by a protease","stype":"mod","name":"cleaved","shortname":"!","mtype":"FRAG"},
"oligo":{"op":"oligo","description":"dimerized???","stype":"mod","name":"oligo","shortname":"deg","mtype":"OTHER"},
"Tphos":{"op":"Tphos","description":"","stype":"mod","name":"Tphos","shortname":"Tp","cvs":[{"id":"00047","db":"MOD","term":"O-phospho L-threonine"}],"mtype":"AAMOD"}
}
)
