51669978674f8d49a13b96e72d71418633719176
max
  Tue Mar 20 02:35:48 2012 -0700
creating a authorYear label on the fly for pubBlat tracks
diff --git src/hg/hgc/pubs.c src/hg/hgc/pubs.c
index a722cbc..cd09f14 100644
--- src/hg/hgc/pubs.c
+++ src/hg/hgc/pubs.c
@@ -56,31 +56,31 @@
 
 char* nameListString = slNameListToString(names, ',');
 slNameFree(names);
 return nameListString;
 }
 
 
 static struct sqlResult* queryMarkerRows(struct sqlConnection* conn, char* markerTable, \
     char* articleTable, char* item, int itemLimit, char* sectionList)
 /* query marker rows from mysql, based on http parameters  */
 {
 char query[4000];
 /* Mysql specific setting to make the group_concat function return longer strings */
 sqlUpdate(conn, "SET SESSION group_concat_max_len = 100000");
 
-safef(query, sizeof(query), "SELECT distinct %s.articleId, url, title, authors, citation," 
+safef(query, sizeof(query), "SELECT distinct %s.articleId, url, title, authors, citation, pmid, "  
     "group_concat(snippet, section SEPARATOR ' (...) ') FROM %s "
     "JOIN %s USING (articleId) "
     "WHERE markerId='%s' AND section in (%s) "
     "GROUP by articleId "
     "ORDER BY year DESC "
     "LIMIT %d",
     markerTable, markerTable, articleTable, item, sectionList, itemLimit);
 
 if (pubsDebug)
     printf("%s", query);
 
 struct sqlResult *sr = sqlGetResult(conn, query);
 
 return sr;
 }
@@ -152,117 +152,129 @@
 printSectionCheckboxes();
 char* sectionList = makeSqlMarkerList();
 printLimitWarning(conn, markerTable, item, itemLimit, sectionList);
 
 printf("<H3>Snippets from Publications:</H3>");
 struct sqlResult* sr = queryMarkerRows(conn, markerTable, articleTable, item, itemLimit, sectionList);
 
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
 {
     char* articleId = row[0];
     char* url       = row[1];
     char* title     = row[2];
     char* authors   = row[3];
     char* citation  = row[4];
-    char* snippets  = row[5];
+    char* pmid      = row[5];
+    char* snippets  = row[6];
     char* addParam  = "";
     if (strstrNoCase(url, "sciencedirect.com"))
         addParam = "?svAppaddApp=298535"; // add the "UCSC matches" sciverse application to article view
     printf("<A HREF=\"%s%s\">%s</A> ", url, addParam, title);
     printf("<SMALL>%s</SMALL>; ", authors);
-    printf("<SMALL>%s</SMALL><BR>", citation);
+    printf("<SMALL>%s ", citation);
+    if (!isEmpty(pmid) && strcmp(pmid, "0")!=0 )
+        printf(", <A HREF=\"http://www.ncbi.nlm.nih.gov/pubmed/%s\">PMID%s</A>\n", pmid, pmid);
+    printf("</SMALL><BR>\n");
     if (pubsDebug)
         printf("articleId=%s", articleId);
     printf("<I>%s</I><P>", snippets);
     printf("<HR>");
 }
 
 freeMem(sectionList);
 sqlFreeResult(&sr);
 }
 
 static char* printArticleInfo(struct sqlConnection *conn, char* item)
 /* Header with information about paper, return documentId */
 {
     char query[512];
 
-    safef(query, sizeof(query), "SELECT articleId, url, title, authors, citation, abstract, pmid FROM %s WHERE displayId='%s'", pubsArticleTable, item);
+    safef(query, sizeof(query), "SELECT articleId, url, title, authors, citation, abstract, pmid FROM %s WHERE articleId='%s'", pubsArticleTable, item);
 
     struct sqlResult *sr = sqlGetResult(conn, query);
     char **row;
     char *articleId=NULL;
-    if ((row = sqlNextRow(sr)) != NULL)
+    if ((row = sqlNextRow(sr)) == NULL)
     {
+        printf("Could not resolve articleId %s, this is an internal error.\n", item);
+        printf("Please send an email to max@soe.ucsc.edu\n");
+        sqlFreeResult(&sr);
+        return NULL;
+    }
+
+    articleId = cloneString(row[0]);
+    char* url      = row[1];
+    char* title    = row[2];
+    char* authors  = row[3];
         char* cit = row[4];
         char* abstract = row[5];
         char* pmid = row[6];
-
         if (strlen(abstract)==0) 
-            {
-                abstract = "(No abstract found for this article. Please use the link to the fulltext above.)";
-            }
-        articleId = cloneString(row[0]);
-        printf("<P>%s</P>\n", row[3]);
-        printf("<A TARGET=\"_blank\" HREF=\"%s\"><B>%s</B></A>\n", row[1], row[2]);
+            abstract = "(No abstract available for this article. "
+                "Please follow the link to the fulltext above.)";
+
+    printf("<P>%s</P>\n", authors);
+    printf("<A TARGET=\"_blank\" HREF=\"%s\"><B>%s</B></A>\n", url, title);
         printf("<P style=\"width:800px; font-size:80%%\">%s", cit);
-        if (nullIfAllSpace(pmid)!=NULL)
+    if (strlen(pmid)!=0 && strcmp(pmid, "0"))
             printf(", <A HREF=\"http://www.ncbi.nlm.nih.gov/pubmed/%s\">PMID%s</A>\n", pmid, pmid);
         printf("</P>\n");
         printf("<P style=\"width:800px; font-size:100%%\">%s</P>\n", abstract);
-	}
+
     sqlFreeResult(&sr);
     return articleId;
 }
 
 static struct hash* getSeqIdHash(struct sqlConnection* conn, char* trackTable, \
     char* articleId, char *item, char* seqName, int start)
 /* return a hash with the sequence IDs for a given chain of BLAT matches */
 {
     char query[512];
     /* check first if the column exists (some debugging tables on hgwdev don't have seqIds) */
     safef(query, sizeof(query), "SHOW COLUMNS FROM %s LIKE 'seqIds';", trackTable);
     char* seqIdPresent = sqlQuickString(conn, query);
     if (!seqIdPresent) {
         return NULL;
     }
 
     /* get sequence-Ids for feature that was clicked (item&startPos are unique) and return as hash*/
     safef(query, sizeof(query), "SELECT seqIds,'' FROM %s WHERE name='%s' "
-        "and chrom='%s' and chromStart=%d", trackTable, item, seqName, start);
+        "and chrom='%s' and chromStart=%d;", trackTable, item, seqName, start);
     if (pubsDebug)
-        puts(query);
+        printf("%s<br>", query);
     
     // split comma-sep list into parts
     char* seqIdCoordString = sqlQuickString(conn, query);
     char* seqIdCoords[1024];
     int partCount = chopString(seqIdCoordString, ",", seqIdCoords, ArraySize(seqIdCoords));
     int i;
 
     // format of part <fileId:3><annotId:5>:<start>-<end>, e.g. 12312345:0-23
     struct hash *seqIdHash = NULL;
     seqIdHash = newHash(0);
     for (i=0; i<partCount; i++) 
     {
         char* annotIdHitCoord[1024];
         chopString(seqIdCoords[i], ":", annotIdHitCoord, ArraySize(annotIdHitCoord));
-        if (pubsDebug)
-            printf("%s, %s<br>", annotIdHitCoord[0], annotIdHitCoord[1]);
-
         // put articleId and annotId together to create annotation(=sequence) Id
         char fullAnnotId[4096];
         safef(fullAnnotId, sizeof(fullAnnotId), "%s%s", articleId, annotIdHitCoord[0]);
+        if (pubsDebug)
+            printf("%s, %s, %s<br>", annotIdHitCoord[0], annotIdHitCoord[1], fullAnnotId);
+
         hashAdd(seqIdHash, fullAnnotId, annotIdHitCoord[1]);
     }
     freeMem(seqIdCoordString);
     return seqIdHash;
 }
 
 static void printSeqHeaders(bool showDesc, bool isClickedSection) 
 {
     printf("<TABLE style=\"background-color: #%s\" WIDTH=\"100%%\" CELLPADDING=\"2\">\n", HG_COL_BORDER);
     printf("<TR style=\"background-color: #%s; color: #FFFFFF\">\n", HG_COL_TABLE_LABEL);
     if (showDesc)
         puts("  <TH style=\"width: 10%\">Article file</TH>\n");
     puts("  <TH style=\"width: 70%\">One table row per sequence, with flanking text, sequence in bold</TH>\n");
     if (pubsDebug)
         puts("  <TH style=\"width: 30%\">Identifiers</TH>\n");
@@ -272,38 +284,38 @@
     puts("</TR>\n");
 }
 
 static void printAddWbr(char* text, int distance) 
 /* a crazy hack for firefox/mozilla that is unable to break long words in tables
  * We need to add a <wbr> tag every x characters in the text to make text breakable.
  */
 {
 int i;
 i = 0;
 char* c;
 c = text;
 bool doNotBreak = FALSE;
 while (*c != 0){
     {
-    if (*c=='&')
+    if ((*c=='&') || (*c=='<'))
        doNotBreak = TRUE;
-    if (*c==';')
+    if (*c==';' || (*c =='>'))
        doNotBreak = FALSE;
 
+    printf("%c", *c);
     if (i % distance == 0 && ! doNotBreak) 
         printf("<wbr>");
-    printf("%c", *c);
     c++;
     i++;
     }
 }
 }
 
 static bool printSeqSection(char* articleId, char* title, bool showDesc, struct sqlConnection* conn, struct hash* clickedSeqs, bool isClickedSection, bool fasta)
 /* print a table of sequences, show only sequences with IDs in hash,
  * There are two sections, respective sequences are shown depending on isClickedSection and clickedSeqs 
  *   - seqs that were clicked on (isClickedSection=True) -> show only seqs in clickedSeqs
  *   - other seqs (isClickedSection=False) -> show all other seqs
  * 
  * */
 {
     // get data from mysql
@@ -331,30 +343,32 @@
     bool foundSkippedRows = FALSE;
     while ((row = sqlNextRow(sr)) != NULL)
     {
         char* fileDesc = row[0];
         char* snippet  = row[1];
         char* locList  = row[2];
         char* artId    = row[3];
         char* fileId   = row[4];
         char* seqId    = row[5];
         char* seq      = row[6];
 
         // annotation (=sequence) ID is a 64 bit int with 10 digits for 
         // article, 3 digits for file, 5 for annotation
         char annotId[100];
         safef(annotId, 100, "%010d%03d%05d", atoi(artId), atoi(fileId), atoi(seqId));
+        if (pubsDebug)
+            printf("%s", annotId);
 
         // only display this sequence if we're in the right section
         if (clickedSeqs!=NULL && ((hashLookup(clickedSeqs, annotId)!=NULL) != isClickedSection)) {
             foundSkippedRows = TRUE;
             continue;
         }
 
         if (fasta)
         {
             printf("<TT>>%s<BR>%s<BR></TT>", annotId, seq);
         }
         else
         {
             printf("<TR style=\"background-color: #%s\">\n", HG_COL_LOCAL_TABLE);
             if (showDesc)
@@ -405,31 +419,31 @@
     /* print sequences, split into two sections 
      * two sections: one for sequences that were clicked, one for all others*/
 {
     struct hash* clickedSeqs = getSeqIdHash(conn, trackTable, articleId, item, seqName, start);
 
     bool skippedRows;
     if (clickedSeqs) 
         skippedRows = printSeqSection(articleId, "Sequences used to construct this feature", \
             fileDesc, conn, clickedSeqs, 1, fasta);
     else 
         skippedRows=1;
 
     if (skippedRows)
         printSeqSection(articleId, "Other Sequences in this article", \
             fileDesc, conn, clickedSeqs, 0, fasta);
-    printf("<P><SMALL>Copyright 2011 Elsevier B.V. All rights reserved.</SMALL><P>");
+    printf("<P><SMALL>Copyright 2012 Elsevier B.V. All rights reserved.</SMALL><P>");
     freeHash(&clickedSeqs);
 
 }
 
 static void printTrackVersion(struct trackDb *tdb, struct sqlConnection* conn, char* item) 
 {
     char versionString[256];
     char dateReference[256];
     char headerTitle[512];
     /* see if hgFixed.trackVersion exists */
     boolean trackVersionExists = hTableExists("hgFixed", "trackVersion");
 
     if (trackVersionExists)
         {
         char query[256];
@@ -481,31 +495,31 @@
 
 void doPubsDetails(struct trackDb *tdb, char *item)
 /* publications custom display */
 {
 
 int start = cgiInt("o");
 int end = cgiInt("t");
 char* trackTable = cgiString("g");
 int fasta = cgiOptionalInt("fasta", 0);
 
 pubsDebug = cgiOptionalInt("debug", 0);
 
 struct sqlConnection *conn = hAllocConn(database);
 printTrackVersion(tdb, conn, item);
 
-if (startsWith("pubsMarker", trackTable)) 
+if (hashFindVal(tdb->settingsHash, "pubsMarkerTable"))
 {
     char* markerTable = hashMustFindVal(tdb->settingsHash, "pubsMarkerTable");
     char* articleTable = hashMustFindVal(tdb->settingsHash, "pubsArticleTable");
     printPositionAndSize(start, end, 0);
     printMarkerSnippets(conn, articleTable, markerTable, item);
 }
 else 
 {
     printPositionAndSize(start, end, 1);
     pubsSequenceTable = hashMustFindVal(tdb->settingsHash, "pubsSequenceTable");
     pubsArticleTable = hashMustFindVal(tdb->settingsHash, "pubsArticleTable");
 
     char* articleId = printArticleInfo(conn, item);
     if (articleId!=NULL) 
     {