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. |