Revision: 4a9625c6af94 Author: John Boyer <john.boyer@xxxxxxxxxxxxxxxxx> Date: Wed Apr 18 17:38:31 2012 Log: Continuing implementation of macro feature http://code.google.com/p/liblouisutdml/source/detail?r=4a9625c6af94 Modified: /liblouisutdml/louisutdml.h /liblouisutdml/readconfig.c /liblouisutdml/semantics.c ======================================= --- /liblouisutdml/louisutdml.h Tue Apr 17 08:55:37 2012 +++ /liblouisutdml/louisutdml.h Wed Apr 18 17:38:31 2012 @@ -383,5 +383,9 @@ int utd2volumes (xmlNode * node); int hasAttrValue (xmlNode *node, char *attrName, char *value); void kill_safely (); +xmlChar * new_macro (xmlChar * name, xmlChar *body); +unsigned char * lookup_macro (xmlChar * name); +int start_macro (xmlNode *node); +int end_macro (); #endif /*louisutdml_h */ ======================================= --- /liblouisutdml/readconfig.c Tue Apr 17 08:55:37 2012 +++ /liblouisutdml/readconfig.c Wed Apr 18 17:38:31 2012 @@ -676,6 +676,8 @@ "58", "brfSem", "59", + "macro", + "60", "style", "90", NULL @@ -996,6 +998,9 @@ case 59: ud->brf_sem = alloc_string (nested->value); break; + case 60: + new_macro (nested->value, nested->value2); + break; case 90: { static const char *actions[] = { ======================================= --- /liblouisutdml/semantics.c Tue Apr 17 08:55:37 2012 +++ /liblouisutdml/semantics.c Wed Apr 18 17:38:31 2012 @@ -290,10 +290,12 @@ char realName[MAXNAMELEN]; if (semanticTable == NULL) semanticTable = hashNew (); + /* See if semantic names and numbers are already in table. */ strcpy (realName, "no"); strcat (realName, SEMANTICSUF); if (hashLookup (semanticTable, (xmlChar *) realName) == notFound) { + /* Enter names and numbers in table before checking for this one. */ for (k = 0; k < end_all; k++) { strcpy (realName, semNames[k]); @@ -311,6 +313,7 @@ k++; } } + /* Now look up the name we called this function with. */ for (k = 0; name[k]; k++) realName[k] = name[k] | 32; realName[k] = 0; @@ -1455,3 +1458,164 @@ return NULL; return lookup_style ((char *) semNames[action]); } + +/* Beginning of macro processing */ + +static int +doSemanticActions (xmlNode * node, int *posx) +{ + int pos = *posx; + HashEntry *nodeEntry = (HashEntry *) node->_private; + char *macro = nodeEntry->macro; + int length = strlen (macro); + char *paramStart = NULL; + int paramLength; + int retVal = 1; + int semNum = atoi (¯o[pos]); + for (; isdigit (macro[pos]) && pos < length; pos++); + if (macro[pos] == '(') + paramStart = ¯o[++pos]; + paramLength = find_group_length ("()", paramStart - 1); + switch (semNum) + { + case no: + if (ud->text_length > 0 && ud->text_length < MAX_LENGTH + && ud->text_buffer[ud->text_length - 1] > 32) + ud->text_buffer[ud->text_length++] = 32; + break; + case skip: + retVal = -1; + case markhead: + ud->head_node = node; + break; + case configtweak: +{ + int k; + int kk = 0; + xmlChar configString[2 * MAXNAMELEN]; + configString[kk++] = ud->string_escape; + for (k = 0; k < paramLength; k++) + { + if (paramStart[k] == '=') + configString[kk++] = ' '; + else if (paramStart[k] == ';') + configString[kk++] = '\n'; + else + configString[kk++] = (xmlChar) paramStart[k]; + } + configString[kk++] = '\n'; + configString[kk] = 0; + if (!config_compileSettings ((char *) configString)) + return 0; +} + ud->main_braille_table = ud->contracted_table_name; + if (!lou_getTable (ud->main_braille_table)) + { + lou_logPrint ("Cannot open main table %s", ud->main_braille_table); + kill_safely (); + } + break; + case htmllink: + if (ud->format_for != browser) + break; + insert_linkOrTarget (node, 0); + break; + case htmltarget: + if (ud->format_for != browser) + break; + insert_linkOrTarget (node, 1); + break; + case boxline: + do_boxline (node); + break; + case blankline: + do_blankline (); + break; + case linespacing: + do_linespacing (node); + break; + case softreturn: + do_softreturn (); + break; + case righthandpage: + do_righthandpage (); + break; + case code: + transcribe_computerCode (node, 0); + break; + case math: + transcribe_math (node, 0); + break; + case graphic: + transcribe_graphic (node, 0); + break; + case chemistry: + transcribe_chemistry (node, 0); + break; + case music: + transcribe_music (node, 0); + break; + case changetable: + change_table (node); + break; + case pagenum: + do_pagenum (); + break; + default: + retVal = 0; + } + *posx = pos; + return retVal; +} + +static int +compileMacro (HashEntry * nodeEntry) +{ + xmlChar *uncompiledMacro = nodeEntry->macro; + xmlChar compiledMacro[4 * MAXNAMELEN]; + int unPos = 0; + int pos = 0; + while (unPos < strlen (uncompiledMacro)) + { + } + strcpy (uncompiledMacro, compiledMacro); + return 1; +} + +int +start_macro (xmlNode * node) +{ + HashEntry *nodeEntry = (HashEntry *) node->_private; + xmlChar *macro; + int pos = 0; + int hasStyle = 0; + if (nodeEntry == NULL || nodeEntry->macro == NULL) + return 0; + /*compile macro the first time it is used. */ + if (isalpha (nodeEntry->macro[0])) + compileMacro (nodeEntry); + macro = nodeEntry->macro; + if (macro[0] == '!') + /* Contains errors */ + return -1; + while (pos < strlen (macro)) + { + if (isdigit (macro[pos])) + doSemanticActions (node, &pos); + if (macro[pos] == ',') + pos++; + if (macro[pos] == '~') + { + start_style (nodeEntry->style, node); + hasStyle = 1; + pos++; + } + } + return hasStyle; +} + +end_macro () +{ +} + +/* End of macro processing */ For a description of the software, to download it and links to project pages go to http://www.abilitiessoft.com