Main Page   Data Structures   File List   Data Fields   Globals  

nccsmilparser.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by André Lindhjem <belgarat@sdf.lonestar.org>,     *
00003  *                         Kjetil Holien <kjetil.holien@gmail.com>,        *
00004  *                         Terje Risa <terje.risa@gmail.com> &             *
00005  *                         Øyvind Nerbråten <oyvind@nerbraten.com>         *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************
00022  *
00023  * \file nccsmilparser.c
00024  * \author André Lindhjem, Kjetil Holien, Terje Risa & Øyvind Nerbråten
00025  * \date 23.02.2006
00026  * 
00027  * A parser for the SMIL 1.0 standard used with Daisy 2.02 books. 
00028  * Collects data and stores it in linked list in the main datastructure. The linked
00029  * list represents the spine of all passages in a smil file.
00030  */
00031  
00032 
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <libxml2/libxml/xmlreader.h>
00037 
00038 #include "nccsmilparser.h"
00039 #include "control.h"
00040 #include "report.h"
00041 #include "common.h"
00042 #include "snprintf/snprintf.h"
00043 #include "libdaisy.h"
00044 
00045 /* Test if the xml reader is present */
00046 #ifdef LIBXML_READER_ENABLED
00047 
00048 
00049 
00050 /* ************************************************** *
00051  *          Static function declarations              *
00052  * ************************************************** */
00053 
00060 static int parseSmilHead (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00061 
00068 static int parseSmilLayout (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00069 
00076 static int parseSmilMeta (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00077 
00084 static int parseSmilRegion (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00085 
00092 static int parseSmilBody (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00093 
00100 static int parseSmilMainSeq (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00101 
00108 static int parseSmilPar (xmlTextReaderPtr reader, struct DaisyData *daisydata);
00109 
00117 static int parseSmilNestedSeq (xmlTextReaderPtr reader, struct DaisyData *daisydata, struct Node *tmpNode);
00118 
00126 static int parseSmilText (xmlTextReaderPtr reader, struct DaisyData *daisydata, struct Node *tmpNode);
00127 
00134 static int parseSmilAudio (xmlTextReaderPtr reader, struct Node *tmpNode);
00135 
00145 static int parseXHTML (struct DaisyData *daisydata, char* filename, char* fragment, struct Node *tmpNode);
00146 
00152 static int parseXHTMLHead (xmlTextReaderPtr reader);
00153 
00159 static int parseXHTMLTitle (xmlTextReaderPtr reader);
00160 
00166 static int parseXHTMLMeta (xmlTextReaderPtr reader);
00167 
00175 static int parseXHTMLBody (xmlTextReaderPtr reader, char *fragment, struct Node *tmpNode);
00176 
00183 static char* parseXHTMLHtmltag (xmlTextReaderPtr reader);
00184 
00185 
00186 /************************ Code for parsing a *.smil files ************************/
00187 
00188 
00189 /* ************************************************** *
00190  *          Global function definitions               *
00191  * ************************************************** */
00192 
00201 int parseNCCSmil (struct DaisyData *daisydata)
00202 {
00203     const xmlChar *name = NULL;
00204     char *nameChar = NULL, tmp[STRLEN];
00205     xmlTextReaderPtr reader = NULL;
00206     int ret, type;
00207     ret = type = 1;
00208     daisydata->smilAlreadyfound = 0;
00209     
00210     snprintf (tmp, sizeof (tmp), "%s%s", daisydata->path, daisydata->smilPos->anchor);
00211     
00212     /* open the smil file */
00213     reader = xmlReaderForFile (tmp, NULL, 0);
00214     if (reader == NULL)
00215     {
00216         char error[STRLEN];
00217         snprintf (error, sizeof (error), "Failed to open SMIL file: %s", daisydata->smilPos->anchor);
00218         report (error, REP_WARNING);
00219         return -1;
00220     }
00221     else 
00222     {
00223         if (DEBUG_NCCSMILPARSER)
00224         {
00225             char error[STRLEN];
00226             snprintf (error, sizeof (error), "Parsing SMIL file: %s", daisydata->smilPos->anchor);
00227             report (error, REP_DEBUG);
00228         }
00229         
00230         /* read the first tag */
00231         ret = xmlTextReaderRead(reader);
00232         if (ret != 1)
00233         {   
00234             char error[STRLEN];
00235             snprintf (error, sizeof (error), "Failed to parse SMIL file: %s", daisydata->smilPos->anchor);
00236             report (error, REP_WARNING);
00237             xmlFreeTextReader (reader);
00238             return -1;
00239         }
00240         name = xmlTextReaderConstName (reader);
00241         if (name == NULL) return 0; 
00242         nameChar = tolowercase((const char *)name);
00243         if (nameChar == NULL) return 0;
00244         if (!strcmp (nameChar, "html")) 
00245         {
00246             ret = xmlTextReaderRead(reader);
00247             if (ret != 1)
00248             {
00249                 char error[STRLEN];
00250                 snprintf (error, sizeof (error), "Failed to parse SMIL file: %s", daisydata->smilPos->anchor);
00251                 report (error, REP_WARNING);
00252                 return -1;
00253             }
00254             name = xmlTextReaderConstName (reader);
00255             if (name == NULL) return 0;
00256             nameChar = tolowercase((const char *)name);
00257             if (nameChar == NULL) return 0;
00258             type = xmlTextReaderNodeType(reader);
00259         }
00260         /* while we haven't reached the html endtag */
00261         while (type != 15 && strcmp (nameChar, "html"))
00262         {       
00263             /* parse tag if <head> */
00264             if (!strcmp (nameChar, "head"))
00265             { 
00266                 ret = parseSmilHead (reader, daisydata);
00267                 if (ret != 1)
00268                 {
00269                     char error[STRLEN];
00270                     snprintf (error, sizeof (error), "Failed to parse SMIL file: %s", daisydata->smilPos->anchor);
00271                     report (error, REP_WARNING);
00272                     xmlFreeTextReader (reader);
00273                     return -1;
00274                 }
00275             }
00276             /* parse tag if <body> */
00277             else if (!strcmp (nameChar, "body"))
00278             {   
00279                 ret = parseSmilBody (reader, daisydata);
00280                 if (ret != 1)
00281                 {
00282                     char error[STRLEN];
00283                     snprintf (error, sizeof (error), "Failed to parse SMIL file: %s", daisydata->smilPos->anchor);
00284                     report (error, REP_WARNING);
00285                     xmlFreeTextReader (reader);
00286                     return -1;
00287                 }
00288             }
00289             ret = xmlTextReaderRead (reader);
00290             if (ret != 1) return ret;
00291             name = xmlTextReaderConstName (reader);
00292             if (name == NULL) return 0;
00293             nameChar = tolowercase((const char *)name);
00294             if (nameChar == NULL) return 0;     
00295             type = xmlTextReaderNodeType(reader);
00296         }
00297         xmlFreeTextReader (reader);
00298         if (ret != 1)
00299         {
00300             char error[STRLEN];
00301             snprintf (error, sizeof (error), "Failed to parse SMIL file: %s", daisydata->smilPos->anchor);
00302             report (error, REP_WARNING);
00303             return -1;
00304         }
00305     }
00306     return ret;
00307 }
00308 
00309 
00310 
00311 /* ************************************************** *
00312  *          Static function definitions               *
00313  * ************************************************** */
00314 
00321 static int parseSmilHead(xmlTextReaderPtr reader, struct DaisyData *daisydata)
00322 {
00323     const xmlChar *name = NULL;
00324     char *nameChar = NULL;
00325     int ret, type;
00326     ret = type = 1;
00327     
00328     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <HEAD>", REP_DEBUG);
00329     type = xmlTextReaderNodeType(reader);
00330     if (type != 1) 
00331     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <HEAD>", REP_ERROR);
00332         return -1;
00333     }
00334     ret = xmlTextReaderRead (reader);
00335     if (ret != 1) return ret;
00336     name = xmlTextReaderConstName (reader);
00337     if (name == NULL) return 0;
00338     nameChar = tolowercase((const char *)name);
00339     if (nameChar == NULL) return 0;
00340     /* while we haven't come to the head closetag */
00341     while (strcmp (nameChar, "head"))
00342     {   
00343         /* parse tag if <layout> */
00344         if (!strcmp (nameChar, "layout")) ret = parseSmilLayout (reader, daisydata);
00345         /* parse tag if <meta> * */
00346         else if (!strcmp (nameChar, "meta")) ret = parseSmilMeta (reader, daisydata);
00347         if (ret != 1) return ret;
00348         ret = xmlTextReaderRead (reader);
00349         if (ret != 1) return ret;
00350         name = xmlTextReaderConstName (reader);
00351         if (name == NULL) return 0;
00352         nameChar = tolowercase((const char *)name);
00353         if (nameChar == NULL) return 0;
00354     }   
00355     type = xmlTextReaderNodeType(reader);
00356     if (type != 15) 
00357     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <HEAD>, endtag expected", REP_ERROR);
00358         return -1;
00359     }   
00360     return ret;
00361 }
00362 
00369 static int parseSmilLayout (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00370 {
00371     const xmlChar *name = NULL;
00372     char *nameChar = NULL;
00373     int ret, type;
00374     ret = type = 1;
00375     
00376     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <LAYOUT>", REP_DEBUG);
00377     type = xmlTextReaderNodeType(reader);
00378     if (type != 1) 
00379     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <LAYOUT>", REP_ERROR);
00380         return -1;
00381     }
00382     ret = xmlTextReaderRead (reader);
00383     if (ret != 1) return ret;
00384     name = xmlTextReaderConstName (reader);
00385     if (name == NULL) return 0;
00386     nameChar = tolowercase((const char *)name);
00387     if (nameChar == NULL) return 0;
00388     /* while we haven't reached the layout endtag */
00389     while (strcmp (nameChar, "layout"))
00390     {   
00391         /* parse tag if <region> + */
00392         if (!strcmp (nameChar, "region")) ret = parseSmilRegion (reader, daisydata);
00393         if (ret != 1) return ret;
00394         ret = xmlTextReaderRead (reader);
00395         if (ret != 1) return ret;
00396         name = xmlTextReaderConstName (reader);
00397         if (name == NULL) return 0;
00398         nameChar = tolowercase((const char *)name);
00399         if (nameChar == NULL) return 0;
00400     }
00401     type = xmlTextReaderNodeType(reader);
00402     if (type != 15) 
00403     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <LAYOUT>, endtag expected", REP_ERROR);
00404         return -1;
00405     }   
00406     return ret;
00407 }
00408 
00415 static int parseSmilMeta (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00416 {
00417     int ret = 1;
00418     /* Attributes:
00419      * ncc:generator ?
00420      * dc:format
00421      * dc:identifier ?
00422      * dc:title ?
00423      * title ?
00424      * ncc:totalElapsedTime ?
00425      * ncc:timeInThisSmil ?
00426      */
00427      
00428     daisydata = daisydata;
00429      
00430     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <META>", REP_DEBUG);
00431     ret = xmlTextReaderRead (reader);
00432     return ret; 
00433 }
00434  
00441 static int parseSmilRegion (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00442 {
00443     int ret = 1;
00444     /* Attributes:
00445      * id
00446      */
00447      
00448     daisydata = daisydata;
00449     
00450     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <REGION>", REP_DEBUG);
00451     ret = xmlTextReaderRead (reader);
00452     return ret; 
00453 }
00454  
00461 static int parseSmilBody (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00462 {
00463     const xmlChar *name = NULL;
00464     char *nameChar = NULL;
00465     int ret, type;
00466     ret = type = 1;
00467     
00468     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <BODY>", REP_DEBUG);
00469     ret = xmlTextReaderRead (reader);
00470     if (ret != 1) return ret;
00471     name = xmlTextReaderConstName (reader);
00472     if (name == NULL) return 0;
00473     nameChar = tolowercase((const char *)name);
00474     if (nameChar == NULL) return 0;
00475     /* while we haven't reached the body endtag */
00476     while (strcmp (nameChar, "body"))
00477     {   
00478         /* parse tag if <seq> */
00479         if (!strcmp (nameChar, "seq")) ret = parseSmilMainSeq (reader, daisydata);
00480         if (ret != 1) return ret;
00481         ret = xmlTextReaderRead (reader);
00482         if (ret != 1) return ret;
00483         name = xmlTextReaderConstName (reader);
00484         if (name == NULL) return 0;
00485         nameChar = tolowercase((const char *)name);
00486         if (nameChar == NULL) return 0;
00487     }
00488     type = xmlTextReaderNodeType(reader);
00489     if (type != 15) 
00490     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <BODY>, endtag expected", REP_ERROR);
00491         return -1;
00492     }   
00493     return ret;
00494 }
00495 
00502 static int parseSmilMainSeq (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00503 {
00504     const xmlChar *name = NULL;
00505     char *nameChar = NULL;
00506     int ret, type;
00507     ret = type = 1;
00508     /* Attributes:
00509      * dur
00510      * id
00511      */
00512     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL main <SEQ>", REP_DEBUG);
00513     type = xmlTextReaderNodeType(reader);
00514     if (type != 1) 
00515     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL main <SEQ>", REP_ERROR);
00516         return -1;
00517     }
00518     ret = xmlTextReaderRead (reader);
00519     if (ret != 1) return ret;
00520     name = xmlTextReaderConstName (reader);
00521     if (name == NULL) return 0;
00522     nameChar = tolowercase((const char *)name);
00523     if (nameChar == NULL) return 0;
00524     /* while we haven't reached the seq end-tag */
00525     while (type != 15 && strcmp (nameChar, "seq"))
00526     {   
00527         /* parse tag if <par> + */
00528         if (!strcmp (nameChar, "par")) ret = parseSmilPar (reader, daisydata);
00529         /* parse tag if <seq> * */
00530         else if (!strcmp (nameChar, "seq")) ret = parseSmilNestedSeq (reader, daisydata, NULL);
00531         if (ret != 1) return ret;
00532         ret = xmlTextReaderRead (reader);
00533         if (ret != 1) return ret;
00534         name = xmlTextReaderConstName (reader);
00535         if (name == NULL) return 0;
00536         nameChar = tolowercase((const char *)name);
00537         if (nameChar == NULL) return 0; 
00538         type = xmlTextReaderNodeType(reader);
00539     }   
00540     return ret;
00541 }
00542 
00549 static int parseSmilPar (xmlTextReaderPtr reader, struct DaisyData *daisydata)
00550 {
00551     const xmlChar *name = NULL;
00552     char *nameChar = NULL;
00553     xmlChar *tmp = NULL;
00554     int ret, type;
00555     struct Node *tmpNode;
00556     ret = type = 1;
00557     /* Attributes:
00558      * endsync
00559      * system-required
00560      * id
00561      */
00562      
00563     daisydata = daisydata;
00564      
00565     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <PAR>", REP_DEBUG);
00566     type = xmlTextReaderNodeType(reader);
00567     if (type != 1) 
00568     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <PAR>", REP_ERROR);
00569         return -1;
00570     }
00571     /* go to the fragment identifier point and parses from there. */
00572     tmp = xmlTextReaderGetAttribute (reader, (xmlChar *)"id");
00573     /* if the par tag has an id attribute, read it and check wheter it matches the fragmentid.
00574        if there is none id attribute, set alreadyfound to 1 and parse the whole smilfile */
00575     if (tmp != NULL) 
00576     {
00577         if (daisydata->smilPos->fragmentIdentifier != NULL)
00578         {
00579             if (!strcmp ((char *)tmp, daisydata->smilPos->fragmentIdentifier))
00580                 daisydata->smilAlreadyfound = 1;
00581         }
00582     }
00583     else
00584         daisydata->smilAlreadyfound = 1;
00585     if (tmp != NULL) xmlFree (tmp); tmp = NULL;
00586     if (daisydata->smilAlreadyfound == 1)
00587     {
00588         ret = xmlTextReaderRead (reader);
00589         if (ret != 1) return ret;
00590         name = xmlTextReaderConstName (reader);
00591         if (name == NULL) return 0;
00592         nameChar = tolowercase((const char *)name);
00593         if (nameChar == NULL) return 0;
00594 
00595         tmpNode = addNewNode(daisydata);        
00596         /* while we haven't come to the par closetag */
00597         while (strcmp (nameChar, "par"))
00598         {   
00599             /* parse tag if <text> */
00600             if (!strcmp (nameChar, "text")) ret = parseSmilText (reader, daisydata, tmpNode);
00601             /* parse tag if <audio> ? */
00602             else if (!strcmp (nameChar, "audio")) ret = parseSmilAudio (reader, tmpNode);
00603             /* parse tag if <seq> * */
00604             else if (!strcmp (nameChar, "seq")) ret = parseSmilNestedSeq (reader, daisydata, tmpNode);
00605             if (ret != 1) return ret;
00606             ret = xmlTextReaderRead (reader);
00607             if (ret != 1) return ret;
00608             name = xmlTextReaderConstName (reader);
00609             if (name == NULL) return 0;
00610             nameChar = tolowercase((const char *)name);
00611             if (nameChar == NULL) return 0;
00612         }
00613         type = xmlTextReaderNodeType(reader);
00614         if (type != 15) 
00615         {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL <PAR>, endtag expected", REP_ERROR);
00616             return -1;
00617         }   
00618     }
00619     /* TODO: what if there's a par tag further inside this par tag? */
00620     else 
00621     {
00622         ret = xmlTextReaderNext (reader);   
00623     }
00624     return ret;
00625 }
00626  
00634 static int parseSmilNestedSeq (xmlTextReaderPtr reader, struct DaisyData *daisydata, struct Node *tmpNode)
00635 {
00636     const xmlChar *name = NULL;
00637     char *nameChar = NULL;
00638     int ret, type;
00639     ret = type = 1;
00640     /* Attributes:
00641      * dur
00642      * id
00643      */
00644     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL nested <SEQ>", REP_DEBUG);
00645     type = xmlTextReaderNodeType(reader);
00646     if (type != 1) 
00647     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL nested <SEQ>", REP_ERROR);
00648         return -1;
00649     }
00650     ret = xmlTextReaderRead (reader);
00651     if (ret != 1) return ret;
00652     name = xmlTextReaderConstName (reader);
00653     if (name == NULL) return 0;
00654     nameChar = tolowercase((const char *)name);
00655     if (nameChar == NULL) return 0;
00656     
00657     /* while we haven't come to the seq closetag */
00658     while (strcmp (nameChar, "seq"))
00659     {   
00660         /* parse tag if <par> 2 */
00661         if (!strcmp (nameChar, "par")) ret = parseSmilPar (reader, daisydata);
00662         /* parse tag if <audio> + */
00663         else if (!strcmp (nameChar, "audio"))
00664         {
00665             if (tmpNode->audiofilename != NULL)
00666                 tmpNode = addNewNode(daisydata);
00667             ret = parseSmilAudio (reader, tmpNode);         
00668         }
00669         if (ret != 1) return ret;
00670         ret = xmlTextReaderRead (reader);
00671         if (ret != 1) return ret;
00672         name = xmlTextReaderConstName (reader); 
00673         if (name == NULL) return 0;
00674         nameChar = tolowercase((const char *)name);
00675         if (nameChar == NULL) return 0;
00676     }
00677     type = xmlTextReaderNodeType(reader);
00678     if (type != 15) 
00679     {   if (DEBUG_NCXPARSER) report ("Failed parsing SMIL nested <SEQ>, endtag expected", REP_ERROR);
00680         return -1;
00681     }   
00682     return ret;
00683 }
00684  
00692 static int parseSmilText (xmlTextReaderPtr reader, struct DaisyData *daisydata, struct Node *tmpNode)
00693 {
00694     xmlChar *attr = NULL;
00695     const xmlChar *name = NULL;
00696     char *nameChar = NULL, *textsrc = NULL, *fragment = NULL, *tmp = NULL;
00697     int ret = 1;
00698     /* Attributes:
00699      * src
00700      * id
00701      * region
00702      */
00703     
00704     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <TEXT>", REP_DEBUG);
00705     name = xmlTextReaderConstName (reader);
00706     if (name == NULL) return 0;
00707     nameChar = tolowercase((const char *)name);
00708     if (nameChar == NULL) return 0;
00709     if (!strcmp (nameChar, "#text")) {
00710         ret = xmlTextReaderRead (reader);
00711         if (ret != 1) return ret;
00712     }
00713     attr = xmlTextReaderGetAttribute(reader, (xmlChar *)"src"); 
00714     
00715     /* splits the text on #.
00716        get the anchor url */
00717     textsrc = strtok ((char *)attr, "#");
00718     
00719     if (DEBUG_NCCSMILPARSER)
00720     {
00721         char error[STRLEN];
00722         snprintf (error, sizeof (error), "Parsing SMIL <TEXT> XMLFile: %s", textsrc);
00723         report (error, REP_DEBUG);
00724     }
00725     
00726     /* storing the file_name of the text file */
00727     tmp = (char *) malloc (strlen (textsrc)+1);
00728     strcpy (tmp, textsrc);
00729     tmpNode->textfilename = tmp;
00730     
00731     /* get the fragment identifier */
00732     fragment = strtok (NULL, "#");
00733     
00734     if (DEBUG_NCCSMILPARSER)
00735     {
00736         char error[STRLEN];
00737         snprintf (error, sizeof (error), "Parsing SMIL <TEXT> Fragment Identifier: %s", fragment);
00738         report (error, REP_DEBUG);
00739     }
00740     
00741     /* storing the fragment identifier for the passage in the text file */
00742     tmp = (char *) malloc (strlen (fragment)+1);
00743     strcpy (tmp, fragment);
00744     tmpNode->fragmentIdentifier = tmp;
00745     
00746     /* parse text file */
00747     if (parseXHTML(daisydata, textsrc, fragment, tmpNode) != 1)
00748     {
00749         char error[STRLEN];
00750         snprintf (error, sizeof (error), "Failed to parse XHTML file: %s", tmpNode->textfilename);
00751         report (error, REP_WARNING);
00752         return -1;
00753     }
00754     if (attr != NULL) xmlFree (attr); attr = NULL;
00755     return ret;
00756 }
00757 
00764 static int parseSmilAudio (xmlTextReaderPtr reader, struct Node *tmpNode)
00765 {
00766     xmlChar *attr = NULL;
00767     char *tempChar = NULL, *value = NULL;
00768     int ret = 1;
00769     /* Attributes:
00770      * src
00771      * id
00772      * clip-begin
00773      * clip-end
00774      */
00775     if (DEBUG_NCCSMILPARSER) report ("Parsing SMIL <AUDIO>", REP_DEBUG);
00776     /* fetch the url anchor to the audio file */
00777     attr = xmlTextReaderGetAttribute (reader, (xmlChar *)"src");
00778     tempChar = (char *) malloc (strlen((char *)attr)+1);
00779     strcpy(tempChar, (char *)attr);
00780     
00781     if (DEBUG_NCCSMILPARSER)
00782     {
00783         char error[STRLEN];
00784         snprintf (error, sizeof (error), "Parsing SMIL <AUDIO> Audiofile: %s", attr);
00785         report (error, REP_DEBUG);
00786     }
00787     
00788     /* storing the audio file_name */
00789     tmpNode->audiofilename = tempChar;  
00790     if (attr != NULL) xmlFree (attr); attr = NULL;
00791     
00792     /* fetch clip-begin */
00793     attr = xmlTextReaderGetAttribute (reader, (xmlChar *)"clip-begin");
00794     value = strtok((char *)attr, "npt=s");
00795     tempChar = (char *) malloc (strlen(value)+1);
00796     strcpy(tempChar, value);
00797     
00798     if (DEBUG_NCCSMILPARSER)
00799     {
00800         char error[STRLEN];
00801         snprintf (error, sizeof (error), "Parsing SMIL <AUDIO> clip-begin: %s", value);
00802         report (error, REP_DEBUG);
00803     }
00804     
00805     /* storing clip-begin */
00806     tmpNode->audioStartPos = tempChar;  
00807     if (attr != NULL) xmlFree (attr); attr = NULL;
00808     
00809     /* fetch clip-end */
00810     attr = xmlTextReaderGetAttribute (reader, (xmlChar *)"clip-end");
00811     value = strtok ((char *)attr, "npt=s");
00812     tempChar = (char *) malloc (strlen(value)+1);
00813     strcpy(tempChar, value);
00814     
00815     if (DEBUG_NCCSMILPARSER)
00816     {
00817         char error[STRLEN];
00818         snprintf (error, sizeof (error), "Parsing SMIL <AUDIO> clip-end: %s", value);
00819         report (error, REP_DEBUG);
00820     }
00821     
00822     /* storing clip-end */
00823     tmpNode->audioStopPos = tempChar;   
00824     if (attr != NULL) xmlFree (attr); attr = NULL;
00825     return ret;
00826 }
00827 
00828 
00829 /************************ END of *.smil parser code ************************/
00830 
00831 
00832 /********************** Code for parsing a xhtml files **********************/
00833 
00834 
00844 static int parseXHTML (struct DaisyData *daisydata, char* filename, char* fragment, struct Node *tmpNode)
00845 {
00846     const xmlChar *name = NULL;
00847     char *nameChar = NULL;
00848     int ret = 1;
00849     xmlTextReaderPtr reader = NULL;
00850     
00851     char tmp[STRLEN];   
00852     snprintf (tmp, sizeof (tmp), "%s/%s", daisydata->path, filename);
00853     
00854     /* open the xhtml file */
00855     reader = xmlReaderForFile (tmp, NULL, 0); 
00856     if (reader == NULL)
00857     {
00858         char error[STRLEN];
00859         snprintf (error, sizeof (error), "Failed to open XHTML file: %s", filename);
00860         report (error, REP_WARNING);
00861         return -1;
00862     }
00863     else 
00864     {
00865         if (DEBUG_NCCXHTML)
00866         {
00867             char error[STRLEN];
00868             snprintf (error, sizeof (error), "Parsing XHTML file: %s", filename);
00869             report (error, REP_DEBUG);
00870         }
00871         
00872         ret = xmlTextReaderRead(reader);
00873         if (ret != 1)
00874         {
00875             char error[STRLEN];
00876             snprintf (error, sizeof (error), "Failed to parse XHTML file: %s", filename);
00877             report (error, REP_WARNING);
00878             xmlFreeTextReader (reader);
00879             return -1;
00880         }
00881         while(ret == 1)
00882         {
00883             name = xmlTextReaderConstName (reader);     
00884             if (name == NULL) return 0;
00885             nameChar = tolowercase((const char *)name);
00886             if (nameChar == NULL) return 0;
00887             /* parse tag if <head> */
00888             if (!strcmp (nameChar, "head"))
00889             {
00890                 ret = parseXHTMLHead (reader);
00891                 if (ret != 1)
00892                 {
00893                     char error[STRLEN];
00894                     snprintf (error, sizeof (error), "Failed to parse XHTML file: %s", filename);
00895                     report (error, REP_WARNING);
00896                     xmlFreeTextReader (reader);
00897                     return -1;
00898                 }
00899             }
00900             /* parse tag if <body> */
00901             else if (!strcmp (nameChar, "body"))
00902             {
00903                 ret = parseXHTMLBody (reader, fragment, tmpNode);
00904                 xmlFreeTextReader (reader);
00905                 if (ret == 1) return 1;
00906                 else return ret;
00907             }
00908             ret = xmlTextReaderRead (reader);
00909         }
00910         xmlFreeTextReader (reader);
00911         if (ret != 0)
00912         {
00913             char error[STRLEN];
00914             snprintf (error, sizeof (error), "Failed to parse XHTML file: %s", filename);
00915             report (error, REP_WARNING);
00916             return -1;
00917         }
00918     }
00919     return ret;
00920 }
00921 
00927 static int parseXHTMLHead (xmlTextReaderPtr reader)
00928 {
00929     const xmlChar *name = NULL;
00930     char *nameChar = NULL;
00931     int ret, type;
00932     ret = type = 1;
00933     
00934     if (DEBUG_NCCXHTML) report ("Parsing XHTML <HEAD>", REP_DEBUG);
00935     type = xmlTextReaderNodeType(reader);
00936     if (type != 1) 
00937     {   if (DEBUG_NCXPARSER) report ("Failed XHTML <HEAD>", REP_ERROR);
00938         return -1;
00939     }
00940     ret = xmlTextReaderRead (reader);
00941     if (ret != 1) return ret;
00942     name = xmlTextReaderConstName (reader);
00943     if (name == NULL) return 0;
00944     nameChar = tolowercase((const char *)name);
00945     if (nameChar == NULL) return 0;
00946     /* while we haven't come to the head closetag */
00947     while (strcmp (nameChar, "head"))
00948     {   
00949         /* parse tag if <title> */
00950         if (!strcmp (nameChar, "title")) ret = parseXHTMLTitle (reader);
00951         /* parse tag if <meta> * */
00952         else if (!strcmp (nameChar, "meta")) ret = parseXHTMLMeta (reader);
00953         if (ret != 1) return ret;
00954         ret = xmlTextReaderRead (reader);
00955         if (ret != 1) return ret;
00956         name = xmlTextReaderConstName (reader);
00957         if (name == NULL) return 0;
00958         nameChar = tolowercase((const char *)name);
00959         if (nameChar == NULL) return 0;
00960     }
00961     type = xmlTextReaderNodeType(reader);
00962     if (type != 15) 
00963     {   if (DEBUG_NCXPARSER) report ("Failed parsing XHTML <HEAD>, endtag expected", REP_ERROR);
00964         return -1;
00965     }   
00966     return ret;
00967 }
00968 
00974 static int parseXHTMLTitle (xmlTextReaderPtr reader)
00975 {
00976     xmlChar *value = NULL;
00977     char *tmp = NULL;
00978     int ret = 1;
00979     
00980     if (DEBUG_NCCXHTML) report ("Parsing XHTML <TITLE>", REP_DEBUG);
00981     ret = xmlTextReaderRead (reader);
00982     if (ret != 1) return ret;
00983     
00984     /* if the title tag has a value */
00985     if (xmlTextReaderHasValue (reader)){
00986         value = xmlTextReaderValue (reader);
00987         tmp =  removewhitespaces ((char *)value);
00988         /* printf ("\t-%s-",tmp);
00989           TODO: The title is never used.. */
00990     }
00991     if(value != NULL) xmlFree(value); value = NULL;
00992     if(tmp != NULL) free(tmp); tmp = NULL;
00993     ret = xmlTextReaderRead (reader);
00994     return ret;
00995 }
00996 
01002 static int parseXHTMLMeta (xmlTextReaderPtr reader){
01003     int ret = 1;
01004     /* Attributes:
01005      * dc:identifier
01006      * other..
01007      */
01008     if (DEBUG_NCCXHTML) report ("Parsing XHTML <META>", REP_DEBUG);
01009     ret = xmlTextReaderRead (reader);
01010     return ret; 
01011 }
01012 
01020 static int parseXHTMLBody (xmlTextReaderPtr reader, char *fragment, struct Node *tmpNode)
01021 {
01022     xmlChar *tmp = NULL, *value = NULL;
01023     const xmlChar *name = NULL; 
01024     char *nameChar = NULL, *temp = NULL, *glue = NULL, part[500];
01025     int ret = 1;
01026     
01027     if (DEBUG_NCCXHTML) report ("Parsing XHTML <BODY>", REP_DEBUG);
01028     ret = xmlTextReaderRead (reader);
01029     if (ret != 1) return ret;
01030     while (ret == 1)
01031     {   
01032         if (tmp != NULL) xmlFree (tmp); tmp = NULL;
01033             
01034         /* fetch the id-attribute */
01035         tmp = xmlTextReaderGetAttribute (reader, (xmlChar *)"id");
01036         
01037             /* if the current node has an id-attribute */
01038             if (tmp != NULL) 
01039             {   
01040                 /* if the id-attribute equals the fragment */
01041                 if (!strcmp ((char *)tmp, fragment))
01042                 {   
01043                     name = xmlTextReaderConstName (reader);
01044                     if (name == NULL) return 0;
01045                     nameChar = tolowercase((const char *)name);
01046                     if (nameChar == NULL) return 0;
01047                     while (ret == 1) 
01048                     {   
01049                         ret = xmlTextReaderRead (reader);
01050                         if (ret != 1) return ret;                       
01051                         if (!strcmp (nameChar, (const char *)xmlTextReaderConstName (reader)))
01052                             ret = 0;
01053                         else
01054                         {                       
01055                             /* get the text-value of the node */
01056                             if (ret == 1)
01057                                 value = xmlTextReaderValue (reader);
01058                             else
01059                                 return ret;
01060                             /* if the value is not NULL */
01061                             if (value != NULL)
01062                             {   
01063                                 /*Temporary solution, get the text-value inside a possible
01064                                   <b> tag, and glues it together with the previous text-value */
01065                                 ret = xmlTextReaderRead (reader);
01066                                 if (ret == 1)
01067                                 {
01068                                     name = xmlTextReaderConstName (reader);
01069                                     if (name == NULL) return 0;
01070                                     nameChar = tolowercase((const char *)name);
01071                                     if (nameChar == NULL) return 0;
01072                                 }
01073                                 else
01074                                     return ret;
01075                                 /* parse tag if <b> */
01076                                 while (!strcmp (nameChar, "b")) 
01077                                 { 
01078                                     glue = parseXHTMLHtmltag(reader);
01079                                     if (glue != NULL)
01080                                     {
01081                                         part[0] = '\0';
01082                                         strcat (part, (char *)value);
01083                                         strcat (part, glue);
01084                                         if (value != NULL) xmlFree (value); value = NULL;
01085                                         if (glue != NULL) xmlFree (glue); glue = NULL;
01086                                         value = malloc (strlen (part)+1);   
01087                                         strcpy ((char *)value, part);
01088                                     }
01089                                     ret = xmlTextReaderRead (reader);
01090                                     if (ret != 1) return ret;
01091                                     ret = xmlTextReaderRead (reader);
01092                                     if (ret == 1)
01093                                     {
01094                                         name = xmlTextReaderConstName (reader);
01095                                         if (name == NULL) return 0;
01096                                         nameChar = tolowercase((const char *)name);
01097                                         if (nameChar == NULL) return 0;
01098                                     }
01099                                     else
01100                                         return ret;
01101                                     if (!strcmp (nameChar, "#text")) {
01102                                         glue = (char *)xmlTextReaderValue (reader);
01103                                         temp = removewhitespaces(glue);
01104                                         part[0] = '\0';
01105                                         strcat (part, (char *)value);
01106                                         /* strcat (part, " "); */
01107                                         strcat (part, glue);
01108                                         if (value != NULL) xmlFree (value); value = NULL;
01109                                         if (temp != NULL) xmlFree (temp); temp = NULL;
01110                                         if (glue != NULL) xmlFree (glue); glue = NULL;
01111                                         value = malloc (strlen (part)+1);   
01112                                         strcpy ((char *)value, part);
01113                                     }
01114                                     ret = xmlTextReaderRead (reader);
01115                                     if (ret != 1) return ret;
01116                                     name = xmlTextReaderConstName (reader);
01117                                     if (name == NULL) return 0;
01118                                     nameChar = tolowercase((const char *)name);
01119                                     if (nameChar == NULL) return 0;
01120                                 }
01121                                 temp = removewhitespaces((char *)value);
01122                                 if (temp != NULL)
01123                                 {
01124                                     tmpNode->textPassage = temp;
01125                                 }
01126                                 if (value != NULL) xmlFree (value); value = NULL;
01127                                 return 1;
01128                             }
01129                         }
01130                     }   
01131                 }
01132             }
01133         if (ret == 1)
01134         {
01135             ret = xmlTextReaderRead (reader);
01136             if (ret != 1) return ret;
01137         }
01138     }
01139     if (tmp != NULL) xmlFree (tmp); tmp = NULL;
01140     return -1;
01141 }
01142  
01149 static char *parseXHTMLHtmltag (xmlTextReaderPtr reader)
01150 {
01151     xmlChar *value = NULL;
01152     char *tempChar = NULL;
01153     int ret = 1;
01154     
01155     ret = xmlTextReaderRead (reader);
01156     if (ret != 1) return NULL;
01157         
01158     if (xmlTextReaderHasValue (reader))
01159     {
01160         value = xmlTextReaderValue (reader);
01161         tempChar = removewhitespaces((char *)value);
01162         if (value != NULL) xmlFree (value); value = NULL;
01163     }
01164     return tempChar;    
01165 }
01166 
01167 
01168 /************************* END of xhtml parser code *************************/
01169 
01170 
01171 #endif

Generated on Tue Sep 5 12:14:07 2006 for libdaisy by doxygen1.2.15