int _repos_publish_file (XML * pubcon, XML * publisher, const char * filespec, XML * object); int _repos_publish_page (XML * pubcon, XML * page, XML * object, XML * publisher); void _repos_publish_prepare (XML * repository); WFTK_EXPORT int repos_publish_all (XML * repository) { XML * pub; XML * pubcon = xml_create ("pubcon"); XML * pubto = xml_loc (repository, ".publish-to"); repos_report_start (repository, "_publog", NULL); repos_report_log (repository, "_publog", "repos_publish_all"); /* Publish pages first. */ repos_publish_pages (repository); /* Mop up non-page publishers. */ pub = xml_firstelem (repository); while (pub) { if (xml_is (pub, "publish")) { /* xml_set (pubcon, "list", xml_attrval (pub, "from")); -- TODO: this was broken for over a year. Sigh. */ if (!*xml_attrval (pub, "to")) { if (pubto) xml_set (pubcon, "fullfilespec", xml_attrval (pubto, "dir")); else xml_set (pubcon, "fullfilespec", "./"); xml_attrcat (pubcon, "fullfilespec", xml_attrval (pub, "as")); xml_set (pubcon, "filespec", xml_attrval (pub, "as")); _repos_publish_file (repository, pub, xml_attrval (pubcon, "fullfilespec"), NULL); } } pub = xml_nextelem (pub); } repos_report_close (repository, "_publog"); xml_free (pubcon); return 0; } WFTK_EXPORT int repos_publish_list (XML * repository, const char * list) { XML * pub; XML * page; XML * pubto = xml_loc (repository, ".publish-to"); XML * pubcon = xml_create ("pubcon"); XML * hook; repos_report_start (repository, "_publog", NULL); repos_report_log (repository, "_publog", "repos_publish_list (%s)", list); _repos_publish_prepare (repository); repos_log (repository, 4, 4, NULL, "publish", "repos_publish_list (%s)", list); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); xml_set (pubcon, "list", list); /* Iterate along publishers, publishing those emanating from the given list. */ pub = xml_firstelem (repository); while (pub) { if (xml_is (pub, "publish")) { if (!strcmp (xml_attrval (pub, "from"), list)) { if (*xml_attrval (pub, "to")) { page = xml_search (repository, "page", "id", xml_attrval (pub, "to")); if (page) _repos_publish_page (pubcon, page, NULL, pub); else repos_report_log (repository, "_publog", "No page id '%s' found for publisher id '%s'", xml_attrval (pub, "to"), xml_attrval (pub, "id")); } else if (*xml_attrval (pub, "as")) { if (pubto) xml_set (pubcon, "fullfilespec", xml_attrval (pubto, "dir")); else xml_set (pubcon, "fullfilespec", "./"); xml_attrcat (pubcon, "fullfilespec", xml_attrval (pub, "as")); xml_set (pubcon, "filespec", xml_attrval (pub, "as")); _repos_publish_file (repository, pub, xml_attrval (pubcon, "fullfilespec"), NULL); } else { repos_report_log (repository, "_publog", "No destination ('to' or 'as') specified for publisher id '%s'", xml_attrval (pub, "id")); } } } pub = xml_nextelem (pub); } repos_report_close (repository, "_publog"); xml_free (pubcon); return 0; } int _repos_publish_obj (XML * pubcon, const char * list, XML * object); WFTK_EXPORT int repos_publish_obj (XML * repository, const char * list, const char * key) { int ret; XML * object; XML * pubcon = xml_create ("pubcon"); XML * hook; repos_report_start (repository, "_publog", NULL); repos_report_log (repository, "_publog", "repos_publish_obj (%s, %s)", list, key); _repos_publish_prepare (repository); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); /* Do the same, but give the specific key to be published. */ /* Find the object. */ object = repos_get (repository, list, key); if (!object) { repos_report_log (repository, "_publog", "object not found"); repos_report_close (repository, "_publog"); xml_free (pubcon); return 0; } ret = _repos_publish_obj (pubcon, list, object); xml_free (object); repos_report_close (repository, "_publog"); xml_free (pubcon); return ret; } int _repos_publish_obj (XML * pubcon, const char * list, XML * object) { XML * pub; XML * page; XML * hook; XML * pubto = NULL; int free_pubcon; XML * repository; if (xml_is (pubcon, "pubcon")) { /* Normal mode. */ repository = xml_search (pubcon, "repository", NULL, NULL); if (!repository) return 0; repository = xml_getbin(repository); if (!repository) return 0; free_pubcon = 0; pubto = xml_loc (repository, ".publish-to"); } else { /* Library-internal call with no publishing context; this is the repository. */ repository = pubcon; pubcon = xml_create ("pubcon"); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); free_pubcon = 1; } xml_set (pubcon, "list", list); hook = xml_search (pubcon, "object", NULL, NULL); if (!hook) { hook = xml_create ("object"); xml_append (pubcon, hook); } xml_setbin (hook, object, NULL); repos_log (repository, 4, 1, NULL, "repmgr", "publishing object from list '%s'", list); pub = xml_firstelem (repository); while (pub) { if (xml_is (pub, "publish")) { if (!strcmp (xml_attrval (pub, "from"), list)) { if (*xml_attrval (pub, "to")) { page = xml_search (repository, "page", "id", xml_attrval (pub, "to")); if (page) _repos_publish_page (pubcon, page, object, pub); } else { if (pubto) xml_set (pubcon, "fullfilespec", xml_attrval (pubto, "dir")); else xml_set (pubcon, "fullfilespec", "./"); xml_attrcat (pubcon, "fullfilespec", xml_attrval (pub, "as")); xml_set (pubcon, "filespec", xml_attrval (pub, "as")); _repos_publish_file (pubcon, pub, xml_attrval (pubcon, "fullfilespec"), object); } } } pub = xml_nextelem (pub); } xml_delete (xml_search (pubcon, "object", NULL, NULL)); if (free_pubcon) xml_free (pubcon); return 0; } |
void _repos_publish_prepare (XML * repository) { XML * page; page = xml_search (repository, "page", NULL, NULL); while (page) { if (xml_is (page, "page")) { if (!*xml_attrval (page, "page")) xml_setf (page, "page", "%s.html", xml_attrval (page, "id")); } page = xml_search_next (repository, page, "page", NULL, NULL); } /* TODO: create default _info publisher, if necessary. */ } WFTK_EXPORT int repos_publish_pages (XML * repository) { XML * page; XML * publisher; int close_report; XML * pubcon = xml_create ("pubcon"); XML * hook; close_report = !repos_report_start (repository, "_publog", NULL); repos_report_log (repository, "_publog", "repos_publish_pages"); _repos_publish_prepare (repository); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); /* Iterate along the pages, publishing each in turn. */ page = xml_search (repository, "page", NULL, NULL); while (page) { if (xml_is (page, "page")) { publisher = xml_search (repository, "publish", "to", xml_attrval (page, "id")); xml_set (pubcon, "list", publisher ? xml_attrval (publisher, "from") : ""); _repos_publish_page (pubcon, page, NULL, publisher); } page = xml_search_next (repository, page, "page", NULL, NULL); } if (close_report) repos_report_close (repository, "_publog"); xml_free (pubcon); return 0; } WFTK_EXPORT int repos_publish_page (XML * repository, const char * key) { XML * page; XML * publisher; XML * pubcon = xml_create ("pubcon"); XML * hook; repos_report_start (repository, "_publog", NULL); repos_report_log (repository, "_publog", "repos_publish_page (%s)", key); _repos_publish_prepare (repository); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); /* Given a page, publish it. */ page = xml_search (repository, "page", "id", key); if (!page) { repos_report_log (repository, "_publog", "No such page as %s", key); repos_report_close (repository, "_publog"); xml_free (pubcon); } publisher = xml_search (repository, "publish", "to", key); xml_set (pubcon, "list", publisher ? xml_attrval (publisher, "from") : ""); _repos_publish_page (pubcon, page, NULL, NULL); repos_report_close (repository, "_publog"); xml_free (pubcon); return 0; } void _repos_merge_layout (XML * repository, XML * publisher, XML * layout) { XML * obj_layout; FILE * file; const char * replaces; XML * member; XML * mark; obj_layout = NULL; if (*xml_attrval (publisher, "defn")) { file = _repos_fopen (repository, xml_attrval (publisher, "defn"), "r"); if (file) { obj_layout = xml_parse_general (file, (XMLAPI_DATARETRIEVE) fread); if (xml_is (obj_layout, "xml-error")) { repos_report_log (repository, "_publog", "Bad XML in layout definition %s for publisher %s", xml_attrval (publisher, "defn"), xml_attrval (publisher, "id")); xml_free (obj_layout); obj_layout = NULL; } else { if (xml_is (obj_layout, "list")) xml_set (publisher, "list-layout", "yes"); xml_copyinto (publisher, obj_layout); obj_layout = publisher; } fclose (file); xml_set (publisher, "defn", ""); } else { repos_report_log (repository, "_publog", "can't find layout definition %s for publisher %s", xml_attrval (publisher, "defn"), xml_attrval (publisher, "id")); } } else { obj_layout = publisher; } if (obj_layout) { if (*xml_attrval (obj_layout, "list-layout")) { member = xml_firstelem (obj_layout); while (member) { replaces = xml_attrval (member, "replaces"); if (!*replaces) replaces = "content"; mark = xml_search (layout, "template:value", "name", replaces); if (mark) xml_replacewithcontent (mark, member); member = xml_nextelem (member); } } else { replaces = xml_attrval (obj_layout, "replaces"); if (!*replaces) replaces = "content"; mark = xml_search (layout, "template:value", "name", replaces); if (mark) xml_replacewithcontent (mark, obj_layout); } } } int _repos_publish_to_files (XML * pubcon, const char * filespec, XML * layout, XML * page, XML * object); int _repos_publish_page (XML * pubcon, XML * page, XML * object, XML * publisher) { XML * layout; XML * repository; XML * hook; XML * pubto; int free_pubcon; if (xml_is (pubcon, "pubcon")) { /* Normal mode. */ repository = xml_search (pubcon, "repository", NULL, NULL); if (!repository) return 0; repository = xml_getbin(repository); if (!repository) return 0; free_pubcon = 0; } else { /* Library-internal call with no publishing context; this is the repository. */ repository = pubcon; pubcon = xml_create ("pubcon"); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); free_pubcon = 1; } pubto = xml_loc (repository, ".publish-to"); xml_delete (xml_search (pubcon, "page", NULL, NULL)); hook = xml_create ("page"); xml_setbin (hook, page, NULL); xml_append (pubcon, hook); xml_delete (xml_search (pubcon, "publisher", NULL, NULL)); hook = xml_create ("publisher"); xml_setbin (hook, publisher, NULL); xml_append (pubcon, hook); /* Find layout for page. */ layout = repos_get_layout (repository, xml_attrval (page, "layout")); if (!layout) return 0; repos_log (repository, 4, 1, NULL, "repmgr", "publishing to page '%s'", xml_attrval (page, "id")); /* If an object is given, get the object format and merge it with the layout. */ /* If no object layout is specified, then no mapping is necessary. */ _repos_merge_layout (repository, publisher, layout); /* Publish filespec. */ if (pubto) xml_set (pubcon, "fullfilespec", xml_attrval (pubto, "dir")); else xml_set (pubcon, "fullfilespec", "./"); xml_attrcat (pubcon, "fullfilespec", xml_attrval (page, "page")); xml_set (pubcon, "filespec", xml_attrval (page, "page")); _repos_publish_to_files (pubcon, xml_attrval (pubcon, "fullfilespec"), layout, page, object); if (free_pubcon) xml_free (pubcon); return 1; } int _repos_publish_file (XML * pubcon, XML * publisher, const char * filespec, XML * object) { XML * layout = NULL; XML * obj_layout; FILE * file; const char * replaces; XML * member; XML * mark; XML * hook; int free_pubcon; XML * repository; if (xml_is (pubcon, "pubcon")) { /* Normal mode. */ repository = xml_search (pubcon, "repository", NULL, NULL); if (!repository) return 0; repository = xml_getbin(repository); if (!repository) return 0; free_pubcon = 0; } else { /* Library-internal call with no publishing context; this is the repository. */ repository = pubcon; pubcon = xml_create ("pubcon"); hook = xml_create ("repository"); xml_setbin (hook, repository, NULL); xml_append (pubcon, hook); hook = xml_create ("files"); xml_append (pubcon, hook); free_pubcon = 1; } xml_delete (xml_search (pubcon, "page", NULL, NULL)); /* If layout named, retrieve it. */ if (*xml_attrval (publisher, "layout")) layout = repos_get_layout (repository, xml_attrval (publisher, "layout")); /* If an object is given, get the object format and merge it with the layout. */ /* If no object layout is specified, then no mapping is necessary. */ _repos_merge_layout (repository, publisher, layout); _repos_publish_to_files (pubcon, filespec, layout, NULL, object); if (free_pubcon) xml_free (pubcon); return 0; } |
static FILE * _repos_pagefile_open (XML * repos, const char * filename) { XML * scratch = xml_create ("s"); FILE * ret; xml_set_nodup (scratch, "dir", xmlobj_getconf (repos, "pagebase", xml_attrval (repos, "basedir"))); if (*filename == '/' || *filename == '\\') { xml_set (scratch, "f", filename); } else { xml_setf (scratch, "f", "%s%s", xml_attrval (scratch, "dir"), filename); } ret = fopen (xml_attrval (scratch, "f"), "w"); xml_free (scratch); return (ret); } char * _repos_publish_getvalue (XML * context, XML * object, const char * value); int _repos_publish_to_files (XML * pubcon, const char * filespec, XML * layout, XML * page, XML * object) { XML * result; XML * publisher; XML * list = NULL; XML * list_t; int free_list = 0; XML * mark; XML * first; XML * prev; XML * cur; XML * next; XML * last; XML * repository; XML * hook; char * filesp = NULL; const char * detail; FILE * file; XML * files; XML * pubto; repository = xml_search (pubcon, "repository", NULL, NULL); repository = xml_getbin (repository); publisher = xml_search (pubcon, "publisher", NULL, NULL); if (publisher) publisher = xml_getbin (publisher); /* Express template, once if object is supplied or filespec is a single file; iteratively otherwise. */ if (object || !strchr (filespec, '[') || !page) { /* This case is a single file, but may express a list. */ repos_report_log (repository, "_publog", " -- write to %s", filespec); xml_set (pubcon, "file", filespec); if (object) { /* Format filespec as flat template. */ filesp = xmlobj_format (object, NULL, filespec); xml_set (pubcon, "file", filesp); } repos_log (repository, 6, 1, NULL, "repmgr", "publishing single object to file %s", filesp ? filesp : filespec); /* Is the template a list template? If so, attempt to figure out which list should be expressed. */ list_t = xml_search (layout, "template:list", NULL, NULL); if (list_t) { xml_set (list_t, "list", xml_attrval (pubcon, "list")); if (!*xml_attrval (list_t, "list")) list_t = NULL; } if (!list_t) { /* Nope, not a list expression, just a plain old page. */ result = xml_template_apply (pubcon, layout, object, _repos_publish_getvalue); } else { list = xml_search (pubcon, "list", NULL, NULL); if (list) list = xml_getbin (list); if (!list) { /* If the publishing context doesn't already have a list, retrieve the named list. */ list = xml_create ("list"); free_list = 1; xml_set (list, "id", xml_attrval (list_t, "list")); xml_set (list, "order", xml_attrval (list_t, "order")); if (!*xml_attrval (list, "order")) xml_set (list, "order", xml_attrval (publisher, "order")); xml_set (list, "record", "record"); repos_list (repository, list); hook = xml_create ("list"); xml_append (pubcon, hook); xml_setbin (hook, list, NULL); } result = xml_template_apply_list (pubcon, layout, list, NULL, _repos_publish_getvalue); } /* Write */ file = _repos_pagefile_open (repository, filesp ? filesp : filespec); if (file) { repos_log (repository, 7, 1, NULL, "repmgr", "file %s opened successfully", filesp ? filesp : filespec); if (!*xml_attrval (result, "type") || !strcmp (xml_attrval (result, "type"), "page")) { fprintf (file, "\n\n"); xml_writecontenthtml (file, result); fprintf (file, "\n\n"); } else { xml_writecontenthtml (file, result); } fclose (file); files = xml_search (pubcon, "files", NULL, NULL); if (!files) { files = xml_create ("files"); xml_append (pubcon, files); } hook = xml_create ("file"); xml_append (files, hook); xml_set (hook, "file", xml_attrval (pubcon, "file")); } xml_free (result); if (filesp) free (filesp); if (!*xml_attrval (publisher, "detail")) { if (free_list) xml_free (list); return 0; } /* So we're now going to write the detail page(s) of this list. Let's retrieve the proper publisher. */ detail = xml_attrval (publisher, "detail"); if (detail) { if (publisher) publisher = xml_search (repository, "publish", "id", xml_attrval (publisher, "detail")); if (!publisher) { repos_report_log (repository, "_publog", "Detail publisher '%s' not found", xml_attrval (publisher, "detail")); } } if (!detail || !publisher) { /* no detail publisher, or not found */ if (free_list) xml_free (list); return 0; } /* Load proper detail page, set in pubcon, error if not found. */ pubto = xml_loc (repository, ".publish-to"); if (pubto) xml_set (pubcon, "fullfilespec", xml_attrval (pubto, "dir")); else xml_set (pubcon, "fullfilespec", "./"); page = xml_search (repository, "page", "id", xml_attrval (publisher, "to")); xml_attrcat (pubcon, "fullfilespec", xml_attrval (page, "page")); xml_set (pubcon, "filespec", xml_attrval (page, "page")); filespec = xml_attrval (pubcon, "fullfilespec"); /* Load and merge detail layout. */ layout = repos_get_layout (repository, xml_attrval (page, "layout")); if (*xml_attrval (publisher, "layout")) layout = repos_get_layout (repository, xml_attrval (publisher, "layout")); _repos_merge_layout (repository, publisher, layout); } /* If we're here, then this filespec refers to multiple files. It might be a detail of a list published above. */ repos_report_log (repository, "_publog", " -- write list %s to %s", xml_attrval (pubcon, "list"), filespec); repos_log (repository, 6, 1, NULL, "repmgr", "publishing multiple objects to files %s", filespec); if (!list) { list = xml_create ("list"); free_list = 1; xml_set (list, "id", xml_attrval (pubcon, "list")); xml_set (list, "order", xml_attrval (publisher, "order")); xml_set (list, "record", "record"); repos_list (repository, list); hook = xml_create ("list"); xml_append (pubcon, hook); xml_setbin (hook, list, NULL); } /* TODO: rewrite all this below to store records in the pubcon by list/key combination and not by list position. */ first = xml_firstelem (list); if (!first) { repos_report_log (repository, "_publog", "list empty"); if (free_list) xml_free (list); return 0; } xml_set (list, "first", xml_attrval (first, "id")); /*first = repos_get (repository, xml_attrval (pubcon, "list"), xml_attrval (first, "id"));*/ hook = xml_search (pubcon, "first", NULL, NULL); if (!hook) { hook = xml_create ("first"); xml_append (pubcon, hook); } xml_setbin (hook, first, NULL); last = xml_lastelem (list); xml_set (list, "last", xml_attrval (last, "id")); /*if (strcmp (xml_attrval (list, "first"), xml_attrval (list, "last"))) { last = repos_get (repository, xml_attrval (pubcon, "list"), xml_attrval (last, "id")); } else { last = xml_copy (first); }*/ hook = xml_search (pubcon, "last", NULL, NULL); if (!hook) { hook = xml_create ("last"); xml_append (pubcon, hook); } xml_setbin (hook, last, NULL); xml_set (list, "cur", xml_attrval (first, "id")); /*cur = xml_copy (first);*/ cur = first; mark = xml_firstelem (list); next = xml_nextelem (mark); /*if (next) next = repos_get (repository, xml_attrval (pubcon, "list"), xml_attrval (next, "id"));*/ hook = xml_search (pubcon, "next", NULL, NULL); if (!hook) { hook = xml_create ("next"); xml_append (pubcon, hook); } xml_setbin (hook, next, NULL); prev = NULL; hook = xml_search (pubcon, "prev", NULL, NULL); if (!hook) { hook = xml_create ("prev"); xml_append (pubcon, hook); } xml_setbin (hook, prev, NULL); mark = xml_firstelem (list); while (mark) { /* Format filespec as flat template. */ /* printf ("cur object: %s\n\n", xml_string (cur));*/ filesp = xmlobj_format (cur, NULL, filespec); xml_set (pubcon, "file", filesp); result = xml_template_apply (pubcon, layout, cur, _repos_publish_getvalue); /* Write */ repos_log (repository, 7, 1, NULL, "repmgr", "publishing object with key %s to %s", xml_attrval (list, "cur"), filesp); file = _repos_pagefile_open (repository, filesp); if (file) { if (!*xml_attrval (result, "type") || !strcmp (xml_attrval (result, "type"), "page")) { fprintf (file, "\n\n"); xml_writecontenthtml (file, result); fprintf (file, "\n\n"); } else { xml_writecontenthtml (file, result); } fclose (file); files = xml_search (pubcon, "files", NULL, NULL); if (!files) { files = xml_create ("files"); xml_append (pubcon, files); } hook = xml_create ("file"); xml_append (files, hook); xml_set (hook, "file", xml_attrval (pubcon, "file")); } free (filesp); xml_free (result); if (!next) break; mark = xml_nextelem (mark); /*if (prev) xml_free (prev);*/ prev = cur; xml_setbin (xml_search (pubcon, "prev", NULL, NULL), prev, NULL); cur = next; /* With new setup, cur and mark are always going to be pointing to the same structure. */ xml_set (list, "prev", xml_attrval (prev, "id")); xml_set (list, "cur", xml_attrval (cur, "id")); xml_set (list, "next", xml_attrval (next, "id")); next = xml_nextelem (mark); /*if (next) next = repos_get (repository, xml_attrval (pubcon, "list"), xml_attrval (next, "id"));*/ xml_setbin (xml_search (pubcon, "next", NULL, NULL), next, NULL); } /*if (prev) xml_free (prev); if (cur) xml_free (cur); if (first) xml_free (first); if (last) xml_free (last);*/ if (free_list) xml_free (list); } |
char * _repos_macro_resolve (XML * repository, XML * page, XML * object, XML * macro, const char * value); /* Quick little hack. */ void xml_read_attr (XML * xml, const char * attr, FILE * file) { char line[1024]; xml_set (xml, attr, ""); while (fgets (line, sizeof(line) - 1, file)) { xml_attrcat (xml, attr, line); } } char * _repos_publish_getvalue (XML * context, XML * object, const char * value) { const char * val; XML * mark; XML * srch; XML * page = context; XML * list = NULL; XML * defn; XML * repository = context; char * chmark; char filename[256]; char filename2[256]; FILE * file; XML * wiki; XML * finished; XML * todo; /* Find top. If the context *is* the top, then we haven't got a page. */ if (xml_is (context, "pubcon")) { page = xml_search (context, "page", NULL, NULL); if (page) page = xml_getbin (page); repository = xml_search (context, "repository", NULL, NULL); if (repository) repository = xml_getbin (repository); list = xml_search (context, "list", NULL, NULL); if (list) list = xml_getbin (list); defn = repos_defn (repository, xml_attrval (context, "list")); } else { /* Don't know if this will ever get used, but ... */ while (xml_parent (repository)) repository = xml_parent (repository); if (page == repository) page = NULL; } /* Macro value? */ srch = repository; if (page) if (xml_parent(page)) srch = xml_parent(page); mark = NULL; while (!mark) { mark = xml_search (srch, "macro", "id", value); if (!mark) { if (srch == repository) break; srch = xml_parent (srch); if (!srch) break; } } if (mark) { val = _repos_macro_resolve (repository, page, object, mark, value); if (val) return ((char *)val); } /* Field value? */ if (*value == '(') { /* Named object in context. */ strncpy (filename, value+1, sizeof (filename)-1); chmark = strchr (filename, ')'); if (chmark) { value += chmark - filename + 2; *chmark = '\0'; object = xml_search (context, filename, NULL, NULL); if (xml_getbin (object)) object = xml_getbin (object); } } if (object) { if (!*value) { /* default value is URL of object */ val = xmlobj_format (object, defn, xml_attrval (context, "filespec")); return ((char *) val); } if (strchr (value, '[')) { val = xmlobj_format (object, defn, value); if (val) return ((char *)val); } else { val = xmlobj_get (object, defn, value); mark = xml_search (defn, "field", "id", value); if (val && !strcmp ("wiki", xml_attrval (mark, "type"))) { wiki = wiki_parse (val); todo = xml_loc (repository, "todo"); if (!todo) { todo = xml_create ("todo"); xml_append (repository, todo); } finished = wiki_build (repository, wiki, todo); xml_free (wiki); free ((void *)val); val = xml_stringcontenthtml (finished); xml_free (finished); } if (val) return ((char *)val); } if (!strcmp (value, "_key")) { return (strdup (xml_attrval (object, "key"))); } if (!strcmp (value, "_list")) { return (strdup (xml_attrval (object, "list"))); } } /* Page attribute? */ if (page) { val = xml_attrval (page, value); if (*val) return (xmlobj_format (object, NULL, val)); if (!strcmp (val, "_page")) { return (strdup (xml_attrval (page, "id"))); } if (!strcmp (value, "_section")) { if (xml_loc (page, ".page")) { return (strdup (xml_attrval (page, "id"))); } else if (xml_is (xml_parent(page), "page")) { return (strdup (xml_attrval (xml_parent (page), "id"))); } else { return (strdup (xml_attrval (page, "id"))); } } } /* HTML text from text directory? */ strcpy (filename, *xml_attrval (repository, "text") ? xml_attrval (repository, "text") : "opmtext"); strcat (filename, "/"); strcat (filename, xml_attrval (page, "id")); strcat (filename, "_"); strcat (filename, value); sprintf (filename2, "%s.html", filename); file = _repos_fopen (repository, filename2, "r"); if (!file) { sprintf (filename2, "%s.htm", filename); file = _repos_fopen (repository, filename2, "r"); } if (file) { mark = xml_create ("scratch"); xml_read_attr (mark, "scratch", file); val = strdup (xml_attrval (mark, "scratch")); xml_free (mark); fclose (file); return (char *) val; } /* Wiki text? */ sprintf (filename2, "%s.wiki", filename); file = _repos_fopen (repository, filename2, "r"); if (!file) { sprintf (filename2, "%s.txt", filename); file = _repos_fopen (repository, filename2, "r"); } if (file) { mark = xml_create ("scratch"); xml_read_attr (mark, "scratch", file); wiki = wiki_parse (xml_attrval (mark, "scratch")); xml_free (mark); todo = xml_loc (repository, "todo"); if (!todo) { todo = xml_create ("todo"); xml_append (repository, todo); } finished = wiki_build (repository, wiki, todo); xml_free (wiki); val = xml_stringcontenthtml (finished); xml_free (finished); fclose (file); return (char *) val; } /* Page field value? */ if (page) { val = xmlobj_get (page, NULL, value); if (val) return ((char *)val); } return (strdup ("")); } |
This code and documentation are released under the terms of the GNU license. They are copyright (c) 2001-2005, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. |