/* ** Copyright (c) 2010 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code to do formatting of event messages: ** ** Technical Notes ** Milestones ** Blog posts ** New articles ** Process checkpoints ** Announcements ** ** Do not confuse "event" artifacts with the "event" table in the ** repository database. An "event" artifact is a technical-note: a ** wiki- or blog-like essay that appears on the timeline. The "event" ** table records all entries on the timeline, including tech-notes. ** ** (2015-02-14): Changing the name to "tech-note" most everywhere. */ #include "config.h" #include #include #include "event.h" /* ** Output a hyperlink to an technote given its tagid. */ void hyperlink_to_event_tagid(int tagid){ char *zId; zId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d", tagid); @ [%z(href("%R/technote/%s",zId))%S(zId)] free(zId); } /* ** WEBPAGE: technote ** WEBPAGE: event ** ** Display a technical note (formerly called an "event"). ** ** PARAMETERS: ** ** name=ID Identify the technical note to display. ID must be ** complete. ** aid=ARTIFACTID Which specific version of the tech-note. Optional. ** v=BOOLEAN Show details if TRUE. Default is FALSE. Optional. ** ** Display an existing tech-note identified by its ID, optionally at a ** specific version, and optionally with additional details. */ void event_page(void){ int rid = 0; /* rid of the event artifact */ char *zUuid; /* UUID corresponding to rid */ const char *zId; /* Event identifier */ const char *zVerbose; /* Value of verbose option */ char *zETime; /* Time of the tech-note */ char *zATime; /* Time the artifact was created */ int specRid; /* rid specified by aid= parameter */ int prevRid, nextRid; /* Previous or next edits of this tech-note */ Manifest *pTNote; /* Parsed technote artifact */ Blob fullbody; /* Complete content of the technote body */ Blob title; /* Title extracted from the technote body */ Blob tail; /* Event body that comes after the title */ Stmt q1; /* Query to search for the technote */ int verboseFlag; /* True to show details */ const char *zMimetype = 0; /* Mimetype of the document */ const char *zFullId; /* Full event identifier */ /* wiki-read privilege is needed in order to read tech-notes. */ login_check_credentials(); if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } zId = P("name"); if( zId==0 ){ fossil_redirect_home(); return; } zUuid = (char*)P("aid"); specRid = zUuid ? uuid_to_rid(zUuid, 0) : 0; rid = nextRid = prevRid = 0; db_prepare(&q1, "SELECT rid FROM tagxref" " WHERE tagid=(SELECT tagid FROM tag WHERE tagname GLOB 'event-%q*')" " ORDER BY mtime DESC", zId ); while( db_step(&q1)==SQLITE_ROW ){ nextRid = rid; rid = db_column_int(&q1, 0); if( specRid==0 || specRid==rid ){ if( db_step(&q1)==SQLITE_ROW ){ prevRid = db_column_int(&q1, 0); } break; } } db_finalize(&q1); if( rid==0 || (specRid!=0 && specRid!=rid) ){ style_header("No Such Tech-Note"); @ Cannot locate a technical note called %h(zId). style_footer(); return; } zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); zVerbose = P("v"); if( !zVerbose ){ zVerbose = P("verbose"); } if( !zVerbose ){ zVerbose = P("detail"); /* deprecated */ } verboseFlag = (zVerbose!=0) && !is_false(zVerbose); /* Extract the event content. */ pTNote = manifest_get(rid, CFTYPE_EVENT, 0); if( pTNote==0 ){ fossil_fatal("Object #%d is not a tech-note", rid); } zMimetype = wiki_filter_mimetypes(PD("mimetype",pTNote->zMimetype)); blob_init(&fullbody, pTNote->zWiki, -1); blob_init(&title, 0, 0); blob_init(&tail, 0, 0); if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){ if( !wiki_find_title(&fullbody, &title, &tail) ){ blob_appendf(&title, "Tech-note %S", zId); tail = fullbody; } }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){ markdown_to_html(&fullbody, &title, &tail); if( blob_size(&title)==0 ){ blob_appendf(&title, "Tech-note %S", zId); } }else{ blob_appendf(&title, "Tech-note %S", zId); tail = fullbody; } style_header("%s", blob_str(&title)); if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){ style_submenu_element("Edit", "%R/technoteedit?name=%!S", zId); if( g.perm.Attach ){ style_submenu_element("Attach", "%R/attachadd?technote=%!S&from=%R/technote/%!S", zId, zId); } } zETime = db_text(0, "SELECT datetime(%.17g)", pTNote->rEventDate); style_submenu_element("Context", "%R/timeline?c=%.20s", zId); if( g.perm.Hyperlink ){ if( verboseFlag ){ style_submenu_element("Plain", "%R/technote?name=%!S&aid=%s&mimetype=text/plain", zId, zUuid); if( nextRid ){ char *zNext; zNext = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nextRid); style_submenu_element("Next", "%R/technote?name=%!S&aid=%s&v", zId, zNext); free(zNext); } if( prevRid ){ char *zPrev; zPrev = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", prevRid); style_submenu_element("Prev", "%R/technote?name=%!S&aid=%s&v", zId, zPrev); free(zPrev); } }else{ style_submenu_element("Detail", "%R/technote?name=%!S&aid=%s&v", zId, zUuid); } } if( verboseFlag && g.perm.Hyperlink ){ int i; const char *zClr = 0; Blob comment; zATime = db_text(0, "SELECT datetime(%.17g)", pTNote->rDate); @

Tech-note [%z(href("%R/artifact/%!S",zUuid))%S(zUuid)] at @ [%z(href("%R/timeline?c=%T",zETime))%s(zETime)] @ entered by user %h(pTNote->zUser) on @ [%z(href("%R/timeline?c=%T",zATime))%s(zATime)]:

@
for(i=0; inTag; i++){ if( fossil_strcmp(pTNote->aTag[i].zName,"+bgcolor")==0 ){ zClr = pTNote->aTag[i].zValue; } } if( zClr && zClr[0]==0 ) zClr = 0; if( zClr ){ @
}else{ @
} blob_init(&comment, pTNote->zComment, -1); wiki_convert(&comment, 0, WIKI_INLINE); blob_reset(&comment); @
@

} if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){ wiki_convert(&fullbody, 0, 0); }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){ cgi_append_content(blob_buffer(&tail), blob_size(&tail)); }else{ @
    @ %h(blob_str(&fullbody))
    @ 
} zFullId = db_text(0, "SELECT SUBSTR(tagname,7)" " FROM tag" " WHERE tagname GLOB 'event-%q*'", zId); attachment_list(zFullId, "

Attachments: