geogebra

Is there an example showing how the geogebra.xml file is structured so I can write a file with custom data using another program?


Is there an example showing how the geogebra.xml file (found in Geogebra's *.ggb file) is structured so I can write a file with custom data using another program?

Version: Geogebra Classic 6 via Firefox web-browser session


Solution

  • I am posting this here to make life easier for others by offering a simplistic and generic approach to the problem.

    Geogebra's *.ggb file is a zip file which can be renamed to *.zip to simplify handling as a zip file.

    Examining that zip file, the contents are reported as:

    $ unzip -l Freq_30.zip
    Archive:  Freq_30.zip
      Length      Date    Time    Name
    ---------  ---------- -----   ----
        11839  2023-10-06 09:50   geogebra_thumbnail.png
           23  2023-10-06 09:50   geogebra_javascript.js
         9860  2023-10-06 09:50   geogebra_defaults2d.xml
         4497  2023-10-06 09:50   geogebra_defaults3d.xml
        26668  2023-10-06 09:50   geogebra.xml
    ---------                     -------
        52887                     5 files
    $ 
    

    As we can see, there are a number of XML files within that zip file. All those files can be extracted into a folder for manipulation. I strongly recommend that you make a duplicate copy of these files as a backup before manipulating the contents.

    After reviewing those files, I concluded that the only one that contains actual geometry constructs (unrelated to viewing, orientation or GUI) is is the geogebra.xml file.

    I created a very simplistic *.ggb model with minimal elements to be able to unravel the puzzle. For my simplified model, I was able to "explode" the geogebra.xml file into (as I perceived it) logical components. These were:

    -rw-rw-r-- 1 user group 5012 Oct  9 21:08 geogebra.xml__01_HEADER
    -rw-rw-r-- 1 user group 1587 Oct  9 21:04 geogebra.xml__02_GEOMETRY_POINT
    -rw-rw-r-- 1 user group 1722 Oct  9 21:05 geogebra.xml__03_GEOMETRY_SEGMENT
    -rw-rw-r-- 1 user group 1929 Oct  9 21:06 geogebra.xml__04_GEOMETRY_FACE
    -rw-rw-r-- 1 user group  288 Oct  9 21:06 geogebra.xml__05_TRAILER
    

    The contents of my finalized versions for each of these are included later (below) for study/review/reference.

    After manipulating these files to my satisfaction, I then reconstituted the geogebra.xml file from the newly-created parts (simple cat command in Linux).

    Having kept the other files that formed the original *.ggb file, I created a new *.ggb file with the appropriate form of the zip command. The *.zip file was then renamed to the *.ggb form expected by Geogebra.

    Using the File/Open options in Geogebra, I was able to load the new file successfully with the modified geometry and continue manipulating that without problems.

    I created a simple script (Geogebra__BuildCustomModel.sh) to simplify the rebuild of the *.gbb file from the component parts, namely:

    #!/bin/sh
    
    ####################################################################################################
    ###
    ### Script to intelligently build custom Geogebra *.ggb file from supplied component files
    ### which are compliant with Geogebra XML object definition structures.
    ###
    ### Author:  Eric Marceau, Ottawa, Canada
    ### Date:    2023-10-10
    ###
    ####################################################################################################
    
    xmlFile="geogebra.xml"      ; rm -f "${xmlFile}"
    zipFile="geogebra_BUILT.zip"    ; rm -f "${zipFile}"
    outFile="geogebra_BUILT.ggb"    ; rm -f "${outFile}"
    
    echo "\n Evaluating input files ..."
    abandon=0
    for file in \
        geogebra.xml__01_HEADER \
        geogebra.xml__02_GEOMETRY_POINT \
        geogebra.xml__03_GEOMETRY_SEGMENT \
        geogebra.xml__04_GEOMETRY_FACE \
        geogebra.xml__05_TRAILER
    do
        if [ -s "${file}" ]
        then
            ls -l "${file}" | awk '{ printf("\t [GOOD] %s\n", $0 ) ; }'
        else
            if [ -f "${file}" ]
            then
                echo "${file}" | awk '{ printf("\t [EMPT] %s\n", $0 ) ; }'
            else
                echo "${file}" | awk '{ printf("\t [MISS] %s\n", $0 ) ; }'
            fi
            abandon=1
        fi
        if [ ${abandon} -eq 1 ]
        then
            echo "\n\t Missing mandatory component(s) for creating Geogebra XML file."
            echo   "\t UNABLE to create the Geogebra model.\n"
            exit 1
        fi
    done
    
    cat \
        geogebra.xml__01_HEADER \
        geogebra.xml__02_GEOMETRY_POINT \
        geogebra.xml__03_GEOMETRY_SEGMENT \
        geogebra.xml__04_GEOMETRY_FACE \
        geogebra.xml__05_TRAILER \
        > "${xmlFile}"
    
    if [ -s "${xmlFile}" ]
    then
        echo "\n\t Geogebra XML file was successfully created:"
        ls -l "${xmlFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
    else
        echo "\n\t Geogebra XML file was NOT created."
        echo   "\t UNABLE to create the Geogebra model.\n"
        exit 1
    fi
    
    zip -Z store \
        "${zipFile}" \
        geogebra_thumbnail.png \
        geogebra_javascript.js \
        geogebra_defaults2d.xml \
        geogebra_defaults3d.xml \
        geogebra.xml
    
    if [ -s "${zipFile}" ]
    then
        echo "\n\t Geogebra ZIPped XML file was successfully created:"
        ls -l "${zipFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
        unzip -l "${zipFile}"
    
        echo "\n\t ZIP file renamed as Geogebra model file:"
        mv "${zipFile}" "${outFile}"
        ls -l "${outFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
    fi
    

    Here is a log for a "rebuild" session:

    $ ./Geogebra__BuildCustomModel.sh
    
     Evaluating input files ...
         [GOOD] -rw-rw-r-- 1 user group 5012 Oct  9 21:08 geogebra.xml__01_HEADER
         [GOOD] -rw-rw-r-- 1 user group 1587 Oct  9 21:04 geogebra.xml__02_GEOMETRY_POINT
         [GOOD] -rw-rw-r-- 1 user group 1722 Oct  9 21:05 geogebra.xml__03_GEOMETRY_SEGMENT
         [GOOD] -rw-rw-r-- 1 user group 1929 Oct  9 21:06 geogebra.xml__04_GEOMETRY_FACE
         [GOOD] -rw-rw-r-- 1 user group  288 Oct  9 21:06 geogebra.xml__05_TRAILER
    
         Geogebra XML file was successfully created:
    
         -rw-rw-r-- 1 user group 10538 Oct 10 09:05 geogebra.xml
      adding: geogebra_thumbnail.png (stored 0%)
      adding: geogebra_javascript.js (stored 0%)
      adding: geogebra_defaults2d.xml (stored 0%)
      adding: geogebra_defaults3d.xml (stored 0%)
      adding: geogebra.xml (stored 0%)
    
         Geogebra ZIPped XML file was successfully created:
    
         -rw-rw-r-- 1 user group 53340 Oct 10 09:05 geogebra_BUILT.zip
    Archive:  geogebra_BUILT.zip
      Length      Date    Time    Name
    ---------  ---------- -----   ----
        27718  2023-10-09 20:30   geogebra_thumbnail.png
           23  2023-10-09 20:30   geogebra_javascript.js
         9772  2023-10-09 20:30   geogebra_defaults2d.xml
         4423  2023-10-09 20:30   geogebra_defaults3d.xml
        10538  2023-10-10 09:05   geogebra.xml
    ---------                     -------
        52474                     5 files
    
         ZIP file renamed as Geogebra model file:
    
         -rw-rw-r-- 1 user group 53340 Oct 10 09:05 geogebra_BUILT.ggb
    $ 
    

    The resulting model seen in Geogebra is as follows: enter image description here

    Here are the contents of the 5 component files for my simplified Geogebra model.

    geogebra.xml__01_HEADER:

    <?xml version="1.0" encoding="utf-8"?>
    
    <!--==============================================================================-->
    <!--============================   START-of-HEADER   =============================-->
    <!--==============================================================================-->
    
    <geogebra format="5.0" version="5.2.805.0" app="classic" platform="w" id="dbae37b5-9aed-4148-8d01-be615e0b4b06"  xsi:noNamespaceSchemaLocation="http://www.geogebra.org/apps/xsd/ggb.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
    <gui>
        <window width="1029" height="641" />
        <perspectives>
    <perspective id="tmp">
        <panes>
            <pane location="" divider="1" orientation="1" />
        </panes>
        <views>
            <view id="1" visible="false" inframe="false" stylebar="true" location="3,3" size="277" window="100,100,600,400" />
            <view id="4" toolbar="0 || 2020 , 2021 , 2022 || 2001 , 2003 , 2002 , 2004 , 2005 || 2040 , 2041 , 2042 , 2044 , 2043" visible="false" inframe="false" stylebar="false" location="1,1" size="300" window="100,100,600,400" />
            <view id="8" toolbar="1001 | 1002 | 1003  || 1005 | 1004 || 1006 | 1007 | 1010 || 1008 | 1009 || 6" visible="false" inframe="false" stylebar="false" location="1,3" size="300" window="100,100,600,400" />
            <view id="2" visible="false" inframe="false" stylebar="true" location="3" size="380" tab="ALGEBRA" window="100,100,600,400" />
            <view id="16" visible="false" inframe="false" stylebar="false" location="1" size="300" window="50,50,500,500" />
            <view id="32" visible="false" inframe="false" stylebar="true" location="1" size="300" window="50,50,500,500" />
            <view id="64" toolbar="0" visible="false" inframe="false" stylebar="false" location="1" size="480" window="50,50,500,500" />
            <view id="128" visible="false" inframe="false" stylebar="false" location="1" size="480" window="50,50,500,500" />
            <view id="4097" visible="false" inframe="false" stylebar="true" location="1" size="237" window="100,100,700,550" />
            <view id="70" toolbar="0 || 2020 || 2021 || 2022" visible="false" inframe="false" stylebar="true" location="1" size="900" window="50,50,500,500" />
            <view id="512" toolbar="0 | 1 501 5 19 , 67 | 2 15 45 18 , 7 37 | 514 3 9 , 13 44 , 47 | 16 51 | 551 550 11 ,  20 22 21 23 , 55 56 57 , 12 | 69 | 510 511 , 512 513 | 533 531 , 534 532 , 522 523 , 537 536 , 535 , 538 | 521 520 | 36 , 38 49 560 | 571 30 29 570 31 33 | 17 | 540 40 41 42 , 27 28 35 , 6 , 502" visible="true" inframe="false" stylebar="false" location="3" size="1029" window="100,100,600,400" />
        </views>
        <toolbar show="true" items="0 73 62 | 1 501 67 , 5 19 , 72 75 76 | 2 15 45 , 18 65 , 7 37 | 4 3 8 9 , 13 44 , 58 , 47 | 16 51 64 , 70 | 10 34 53 11 , 24  20 22 , 21 23 | 55 56 57 , 12 | 36 46 , 38 49  50 , 71  14  68 | 30 29 54 32 31 33 | 25 17 26 60 52 61 | 40 41 42 , 27 28 35 , 6" position="1" help="false" />
        <input show="true" cmd="true" top="algebra" />
        <dockBar show="false" east="false" />
    </perspective>
        </perspectives>
        <labelingStyle  val="0"/>
        <font  size="16"/>
    </gui>
    <euclidianView>
        <viewNumber viewNo="1"/>
        <size  width="277" height="588"/>
        <coordSystem xZero="320.50000000000017" yZero="183.5" scale="50.00000000000002" yscale="50"/>
        <evSettings axes="true" grid="true" gridIsBold="false" pointCapturing="3" rightAngleStyle="1" checkboxSize="26" gridType="3"/>
        <bgColor r="255" g="255" b="255"/>
        <axesColor r="37" g="37" b="37"/>
        <gridColor r="192" g="192" b="192"/>
        <lineStyle axes="1" grid="0"/>
        <axis id="0" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
        <axis id="1" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
    </euclidianView>
    <algebraView>
        <mode val="1"/>
        <collapsed val="0"/>
    </algebraView>
    <kernel>
        <uses3D val="true"/>
        <continuous val="false"/>
        <usePathAndRegionParameters val="true"/>
        <decimals val="2"/>
        <angleUnit val="degree"/>
        <algebraStyle val="2" spreadsheet="0"/>
        <coordStyle val="0"/>
    </kernel>
    <tableview min="0" max="0" step="0"/>
    <scripting blocked="false" disabled="false"/>
    <euclidianView3D>
        <coordSystem xZero="-0.6504528252066868" yZero="-0.33047043474869997" zZero="-2.4777010833587454" scale="60.67107623140951" xAngle="20" zAngle="-60"/>
        <evSettings axes="true" grid="false" gridIsBold="false" pointCapturing="3" rightAngleStyle="1" gridType="3"/>
        <axis id="0" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
        <axis id="1" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
        <axis id="2" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
        <plate show="true"/>
        <bgColor r="255" g="255" b="255"/>
        <clipping use="false" show="false" size="1"/>
        <projection type="0"/>
    </euclidianView3D>
    <construction title="" author="" date="">
    
    <!--==============================================================================-->
    <!--=============================   END-of-HEADER   ==============================-->
    <!--==============================================================================-->
    

    geogebra.xml__02_GEOMETRY_POINT:

    <!--==============================================================================-->
    <!--============================   START-of-POINTS   =============================-->
    <!--==============================================================================-->
    
    <expression label="MYPOINT" exp="(2, 1, 3)" type="point"/>
    <element type="point3d" label="MYPOINT">
        <show object="true" label="true" ev="4"/>
        <objColor r="255" g="0" b="0" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <animation step="0.1" speed="1" type="1" playing="false"/>
        <pointSize val="5"/>
        <coords x="2" y="1" z="3" w="1"/>
    </element>
    
    <expression label="OTPOINT" exp="(-1, -1, 2)" type="point"/>
    <element type="point3d" label="OTPOINT">
        <show object="true" label="true" ev="4"/>
        <objColor r="0" g="255" b="0" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <animation step="0.1" speed="1" type="1" playing="false"/>
        <pointSize val="5"/>
        <coords x="-1" y="-1" z="2" w="1"/>
    </element>
    
    <expression label="EXPOINT" exp="(1, 1, 6)" type="point"/>
    <element type="point3d" label="EXPOINT">
        <show object="true" label="true" ev="4"/>
        <objColor r="0" g="0" b="255" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <animation step="0.1" speed="1" type="1" playing="false"/>
        <pointSize val="5"/>
        <coords x="1" y="1" z="6" w="1"/>
    </element>
    
    <!--==============================================================================-->
    <!--=============================   END-of-POINTS   ==============================-->
    <!--==============================================================================-->
    

    geogebra.xml__03_GEOMETRY_SEGMENT:

    <!--==============================================================================-->
    <!--===========================   START-of-SEGMENTS  =============================-->
    <!--==============================================================================-->
    
    <command name="Segment">
        <input a0="MYPOINT" a1="OTPOINT"/>
        <output a0="MYLINE"/>
    </command>
    <element type="segment3d" label="MYLINE">
        <show object="true" label="false" ev="4"/>
        <objColor r="255" g="0" b="0" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <lineStyle thickness="1" type="0" typeHidden="1"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    
    <command name="Segment">
        <input a0="MYPOINT" a1="EXPOINT"/>
        <output a0="OTLINE"/>
    </command>
    <element type="segment3d" label="OTLINE">
        <show object="true" label="false" ev="4"/>
        <objColor r="0" g="255" b="0" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <lineStyle thickness="1" type="0" typeHidden="1"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    
    <command name="Segment">
        <input a0="OTPOINT" a1="EXPOINT"/>
        <output a0="EXLINE"/>
    </command>
    <element type="segment3d" label="EXLINE">
        <show object="true" label="false" ev="4"/>
        <objColor r="0" g="0" b="255" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <lineStyle thickness="1" type="0" typeHidden="1"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    
    <!--==============================================================================-->
    <!--============================   END-of-SEGMENTS  ==============================-->
    <!--==============================================================================-->
    

    geogebra.xml__04_GEOMETRY_FACE:

    <!--==============================================================================-->
    <!--=============================   START-of-FACE   ==============================-->
    <!--==============================================================================-->
    
    <command name="Polygon">
        <input a0="MYPOINT" a1="OTPOINT" a2="EXPOINT"/>
        <output a0="MYFACE" a1="expoint" a2="mypoint" a3="otpoint"/>
    </command>
    <element type="polygon3d" label="MYFACE">
        <lineStyle thickness="0" type="0" typeHidden="0" opacity="114"/>
        <show object="true" label="true" ev="4"/>
        <objColor r="255" g="255" b="102" alpha="0.1"/>
        <layer val="0"/>
        <labelMode val="0"/>
    </element>
    <element type="segment3d" label="expoint">
        <show object="false" label="false" ev="4"/>
        <objColor r="192" g="192" b="192" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <auxiliary val="false"/>
        <lineStyle thickness="0" type="0" typeHidden="0"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    <element type="segment3d" label="mypoint">
        <show object="false" label="false" ev="4"/>
        <objColor r="192" g="192" b="192" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <auxiliary val="false"/>
        <lineStyle thickness="0" type="0" typeHidden="0"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    <element type="segment3d" label="otpoint">
        <show object="false" label="false" ev="4"/>
        <objColor r="192" g="192" b="192" alpha="0"/>
        <layer val="0"/>
        <labelMode val="0"/>
        <auxiliary val="false"/>
        <lineStyle thickness="0" type="0" typeHidden="0"/>
        <outlyingIntersections val="false"/>
        <keepTypeOnTransform val="true"/>
    </element>
    
    <!--==============================================================================-->
    <!--==============================   END-of-FACE   ===============================-->
    <!--==============================================================================-->
    

    geogebra.xml__05_TRAILER:

    <!--==============================================================================-->
    <!--============================   START-of-TRAILER   ============================-->
    <!--==============================================================================-->
    
    </construction>
    </geogebra>