]> granicus.if.org Git - graphviz/commitdiff
Convert mkattrs.sh to Python/Jinja2 templating
authorMark Hansen <mark@markhansen.co.nz>
Sun, 17 May 2020 07:12:52 +0000 (17:12 +1000)
committerMark Hansen <mark@markhansen.co.nz>
Mon, 1 Jun 2020 10:43:34 +0000 (20:43 +1000)
doc/info/attrs.html
doc/infosrc/Makefile
doc/infosrc/attrs
doc/infosrc/mkattrs.py [new file with mode: 0755]
doc/infosrc/mkattrs.sh [deleted file]
doc/infosrc/templates/attrs.html.j2 [new file with mode: 0644]

index 676a4a1883180ed6110fd4d86cb1d8667f75661d..7a9a40756ab331d3da1de941596847039a63dd06 100644 (file)
@@ -90,11 +90,11 @@ of the layout programs.
 </TD><TD>GC</TD><TD>double</TD><TD ALIGN="CENTER">0.3</TD><TD>0</TD><TD>sfdp, fdp only</TD> </TR>
  <TR><TD><A NAME=a:URL HREF=#d:URL>URL</A>
 </TD><TD>ENGC</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
  <TR><TD><A NAME=a:_background HREF=#d:_background>_background</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:area HREF=#d:area>area</A>
-</TD><TD>NC</TD><TD>double</TD><TD ALIGN="CENTER">1.0</TD><TD>&#62;0</TD><TD>patchwork only</TD> </TR>
+</TD><TD>NC</TD><TD>double</TD><TD ALIGN="CENTER">1.0</TD><TD>&gt;0</TD><TD>patchwork only</TD> </TR>
  <TR><TD><A NAME=a:arrowhead HREF=#d:arrowhead>arrowhead</A>
 </TD><TD>E</TD><TD><A HREF=#k:arrowType>arrowType</A>
 </TD><TD ALIGN="CENTER">normal</TD><TD></TD><TD></TD> </TR>
@@ -109,14 +109,14 @@ of the layout programs.
  <TR><TD><A NAME=a:bgcolor HREF=#d:bgcolor>bgcolor</A>
 </TD><TD>GC</TD><TD><A HREF=#k:color>color</A>
 <BR><A HREF=#k:colorList>colorList</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:center HREF=#d:center>center</A>
 </TD><TD>G</TD><TD><A HREF=#k:bool>bool</A>
 </TD><TD ALIGN="CENTER">false</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:charset HREF=#d:charset>charset</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">"UTF-8"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;UTF-8&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:class HREF=#d:class>class</A>
-</TD><TD>ENCG</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg only</TD> </TR>
+</TD><TD>ENCG</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg only</TD> </TR>
  <TR><TD><A NAME=a:clusterrank HREF=#d:clusterrank>clusterrank</A>
 </TD><TD>G</TD><TD><A HREF=#k:clusterMode>clusterMode</A>
 </TD><TD ALIGN="CENTER">local</TD><TD></TD><TD>dot only</TD> </TR>
@@ -125,9 +125,9 @@ of the layout programs.
 <BR><A HREF=#k:colorList>colorList</A>
 </TD><TD ALIGN="CENTER">black</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:colorscheme HREF=#d:colorscheme>colorscheme</A>
-</TD><TD>ENCG</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>ENCG</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:comment HREF=#d:comment>comment</A>
-</TD><TD>ENG</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>ENG</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:compound HREF=#d:compound>compound</A>
 </TD><TD>G</TD><TD><A HREF=#k:bool>bool</A>
 </TD><TD ALIGN="CENTER">false</TD><TD></TD><TD>dot only</TD> </TR>
@@ -158,16 +158,16 @@ of the layout programs.
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">96.0<BR>0.0</TD><TD></TD><TD>svg, bitmap output only</TD> </TR>
  <TR><TD><A NAME=a:edgeURL HREF=#d:edgeURL>edgeURL</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:edgehref HREF=#d:edgehref>edgehref</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:edgetarget HREF=#d:edgetarget>edgetarget</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:edgetooltip HREF=#d:edgetooltip>edgetooltip</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, cmap only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, cmap only</TD> </TR>
  <TR><TD><A NAME=a:epsilon HREF=#d:epsilon>epsilon</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">.0001 * # nodes(mode == KK)<BR>.0001(mode == major)<BR>.01(mode == sgd)</TD><TD></TD><TD>neato only</TD> </TR>
  <TR><TD><A NAME=a:esep HREF=#d:esep>esep</A>
@@ -185,9 +185,9 @@ of the layout programs.
 </TD><TD>ENGC</TD><TD><A HREF=#k:color>color</A>
 </TD><TD ALIGN="CENTER">black</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:fontname HREF=#d:fontname>fontname</A>
-</TD><TD>ENGC</TD><TD>string</TD><TD ALIGN="CENTER">"Times-Roman"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>ENGC</TD><TD>string</TD><TD ALIGN="CENTER">&#34;Times-Roman&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:fontnames HREF=#d:fontnames>fontnames</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg only</TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg only</TD> </TR>
  <TR><TD><A NAME=a:fontpath HREF=#d:fontpath>fontpath</A>
 </TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">system-dependent</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:fontsize HREF=#d:fontsize>fontsize</A>
@@ -196,12 +196,12 @@ of the layout programs.
 </TD><TD>G</TD><TD><A HREF=#k:bool>bool</A>
 </TD><TD ALIGN="CENTER">true</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:gradientangle HREF=#d:gradientangle>gradientangle</A>
-</TD><TD>NCG</TD><TD>int</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>NCG</TD><TD>int</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:group HREF=#d:group>group</A>
-</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:headURL HREF=#d:headURL>headURL</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:head_lp HREF=#d:head_lp>head_lp</A>
 </TD><TD>E</TD><TD><A HREF=#k:point>point</A>
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
@@ -210,44 +210,44 @@ of the layout programs.
 </TD><TD ALIGN="CENTER">true</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:headhref HREF=#d:headhref>headhref</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:headlabel HREF=#d:headlabel>headlabel</A>
 </TD><TD>E</TD><TD><A HREF=#k:lblString>lblString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:headport HREF=#d:headport>headport</A>
 </TD><TD>E</TD><TD><A HREF=#k:portPos>portPos</A>
 </TD><TD ALIGN="CENTER">center</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:headtarget HREF=#d:headtarget>headtarget</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:headtooltip HREF=#d:headtooltip>headtooltip</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, cmap only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, cmap only</TD> </TR>
  <TR><TD><A NAME=a:height HREF=#d:height>height</A>
 </TD><TD>N</TD><TD>double</TD><TD ALIGN="CENTER">0.5</TD><TD>0.02</TD><TD></TD> </TR>
  <TR><TD><A NAME=a:href HREF=#d:href>href</A>
 </TD><TD>GCNE</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
  <TR><TD><A NAME=a:id HREF=#d:id>id</A>
 </TD><TD>GCNE</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, postscript, map only</TD> </TR>
  <TR><TD><A NAME=a:image HREF=#d:image>image</A>
-</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:imagepath HREF=#d:imagepath>imagepath</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:imagepos HREF=#d:imagepos>imagepos</A>
-</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">"mc"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">&#34;mc&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:imagescale HREF=#d:imagescale>imagescale</A>
 </TD><TD>N</TD><TD><A HREF=#k:bool>bool</A>
 <BR>string</TD><TD ALIGN="CENTER">false</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:inputscale HREF=#d:inputscale>inputscale</A>
-</TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>fdp, neato only</TD> </TR>
+</TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>fdp, neato only</TD> </TR>
  <TR><TD><A NAME=a:label HREF=#d:label>label</A>
 </TD><TD>ENGC</TD><TD><A HREF=#k:lblString>lblString</A>
-</TD><TD ALIGN="CENTER">"&#92;N" (nodes)<BR>"" (otherwise)</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;\&amp;#92;N&#34; (nodes)<BR>&#34;&#34; (otherwise)</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labelURL HREF=#d:labelURL>labelURL</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:label_scheme HREF=#d:label_scheme>label_scheme</A>
 </TD><TD>G</TD><TD>int</TD><TD ALIGN="CENTER">0</TD><TD>0</TD><TD>sfdp only</TD> </TR>
  <TR><TD><A NAME=a:labelangle HREF=#d:labelangle>labelangle</A>
@@ -261,40 +261,40 @@ of the layout programs.
 </TD><TD>E</TD><TD><A HREF=#k:color>color</A>
 </TD><TD ALIGN="CENTER">black</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labelfontname HREF=#d:labelfontname>labelfontname</A>
-</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">"Times-Roman"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">&#34;Times-Roman&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labelfontsize HREF=#d:labelfontsize>labelfontsize</A>
 </TD><TD>E</TD><TD>double</TD><TD ALIGN="CENTER">14.0</TD><TD>1.0</TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labelhref HREF=#d:labelhref>labelhref</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:labeljust HREF=#d:labeljust>labeljust</A>
-</TD><TD>GC</TD><TD>string</TD><TD ALIGN="CENTER">"c"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>GC</TD><TD>string</TD><TD ALIGN="CENTER">&#34;c&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labelloc HREF=#d:labelloc>labelloc</A>
-</TD><TD>NGC</TD><TD>string</TD><TD ALIGN="CENTER">"t"(clusters)<BR>"b"(root graphs)<BR>"c"(nodes)</TD><TD></TD><TD></TD> </TR>
+</TD><TD>NGC</TD><TD>string</TD><TD ALIGN="CENTER">&#34;t&#34;(clusters)<BR>&#34;b&#34;(root graphs)<BR>&#34;c&#34;(nodes)</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:labeltarget HREF=#d:labeltarget>labeltarget</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:labeltooltip HREF=#d:labeltooltip>labeltooltip</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, cmap only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, cmap only</TD> </TR>
  <TR><TD><A NAME=a:landscape HREF=#d:landscape>landscape</A>
 </TD><TD>G</TD><TD><A HREF=#k:bool>bool</A>
 </TD><TD ALIGN="CENTER">false</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layer HREF=#d:layer>layer</A>
 </TD><TD>ENC</TD><TD><A HREF=#k:layerRange>layerRange</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layerlistsep HREF=#d:layerlistsep>layerlistsep</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">","</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;,&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layers HREF=#d:layers>layers</A>
 </TD><TD>G</TD><TD><A HREF=#k:layerList>layerList</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layerselect HREF=#d:layerselect>layerselect</A>
 </TD><TD>G</TD><TD><A HREF=#k:layerRange>layerRange</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layersep HREF=#d:layersep>layersep</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">" :&#92;t"</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34; </TD><TD>&amp;#92;t&#34;</TD><TD></TD> </TR>
  <TR><TD><A NAME=a:layout HREF=#d:layout>layout</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:len HREF=#d:len>len</A>
 </TD><TD>E</TD><TD>double</TD><TD ALIGN="CENTER">1.0(neato)<BR>0.3(fdp)</TD><TD></TD><TD>fdp, neato only</TD> </TR>
  <TR><TD><A NAME=a:levels HREF=#d:levels>levels</A>
@@ -302,21 +302,21 @@ of the layout programs.
  <TR><TD><A NAME=a:levelsgap HREF=#d:levelsgap>levelsgap</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">0.0</TD><TD></TD><TD>neato only</TD> </TR>
  <TR><TD><A NAME=a:lhead HREF=#d:lhead>lhead</A>
-</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:lheight HREF=#d:lheight>lheight</A>
 </TD><TD>GC</TD><TD>double</TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
  <TR><TD><A NAME=a:lp HREF=#d:lp>lp</A>
 </TD><TD>EGC</TD><TD><A HREF=#k:point>point</A>
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
  <TR><TD><A NAME=a:ltail HREF=#d:ltail>ltail</A>
-</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:lwidth HREF=#d:lwidth>lwidth</A>
 </TD><TD>GC</TD><TD>double</TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
  <TR><TD><A NAME=a:margin HREF=#d:margin>margin</A>
 </TD><TD>NCG</TD><TD>double<BR><A HREF=#k:point>point</A>
-</TD><TD ALIGN="CENTER">&#60;device-dependent&#62;</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;device-dependent&gt;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:maxiter HREF=#d:maxiter>maxiter</A>
-</TD><TD>G</TD><TD>int</TD><TD ALIGN="CENTER">100 &#42; # nodes(mode == KK)<BR>200(mode == major)<BR>30(mode == sgd)<BR>600(fdp)</TD><TD></TD><TD>fdp, neato only</TD> </TR>
+</TD><TD>G</TD><TD>int</TD><TD ALIGN="CENTER">100 * # nodes(mode == KK)<BR>200(mode == major)<BR>30(mode == sgd)<BR>600(fdp)</TD><TD></TD><TD>fdp, neato only</TD> </TR>
  <TR><TD><A NAME=a:mclimit HREF=#d:mclimit>mclimit</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">1.0</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:mindist HREF=#d:mindist>mindist</A>
@@ -348,11 +348,11 @@ of the layout programs.
 <BR><A NAME=a:nslimit1 HREF=#d:nslimit1>nslimit1</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER"></TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:ordering HREF=#d:ordering>ordering</A>
-</TD><TD>GN</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>GN</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:orientation HREF=#d:orientation>orientation</A>
 </TD><TD>N</TD><TD>double</TD><TD ALIGN="CENTER">0.0</TD><TD>360.0</TD><TD></TD> </TR>
  <TR><TD><A NAME=aa:orientation HREF=#dd:orientation>orientation</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:outputorder HREF=#d:outputorder>outputorder</A>
 </TD><TD>G</TD><TD><A HREF=#k:outputMode>outputMode</A>
 </TD><TD ALIGN="CENTER">breadthfirst</TD><TD></TD><TD></TD> </TR>
@@ -425,15 +425,15 @@ of the layout programs.
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">96.0<BR>0.0</TD><TD></TD><TD>svg, bitmap output only</TD> </TR>
  <TR><TD><A NAME=a:root HREF=#d:root>root</A>
 </TD><TD>GN</TD><TD>string<BR><A HREF=#k:bool>bool</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;(graphs)<BR>false(nodes)</TD><TD></TD><TD>circo, twopi only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;(graphs)<BR>false(nodes)</TD><TD></TD><TD>circo, twopi only</TD> </TR>
  <TR><TD><A NAME=a:rotate HREF=#d:rotate>rotate</A>
 </TD><TD>G</TD><TD>int</TD><TD ALIGN="CENTER">0</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:rotation HREF=#d:rotation>rotation</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">0</TD><TD></TD><TD>sfdp only</TD> </TR>
  <TR><TD><A NAME=a:samehead HREF=#d:samehead>samehead</A>
-</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:sametail HREF=#d:sametail>sametail</A>
-</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>dot only</TD> </TR>
+</TD><TD>E</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:samplepoints HREF=#d:samplepoints>samplepoints</A>
 </TD><TD>N</TD><TD>int</TD><TD ALIGN="CENTER">8(output)<BR>20(overlap and image maps)</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:scale HREF=#d:scale>scale</A>
@@ -449,7 +449,7 @@ of the layout programs.
 </TD><TD>N</TD><TD><A HREF=#k:shape>shape</A>
 </TD><TD ALIGN="CENTER">ellipse</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:shapefile HREF=#d:shapefile>shapefile</A>
-</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD>N</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:showboxes HREF=#d:showboxes>showboxes</A>
 </TD><TD>ENG</TD><TD>int</TD><TD ALIGN="CENTER">0</TD><TD>0</TD><TD>dot only</TD> </TR>
  <TR><TD><A NAME=a:sides HREF=#d:sides>sides</A>
@@ -461,7 +461,7 @@ of the layout programs.
 </TD><TD>N</TD><TD>double</TD><TD ALIGN="CENTER">0.0</TD><TD>-100.0</TD><TD></TD> </TR>
  <TR><TD><A NAME=a:smoothing HREF=#d:smoothing>smoothing</A>
 </TD><TD>G</TD><TD><A HREF=#k:smoothType>smoothType</A>
-</TD><TD ALIGN="CENTER">"none"</TD><TD></TD><TD>sfdp only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;none&#34;</TD><TD></TD><TD>sfdp only</TD> </TR>
  <TR><TD><A NAME=a:sortv HREF=#d:sortv>sortv</A>
 </TD><TD>GCN</TD><TD>int</TD><TD ALIGN="CENTER">0</TD><TD>0</TD><TD></TD> </TR>
  <TR><TD><A NAME=a:splines HREF=#d:splines>splines</A>
@@ -469,15 +469,15 @@ of the layout programs.
 <BR>string</TD><TD ALIGN="CENTER"></TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:start HREF=#d:start>start</A>
 </TD><TD>G</TD><TD><A HREF=#k:startType>startType</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>fdp, neato only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>fdp, neato only</TD> </TR>
  <TR><TD><A NAME=a:style HREF=#d:style>style</A>
 </TD><TD>ENCG</TD><TD><A HREF=#k:style>style</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:stylesheet HREF=#d:stylesheet>stylesheet</A>
-</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg only</TD> </TR>
+</TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg only</TD> </TR>
  <TR><TD><A NAME=a:tailURL HREF=#d:tailURL>tailURL</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:tail_lp HREF=#d:tail_lp>tail_lp</A>
 </TD><TD>E</TD><TD><A HREF=#k:point>point</A>
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
@@ -486,25 +486,25 @@ of the layout programs.
 </TD><TD ALIGN="CENTER">true</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:tailhref HREF=#d:tailhref>tailhref</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:taillabel HREF=#d:taillabel>taillabel</A>
 </TD><TD>E</TD><TD><A HREF=#k:lblString>lblString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:tailport HREF=#d:tailport>tailport</A>
 </TD><TD>E</TD><TD><A HREF=#k:portPos>portPos</A>
 </TD><TD ALIGN="CENTER">center</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:tailtarget HREF=#d:tailtarget>tailtarget</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, map only</TD> </TR>
+</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:tailtooltip HREF=#d:tailtooltip>tailtooltip</A>
 </TD><TD>E</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, cmap only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, cmap only</TD> </TR>
  <TR><TD><A NAME=a:target HREF=#d:target>target</A>
 </TD><TD>ENGC</TD><TD><A HREF=#k:escString>escString</A>
-<BR>string</TD><TD ALIGN="CENTER">&#60;none&#62;</TD><TD></TD><TD>svg, map only</TD> </TR>
+<BR>string</TD><TD ALIGN="CENTER">&lt;none&gt;</TD><TD></TD><TD>svg, map only</TD> </TR>
  <TR><TD><A NAME=a:tooltip HREF=#d:tooltip>tooltip</A>
 </TD><TD>NEC</TD><TD><A HREF=#k:escString>escString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD>svg, cmap only</TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD>svg, cmap only</TD> </TR>
  <TR><TD><A NAME=a:truecolor HREF=#d:truecolor>truecolor</A>
 </TD><TD>G</TD><TD><A HREF=#k:bool>bool</A>
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>bitmap output only</TD> </TR>
@@ -513,7 +513,7 @@ of the layout programs.
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
  <TR><TD><A NAME=a:viewport HREF=#d:viewport>viewport</A>
 </TD><TD>G</TD><TD><A HREF=#k:viewPort>viewPort</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:voro_margin HREF=#d:voro_margin>voro_margin</A>
 </TD><TD>G</TD><TD>double</TD><TD ALIGN="CENTER">0.05</TD><TD>0.0</TD><TD>not dot</TD> </TR>
  <TR><TD><A NAME=a:weight HREF=#d:weight>weight</A>
@@ -524,7 +524,7 @@ of the layout programs.
 </TD><TD>G</TD><TD>string</TD><TD ALIGN="CENTER"></TD><TD></TD><TD>xdot only</TD> </TR>
  <TR><TD><A NAME=a:xlabel HREF=#d:xlabel>xlabel</A>
 </TD><TD>EN</TD><TD><A HREF=#k:lblString>lblString</A>
-</TD><TD ALIGN="CENTER">""</TD><TD></TD><TD></TD> </TR>
+</TD><TD ALIGN="CENTER">&#34;&#34;</TD><TD></TD><TD></TD> </TR>
  <TR><TD><A NAME=a:xlp HREF=#d:xlp>xlp</A>
 </TD><TD>NE</TD><TD><A HREF=#k:point>point</A>
 </TD><TD ALIGN="CENTER"></TD><TD></TD><TD>write only</TD> </TR>
index a04f93564edd48ce9d9bbe1b8875c4e43c409d8f..31b0b8a98364ad5b78363b98cf636f66b33aa57a 100644 (file)
@@ -119,10 +119,10 @@ sdlshapes.ps : sdlshapes.dot
 sdlshapes.png : sdlshapes.ps
        ./ps_to_png.sh sdlshapes.ps sdlshapes.png
 
-attrs.html : attrs.1 attrs types mkattrs.sh mktypes.sh
-       cat attrs.1 > attrs.html
-       ./mkattrs.sh < attrs >> attrs.html
-       ./mktypes.sh < types >> attrs.html
+attrs.html : attrs.1 attrs types mkattrs.py mktypes.sh
+       cat attrs.1 > $@
+       ./mkattrs.py < attrs >> $@
+       ./mktypes.sh < types >> $@
 
 colors.html : colors.1 colors.n ../../lib/common/color_names ../../lib/common/svgcolor_names ../../lib/common/brewer_colors mkcolors.awk brewer.awk svg.awk
        mkdir -p colortmp
@@ -216,7 +216,7 @@ distclean : clean
        rm -f $(A2GIF) $(AGIF) $(SGIF) $(MPJG) $(MGIF) $(MPNG) $(XGIF) shapes
        (for s in $$(cat shapelist); do rm -f $$s.gif; done)
 
-EXTRA_DIST = $(XGIF) mklang.y mkarrows.sh mkattrs.sh mkshapes.sh mkstyles.sh mktapers.sh \
+EXTRA_DIST = $(XGIF) mklang.y mkarrows.sh mkattrs.py mkshapes.sh mkstyles.sh mktapers.sh \
              mktypes.sh mkarrowtbl.sh mkoutput.py mkshhtml.sh \
                   ps_to_png.sh arrow_grammar grammar html_grammar \
              shapelist attrs.1 colors.1 colors.n \
index 13fd5d9cd14bf78d43f31dc45649a4ae9f0c5e89..78695d75a5ede866c95ec21ce9ae5ef42463a7ef 100644 (file)
@@ -91,7 +91,7 @@ Style of arrowhead on the head node of an edge.
 This will only appear if the <A HREF=#d:dir>dir</A> attribute
 is "forward" or "both".
 See the <A HREF=#h:undir_note>limitation</A>.
-:arrowsize (E_arrowsz):E:double:1.0:0.0;
+:arrowsize:E:double:1.0:0.0;
 Multiplicative scale factor for arrowheads.
 :arrowtail:E:arrowType:normal;
 Style of arrowhead on the tail node of an edge.
@@ -227,7 +227,7 @@ If true, use edge concentrators.
 This merges multiedges into a single edge and causes partially parallel
 edges to share part of their paths. The latter feature is not yet available
 outside of dot.
-:constraint (E_constr):E:bool:true;  dot
+:constraint:E:bool:true;  dot
 If false, the edge is not used in ranking the nodes. For example,
 in the graph
 <PRE>
@@ -338,7 +338,7 @@ for setting the gradient angle.
 Note that a cluster inherits the root graph's attributes if defined.
 Thus, if the root graph has defined a <B>fillcolor</B>, this will override a
 <B>color</B> or <B>bgcolor</B> attribute set for the cluster.
-:fixedsize  (N_fixed):N:bool/string:false;
+:fixedsize:N:bool/string:false;
 If <tt>false</tt>, the size of a node is determined by smallest width and height
 needed to contain its label and image, if any, with a margin specified by
 the <A HREF=#d:margin><TT>margin</TT></A> attribute. The width
@@ -596,7 +596,7 @@ If a node's <A HREF=#d:shape>shape</A> is record, then the label can
 have a <A HREF=shapes.html#record>special format</A>
 which describes the record layout.
 <P>
-Note that a node's default label is "\&#92;N", so the node's name or ID becomes
+Note that a node's default label is "&#92;N", so the node's name or ID becomes
 its label. Technically, a node's name can be an HTML string but this will not
 mean that the node's label will be interpreted as an <a href="shapes.html#html">HTML-like label</a>. This is
 because the node's actual label is an ordinary string, which will be replaced 
@@ -623,7 +623,7 @@ Multiplicative scaling factor adjusting the distance that
 the headlabel(taillabel) is from the head(tail) node.
 The default distance is 10 points. See <A HREF=#d:labelangle>labelangle</A>
 for more details.
-:labelfloat (E_label_float):E:bool:false;
+:labelfloat:E:bool:false;
 If true, allows edge labels to be less constrained in position.
 In particular, it may appear on top of other edges.
 :labelfontcolor:E:color:black;
@@ -754,7 +754,7 @@ the cluster bounding box. By default, this is 8 points.
 <P>
 For nodes, this attribute specifies space left around the node's label.
 By default, the value is <TT>0.11,0.055</TT>.
-:maxiter:G:int:100 &#42; # nodes(mode == KK)/200(mode == major)/30(mode == sgd)/600(fdp);  neato,fdp
+:maxiter:G:int:100 * # nodes(mode == KK)/200(mode == major)/30(mode == sgd)/600(fdp);  neato,fdp
 Sets the number of iterations used.
 :mclimit:G:double:1.0;  dot
 Multiplicative scale factor used to alter the MinQuit (default = 8)
diff --git a/doc/infosrc/mkattrs.py b/doc/infosrc/mkattrs.py
new file mode 100755 (executable)
index 0000000..3d5b545
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# Filter taking a list of attribute descriptions as stdin
+# and producing a summary table, followed by a list of
+# attribute descriptions.
+# Uses `templates/attrs.html.j2`
+# See `attrs` file for format documentation.
+
+from dataclasses import dataclass
+import jinja2
+import markupsafe
+import re
+import sys
+from typing import List, Dict
+
+@dataclass
+class Term:
+  """ One <dt> item. """
+  name: str
+  # Anchor (<a name="#">) for definition
+  d_anchor: str = ""
+  # Anchor (<a name="#">) for table at the top
+  a_anchor: str = ""
+
+@dataclass
+class Attribute:
+    terms: List[Term]
+    # use string : this is a string formed of G,N,C,E
+    uses: str
+    kinds: List[str]
+    flags: List[str]
+    html_description: str
+    defaults: List[str]
+    minimums: List[str]
+
+attrs : List[Attribute] = []
+
+for line in sys.stdin:
+    # Skip comment lines.
+    if line.startswith('#'):
+        continue
+
+    if line.startswith(':'):
+        # This is a header line. Grab out the values.
+        #    :name:uses:kind[:dflt[:minv]];  [notes]
+        headers, _, flags = line.rpartition(';')
+        parts = headers.split(':')
+
+        attr = Attribute(
+            terms=[Term(name=name) for name in parts[1].split('/')],
+            uses=parts[2],
+            kinds=parts[3].split('/'),
+            flags=[flag for flag in flags.strip().split(',') if flag],
+            # Set an empty string html description, ready to append to.
+            html_description='',
+            # Remaining fields are optional.
+            # First, check for default value: this has format :dflt1[/dflt2]*
+            defaults=parts[4].split('/') if len(parts) >= 5 else [],
+            # Check for minimum value: this has format /min1[/min2]*
+            minimums=parts[5].split('/') if len(parts) >= 6 else [],
+        )
+        attrs.append(attr)
+
+    else:
+        # This is an HTML line, possibly a continuation of a previous HTML line.
+        attr.html_description += '  ' + line
+
+
+attrs.sort(key=lambda attr: ''.join(term.name for term in attr.terms))
+
+for attr in attrs:
+  attr.html_description = markupsafe.Markup(attr.html_description)
+
+# The specification allows items with the same attribute name.
+# This creates unique anchor keys, which are n copies of 'a' and 'd'.
+a_anchors_used = set()
+d_anchors_used = set()
+for attr in attrs:
+  for term in attr.terms:
+    a_key = 'a'
+    d_key = 'd'
+    a_anchor = a_key + ':' + term.name
+    d_anchor = d_key + ':' + term.name
+    while a_anchor in a_anchors_used:
+      a_key += 'a'
+      a_anchor = a_key + ':' + term.name
+    while d_anchor in d_anchors_used:
+      d_key += 'd'
+      d_anchor = d_key + ':' + term.name
+    a_anchors_used.add(a_anchor)
+    d_anchors_used.add(d_anchor)
+    term.a_anchor = a_anchor
+    term.d_anchor = d_anchor
+
+
+env = jinja2.Environment(
+    # Load template files from ./templates/
+    loader=jinja2.FileSystemLoader('templates'),
+    # Auto-HTML-escape any html or xml files.
+    autoescape=jinja2.select_autoescape(['html', 'xml', 'html.j2', 'xml.j2']),
+    # Whitespace control
+    trim_blocks=True,
+    lstrip_blocks=True,
+    # Raise exception on any attempt to access undefined variables.
+    undefined=jinja2.StrictUndefined,
+)
+template = env.get_template('attrs.html.j2')
+print(template.render(attrs=attrs))
diff --git a/doc/infosrc/mkattrs.sh b/doc/infosrc/mkattrs.sh
deleted file mode 100755 (executable)
index 39df45d..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-#! /bin/ksh
-typeset -A uses kinds dflts minvs flags descs namecnt
-typeset -i J L
-name=
-use=
-kind=
-dflt=
-minv=
-flag=
-
-# Filter taking a list of attribute descriptions as stdin
-# and producing a summary table, followed by a list of
-# attribute descriptions.
-
-set -f   # Turn of globbing
-
-# Map special HTML characters into their HTML representation.
-# This can be escaped using '\'.
-protect ()
-{
-  s=
-  L=${#1}
-  for (( J=0 ; J<L ; J++ ))
-  do
-    c=${1:J:1}
-    case $c in
-      '<' )
-        s=${s}'&#60;'
-        ;;
-      '>' )
-        s=${s}'&#62;'
-        ;;
-#      '&' )
-#        s=${s}'&#38;'
-#        ;;
-      '\' )
-        if (( J == L-1 ))
-        then
-          s=${s}'\'
-        else
-          (( J++ ))
-          c=${1:J:1}
-          s=${s}$c
-        fi
-        ;;
-      * )
-        s=${s}$c
-        ;;
-    esac
-  done
-  print -r -n -- $s
-}
-
-# The specification allows items with the same attribute name.
-# If there is more than one, the later ones are indexed by
-# <name>:<n>, where each gets a distinct positive n.
-# This function takes the index name, extracts the real name
-# and stores it in realname, and creates the anchor keys,
-# which are n copies of 'a' and 'd'.
-function setRealnameNKeys 
-{
-  if [[ $1 == *:* ]]
-  then
-    realname=${1%:*}
-    J=${1##*:}
-  else
-    realname=$1
-    J=0
-  fi
-  AKEY=a
-  DKEY=d
-  while (( J > 0 ))
-  do
-    AKEY=${AKEY}a
-    DKEY=${DKEY}d
-    (( J-- ))
-  done
-}
-
-# Header has the format name:uses:kind[:dflt[:min]];  notes
-function parseHdr 
-{
-# get flags to the right of ';'
-  flag="${1##*;}"
-  flag="${1##*;*( )}"
-  if [[ -n $flag ]]
-  then
-    flag=${flag//,/ } # change optional commas to spaces
-  fi
-
-# strip off flags to the right of ';'
-  opts="${1%;*}"
-
-# get name: this has the format name1[/name2]* notes
-  name=${opts%%:*}
-  rest=${opts#*:}
-  name=${name%% *} # strip off notes
-
-# there may be duplicate names with separate entries.
-# Keep count of name uses, and modify name with :i.
-  J=${namecnt[$name]}
-  namecnt[$name]=$(( J+1 ))
-  if (( J > 0 )) 
-  then
-    name=${name}:$J
-  fi
-  
-# get use string : this is a string formed of G,N,C,E
-  use=${rest%%:*}
-  rest=${rest#${use}:}
-
-# get kind string: this has format kind1[/kind2]*
-  kind=${rest%%:*}
-  rest=${rest#${kind}}
-
-# Remaining fields are optional.
-# First, check for default value: this has format :dflt1[/dflt2]*
-  if [[ -z "$rest" ]]
-  then 
-    dflt=
-    minv=
-    return
-  fi
-  rest=${rest#:}
-# If rest contains a ':' not preceded by a space, we take this to
-# mean that a minval field is present, and split rest at that ':'.
-# Everything preceding the ':' becomes the dflt. 
-# If there is no such colon (that is, there is no colon, or all
-# colons are preceded by a space, we assume there is no minval, and
-# use all of rest as dflt.
-# This allows dflt to contain a ':' as long as it is preceded by a space.
-  if [[ $rest == *[![:space:]]:* ]]
-  then
-    dflt=${rest%:*}
-    rest=${rest#"${dflt}"}
-  else
-    dflt=${rest}
-    rest=
-  fi
-
-# Check for minimum value: this has format :min1[/min2]*
-  if [[ -z "$rest" ]]
-  then 
-    minv=
-    return
-  fi
-  minv=${rest#:}
-}
-
-OLDIFS="$IFS"
-IFS=
-while read line
-do
-  c=${line:0:1}
-  if [[ $c == '#' ]]
-  then continue
-  elif [[ $c == ':' ]]
-  then
-    if [[ -n "$name" ]]
-    then
-      descs[$name]=$txt
-      txt=""
-    fi
-    line=${line#:}
-    parseHdr $line
-    uses[$name]="$use"
-    kinds[$name]="$kind"
-    dflts[$name]="$dflt"
-    minvs[$name]="$minv"
-    flags[$name]="$flag"
-  else
-    txt="$txt  ${line}\n"
-  fi
-done
-IFS="$OLDIFS"
-
-if [[ -n "$name" ]]
-then
-  descs[$name]=$txt
-  txt=""
-fi
-
-#print ${!descs[@]}
-#print ${uses[@]}
-#print ${kinds[@]}
-#print ${dflts[@]}
-#print ${minvs[@]}
-#print ${flags[@]}
-#print ${descs[@]}
-#exit
-
-print "<TABLE ALIGN=CENTER>"
-print "<TR><TH>Name</TH><TH><A HREF=#h:uses>Used By</A></TH><TH>Type</TH><TH ALIGN=CENTER>Default</TH><TH>Minimum</TH><TH>Notes</TH></TR>"
-
-set -s ${!descs[@]}
-for i
-do
-  print -n " <TR>"
-  print -n "<TD>"
-  setRealnameNKeys $i
-  first=yes
-  for n in ${realname//\// }
-  do
-    if [[ -n $first ]]
-    then
-      first=
-    else
-      print -n "<BR>"
-    fi 
-    printf "<A NAME=%s:%s HREF=#%s:%s>%s</A>\n" $AKEY $n $DKEY $n $n
-  done
-  print -n "</TD>"
-
-  printf "<TD>%s</TD>" "${uses[$i]}"  
-
-  print -n "<TD>";
-  first=yes
-  kind=${kinds[$i]}
-  for n in ${kind//\// }
-  do
-    if [[ -n $first ]]
-    then
-      first=
-    else
-      print -n "<BR>"
-    fi 
-    case $n in
-      double )
-        print -n "double"
-        ;;
-      int )
-        print -n "int"
-        ;;
-      string )
-        print -n "string"
-        ;;
-      bool )
-        printf "<A HREF=#k:bool>bool</A>\n"
-        ;;
-      * )
-        printf "<A HREF=#k:%s>%s</A>\n" $n $n
-        ;;
-    esac
-  done
-  print -n "</TD>"
-
-  print -n "<TD ALIGN=\"CENTER\">";
-  first=yes
-  dflt=${dflts[$i]}
-  OLDIFS="$IFS"
-  IFS='/'
-  for n in ${dflt}
-  do
-    if [[ -n $first ]]
-    then
-      first=
-    else
-      print -n "<BR>"
-    fi 
-    n=$(protect $n)
-    print -r -n -- $n
-  done
-  print -n "</TD>"
-  IFS="$OLDIFS"
-
-  print -n "<TD>";
-  first=yes
-  minv=${minvs[$i]}
-  OLDIFS="$IFS"
-  IFS='/'
-  for n in ${minv}
-  do
-    if [[ -n $first ]]
-    then
-      first=
-    else
-      print -n "<BR>"
-    fi 
-    n=$(protect $n)
-    print -n -- $n
-  done
-  IFS="$OLDIFS"
-  print -n "</TD>"
-
-  print -n "<TD>"
-  flag=${flags[$i]}
-  case $flag in
-    "" )
-      ;;
-    "notdot" )
-      print -n "not dot"
-      ;;
-    * )
-      set -A farray $flag
-      L=${#farray[@]}
-      for (( J = L-1 ; J >= 0 ; J-- ))
-      do
-        n=${farray[$J]}
-        if [[ $n == "ps" ]]
-        then
-          n=postscript
-        elif [[ $n == "bitmap" ]]
-        then
-          n="bitmap output"
-        fi
-        print -n $n
-        if (( J > 0 ))
-        then
-          print -n ', '
-        fi
-      done
-      print -n " only"
-      ;;
-  esac
-  print -n "</TD>"
-  print " </TR>"
-done
-
-print "</TABLE>"
-
-print "<HR>"
-
-#set -s ${!descs[@]}
-print "<H1>Attribute Descriptions</H1>\n<DL>"
-for i
-do
-  setRealnameNKeys $i
-
-  first=yes
-  for n in ${realname//\// }
-  do
-    if [[ -n $first ]]
-    then
-      first=
-    else
-      print -n ","
-    fi 
-    printf "<DT><A NAME=%s:%s HREF=#%s:%s><STRONG>%s</STRONG></A>\n" $DKEY $n $AKEY $n $n
-  done
-  print "<DD>${descs[$i]}"
-done
-print "</DL>\n<HR>"
-
-exit 0
diff --git a/doc/infosrc/templates/attrs.html.j2 b/doc/infosrc/templates/attrs.html.j2
new file mode 100644 (file)
index 0000000..25dc261
--- /dev/null
@@ -0,0 +1,68 @@
+<TABLE ALIGN=CENTER>
+<TR><TH>Name</TH><TH><A HREF=#h:uses>Used By</A></TH><TH>Type</TH><TH ALIGN=CENTER>Default</TH><TH>Minimum</TH><TH>Notes</TH></TR>
+{% for attr in attrs %}
+ <TR><TD>
+  {%- for term in attr.terms -%}
+    {%- if not loop.first -%}
+    <BR>
+    {%- endif -%}
+    <A NAME={{ term.a_anchor }} HREF=#{{ term.d_anchor }}>{{ term.name }}</A>
+  {% endfor -%}
+  </TD><TD>{{ attr.uses }}</TD><TD>
+  {%- for kind in attr.kinds -%}
+    {%- if not loop.first -%}
+    <BR>
+    {%- endif -%}
+    {%- if kind in ['double', 'int', 'string'] -%}
+      {{ kind }}
+    {%- elif kind == 'bool' -%}
+      <A HREF=#k:bool>bool</A>
+    {% else -%}
+      <A HREF=#k:{{kind}}>{{kind}}</A>
+    {% endif -%}
+  {%- endfor -%}
+  </TD><TD ALIGN="CENTER">
+  {%- for default in attr.defaults -%}
+    {%- if not loop.first -%}
+    <BR>
+    {%- endif -%}
+    {{ default }}
+  {%- endfor -%}
+  </TD><TD>
+  {%- for minimum in attr.minimums -%}
+    {%- if not loop.first -%}
+    <BR>
+    {%- endif -%}
+    {{- minimum -}}
+  {%- endfor -%}
+  </TD><TD>
+  {%- if attr.flags == [] -%}
+  {%- elif attr.flags == ['notdot'] -%}
+    not dot
+  {%- else -%}
+    {%- for flag in attr.flags | reverse -%}
+      {%- if flag == 'ps' -%}
+        postscript
+      {%- elif flag == 'bitmap' -%}
+        bitmap output
+      {%- else -%}
+        {{ flag }}
+      {%- endif -%}
+      {%- if not loop.last %}, {% endif -%}
+    {%- endfor %} only
+  {%- endif -%}
+  </TD> </TR>
+{% endfor %}
+</TABLE>
+<HR>
+<H1>Attribute Descriptions</H1>
+<DL>
+{% for attr in attrs %}
+  {% for term in attr.terms %}
+    {% if not loop.first %},{% endif %}
+<DT><A NAME={{term.d_anchor}} HREF=#{{term.a_anchor}}><STRONG>{{ term.name }}</STRONG></A>
+  {% endfor %}
+<DD>{{ attr.html_description }}
+{% endfor %}
+</DL>
+<HR>