Getting Started With PHP

From Symgate Developer's Wiki
Jump to: navigation, search

This document explains how to get started using the symboliser with PHP.

Contents

Setting up your environment

Using Symgate requires PHP 5.2 or higher. It does not work with any 4.x, 5.0.x, or 5.1.x branches, sorry. You will need to update your PHP if you are using an earlier version.

To get started with PHP, you'll have to download the required include files, and unpack them to your project directory. You should include the "include/symgate.php" file where you want to use the symboliser.

The PHP includes define one object for every type in the schema. The reference documentation has complete documentation on all the available types. Class names in PHP have the same names as the types defined by the schema, except that they have a prefix: "CML_" for cml types (defined in http://ws.widgit.com/schemal/cml.xsd), "WL_" for wordlist types (defined in http://ws.widgit.com/schema/wordlist.xsd) and "SG_" for symgate types (defined in http://ws.widgit.com/schema/symgate.wsdl).

You'll find CML objects define the actual document content, Wordlist objects are used to define and manipulate wordlists, and Symgate objects are usually input or output parameters from the Symgate operations themselves.

Performing an operation

About Requests and Responses

Each operation within the symboliser takes a single request object, and returns a repsonse object.

Information on what type of object is required for, and returned by each operation is an important part of the Reference Documentation.

Account Parameters

Request objects will always require an accountID object (as it's creds member) which contains your account name and key.

Example: Creating your accountID object:

require_once ( "include/symgate.php" ) ;
 
$creds = new SG_accountId ( "accountname" , "keyvalue" ) ;

Request Options

Parse Options

Request objects that process text-based input (plain text, or HTML) will require a symboliserParseOptions object, as their options member - this contains information required to convert the text to symbolised data. At present, this simply defines the language you want to use (or whether you want to use automatic language detection), as well as some options governing how the text is parsed, and how the CML is generated.

You should specify the language parameter if you want to define the actual language you want the symboliser to use.

Alternatively, you can use language detection if you are unsure of the input language. To do this, you should specify the fallbackLanguage and englishDialect parameters instead of the language parameter. This causes the symboliser to detect the language by analysing the input text, choosing the fallbackLanguage if it is unsure (which is sometimes the case when symbolising a small number of words). The englishDialect parameter is used to specify which version of English to use if the input is determined to be English, as language detection cannot detect between UK, American, and Australian English.

The schema defines a choice of either language, or fallbackLanguage and englishDialect. You should not try and mix them.

The other options available are booleans, which govern how the CML is generated:

  • collapseWhitespace - if this is set to true, any groups of whitespace characers in the input will be collapsed to a single space before processing. If false, then sending sequences of spaces will result in additional cmaps being generated. Default: true
  • generateBlankAlternatives - if this is set to true, every symbol will have an additional alternative created for it that contains just the text, and no symbol. This is useful if you always want to have an option to switch a symbol off. Default: false
  • allowRecursiveAltlists - if this is set to true, then the symboliser will generate output in which altlists can contain other altlists. This can result in smaller output, but is harder to parse. Default: false

Example: Creating your symboliserParseOptions object:

// symbolise in UK English:
$parseOptions = new SG_symboliserParseOptions ( "English_UK" ) ;  // use defaults
 
// Use language detection to determine symbolisation language, fall back to Swedish if unsure,
// but use US English as the dialect if English is detected as the language.
$parseOptions = new SG_symboliserParseOptions ( "Swedish" , true , false , false , "English_US" ) ;

Rendering Options

Similarly, request objects that perform rendering operations (such as conceptToSymbol, or cmlToXHTML) require a symboliserRenderOptions object as their options member. This contains information on how the symbols should look, for example what symbol set to use.

In many cases, the defaults will be OK. The options available are:

  • symset: defines which symbol system to use. Currently 'Widrebus' is the only supported option, although support for more is planned
  • coloredSymbols: specifies whether to use coloured, or "black-and-white" symbols. Specify 'true' for coloured symbols. Specify false for line-drawn symbols.
  • lineColor: specifies what line colour to use (in hex) when using line-drawn rather than coloured symbols. Default is "000000" for black lines.
  • basesize: Where releveant, this controls the base height of the rendered symbols.
  • languageLevel: an ingeger which allows you to control the way symbols are generated. Setting a number > 0 causes certain types of symbols to be switched off, to allow for different comprehension levels. currently unimplemented!
  • qualifierOptions: allows you to switch off certaion types of symbol qualifiers (such as plural qualifiers) to reduce clutter. This may or may not be appropriate, depending on content.
  • conceptFilter: Allows the filtering of certain types of symbol based on their concept code. This is for advanced users, but the default of '??02010' is recommended, as it filters out the sex education symbols.

Example: Creating your symboliserRenderOptions object:

// construct the object, using Colored WLS symbols, at 120px high
$renderOptions = new SG_symboliserRenderOptions ( 120 , "Widrebus" , true ) ;
 
// languageLevel, qualifierOptions, and conceptFilter will use their default values

Wordlist Options

Many requests take a wordlistInfo object as their wordlists member. These allow you to reference any additional wordlists you may have defined, to add vocabulary. You will probably not be using them immediately, but it is important to remember that any call to a rendering-type operation should have wordlist information that is identical to the parsing-type operation that generated the input for it.

However, for your inital usage of the symboliser, it is best to leave this option empty (null object). See Using Wordlists if you want to get started with these.

Other parameters

Finally, request objects will contain the input for the operation itself, such as the text member in the textToCML operation.

There may also be additional operation-specific input options seperate from the parse/render options. For example, the conceptToSymbol operation takes an ImagePathFormat parameter, that specifies whether to return image paths as full URIs (recommended for web application developers), or intallation-relative paths (recommended for client application developers). - These additional parameters will be described in the documenation for the specific operation.

Putting it together: Performing a request

Once you have created your request object, getting your response is simple. All you need to do is invoke the relevant symboliser operation and obtain the result.

Operations are invoked through the SG_symboliser object. (For wordlist operations, there is also an SG_wordlistManager object available)

Here is an example of how to symbolise "Hello World!" into CML.

Example: Calling textToCML:

<?php
 
require_once ( "include/symgate.php" ) ;
 
//Create our symboliser object, to be able to call the relevant operations
$symboliser = new SG_symboliser ;
 
//Account Details
$creds = new SG_accountID ( "my_account" , "my_key" ) ;
 
//Parse Options
$parseOptions = new SG_symboliserParseOptions ( "English_UK" ) ;
 
//Create the Request. textToCML requires a 'symboliserTextInput' object as the request
$textToCMLRequest = new SG_symboliserTextInput ( $creds , $options , "Hello World!" ) ;
 
//Call the textToCML operation to convert the text to CML
$cml = $symboliser->textToCML ( $textToCMLRequest ) ;
 
// print out the CML
var_dump ( $cml ) ;
 
?>

Parsing CML

The basic structure if CML is described in Getting Started: Basic Concepts.

This section will show you how to iterate over a CML document, and thus learn something about it's structure and how to access and manipulate the objects that it contains.

Iterating over CML

Example Description

This example assumes we are converting from plain text, not HTML (which produces more complex output).

A cml object contaions a body and a header. The header will be blank if we are symbolising from plain text. The body contains a list of elements which will be paragraphs or horizontal lines (again, the latter will not be present with a plain text source.)

Paragraphs, contain a list of sentences, and these contain a list of elements which can be cmaps or altlists (and with an HTML source, also links, linebreaks, images or form controls.)

Cmaps contain the text to be displayed along with a list of concept codes which can be passed back to the symboliser to produce a symbol.

Altlists contain a list of 'alternatives' describing the same part of the document. Each alternative can contain any of the elements that a sentence can, although in practice the symboliser does not generate recursive altlists (calts that contain further altlists) for the sake of simplicity.

This example will take some CML, and iterate over the result, printing text information to the console about all of the object types that it finds.

Example Code

Download an example program that converts some text to CML, and iterates over the result (as shown below) here:

Example: Iterating over a CML document in PHP:

// iterate over the body elements:
for ( $iParagraph = 0 ; $iParagraph < count ( $cml->body->elements ) ; $iParagraph ++ )
{
    //normally they will be paragraphs, but they may be a horizontal line
    if ( get_class ( $cml->body->elements [ $iParagraph ] ) == "CML_hr" )
    {
        echo "--Horizontal Rule--\n" ;
    }
 
    if ( get_class ( $cml->body->elements [ $iParagraph ] ) == "CML_cp" )
    {
        $paragraph = $cml->body->elements [ $iParagraph ] ;
        echo "--Paragraph " . $iParagraph . ", Language: " . $paragraph->language . "--\n" ;
 
        //If we find a paragraph, continue to iterate over the sentences it contains
        for ( $iSentence = 0 ; $iSentence < count ( $paragraph->sentences ) ; $iSentence ++ )
        {
            $sentence = $paragraph->sentences [ $iSentence ] ;
            echo " --Sentence " . $iSentence . "--\n" ;
 
            for ( $iElement = 0 ; $iElement < count ( $sentence->elements ) ; $iElement ++ )
            {
                // this is the hard part. sentences usually consist of cmaps and altlists when converting
                // from plain text, but when converting from HTML they may also contain links, linebreaks,
                // images and form controls. For simplicity, we will only handle cmaps and altlists here for now
 
                if ( get_class ( $sentence->elements [ $iElement ] ) == "CML_cmap" )
                {
                    //it's a cmap, display the concept code count and text
                    $cmap = $sentence->elements [ $iElement ] ;
                    echo "  --element " . $iElement
                        . ", type: cmap with " . count ( $cmap->concepts )
                        . " conceptcodes, text: " . $cmap->text
                        . "--\n" ;
                }
 
                if ( get_class ( $sentence->elements [ $iElement ] ) == "CML_altlist" )
                {
                    $altlist = $sentence->elements [ $iElement ] ;
                    // it's an altlist, display the alternative count, and then ...
                    echo "  --element " . $iElement
                        . ", type: altlist with " . count ( $altlist->alternatives )
                        . " alternatives--\n" ;
 
                    // ... display the contents of each alternative
 
                    for ( $iAlternative = 0 ; $iAlternative < count ( $altlist->alternatives ) ; $iAlternative ++ )
                    {
                        $alternative = $altlist->alternatives [ $iAlternative ] ;
                        echo "   --alternative " . $iAlternative
                            . ", priority: " . $alternative->priority
                            . ", preferred: " . $alternative->preferred
                            . "--\n" ;
 
                        for ( $iAltElement = 0 ; $iAltElement < count ( $alternative->elements ) ; $iAltElement ++ ) 
                        {
                            // again, this element can be a cmap, altlist, or any of the HTML-related entities
                            // mentioned above. *however*, while it is allowed bt the schema, the symboliser will
                            // not generate recursive altlists (calts that contain altlists) as they are harder
                            // for client applications to parse (unless you enable this feature in the options).
                            // thus, we are likely to have a cmap here
 
                            if ( get_class ( $alternative->elements [ $iAltElement ] ) == "CML_cmap" )
                            {
                                //it's a cmap, display the concept code count and text
                                $cmap = $alternative->elements [ $iAltElement ] ;
                                echo "  --element " . $iElement
                                    . ", type: cmap with " . count ( $cmap->concepts )
                                    . " conceptcodes, text: " . $cmap->text
                                    . "--\n" ;
                            }
                        }
                    }
                }
            }
        }
    }
}

Example Output

Calling the above program, using the "Hello World!" example above to set up the request (which was omitted from the example code here), produces the following output:

--Paragraph 0, Language: English_UK--
 --Sentence 0--
  --element 0, type: cmap with 1 conceptcodes, text: Hello--
  --element 1, type: altlist with 2 alternatives--
   --alternative 0, priority: 0, preferred: False--
    --element 0, type: cmap with 1 conceptcodes, text: World!--
   --alternative 1, priority: 1, preferred: False--
    --element 0, type: cmap with 1 conceptcodes, text: World!--

The CML generated by passing "Hello World!" to the textToCML operation, looks like this:

<cml>
 <body>
  <cp size="0" language="English_UK" >
   <cs>
    <cmap>
     <cc base="hello" tags="Noun+Sg" code="30800030690000000" pos="NOUN" />
     <text>Hello</text>
    </cmap>
    <altlist>
     <calt priority="0" >
      <cmap>
       <cc base="world" tags="Noun+Sg" code="30120600010100000" pos="NOUN" />
       <text>World!</text>
      </cmap>
     </calt>
     <calt priority="1" >
      <cmap>
       <cc base="world" tags="Noun+Sg" code="30120600000000000" pos="NOUN" />
       <text>World!</text>
      </cmap>
     </calt>
    </altlist>
   </cs>
  </cp>
 </body>
</cml>

Rendering CML

Once you have a CML document prepared the way you want it, you will want to display it to the user.

This can currently be done by either using the reference XHTML renderer, using the cmlToXHTML symboliser operation, or by rendering the CML yourself.

Using the reference XHTML renderer

Using the reference XHTML renderer is simple. Simply call the cmlToXHTML operation, providing the standard creds and wordlist options, along with your CML object for rendering, a symboliserRenderOptions object describing how you want your CML to be displayed, and an XHTMLOutputFormat parameter, saying whether you want a full document output (complete with <html>, <head> and <body> sections) or just as a partial document fragment to be inserted into another document.

Example: Using the reference renderer in PHP:

$renderOptions = new SG_symboliserRenderOptions ; // use default rendering options
$renderRequest = new SG_cmlToXHTMLRequest ( $creds , $options , $cml , "FullDocument" ) ;
 
$xhtml = $symboliser->cmlToXHTML ( $renderRequest ) ;

The output of this example code, when given the above "Hello World!" example, looks like this.

Rendering CML Yourself

As you have already seen above, and in the "Getting Started: Basic Concepts" section, your CML document is essentially made up of a series of cmap objects, inside various other containers. It is the cmap objects that we wish to render, as they contain the information on the text and graphics that we will want to display.

Choosing which cmaps to display

As you are aware, there can be many symbol alternatives in a document, represented by an altlist. If you are rendering a document to the user for reading (as opposed to an author, for selecting the appropriate alternatives), you will want to iterate over the document as shown above, and choose the alternative that has it's "preferred" attribute set. If no preferred attribute is set for the altlist, you should use the alternative with the lowest 'priority' value.

Getting hold of the graphics to display

For each cmap, you will want to display any symbols it represents, with the contents of it's "text" member displayed underneath.

Getting the information on what symbols to display requires an additional step. Cmaps contain conceptcode elements, which must be passed to the conceptToSymbol operation, which tells you which actual graphic files must be displayed.

Once you have called conceptToSymbol with all the conceptcodes you are interested in rendering, you end up with a collection of CML symbol objects, which tell you which graphics to display for the given symbol.

Displaying your symbol in a web page

We recommend using an HTML table element in order to display the graphics that make up a symbol in the correct places. (The correct places are described in "How To Render Symbols")

We realise that this can cause consternation for developers who have spent the last few years learning why tables are bad, and CSS is good. If this bothers you, you might want to read Why Using Tables for Rendering Symbols is a Good Idea (even on a CSS-powered site.)

Note, this is not the only way symbols can be rendered on a web page, but from experience we find it the simplest.

Symbols can be treated as a table with up to 5 columns, starting with the topLeft and bottomLeft qualifiers in the first column, the full-left in the second, the main and top symbols in the third column, the full-right in the fourth, and the top-right and bottom-right in the fifth.

The following example code shows how this might be achieved in some detail:

// start writing the symbol table
echo "<table class='cml_symtable'>\n" ;
 
// find out how many rows we need in the table. Normally one, unless
// there are 'short' qualifiers
$nRows = 1 ;
if ( strlen ( $symbol->topleft ) > 0 ||
     strlen ( $symbol->bottomleft ) > 0 ||
     strlen ( $symbol->topright ) > 0 ||
     strlen ( $symbol->bottomright ) > 0 )
{
    $nRows = 2 ;
}
 
for ( $iRow = 0 ; $iRow < $nRows ; $iRow ++ )
{
    echo "<tr class='cml_symtable_row'>\n" ;
 
    // write the small-left qualifier column
    if ( strlen ( $symbol->topleft ) > 0 ||
         strlen ( $symbol->bottomleft ) > 0 )
    {
        $qual = $iRow == 0 ? $symbol->topleft : $symbol->bottomleft ;
 
        echo "<td class='cml_symtable_cell'>\n" ;
        echo "<img class='cml_symbol_image' src='" . $qual . "' alt='' />\n" ;
        echo "</td>\n" ;
    }
 
    // write the full-left qualifier column
    if ( strlen ( $symbol->fullleft ) > 0 && $iRow == 0 )
    {
        // if there are 2 rows, make this column cover both
        if ( $nRows == 2 )
            echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
        else
            echo "<td class='cml_symtable_cell'>\n" ;
 
        echo "<img class='cml_symbol_image' src='" . $symbol->fullleft . "' alt='' />\n" ;
 
        echo "</td>\n" ;
    }
 
    // write the center column..
    if ( $iRow == 0 )
    {
        $altText = $cmap->text;
        $altText = str_replace( "\'" , "\\\'" , $altText ) ; // escape quotes in the alt text
 
        // if there are 2 rows, make this column cover both
        if ( $nRows == 2 )
            echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
        else
            echo "<td class='cml_symtable_cell'>\n" ;
 
        if ( strlen ( $symbol->top ) > 0 )
        {
            // write a table to justify the top, and main qualifiers
            echo "<table class='cml_inner_symtable'>\n" ;
            echo "<tr class='cml_inner_symtable_row'>\n" ;
            echo "<td class='cml_inner_symtable_cell'>\n" ;
 
            // write the top qualifier
            echo "<img class='cml_symbol_image' src='" . $symbol->top . "' alt='' />\n" ;
 
            echo "</td>\n" ;
            echo "</tr>\n" ;
            echo "<tr class='cml_inner_symtable_row'>\n" ;
            echo "<td class='cml_inner_symtable_cell'>\n" ;
 
            // write the main symbol
            echo "<img class='cml_symbol_image' src='" . $symbol->main . "' alt='' />\n" ;
 
            echo "</td>\n" ;
            echo "</tr>\n" ;
            echo "</table>\n" ;
        }
        else
        {
            // there is no top qualifer, just write the main symbol
            echo "<img class='cml_symbol_image' src='" . $symbol->main . "' alt='' />\n" ;
        }
 
        echo "</td>\n" ;
    }
 
    // write the full-right qualifier column
    if ( strlen ( $symbol->fullright ) > 0 && $iRow == 0 )
    {
        // if there are 2 rows, make this column cover both
        if ( $nRows == 2 )
            echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
        else
            echo "<td class='cml_symtable_cell'>\n" ;
 
        echo "<img class='cml_symbol_image' src='" . $symbol->fullright . "' alt='' />\n" ;
 
        echo "</td>\n" ;
    }
 
    // write the small-right qualifier column
    if ( strlen ( $symbol->topright ) > 0 ||
         strlen ( $symbol->bottomright ) > 0 )
    {
        $qual = $iRow == 0 ? $symbol->topright : $symbol->bottomright ;
 
        echo "<td class='cml_symtable_cell'>\n" ;
        echo "<img class='cml_symbol_image' src='" . $qual . "' alt='' />\n" ;
        echo "</td>\n" ;
    }
}
 
echo "</table>\n" ;

Note that the above example uses spacer GIFs to vertically-justify the top and bottom qualifiers. You should also note that it does not attempt to resize the images if there is a top qualifier present. If a top qualifier is present, and you are using fullURI pathnames as the output from conceptToSymbol, you will automatically get a link to a main symbol whose height is 80% of the base, and a top symbol that takes up the other 20%.

You will also want to display the text along with each symbol. Traditionally, the text is rendered underneath the symbol, and centered beneath it. The simplest way to do this might be to use an additional row in the symbol table.

If you want your symbols to wrap, like a conventional text document, the best way that we can find to achieve this is to surround each symbol table with a <div>, with the css attribute "float: left" set. Ideally it might be better to use the "display: inline-block" attribute, but browser support for this is patchy.

Putting it all together

Hopefully this will given you an overview of how to do most important CML-related tasks using the symbolisation engine, within the context of your own PHP application.

Example Code

A complete examples of a program that takes a string, converts it to CML, and then manually renders the relevant cmaps as an HTML page is listed below.

Note, that this is a very simple implementation of an HTML renderer, which has several drawbacks. These are discussed further in Improving Our Manual Renderer.

You can download the example code here:

Note that this example is in the form of a console application, that prints the rendered HTML to stdout. The Example Output is listed below

Example: Manually rendering CML in PHP (simple)

<?php
 
    require_once ( "include/symgate.php" ) ;
 
    // a function to write the HTML for a single CMAP
    function WriteCMap ( $creds , $renderOpts , $cmap , $symboliser )
    {
 
        /************************** Write an HTML header for the cmap **************************/
 
        // create a div for the whole cmap
        echo "<div class='cml_cmap'>\n" ;
 
        //generate a div for each symbol
        echo "<div class='cml_symbol'>\n" ;
        //another css float hack
        echo "<div class='cml_symbol_start'></div>\n" ;
 
        $rendered = false ;
 
        if ( count ( $cmap->concepts ) > 0 )
        {
            /************************** Get the symbol(s) from the cmap **************************/
            //NOTE: This is not very efficient. We are calling conceptToSymbol *once per cmap*. This
            //is because the example is more readable that way. In a production environment, you may
            //want to create a list of all your concepts, and then call conceptToSymbol once.
 
            //Note also that this is not the only way that you can write HTML containing symbols, but
            //it's a simple method that works for us, and matches fairly closely what the reference
            //renderer does.
 
            //create the request
            $conceptToSymbolRequest = new SG_conceptToSymbolRequest ( $creds , $renderOpts , "FullURI" , $cmap->concepts ) ;
 
            $conceptToSymbolResponse = $symboliser->conceptToSymbol ( $conceptToSymbolRequest ) ;
            $symbols_for_concepts = $conceptToSymbolResponse->symbols ;
            // note the output is an array of symbol arrays... One symol array refers to each concept
            // in the input array, as each concept can generate one or more (or zero) symbols
 
            /************************** Write the CMap as HTML **************************/
 
            //we want a blank placeholder image, for short-qualifers (topleft, bottomleft, etc) that are missing
            $blankQual = "http://widrebus.symgate.com/" .
                    $creds->account .
                    "/col/" .
                    (int)($renderOpts->basesize / 2) .
                    "/blank.sym" ;
            //.sym files are automatically returned as png for firefox and ie7, and gif for ie6
 
            for ( $iSymbolList = 0 ; $iSymbolList < count ( $symbols_for_concepts ) ; $iSymbolList ++ )
            {
                for ( $iSymbol = 0 ; $iSymbol < count ( $symbols_for_concepts [ $iSymbolList ] ) ; $iSymbol ++ )
                {
                    $symbol = $symbols_for_concepts [ $iSymbolList ] [ $iSymbol ] ;
 
                    // start writing the symbol table
                    echo "<table class='cml_symtable'>\n" ;
 
                    // find out how many rows we need in the table. Normally one, unless
                    // there are 'short' qualifiers
                    $nRows = 1 ;
                    if ( strlen ( $symbol->topleft ) > 0 ||
                         strlen ( $symbol->bottomleft ) > 0 ||
                         strlen ( $symbol->topright ) > 0 ||
                         strlen ( $symbol->bottomright ) > 0 )
                    {
                        $nRows = 2 ;
                    }
 
                    for ( $iRow = 0 ; $iRow < $nRows ; $iRow ++ )
                    {
                        echo "<tr class='cml_symtable_row'>\n" ;
 
                        // write the small-left qualifier column
                        if ( strlen ( $symbol->topleft ) > 0 ||
                             strlen ( $symbol->bottomleft ) > 0 )
                        {
                            $qual = $iRow == 0 ? $symbol->topleft : $symbol->bottomleft ;
 
                            echo "<td class='cml_symtable_cell'>\n" ;
                            echo "<img class='cml_symbol_image' src='" . $qual . "' alt='' />\n" ;
                            echo "</td>\n" ;
                        }
 
                        // write the full-left qualifier column
                        if ( strlen ( $symbol->fullleft ) > 0 && $iRow == 0 )
                        {
                            // if there are 2 rows, make this column cover both
                            if ( $nRows == 2 )
                                echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
                            else
                                echo "<td class='cml_symtable_cell'>\n" ;
 
                            echo "<img class='cml_symbol_image' src='" . $symbol->fullleft . "' alt='' />\n" ;
 
                            echo "</td>\n" ;
                        }
 
                        // write the center column..
                        if ( $iRow == 0 )
                        {
                            $altText = $cmap->text;
                            $altText = str_replace( "\'" , "\\\'" , $altText ) ; // escape quotes in the alt text
 
                            // if there are 2 rows, make this column cover both
                            if ( $nRows == 2 )
                                echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
                            else
                                echo "<td class='cml_symtable_cell'>\n" ;
 
                            if ( strlen ( $symbol->top ) > 0 )
                            {
                                // write a table to justify the top, and main qualifiers
                                echo "<table class='cml_inner_symtable'>\n" ;
                                echo "<tr class='cml_inner_symtable_row'>\n" ;
                                echo "<td class='cml_inner_symtable_cell'>\n" ;
 
                                // write the top qualifier
                                echo "<img class='cml_symbol_image' src='" . $symbol->top . "' alt='' />\n" ;
 
                                echo "</td>\n" ;
                                echo "</tr>\n" ;
                                echo "<tr class='cml_inner_symtable_row'>\n" ;
                                echo "<td class='cml_inner_symtable_cell'>\n" ;
 
                                // write the main symbol
                                echo "<img class='cml_symbol_image' src='" . $symbol->main . "' alt='' />\n" ;
 
                                echo "</td>\n" ;
                                echo "</tr>\n" ;
                                echo "</table>\n" ;
                            }
                            else
                            {
                                // there is no top qualifer, just write the main symbol
                                echo "<img class='cml_symbol_image' src='" . $symbol->main . "' alt='' />\n" ;
                            }
 
                            echo "</td>\n" ;
                        }
 
                        // write the full-right qualifier column
                        if ( strlen ( $symbol->fullright ) > 0 && $iRow == 0 )
                        {
                            // if there are 2 rows, make this column cover both
                            if ( $nRows == 2 )
                                echo "<td class='cml_symtable_cell' rowspan='2'>\n" ;
                            else
                                echo "<td class='cml_symtable_cell'>\n" ;
 
                            echo "<img class='cml_symbol_image' src='" . $symbol->fullright . "' alt='' />\n" ;
 
                            echo "</td>\n" ;
                        }
 
                        // write the small-right qualifier column
                        if ( strlen ( $symbol->topright ) > 0 ||
                             strlen ( $symbol->bottomright ) > 0 )
                        {
                            $qual = $iRow == 0 ? $symbol->topright : $symbol->bottomright ;
 
                            echo "<td class='cml_symtable_cell'>\n" ;
                            echo "<img class='cml_symbol_image' src='" . $qual . "' alt='' />\n" ;
                            echo "</td>\n" ;
                        }
                    }
 
                    echo "</table>\n" ;
                    $rendered = true ;
                }
            }
        }
 
        if ( !$rendered )
        {
            // if we haven't rendered any symbols, we should use a blank placeholder instead, to ensure the
            // text is positioned correctly
            $blankUri = "http://widrebus.symgate.com/" .
                $creds->account .
                "/col/" .
                $renderOpts->basesize .
                "/blank.sym";
            //.sym files are automatically returned as png for firefox and ie7, and gif for ie6
 
            echo "<div class='cml_symbol_single'>\n" ;
            echo "<img class='cml_symbol_image' src='" . blankUri . "' alt='' />\n" ;
            echo "</div>\n" ;
        }
 
        /************************** Write the text for the cmap, and close the tags **************************/
 
        echo "<div class='cml_symbol_end'></div>\n" ;
        echo "</div>\n" ;
 
        echo "<div class='cml_cmap_text'>\n" ;
 
        if ( $cmap->emphasis )
            echo "<i>\n" ;
        if ( $cmap->strong )
            echo "<b>\n" ;
 
        echo $cmap->text ;
 
        if ( $cmap->strong )
            echo "</b>\n" ;
        if ( $cmap->emphasis )
            echo "</i>\n" ;
 
        echo "</div>\n" ;
        echo "</div>\n" ;
    }
 
 
    /************************** Create our configuration objects **************************/
 
    // create our symboliser
    $symboliser = new SG_symboliser ;
 
    // create our creds
    $creds = new SG_accountID ( "your_account" , "your_key" ) ;
    // use UK English and default options
    $parseOpts = new SG_symboliserParseOptions ( "English_UK" ) ;
    // use default rendering options
    $renderOpts = new SG_symboliserRenderOptions ( ) ;
 
    /************************** Convert the text to CML **************************/
    // create our request object
    $request = new SG_symboliserTextInput ( $creds , $parseOpts , "Hello World!" ) ;
 
    // process the request to get some CML
    $cml = $symboliser->textToCML ( $request ) ;
 
    /************************** Write our page header **************************/
    echo "<html>\n" ;
    echo "<head>\n" ;
    echo "<title>Symbolisation Example</title>\n" ;
    echo "<link rel='stylesheet' href='http://www.symgate.com/cml/cml.css'>\n" ;
    echo "</head>\n" ;
    echo "<body>\n" ;
 
    /****************************** Write out the HTML body ******************************/
 
    // iterate over the body elements. We'll call the WriteCMap helper function for
    // all the relevant cmap objects.
    for ( $iParagraph = 0 ; $iParagraph < count ( $cml->body->elements ) ; $iParagraph ++ )
    {
        //normally they will be paragraphs. We can ignore anything else.
        if ( get_class ( $cml->body->elements [ $iParagraph ] ) == "CML_cp" )
        {
            //create a new DIV for the paragraph:
            echo "<div class='cml_paragraph'>\n" ;
            //hack to ensure the float attribute gets properly cleared on all browsers (see cml.css)
            echo "<div class='cml_paragraph_start'></div>\n" ;
 
            $paragraph = $cml->body->elements [ $iParagraph ] ;
 
            //each paragraph contains several sentences. They don't need to be rendered any differently.
            for ( $iSentence = 0 ; $iSentence < count ( $paragraph->sentences ) ; $iSentence ++ )
            {
                $sentence = $paragraph->sentences [ $iSentence ] ;
 
                // process each sentence element
                for ( $iElement = 0 ; $iElement < count ( $sentence->elements ) ; $iElement ++ )
                {
                    // if the element is a cmap, call the WriteCMap helper function (see above)
                    if ( get_class ( $sentence->elements [ $iElement ] ) == "CML_cmap" )
                    {
                        //it's a cmap, display the concept code count and text
                        $cmap = $sentence->elements [ $iElement ] ;
                        WriteCMap ( $creds , $renderOpts , $cmap , $symboliser ) ;
                    }
 
                    // otherwise, for an altlist, find the correct alternative to render:
                    if ( get_class ( $sentence->elements [ $iElement ] ) == "CML_altlist" )
                    {
                        $altlist = $sentence->elements [ $iElement ] ;
                        $alternativeToRender = NULL ;
                        $renderedPriority = 65536 ;
 
                        for ( $iAlternative = 0 ; $iAlternative < count ( $altlist->alternatives ) ; $iAlternative ++ )
                        {
                            $alternative = $altlist->alternatives [ $iAlternative ] ;
 
                            //if the alternative has the preferred value set, choose it
                            if ( $alternative->preferred )
                            {
                                $alternativeToRender = $alternative ;
                                $renderedPriority = -1 ;
                            }
 
                            //otherwise, if the alternative's priority value is lower than any we've
                            //seen so far, choose it
                            if ( $alternative->priority < $renderedPriority )
                            {
                                $alternativeToRender = $alternative ;
                                $renderedPriority = $alternative->priority ;
                            }
                        }
 
                        // now that we've found the alternative to render, render all the items it contains
                        for ( $iAltElement = 0 ; $iAltElement < count ( $alternativeToRender->elements ) ; $iAltElement ++ ) 
                        {
                            // we're only interested in cmaps here
                            if ( get_class ( $alternativeToRender->elements [ $iAltElement ] ) == "CML_cmap" )
                            {
                                //it's a cmap, display the concept code count and text
                                $cmap = $alternativeToRender->elements [ $iAltElement ] ;
                                WriteCMap ( $creds , $renderOpts , $cmap , $symboliser ) ;
                            }
                        }
                    }
                }
            }
 
            //write our paragraph footer:
            echo "<div class='cml_paragraph_end'></div>\n" ;
            echo "</div>\n" ;
        }
    }
 
    /************************** Write our page footer **************************/
    echo "</body>\n" ;
    echo "</html>\n" ;
?>

HTML Output

Expected HTML output from the above example:

<html>
<head>
<title>Symbolisation Example</title>
<link rel='stylesheet' href='http://www.symgate.com/cml/cml.css'>
</head>
<body>
<div class='cml_paragraph'>
<div class='cml_paragraph_start'></div>
<div class='cml_cmap'>
<div class='cml_symbol'>
<div class='cml_symbol_start'></div>
<table class='cml_symtable'>
<tr class='cml_symtable_row'>
<td class='cml_symtable_cell'>
<img class='cml_symbol_image' src='http://widrebus.symgate.com/widgit/col/100/graphics/widgit rebus/h/hello.svg.sym' alt='' />
</td>
</table>
<div class='cml_symbol_end'></div>
</div>
<div class='cml_cmap_text'>
Hello
</div>
</div>
<div class='cml_cmap'>
<div class='cml_symbol'>
<div class='cml_symbol_start'></div>
<table class='cml_symtable'>
<tr class='cml_symtable_row'>
<td class='cml_symtable_cell'>
<img class='cml_symbol_image' src='http://widrebus.symgate.com/widgit/col/100/graphics/widgit rebus/e/earth 2.svg.sym' alt='' />
</td>
</table>
<div class='cml_symbol_end'></div>
</div>
<div class='cml_cmap_text'>
World!
</div>
</div>
<div class='cml_paragraph_end'></div>
</div>
</body>
</html>
Personal tools