#!/usr/bin/python # This file is part of Espruino, a JavaScript interpreter for Microcontrollers # # Copyright (C) 2013 Gordon Williams # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # ---------------------------------------------------------------------------------------- # Builds HTML documentation for functions from the JSON included in comments in # jswrap_*.c files # ---------------------------------------------------------------------------------------- import subprocess; import re; import json; import sys; import os; sys.path.append("."); import common # Scans files for comments of the form /*JSON......*/ and then writes out an HTML file describing # all the functions jsondatas = common.get_jsondata(True) classes = [] for jsondata in jsondatas: if "class" in jsondata: if not jsondata["class"] in classes: classes.append(jsondata["class"]) htmlFile = open('functions.html', 'w') def html(s): htmlFile.write(s+"\n"); def htmlify(d): d = re.sub(r'```([^`]+)```', r'\1', d) # code tags d = re.sub(r'`([^`]+)`', r'\1', d) # code tags d = re.sub(r'(http://[^ ]+)', r'\1', d) # links tags d = re.sub(r'\[([^\]]*)\]\(([^\)]*)\)', r'\1', d) # links tags return d def html_description(ds,current): if not isinstance(ds, list): ds = [ ds ] for d in ds: for link in links: if link!=current: d = d.replace(" "+link+" ", " "+link+" ") d = d.replace(" "+link+".", " "+link+".") d = d.replace(" "+link+"(", " "+link+"(") html("

"+htmlify(d)+"

") def get_prefixed_name(jsondata): s="" if "class" in jsondata: s=s+jsondata["class"]+"." s=s+jsondata["name"] return s def get_fullname(jsondata): s = common.get_prefix_name(jsondata) if s!="": s = s + " " if jsondata["type"]!="constructor": if "class" in jsondata: s=s+jsondata["class"]+"." s=s+jsondata["name"] return s def get_surround(jsondata): s = common.get_prefix_name(jsondata) if s!="": s = s + " " if jsondata["type"]!="constructor": if "class" in jsondata: s=s+jsondata["class"]+"." s=s+jsondata["name"] if not common.is_property(jsondata): args = []; if "params" in jsondata: for param in jsondata["params"]: args.append(param[0]); if param[1]=="JsVarArray": args.append("..."); s=s+"("+",".join(args)+")" return s def get_link(jsondata): s="l_"; if "class" in jsondata: s=s+jsondata["class"]+"_" else: s=s+"_global_" s=s+jsondata["name"] return s html("") html(" ") html(" Espruino Reference") html(" ") html(" ") html(" ") html("

Espruino Software Reference

") html("

Version "+common.get_version()+"

") html("

Contents

") html("

Globals

") html(" ") html("

"+className+"

") html(" ") html("

Detail

") lastClass = "XXX" for jsondata in detail: className = "" niceName = "" linkName = "" if "class" in jsondata: className=jsondata["class"] niceName=className+" Class" linkName=className else: className="" niceName="Global Functions" linkName="_global" if className!=lastClass: lastClass=className html("

"+niceName+"

") html("

(top)

") for j in jsondatas: if (j["type"]=="class" or j["type"]=="library") and j["class"]==className: ds = html_description(j["description"], className) instances = [] for j in jsondatas: if "instanceof" in j and j["instanceof"]==className: instances.append(j) if len(instances)>0: html("

Instances

") html(" ") html("

Methods and Fields

") html(" ") html("

"+get_fullname(jsondata)+"

") html("

(top)

") html("

Call type:

") html("

"+get_surround(jsondata)+"

") if "description" in jsondata: html("

Description

") desc = jsondata["description"] if not isinstance(desc, list): desc = [ desc ] if ("ifdef" in jsondata) or ("ifndef" in jsondata): conds = "" if "ifdef" in jsondata: conds = common.get_ifdef_description(jsondata["ifdef"]) if "ifndef" in jsondata: if conds!="": conds += " and " conds = "not "+common.get_ifdef_description(jsondata["ifndef"]) desc.append("Note: This is only available in some devices: "+conds); html_description(desc, jsondata["name"]) html("

Parameters

") if "params" in jsondata: for param in jsondata["params"]: desc = "" if len(param)>2: desc=param[2] if isinstance(desc, list): desc = '
'.join(desc) extra = "" if param[1]=="JsVarArray": extra = ", ..."; html("

"+param[0]+extra+" "+htmlify(desc)+"

") else: html("

No parameters

") html("

Returns

") if "return" in jsondata: desc = "" if len(jsondata["return"])>1: desc=jsondata["return"][1] if desc=="": desc="See description above" html("

"+htmlify(desc)+"

") else: html("

No return value (undefined)

") html(" ") html("") # -------------------------------------------------------------------------- # Write/create keywords # -------------------------------------------------------------------------- keywords = {} for j in jsondatas: if ("name" in j): item = { "title" : get_surround(j), "path": "/Reference#"+get_link(j) }; jkeywords = [ j["name"] ] if get_prefixed_name(j)!=j["name"]: jkeywords.append(get_prefixed_name(j)) if "class" in j: jkeywords.append(j["class"]) for k in jkeywords: k = k.lower() if not k in keywords: keywords[k] = [ item ] else: keywords[k].append(item) #print(json.dumps(keywords, sort_keys=True, indent=2)) keywordFile = open('function_keywords.js', 'w') keywordFile.write(json.dumps(keywords, sort_keys=True, indent=2)); # ---------------------------- Just random helper stuff builtins = [] for jsondata in jsondatas: if jsondata["type"]=="staticmethod" or jsondata["type"]=="staticproperty" or jsondata["type"]=="class": if not jsondata["class"] in builtins: builtins.append(jsondata["class"]) elif jsondata["type"]=="function" or jsondata["type"]=="variable" or jsondata["type"]=="class": if not jsondata["name"] in builtins: builtins.append(jsondata["name"]) print "------------------------------------------------------" print('Global classes and functions: '+' '.join(builtins)); print "------------------------------------------------------"