350733c85caaaebfe5c82892e57a38d60e70c1c3 max Mon Jul 20 11:23:01 2020 -0700 fixing a previous commit that I had reverted, refs #25887. Code review note: ignore the original commit and its reverted cousin This is the only relevant commit. diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 7d44b40..7fe281e 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -2132,56 +2132,84 @@ } struct highlightVar // store highlight information { struct highlightVar *next; char *db; char *chrom; long chromStart; long chromEnd; char *hexColor; }; struct highlightVar *parseHighlightInfo() // Parse highlight info from cart var to a linked list of highlightVar structs -// db.chrom:start-end#hexColor|db.chrom:start-end#hexColor|... +// Accepts three input formats for the highlight variable: +// 1) db.chrom:start-end (format in very old carts) +// 2) db.chrom:start-end#hexColor|db.chrom:start-end#hexColor|... (old format) +// 3) db#chrom#start#end#hexColor|db#chrom#start#end#hexColor|... (current format, to allow . in seq names) +// { struct highlightVar *hlList = NULL; char *highlightDef = cartOptionalString(cart, "highlight"); if(highlightDef) { char *hlArr[256]; int hlCount = chopByChar(cloneString(highlightDef), '|', hlArr, ArraySize(hlArr)); int i; for (i=0; i<hlCount; i++) { char *oneHl = hlArr[i]; struct highlightVar *h; + char *chromStart, *chromEnd; AllocVar(h); + if (countSeparatedItems(oneHl, '#')==5) + // the new format: db#chrom#start#end#color + { + h->db = cloneNextWordByDelimiter(&oneHl,'#'); + h->chrom = cloneNextWordByDelimiter(&oneHl,'#'); + chromStart = cloneNextWordByDelimiter(&oneHl,'#'); + chromEnd = cloneNextWordByDelimiter(&oneHl,'#'); + h->hexColor = cloneString(oneHl); + } + else // the syntax only used in old saved sessions + // the old format: db.chr:start-end followed optionally by #color + { h->db = cloneNextWordByDelimiter(&oneHl,'.'); h->chrom = cloneNextWordByDelimiter(&oneHl,':'); + chromStart = cloneNextWordByDelimiter(&oneHl,'-'); + chromEnd = cloneNextWordByDelimiter(&oneHl,'#'); + if (oneHl && *oneHl != '\0') + h->hexColor = cloneString(oneHl); + } + + if (!isEmpty(chromStart) && !isEmpty(chromEnd) && + isNumericString(chromStart) && isNumericString(chromEnd) && + !isEmpty(h->db) && !isEmpty(h->chrom)) + { // long to handle virt chrom coordinates - h->chromStart = atol(cloneNextWordByDelimiter(&oneHl,'-')); - h->chromEnd = atol(cloneNextWordByDelimiter(&oneHl,'#')); + h->chromStart = atol(chromStart); + h->chromEnd = atol(chromEnd); h->chromStart--; // Not zero based - if (highlightDef && *highlightDef != '\0') - h->hexColor = cloneString(oneHl); slAddHead(&hlList, h); } + } + slReverse(&hlList); } + return hlList; } static void highlightRegions(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight) // Highlights regions in the image. Only done if theImgBox is not defined. // Thus it is done for ps/pdf and view image but the hgTracks image is highlighted via js { struct highlightVar *hlList = parseHighlightInfo(); if(hlList && theImgBox == NULL) // Only highlight region when imgBox is not used. (pdf and show-image) { struct highlightVar *h; for (h=hlList; h; h=h->next) { if (virtualSingleChrom()) // DISGUISE VMODE @@ -9135,31 +9163,31 @@ } void remapHighlightPos() // Remap non-virt highlight position if any to new virtMode chrom. { if (virtualSingleChrom()) return; struct highlightVar *h = parseHighlightInfo(); if (h && h->db && sameString(h->db, database)) { long virtStart = 0, virtEnd = 0; if (findNearestVirtMatch(h->chrom, h->chromStart, h->chromEnd, FALSE, &virtStart, &virtEnd)) // try to find the nearest match { // save new highlight position to cart var char cartVar[1024]; - safef(cartVar, sizeof cartVar, "%s#%s#%ld#%ld#%s", h->db, "virt", virtStart, virtEnd, h->hexColor); + safef(cartVar, sizeof cartVar, "%s.%s:%ld-%ld#%s", h->db, "virt", virtStart, virtEnd, h->hexColor); cartSetString(cart, "highlight", cartVar); } else { // erase the highlight cartvar if it has no overlap with the new virt chrom cartRemove(cart, "highlight"); } } } void tracksDisplay() /* Put up main tracks display. This routine handles zooming and * scrolling. */ {