1+ // ==UserScript==
2+ // @name Register Table Ziggifier
3+ // @namespace http://tampermonkey.net/
4+ // @version 2025-07-28
5+ // @description This userscript tries to catch register definition tables on the arm documentation and convert them into Zig code
6+ // @author xq
7+ // @match https://developer.arm.com/documentation/*
8+ // @icon https://www.google.com/s2/favicons?sz=64&domain=arm.com
9+ // @grant none
10+ // ==/UserScript==
11+
12+ /**
13+ *
14+ * Try on:
15+ * - https://developer.arm.com/documentation/100235/0100/The-Cortex-M33-Peripherals/System-Control-Block/MemManage-Fault-Address-Register?lang=en
16+ * - https://developer.arm.com/documentation/dui0662/b/Cortex-M0--Peripherals/System-Control-Block/System-Control-Register?lang=en
17+ *
18+ */
19+
20+ ( function ( ) {
21+ 'use strict' ;
22+
23+ console . log ( "startup..." ) ;
24+ let pattern = / \[ ( \d + ) (?: : ( \d + ) ) ? \] / ;
25+
26+ function process ( )
27+ {
28+ for ( const table of document . querySelectorAll ( "table.c-table" ) )
29+ {
30+ console . log ( table ) ;
31+ let fields = [ ] ;
32+ for ( const row of table . rows )
33+ {
34+ if ( row . cells . length != 3 ) {
35+ continue ;
36+ }
37+ let cells = Array . from ( row . cells ) . map ( x => x . innerText ) ;
38+ const match = pattern . exec ( cells [ 0 ] ) ;
39+ if ( match == null ) {
40+ console . log ( "skip" , cells ) ;
41+ continue ;
42+ }
43+ let msb = Number ( match [ 1 ] ) ;
44+ let lsb = Number ( match [ 2 ] || match [ 1 ] ) ;
45+
46+ fields . push ( {
47+ lsb : lsb ,
48+ msb : msb ,
49+ name : cells [ 1 ] ,
50+ func : cells [ 2 ] ,
51+ } ) ;
52+
53+ }
54+ fields . sort ( ( a , b ) => a . lsb - b . lsb ) ;
55+ var str = `packed struct(u${ fields [ fields . length - 1 ] . msb + 1 } ) {\n` ;
56+ for ( const fld of fields ) {
57+ let suffix = "" ;
58+ if ( fld . name == "-" ) {
59+ fld . name = `_reserved${ fld . lsb } ` ;
60+ suffix = " = 0" ;
61+ }
62+ let size = `${ fld . msb } :${ fld . lsb } ` ;
63+ if ( fld . msb == fld . lsb ) {
64+ size = `${ fld . msb } ` ;
65+ }
66+
67+ str += "\n" ;
68+
69+ let docs = fld . func . replaceAll ( "\n\n" , "\n" ) . split ( "\n" ) ;
70+
71+ if ( docs . length == 1 ) {
72+ docs [ 0 ] = `[${ size } ] ` + docs [ 0 ] ;
73+ } else {
74+ docs = [ `[${ size } ]` ] . concat ( docs ) ;
75+ }
76+
77+ for ( const line of docs )
78+ {
79+ str += ` /// ${ line } \n` ;
80+ }
81+ str += ` ${ fld . name } : u${ fld . msb - fld . lsb + 1 } ${ suffix } ,\n` ;
82+ }
83+ str += "}" ;
84+ console . log ( fields ) ;
85+ console . log ( str ) ;
86+
87+ const codeblock = document . createElement ( "textarea" ) ;
88+ codeblock . value = str ;
89+ codeblock . style . width = "100%" ;
90+ codeblock . style . fontFamily = "monospace" ;
91+ codeblock . style . fontSize = "smaller" ;
92+ codeblock . style . height = "20em" ;
93+ codeblock . style . resize = "vertical" ;
94+
95+ const cell = document . createElement ( "TD" ) ;
96+ cell . setAttribute ( "colspan" , 3 ) ;
97+ cell . appendChild ( codeblock ) ;
98+
99+ const appendix = document . createElement ( "TR" ) ;
100+ appendix . appendChild ( cell ) ;
101+
102+ const tbody = document . createElement ( "TBODY" ) ;
103+ tbody . appendChild ( cell ) ;
104+
105+ table . appendChild ( tbody ) ;
106+
107+ }
108+ }
109+
110+ setTimeout ( process , 1000 ) ;
111+
112+ } ) ( ) ;
0 commit comments