Function hgeo_to_html(geo,fn)
         hgeo_to_html(geo,fn,outputformat)
         hgeo_to_html(geo,fn,outputformat,htmltemplate)
         geo_complete = hgeo_to_html(geo,....)

writes the geometric data given by struct geo into a html/js file 
with name fn.

The html/js file is based on the template file hgeo_example.html 
residing in one of the Octave load paths (normally, the template
file resides in the same directory as the m-file of this function).
If another template file has to be used, its name is given by the
fourth input argument htmltemplate.

The js file with javascript subroutines, hgeo_three_bundle.js, is 
needed in companion with the html/js file for the web browser to
show the given geometry and interact with it. The js file will be 
written in the same directory as the html/js file, due to an internal
call to function hgeo_collect_js_scripts().

The first input argument contains typically the struct geo, but instead,
it can contain a row cellarray of two structs, {geo1, geo2}, when
two geometries are to be shown next to each other in the web browser
(e.g. the geometry proper and the legend).

Struct geo is organised in the following way:

   geo.shorttitle (optional) : a string for the window title (i.e. the 
                  contents of the html <title> tag). 

   geo.longtitle (optional) : a string with a longer description printed 
                  at the top of the page. 

   geo.camerastations (optional) : a cellarray of nC rows and 10 columns.
                  Each row contains a steady camera position, i.e. x,y,z position
                  of the camera, the x,y,z upright direction of the camera, 
                  the x,y,z position of the focus point, and a matrix cp, 
                  respectively. Matrix cp is empty, or contains data on 
                  one or more clipping planes; matrix cp has 6 columns for
                  the x,y,z components of the plane normal (pointing into
                  the space to be clipped away) and the x,y,z components of
                  a position on the plane, repectively.

                  For backward compatibility, geo.camerastations may consist
                  of a matrix of nC rows and 9 columns (and no clipping planes
                  can thus be defined).

   geo.camerastationnames (optional) : a cellarray of nC rows and 1 column of
                  strings. Each row contains a name or description of the 
                  camera station given to the same row in geo.camerastations.

   geo.cameratour (optional) : a matrix of nC rows and 9 columns.
                  Each row contains a moment in the tour, i.e. x,y,z position
                  of the camera, the x,y,z upright direction of the camera, 
                  and the x,y,z position of the focus point, respectively.

   geo.cameraorbitmodes (optional) : a record with data on settings for 
                  different orbit modes. See into the code of hgeo_subroutines.js
                  for explanation.

   geo.colors (necessary) : a matrix of nC rows and 3 columns. At each
                  row a color is defined by its red, green, blue channels (with 
                  values from 0 to 1).

                  When the first input argument consists of a cellarray of
                  structs {geo1, geo2}, one may omit geo2.colors. In that case
                  the colors of the first geometry, geo1.colors, are used for 
                  the second one too.

   geo.stepnames (optional) : a cellarray of nS rows and 1 column of strings,
                  Each row contains a name or description of the time step.

   geo.facepoints (optional) : a matrix of nFP rows and 3 columns. 
                  Each row contains the x,y,z coordinates of a point.

   geo.facepointnames (optional) : a cellarray with nFP rows and 1 column of strings.
                  Each row contains a name or description of the point 
                  given on the same row in geo.facepoints.

   geo.faces (optional) : a matrix of nF rows and 4 columns. 
                  Each row contains either four indices to rows in geo.facepoints, 
                  by which the points of a quadrangle are defined, or three indices 
                  (to rows in geo.facepoints) and zero or NaN, by which the points
                  of a triangle is defined. Points are listed counter-clockwise 
                  as seen from a point away from the plane of the face in the 
                  direction of the normal of the plane.

   geo.facecolors (optional) : a matrix of nF rows and 1 or nS columns.
                  Each row contains one or more indices to rows in geo.colors, 
                  and/or 0 or NaN when the face is invisible. Each row 
                  corresponds to the same row in geo.faces. Each column
                  corresponds to the row in geo.stepnames with the same index.
    
                  If geo.facecolors is not given (or if it is empty but geo.faces
                  is not empty), then it will be automatically produced so that 
                  each face has its own color.

   geo.facenames (optional) : a cellarray of nF rows and 1 column of strings.
                  Each row contains a name or description of the face 
                  given on the same row in geo.faces.

   geo.linepoints (optional) : a matrix of nLP rows and 3 columns.
                  Each row contains the x,y,z coordinates of a point.

   geo.lines (optional) : a matrix of nL rows and 2 columns; 
                  Each row contains two indices to rows in geo.linepoints, by
                  which the begin and end points of a line segment are defined.

   geo.linecolors (optional) : a matrix of nL rows and 1 or nS columns.
                  Each row contains one or more indices to rows in geo.colors, 
                  and/or 0 or NaN when the line is invisible. Each row 
                  corresponds to the same row in geo.lines. Each column
                  corresponds to the row in geo.stepnames with the same index.

   geo.texts (optional) : a cellarray of nT rows and 4 columns.
                  Each row contains the x,y,z coordinates of the anchor of a 
                  text block, and a text string.

   geo.textcode (optional) : a string indicating the type of coding used for 
                  the 4th column in geo.text. Possible values are:
                    geo.textcode = "latex" (default)
                    geo.textcode = "circumflex"
                  The latter coding is the native coding:
                    ^U...^E  superscript
                    ^D...^E  subscript
                    ^S...^E  slanted (italic)
                    ^C...^E  character name; e.g. aunknown, ahere<-, ahere->, a<-, a->, acircum
                    ^N       new line
                    ^Oxy     y is overwritten by x
                    ^Axy     diacritic x is put above or below y; x is to be replaced by:
                                a  for a acute 
                                g  for a grave
                                e  for a circumflex
                                U  for an umlaut or diaeresis
                                t  for a tilde
                                l  for a macron
                                p  for a dot above
                                u  for a breve
                                v  for a caron
                                H  for a double acute
                                c  for a cedilla
                                d  for a dot below
                                b  for a line below
                                r  for a ring above
                                x  for a stroke through
                                k  for a ogonek
                  Combinations are possible, e.g.:
                    ^O^Cacircum^E3   the digit 3 in a circle
                    ^Aa^Agu          the lower-case letter u with a grave and an acute on top

                  If the latex coding is applied, the code of the texts is converted into
                  the circumflex coding by function convert_to_circumflex(). 
                  Unfortunately, the convertion is not complete (yet)! For the moment, 
                  only super/subscripting and new lines are converted.

   geo.textcolors (optional) : a matrix of nT rows and 1 or nS columns.
                  Each row contains one or more indices to rows in geo.textproperties, 
                  and/or 0 or NaN when the text is invisible. Each row 
                  corresponds to the same row in geo.texts. Each column
                  corresponds to the row in geo.stepnames with the same index.

   geo.textproperties (optional) : a column cellarray, in which each element contains 
                  either one row cellarray of property-value pairs, or a struct. These 
                  property-value pairs must be given: 
                  "v", [1, 0, 0] : 3-d direction of the baseline of the text
                  "w", [0, 1, 0] : 3-d direction of the vertical of the text
                  "xheight", 1 : height of lower-case letter x in absolute length units
                  "color", [1, 1, 1] : r,g,b channels (value from 0 to 1)
                  The following property-value pairs are optional, and the default values are presented:
                  "font", "a" : the font name; font "a" is the default 
                  "xwidthoverxheight", 1 : ratio of width to height of lower-case letter x
                  "includedylinedown", 1 : whether (1) or not (0) lineglyphshapes[font]["dylinedown"] is added to the line skip
                  "lineskipconstant", 0 : whether (1) or not (0) the line skip is kept constant, of it depends on the possible extra vertical space due to diacritics, superscipts and subscripts
                  "slant", 0.2 : slant proportion: after slanting, a vertical line through x,y (0,0) and (0,xheight) wil go through (0,0) and (0+slant*xheight,xheight) 
                  "anchorvertical", "top" : position of the text block anchor along its vertical; possible values are: top, halfxheightabovefirstbaseline, firstbaseline, centre, lastbaseline, bottom
                  "anchorhorizontal", "left" : position of the text block anchor along its horizontal (i.e. baselines); possible values are: left, centre, right
                  "alignment", "centre" : horizontal alignment of lines within the text block; possible values are: left, centre, right

The values of the fields of geo are not checked for mistakes! 

Note e.g. that geo.faces depends on geo.facepoints (because an integer in 
geo.faces is the row index in geo.facepoints), and geo.facecolors depends on 
geo.faces, geo.stepnames and geo.colors (because each row in geo.facecolors 
corresponds to the same row in geo.faces, because each column in geo.facecolors 
corresponds to the row in geo.stepnames, and because an integer in 
geo.facecolors is the row index in geo.colors). The same principle applies to 
the group of geo.linepoints, geo.lines, geo.linecolors, geo.stepnames and 
geo.colors, and to the group of geo.texts, geo.textcolors, geo.stepnames and 
geo.textproperties.

The output is a html/js file. It can be loaded into a browser capable of webgl 
and javascript. The file with javascript subroutines, hgeo_three_bundle.js, 
should be available (residing in the same directory as the html/js file), and it 
contains javascript libraries three.js, OrbitControls.js and StereoEffect.js 
together with dedicated subroutines. 

If fn is empty, no html/js file is written. The filename must not collide
with hgeo_example.html nor with the filename given by input argument 
htmltemplate.

If geo_complete is given as output argument, it will contain the completed
version of struct geo, i.e. all the missing fields (optional or not) are 
added, and some fields are converted or reorganised.

In the html/js file, the (completed) struct geo will be written as a
javascript object. Optionally, its format can be controlled 
by the third input argument outputformat, which may have one
of the following values:
  1 : in verbose javascript (by a call to a dedicated internal function).
  2 : in compact javascript (by a call to the general function value2json()).
  3 : as a json-string argument within JSON.parse("....")
  4 : as a multiline json-string argument within JSON.parse(`....`)
  5 : as a multiline json-string argument within JSON.parse("....")
At default, outputformat = 5.

Internally, the following non-standard Octave m-files are called:
-- value2json.m,
-- convert_to_circumflex.m,
-- hgeo_collect_js_scripts.m.


(c) 2026 fabien van mook

2026.08.20 release of this file within package "fvm-hgeo" under GNU GPLv3+