• The JavaScript for rendering the matrixes and lists:

    • 'Reads' the annotated command list data from a multi-line JavaScript string...
    • ...and re-composes for each command 1 to n lines (in loadGC9A01 and loadILI9341(...) functions).
    • Creates for each controller a Commands-object (using function Cmds(...) constructor).
    • Creates command-objects for all commands and headers as 'round pegs in square holes' (using function Cmd(...) constructor) and some other data-objects and places references of them in multiple lists for the various needs in rendering and usage:
      • Plain array list with command AND header objects
      • An object with a property for each command with the 0x## command id as name
      • The 16x16 matrix withe the coverage of the commands
    • Updates the matrixes with the commands-commands object (change . to : where other controller has a command for the code).
    • Renders the matrixes.
    • Renders the mixed-in lists.
    • Renders the pure lists.

    Rendering is plain generation of html with short inline event handlers invoking global JavaScript functions. Some CSS is defined and as classes and some is inline (looking for TCL).

    It was a fun experience to come up with minimal annotation on tables copied from .pdf and write the complementing logic for the rendering. Noteworthy is the debug support for getting the annotations right: an incrementing line counter - lCnt - set to the line number of the first line of the multiline of the command list data and some other intermediary data and the initial pure list rendering helped to quickly get all annotations complete and straight.

    To see the annotated, complete command list data string, click/'run' the .html filein/from the previous post and look at the source in the browser (or download it and look at it in an editor).

    Here the html code w/ only fragments of the annotated, complete command list data string:

    <html>
    <!-- GC9A01  240x240 round/square clock display dirver /
         ILI9341 240x320 rectangular display w/ and w/o (resistive) touch screen
         commands comparions / mapping
         in space of Espruino.com
         20211005_allObjects;
      -->
    <head>
    <title>GC9A01 / ILI9341 LCD Controller Commands Comparison / Mapping by ao</title>
    <style>
    table { border: 1; }
    h, td, th { border: 1px solid grey; }
    td { text-align: center; vertical-align: top; font-family: Monaco, Lucida Sans Typewriter, Couorier New, sans-serif; }
    th { text-align: center; vertical-align: top; font-family: Monaco, Lucida Sans Typewriter, Couorier New, sans-serif; }
    tr.cmd1_mx>td { background-color: [#FFFFE0](https://forum.espruino.com/sea­rch/?q=%23FFFFE0); border-top: 3px solid [#FFFFFF](https://forum.espruino.com/sea­rch/?q=%23FFFFFF); border-left: 3px solid [#FFFFFF](https://forum.espruino.com/sea­rch/?q=%23FFFFFF); padding: 0.2em; cursor: pointer; }
    tr.cmd1_l0>td { background-color: [#FFFFE0](https://forum.espruino.com/sea­rch/?q=%23FFFFE0); border-top: 1px solid #171717; }
    tr.cmd1_lx>td { background-color: [#FFFFF0](https://forum.espruino.com/sea­rch/?q=%23FFFFF0); } 
    tr.cmd2_mx>td { background-color: [#E0FFFF](https://forum.espruino.com/sea­rch/?q=%23E0FFFF); border-top: 3px solid [#FFFFFF](https://forum.espruino.com/sea­rch/?q=%23FFFFFF); border-left: 3px solid [#FFFFFF](https://forum.espruino.com/sea­rch/?q=%23FFFFFF); padding: 0.2em; cursor: pointer; }
    tr.cmd2_l0>td { background-color: [#E0FFFF](https://forum.espruino.com/sea­rch/?q=%23E0FFFF); border-top: 1px solid #171717; }
    tr.cmd2_lx>td { background-color: [#F0FFFF](https://forum.espruino.com/sea­rch/?q=%23F0FFFF); }
    tr.cmd3_l0>td { background-color: [#D8BFD8](https://forum.espruino.com/sea­rch/?q=%23D8BFD8); border-top: 1px solid #171717; }
    tr.cmd3_lx>td { background-color: [#E6E6FA](https://forum.espruino.com/sea­rch/?q=%23E6E6FA); }
    table.cmds { border-collapse: collapse; }
    table.cmds>td { margin:0; padding:2px; border:1px solid grey; }
    .hbar { margin: 0.8em 0 0 0; height:2em; background-color:#FFC0CB; }
    .topLink { margin: 0 0 0.6em 0; height:1em; }
    </style>
    </head>
    <body onload="loadCmds(); renderCmds();">
    <a id="top"><h3>GC9A01 / ILI9341 LCD Controller Commands Comparison / Mapping by allObjects</h3>
    <p><i>Information is taken from respective data sheet .pdfs and annotated for rendering.</i></p>
    <div style="display:none;">
    <button onclick="loadCmds();">Load</button> -
    <button onclick="renderCmds();">Render</button>
    </div>
    <div>
    Table of content:<ul>
    <li><a href="ILI9341_GC9A01_mxs">ILI9341 <--> GC9A01 Command Matrixes</a> - Hover over and click cells</li>
    <li><a href="#ILI9341_GC9A01">ILI9341 ---> GC9A01 commands mixed in</a> - Click bold 0x## command id or name</li>
    <li><a href="#GC9A01_ILI9341">GC9A01 ---> ILI9341 commands mixed in</a> - Click bold 0x## command id or name</li>
    <li><a href="#GC9A01">GC9A01 commands</a> - Click bold 0x## command id or name</li>
    <li><a href="#ILI9341">ILI9341 commands</a> - Click bold 0x## command id or name</li>
    </div>
    <div class="hbar""></div>
    <div class="topLink"><a id="ILI9341_GC9A01_mxs"></a><a href="#top">top</a></div>
    <div><table><tr><td id="ILI9341mx" style="border:0;"></td>
            <td style="border:0;">&nbsp;&nbsp;&nbsp;</td­>
            <td id="GC9A01mx" style="border:0;"></td></tr></table></di­v>
    <div class="hbar""></div>
    <div class="topLink"><a id="ILI9341_GC9A01"></a><a href="#top">top</a></div>
    <div id="cmdsILI9341_mi_cmdsGC9A01"></div>
    <div class="topLink"><a id="ILI9341_GC9A01"></a><a href="#top">top</a></div>
    <div id="cmdsGC9A01_mi_cmdsILI9341"></div>
    <div class="hbar""></div>
    <div class="topLink"><a id="GC9A01"></a><a href="#top">top</a></div>
    <div id="cmdsGC9A01"></div>
    <div class="hbar""></div>
    <div class="topLink"><a id="ILI9341"></a><a href="#top">top</a></div>
    <div id="cmdsILI9341"></div>
    <div class="hbar""></div>
    <div class="topLink"><a id="bot"></a><a href="#top">top</a></div>
    <script>
    var cmdsGC9A01, cmdsILI9341;
    function loadCmds() {
      loadGC9A01(1); loadILI9341(2);
    }
    function renderCmds() {
      cmdsILI9341.adjustWith(cmdsGC9A01);    cmdsGC9A01.adjustWith(cmdsILI9341);
      cmdsILI9341.renderMx(cmdsGC9A01);      cmdsGC9A01.renderMx(cmdsILI9341);
      cmdsILI9341.renderMixedIn(cmdsGC9A01); cmdsGC9A01.renderMixedIn(cmdsILI9341);
      cmdsGC9A01.render();                   cmdsILI9341.render();
    }
    </script><script>
    
    // --------------------------
    
    function loadGC9A01(clrId) {
    
    var lCntDataStart = 80; // for annotation debugging - 1st line where multi-line cmds data starts / opening back tick
    var cmdsData /* cmds source ILI9341 */ = `
    A|e GC9A01 Regular Command Set |
    A| C_ID | Command Function
    -| D/CX | RDX | WRX | D17-8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | HEX |
    5| Read Display Identification Information 2
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 04h |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |8 ID_1[7:0]                    | 00 |
    -| 1 | ^ | 1 | XX |8 ID_2[7:0]                    | 9A |
    -| 1 | ^ | 1 | XX |8 ID_3[7:0]                    | 01 |
    6| Read Display Status
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 09h |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |7 D[31:25]                 | X | 00 |
    -| 1 | ^ | 1 | XX | X |3 D[22:20] |4 D[19:16]     | 61 |
    -| 1 | ^ | 1 | XX | X | X | X | X | X |3 D[10:8]  | 00 |
    -| 1 | ^ | 1 | XX |3 D[7:5]   | X | X | X | X | X | 00 |
    1| Enter Sleep Mode
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 10h |
    1| Sleep OUT
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 11h |
    1| Partial Mode ON
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 12h |
    #
    # ....
    # for complete annotated command list, sie source of clickable .html
    # ....
    #
    7| SET_GAMMA4
    -| 0 | 1 | ^ | XX | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | F3h |
    -| 1 | 1 | ^ | XX | 0 |7 dig2gam_vr43_p[6:0]                  | 3F |
    -| 1 | 1 | ^ | XX |3 dig2gam_vr27_p[2:0] |5 dig2gam_vr57_p[4:0] | 98 |
    -| 1 | 1 | ^ | XX |3 dig2gam_vr36_p[2:0] |5 dig2gam_vr59_p[4:0] | B4 |
    -| 1 | 1 | ^ | XX | 0 | 0 |6 dig2gam_vr61_p[5:0]  | 14 |
    -| 1 | 1 | ^ | XX | 0 | 0 |6 dig2gam_vr62_p[5:0]              | 18 |
    -| 1 | 1 | ^ | XX |4 dig2gam_vr50_p[3:0] |4 dig2gam_vr63_p[3:0] | CD |
    `;
    cmdsGC9A01 = new Cmds("GC9A01",clrId,cmdsData);
    cmdsGC9A01.load(lCntDataStart);
    }
    </script><script>
    
    // --------------------------
    
    function loadILI9341(clrId) {
    
    var lCntDataStart = 127; // for annotation debugging - 1st line where multi-line cmds data starts / opening back tick
    var cmdsData /* cmds source ILI9341 */ = `
    A|e ILI9341 Regular Command Set |
    A| Command Function
    -| D/CX | RDX | WRX | D17-8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Hex |
    1| No Operation
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00h |
    1| Software Reset
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 01h |
    5| Read Display Identification Information
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 04h |
    -| 1 | 1 | ^ | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |8 ID1 [7:0]                    | XX |
    -| 1 | ^ | 1 | XX |8 ID2 [7:0]                    | XX |
    -| 1 | ^ | 1 | XX |8 ID3 [7:0]                    | XX |
    6| Read Display Status
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 09h |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |7 D [31:25]                | X | 00 |
    -| 1 | ^ | 1 | XX | X |3 D [22:20] |4 D [19:16]   | 61 |
    -| 1 | ^ | 1 | XX | X | X | X | X | X |3 D [10:8] | 00 |
    -| 1 | ^ | 1 | XX |3 D [7:5]  | X | X | X | X | X | 00 |
    3| Read Display Power Mode
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0Ah |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |6 D [7:2]              | 0 | 0 | 08 |
    3| Read Display MADCTL
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0Bh |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |6 D [7:2]              | 0 | 0 | 00 |
    3| Read Display Pixel Format
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0Ch |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX | RIM |3 DPI [2:0] | X |3 DBI [2:0] | 06 |
    3| Read Display Image Format
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0Dh |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX | X | X | X | X | X |3 D [2:0]  | 00 |
    3| Read Display Signal Mode
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0Eh |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |6 D [7:2]              | 0 | 0 | 00 |
    3| Read Display Self-Diagnostic Result
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0Fh |
    -| 1 | ^ | 1 | XX | X | X | X | X | X | X | X | X | XX |
    -| 1 | ^ | 1 | XX |2 D [7:6] | X | X | X | X | X | X | 00 |
    1| Enter Sleep Mode
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 10h |
    1| Sleep OUT
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 11h |
    1| Partial Mode ON
    -| 0 | 1 | ^ | XX | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 12h |
    #
    # ....
    # for complete annotated command list, sie source of clickable .html
    # ....
    #
    4| Interface Control
    -| 0 | 1 | ^ | XX | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | F6h |
    -| 1 | 1 | ^ | XX | MY_EOR | MX_EOR | MV_EOR | X | BGR_EOR | X | X | WEMODE | 01 |
    -| 1 | 1 | ^ | XX | X | X |2 EPF [1:0] | X | X |2 MDT [1:0] | 00 |
    -| 1 | 1 | ^ | XX | X | X | ENDIAN | X |2 DM [1:0] | RM | RIM | 00 |
    `;
    cmdsILI9341 = new Cmds("ILI9341",clrId,cmdsData);
    cmdsILI9341.load(lCntDataStart);
    }
    </script>
    <script>
    var p; // prototype
    
    // -----------------------------
    
    function Cmds(id, clrId, data) {
    
      this.id = id;
      this.clrId = clrId;
      this.data = data;
      this.cmdsById = {};
      this.cmds = [];
      this.cmx = [];
      for (var j=0; j<16; j++) { var r = [];
        for (var i=0; i<16; i++) { r.push([j,i,"."]); // [0]high Nib, [1]lowNib, [2]commandHex }
        } this.cmx.push(r); }
    } p = Cmds.prototype;
    p.gtNodeId = function() { return "cmds"+this.id; } // "cmdsILI9341"
    p.load = function(lCntDataStart) { // <---- source code line where multi-line string begins / line of opening back tick
      var loadC = { lCnt:lCntDataStart - 1 // because it does inc at the beginning
                  , pos:0, eodPos:this.data.length, lin:"" }
        , cmd = null
        , lin, bLCt, lCnt, lChr, linSeg, eChr, segs, cmdh, cmdId, hiN, loN
        ;
      while ((linSeg = this._nexLin(loadC).lin).length > 0) {
        // console.log(loadC.lCnt+": "+linSeg);
        if (! cmd) { // cmd does not exist yet / has not started yet expecting line with num or Alpha lines begin
          if ((lCnt = "A".indexOf(lChr = linSeg.charAt(0))+1) > 0) { // ABC... 123...line(s) heading, currently only 1 lines
            cmd = new Cmd("H",loadC.lCnt,lCnt,linSeg);
          } else if ((lCnt = "123456789abcdefg".indexOf(lChr)+1) > 0) { // 123... 123...line(s) cmd, currently 1..6 lines
            cmd = new Cmd("C",loadC.lCnt,lCnt,linSeg);
          } else { throw "Unexpected first line(Segment) "+loadC.lCnt+": "+linSeg; }
          this.cmds.push(cmd); lin=linSeg.substr(1);
        } else { // cmd exists, append to current 'open' line
          if ((lChr = linSeg.charAt(0)) == "-") { // continuation
            lin+=linSeg.substr(1); // drop line char and concatenate
          } else { throw "Unexpected 2nd to n-nth line(Segment) "+loadC.lCnt+": "+linSeg; }
        }
        eChr = lin.charAt(lin.length - 1);
        if (eChr == "|") { // e<a href="GC9A01_ILI9341_cmds_map.html">GC9A­01 / ILI9341 LCD Controller Commands Comparison / Mapping by ao</a>nd of line - finish line
          if (cmd.lins.length == 0) { // 1st line complete - first line(segment) added to lines on cmd construction
            if        (cmd.typ == "C") { // A command line (not a header one) - has command code / id as last arg
              segs = lin.split ("|"); cmdh = segs[segs.length - 2].trim().toUpperCase();
              hiN = "0123456789ABCDEF".indexOf(cmdh.charAt(0­)); loN = "0123456789ABCDEF".indexOf(cmdh.charAt(1­));
              if (cmdh.length != 3 || hiN < 0 || loN < 0) {
                throw "Unexpected XXh(ex) of command at/near n-nth line(Segment) "+loadC.lCnt+": "+linSeg; }
              cmd.stId(cmdId = "0x"+cmdh.substring(0,2)); this.cmdsById[cmd.id] = cmd;
              this.cmx[hiN][loN][2] = cmdId.substr(2); // occupying command coverage matrix
            } else if (cmd.typ == "H") { // A header line (not a command one)
              // nothing id-wise to do for header
            } else { throw "Unexpected line type: "+cmd.typ+" (line: "+lin+")" }
          }
          if (cmd.lins.length < cmd.lCnt) { // check for too many lines / should actually never fire
            cmd.lins.push(lin); lin = "";
            if (cmd.lins.length == cmd.lCnt) { // command complete, 'close' it - all lines added
              cmd.close();
              cmd = null; // setup for next cmd / controls start of next cmd
            }
          } else { throw "Unexpected to many lines at line(Segment) "+loadC.lCnt+": "+linSeg; }
        }
        linSeg = ""; 
      }   
      return this;
    }
    p._nexLin = function(c) { // skip empty and # commented linea
      var lin = "", eolPos;
      while ( c.pos < c.eodPos && ! lin.length > 0) {
        c.lCnt++; // inc source line count
        eolPos = this.data.indexOf("\n",c.pos);
        if (eolPos < 0) { eolPos = c.eodPos; }
        if (c.pos < eolPos) { lin = this.data.substring(c.pos, eolPos).trim(); }
        c.pos = eolPos + 1;
        if (lin.length > 0 && lin.charAt(0) == "#") { lin == ""; }
      }
      c.lin = lin;
      return c;
    }
    p.adjustWith = function(aCmds) { // adjust mainly matrix (replace . with : when other cmd code present)
      var cmx = this.cmx, r, c, v
        , aCmx = aCmds.cmx, aR, aC, aV
        , j, i
        ;
        for (j=0;j<16;j++) { r = cmx[j]; aR = aCmx[j];
          for (i=0;i<16;i++) { c = r[i]; aC = aR[i]; 
            if (c[2] == "." && aC[2] != ".") {
              c[2] = ":"; 
        } } }
    }
    p.render = function() { // render all own
      var _ = this
        , hfs = ['<table class="cmds">'
                +'<tr style="display:none;"><td>.</td>'
                +   '<td>.</td><td>.</td><td>.</td><td>.</td­><td>.</td><td>.</td><td>.</td>'
                +   '<td>.</td><td>.</td><td>.</td><td>.</td­><td>.</td><td>.</td><td>.</td></tr>'
                ]
        , id = this.id
        , idSel = "_"+id
        , clrId = this.clrId
        ;
      this.cmds.forEach(function(cmd) { hfs.push(cmd.render(idSel, clrId, clrId)); });
      hfs.push('</table>');
      document.getElementById(this.gtNodeId())­.innerHTML = hfs.join("");
    }
    p.renderMixedIn = function(mCmds) { // render own and mix in other cmds where available
      var _ = this
        , id = _.id
        , idSel = "mi"+id
        , clrId = _.clrId
        , mId = mCmds.id
        , mClrId = mCmds.clrId // color id of cmd to mix in
        , hfs = ['<table class="cmds">'
                +'<tr style="display:none;"><td>.</td>'
                +   '<td>.</td><td>.</td><td>.</td><td>.</td­><td>.</td><td>.</td><td>.</td>'
                +   '<td>.</td><td>.</td><td>.</td><td>.</td­><td>.</td><td>.</td><td>.</td></tr>'
                +'<tr class="cmd'+clrId+ '_l0"><td colspan="15" style="text-align:left;">'+id+' commands</td><tr>'
                +'<tr class="cmd'+mClrId+'_l0"><td colspan="15" style="text-align:left;">mixed-in with '+mId+' commands:</td></tr>'
                +'<tr><td colspan="15" style="text-align:left;">GRAY MARKED ones are NOT AVALABLE in '+mId+'</td></tr>'
                ]
        , mCmd // cmd to mix in
        ;
      this.cmds.forEach(function(cmd) {
        if (cmd.typ == "C") { // only commands
          mCmd = mCmds.cmdsById[cmd.id];
          hfs.push(cmd.render(idSel, clrId, (mCmd) ? clrId : 0));
          if (mCmd) { hfs.push(mCmd.render(null, mClrId, mClrId)); }
        }
      });
      hfs.push('</table>');
      document.getElementById(this.gtNodeId()+­"_mi_"+mCmds.gtNodeId()).innerHTML = hfs.join("");
    }
    p.renderMx = function(mCmds) {
      var id = this.id, csById = this.cmdsById, cmx = this.cmx, cr, c, j, i, h, cc, cId
        , mCmdsById = mCmds.cmdsById, mCmd
        , trBeg = '<tr class="cmd'+this.clrId+'_mx" style="border-left:1px solid [#EFEFEF](https://forum.espruino.com/sea­rch/?q=%23EFEFEF);">', hStr
        , hs = ['<table><tr class="cmd'+this.clrId+'_mx" style="visibility:hidden;">'
               +'<td>XX</td><td>XX</td><td>XX</td><td>X­X</td><td>XX</td><td>XX</td><td>XX</td><­td>XX</td>'
               +'<td>XX</td><td>XX</td><td>XX</td><td>X­X</td><td>XX</td><td>XX</td><td>XX</td><­td>XX</td>'
               +'</tr>']
        ;
      hs.push('<tr><th colspan="16">'+id+' Commands Matrix / Coverage</th></tr>');
      hs.push('<tr><td colspan="16" id="inmc'+id+'"'
             +' style="text-align:left; padding-left:0.3em;">&nbsp;<br>&nbsp;</t­d></tr>');
      for (j=0; j<16; j++) { cr = cmx[j]; hs.push(trBeg);
        for (i=0; i<16; i++) {  h = "0123456789ABCDEF".charAt(j)+"0123456789­ABCDEF".charAt(i);
          hs.push('<td id="0x'+h+'m'+id+'"');
          if (( cc = cr[i][2]) != "." && cc != ":") { cId = "0x"+cc;
            hs.push(' onclick="mxcClicked(this);" onmouseenter="mxcEnter(this);" onmouseleave="mxcLeave(this);"');
            hs.push(' title="'+cId+' - '+csById[cId].nam);
            if (mCmd = mCmdsById[cId]) {
              hs.push('\n     ---> '+mCmd.nam+'"');
              hs.push(' style="');
            } else {
              hs.push('" style="background-color:#F0F0F0;');
            }
          } else {
            hs.push(' style="cursor: default;')
          }
          if (i === 0) { hs.push(' border-left:1px solid [#EFEFEF](https://forum.espruino.com/sea­rch/?q=%23EFEFEF);'); } 
          hs.push('">'+cc+'</td>'); // close style in td beg tag
      } hs.push('</tr>'); } hs.push('</table>');
      hStr = hs.join("");
      document.getElementById(id+"mx").innerHT­ML = hStr;
    }
    </script>
    <script>
    
    // -----------------------------
    
    function Cmd(typ,lBeg,lCnt,linSeg0) {
    
      this.id = "";
      this.nam = "";
      this.typ = typ;
      this.lBeg = lBeg;
      this.lCnt = lCnt;
      this.lins = [];
      this.linSeg0 = linSeg0;
    } p = Cmd.prototype;
    p.stId  = function(id) { this.id = id; }
    p.close = function() {
      var elt, elts = this.lins[0].split("|");
      this.nam = (((elt = elts[1]).charAt(0) == " ") ? elt : elt.substr(1)).trim();
      this.linSeg0 = "";
      console.log(((this.typ == "C") ? this.id+": " : "***** ")+this.nam);
    }
    p.render = function(cmdsIdSel, clrId, clrIdAlt) {
      var _ = this, h = [], elts, edx, edxMax, elt, cChr, cols, xCols, cCols, bPos;
      if (this.typ == "C") { // command
        this.lins.forEach(function(lin,x) {
          elts = lin.split("|");
          edxMax = elts.length - 2; 
          if (x == 0) {
            h.push('<tr class="cmd'+clrId+'_l0">');
            h.push('<td style="text-align:left; padding:0 0.5em 0 0.5em;');
            if (clrId != clrIdAlt) { h.push(' background-color: [#C0C0C0](https://forum.espruino.com/sea­rch/?q=%23C0C0C0);'); } // [#DDA0DD](https://forum.espruino.com/sea­rch/?q=%23DDA0DD) [#C0C0C0](https://forum.espruino.com/sea­rch/?q=%23C0C0C0)
            if (cmdsIdSel) { h.push(' font-weight:bold; cursor:pointer;'); }
            h.push('"');
            if (_.lCnt > 1) { h.push(' rowspan="'+_.lCnt+'"'); }
            if (cmdsIdSel) {
              h.push(' id="'+_.id+cmdsIdSel+'_id"');
              h.push(' onclick="'+((cmdsIdSel.charAt(0) == "m") ? 'miIdClicked' : 'lIdClicked')+'(this);"'); }
            h.push('>');
            h.push(_.id);
            h.push('</td>')
            h.push('<td style="width:12.0em; text-align:left; font-family:Arial;');
            if (cmdsIdSel) { h.push(' font-weight:bold; cursor:pointer;'); }
            h.push('"');
            if (_.lCnt > 1) { h.push(' rowspan="'+_.lCnt+'"'); }
            if (cmdsIdSel) {
              h.push(' id="'+_.id+cmdsIdSel+'_nam"');
              h.push(' onclick="'+((cmdsIdSel.charAt(0) == "m") ? 'miNameClicked' : 'lNameClicked')+'(this);"'); }
            h.push('>');
            h.push(_.nam);
            h.push('</td>');
            edx = 1;
          } else {
            h.push('<tr class="cmd'+clrId+'_lx">');
            edx = 0
          }
          while (++edx <= edxMax) {
            elt = elts[edx]; cChr = elt.charAt(0);
            h.push('<td');
            if (edx == edxMax) { h.push(' style="text-align:left; padding:0 0.5em 0 0.5em;"'); }
            if (cChr == " ") {
              bPos = 0;
            } else {
              if ((cols = "123456789abcde".indexOf(cChr)+1)>1) { h.push(' colspan="'+cols+'"'); }
              bPos = 1;
            }
            h.push('>'+elt.substr(bPos).trim());
            h.push('</td>');
          }
          h.push('</tr>');
        } );
      } else { // header
        this.lins.forEach(function(lin,x) {
          elts = lin.split("|");
          edxMax = elts.length - 2; 
          h.push('<tr class="cmd'+clrId+'_hdr">');
          edx = 0;
          while (++edx <= edxMax) {
            elt = elts[edx]; cChr = elt.charAt(0);
            h.push('<th');
            if (x == 0 && edx == 1) {
              if (edx == 1 && _.lCnt > 1) { h.push(' rowspan="'+_.lCnt+'"'); }
              xCols = 1;
            } else {
              xCols = 0;
            }
            cols = xCols + 1; bPos = 0;
            if (cChr != " ") {
              if ((cCols = "123456789abcde".indexOf(cChr)+1)>1) { cols = xCols + cCols; }
              bPos = 1;
            }
            if (cols > 1) { h.push(' colspan="'+cols+'"'); }
            h.push('>'+elt.substr(bPos).trim());
            h.push('</th>');
          }
          h.push('</tr>');
        } );
      }
      h = h.join("");
      return h;
    }
    </script>
    <script>
    
    //  -----------------------------
    
    // (value driven) event handlers; function name (and 'evented' dom node id) determine action
    
    function mxcEnter(mxc) { // matrix cell entering
      var elts =  mxc.title.split("\n");
      if (elts.length == 2) { elts[1] = '&nbsp;&nbsp;'+elts[1]; } else { elts.push('&nbsp;'); }
      document.getElementById("inmc"+mxc.id.su­bstring(5)).innerHTML = elts.join("<br>")
    }
    function mxcLeave(mxc) { // matrix cell leaving
      document.getElementById("inmc"+mxc.id.su­bstring(5)).innerHTML = '&nbsp;<br>&nbsp;'; }
    function mxcClicked(mxc) { // matrix cell (cmd id) clicked --> mixed in list
      location.hash = "#"+mxc.id.replace("m","mi")+"_id"; }
    function miIdClicked(miIdC) { // mixed in list cmd id clicked -->  pure list
      location.hash = "#"+miIdC.id.replace("mi","_"); }
    function miNameClicked(miNameC) { // mixed in list cmd name clicked ---> back to matrix
      location.hash = "#ILI9341_GC9A01_mxs"; }
    function lIdClicked(lIdC) { // pure list cmd id clicked ---> wrap-around back to matrix
      location.hash = "#ILI9341_GC9A01_mxs"; }
    function lNameClicked(lNameC) { // [ire list cmd name clicked ---> back to mixed in list
      location.hash = "#"+lNameC.id.replace("_","mi").replace(­"minam","_id"); }
    </script>
    </body>
    </html>
    
About

Avatar for allObjects @allObjects started