f19df2f83650190a467c3b1226b3e8a23f6d48c0 braney Thu Sep 17 17:04:48 2026 -0700 hgc: build the chain and net details pages with htmlPrintf The chain, snake, quickLift-chain and net click handlers assembled their output with plain printf. Route the values they print -- assembly and organism names, sequence names, positions, the chain id and the quickLiftDb setting -- through htmlPrintf instead, in the four handlers and in the five linkToOtherBrowser* anchor helpers they share. The anchor statements are split rather than converted whole, so that hgTracksName(), cartSidUrlString() and the genark hubUrl stay in a plain printf and only the values go through htmlPrintf. Converting a whole statement rewrites the '/' of ../cgi-bin/hgTracks as an entity on every chain, net, maf and ortho details page; split this way the output is unchanged for ordinary data. Verified against the shared build: the native chainMm39, multiz100way and quickLift "Alignment Differences" pages are byte-identical, and netMm39 differs only in the label "N's", which renders the same. refs #20824 diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index c51d863f3e8..d45e5586048 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -3949,77 +3949,79 @@ sqlSafef(query, sizeof(query), "select * from %s where id = %d", table, id); sr = sqlGetResult(conn, query); row = sqlNextRow(sr); if (row == NULL) errAbort("Can't find %d in %s", id, table); chain = chainHeadLoad(row + hasBin); sqlFreeResult(&sr); chainDbAddBlocks(chain, track, conn); return chain; } void linkToOtherBrowserHub(char *otherDb, char *chrom, int start, int end, char *hubUrl) /* Make anchor tag to open another browser window. */ { -printf("<A TARGET=\"_blank\" HREF=\"%s?genome=%s&position=%s%%3A%d-%d&hubUrl=%s\">", - hgTracksName(), otherDb, chrom, start+1, end, hubUrl); +printf("<A TARGET=\"_blank\" HREF=\"%s?genome=", hgTracksName()); +htmlPrintf("%s&position=%s%%3A%d-%d", otherDb, chrom, start+1, end); +printf("&hubUrl=%s\">", hubUrl); } void linkToOtherBrowserExtra(char *otherDb, char *chrom, int start, int end, char *extra) /* Make anchor tag to open another browser window. */ { -printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&%s&position=%s%%3A%d-%d\">", - hgTracksName(), otherDb, extra, chrom, start+1, end); +printf("<A TARGET=\"_blank\" HREF=\"%s?db=", hgTracksName()); +htmlPrintf("%s&%s&position=%s%%3A%d-%d\">", otherDb, extra, chrom, start+1, end); } void linkToOtherBrowserSearch(char *otherDb, char *tag) /* Make anchor tag to open another browser window. */ { -printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&ct=&position=%s\">", - hgTracksName(), otherDb, tag); +printf("<A TARGET=\"_blank\" HREF=\"%s?db=", hgTracksName()); +htmlPrintf("%s&ct=&position=%s\">", otherDb, tag); } void linkToOtherBrowser(char *otherDb, char *chrom, int start, int end) /* Make anchor tag to open another browser window. */ { -printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&ct=&position=%s%%3A%d-%d\">", - hgTracksName(), otherDb, chrom, start+1, end); +printf("<A TARGET=\"_blank\" HREF=\"%s?db=", hgTracksName()); +htmlPrintf("%s&ct=&position=%s%%3A%d-%d\">", otherDb, chrom, start+1, end); } void linkToOtherBrowserTitle(char *otherDb, char *chrom, int start, int end, char *title) /* Make anchor tag to open another browser window. */ { -printf("<A TARGET=\"_blank\" TITLE=\"%s\" HREF=\"%s?db=%s&ct=&position=%s%%3A%d-%d\">", - title, hgTracksName(), otherDb, chrom, start+1, end); +htmlPrintf("<A TARGET=\"_blank\" TITLE=\"%s\" HREF=\"", title); +printf("%s?db=", hgTracksName()); +htmlPrintf("%s&ct=&position=%s%%3A%d-%d\">", otherDb, chrom, start+1, end); } void chainToOtherBrowser(struct chain *chain, char *otherDb, char *otherOrg, char *hubUrl) /* Put up link that lets us use chain to browser on * corresponding window of other species. */ { struct chain *subChain = NULL, *toFree = NULL; int qs,qe; chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree); if (subChain != NULL && otherOrg != NULL) { qChainRangePlusStrand(subChain, &qs, &qe); if (hubUrl) linkToOtherBrowserHub(otherDb, subChain->qName, qs-1, qe, hubUrl); else linkToOtherBrowser(otherDb, subChain->qName, qs-1, qe); - printf("Open %s browser</A> at position corresponding to the part of chain that is in this window.<BR>\n", trackHubSkipHubName(otherOrg)); + htmlPrintf("Open %s browser</A> at position corresponding to the part of chain that is in this window.<BR>\n", trackHubSkipHubName(otherOrg)); } chainFree(&toFree); } struct dnaSeq *otherChromSeq(struct twoBitFile *otherTbf, char *otherDb, char *otherChrom, int otherStart, int otherEnd) /* This fetches sequence from tdb->otherTwoBitUrl if available, if not * tries to find it via otherDb */ { if (otherTbf != NULL) { return twoBitReadSeqFrag(otherTbf, otherChrom, otherStart, otherEnd); } else { @@ -4038,41 +4040,47 @@ char *aliasQName = qName; boolean otherIsActive = FALSE; char *hubUrl = NULL; if (hDbIsActive(otherDb)) otherIsActive = TRUE; else hubUrl = genarkUrl(otherDb); // may be NULL char headerText[256]; safef(headerText, sizeof headerText, "reference: %s, query: %s\n", trackHubSkipHubName(database), trackHubSkipHubName(otherDb) ); genericHeader(parentTdb, headerText); if (hubUrl != NULL) - printf("<A HREF=\"hgTracks?hubUrl=%s&genome=%s&position=%s:%d-%d\" TARGET=_BLANK>%s:%d-%d</A> link to block in query assembly: <B>%s</B></A><BR>\n", hubUrl, otherDb, aliasQName, qs, qe, aliasQName, qs, qe, trackHubSkipHubName(otherDb)); + { + printf("<A HREF=\"hgTracks?hubUrl=%s&genome=", hubUrl); + htmlPrintf("%s&position=%s:%d-%d\" TARGET=_BLANK>%s:%d-%d</A> link to block in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, qs, qe, aliasQName, qs, qe, trackHubSkipHubName(otherDb)); + } else if (otherIsActive) - printf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d\" TARGET=_BLANK>%s:%d-%d</A> link to block in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, qs, qe, aliasQName, qs, qe, trackHubSkipHubName(otherDb)); + htmlPrintf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d\" TARGET=_BLANK>%s:%d-%d</A> link to block in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, qs, qe, aliasQName, qs, qe, trackHubSkipHubName(otherDb)); int qCenter = (qs + qe) / 2; int newQs = qCenter - qWidth/2; int newQe = qCenter + qWidth/2; if (hubUrl != NULL) - printf("<A HREF=\"hgTracks?hubUrl=%s&genome=%s&position=%s:%d-%d\" TARGET=\"_blank\">%s:%d-%d</A> link to same window size in query assembly: <B>%s</B></A><BR>\n", hubUrl,otherDb, aliasQName, newQs, newQe,aliasQName, newQs, newQe, trackHubSkipHubName(otherDb) ); + { + printf("<A HREF=\"hgTracks?hubUrl=%s&genome=", hubUrl); + htmlPrintf("%s&position=%s:%d-%d\" TARGET=\"_blank\">%s:%d-%d</A> link to same window size in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, newQs, newQe,aliasQName, newQs, newQe, trackHubSkipHubName(otherDb) ); + } else if (otherIsActive) - printf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d\" TARGET=\"_blank\">%s:%d-%d</A> link to same window size in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, newQs, newQe,aliasQName, newQs, newQe, trackHubSkipHubName(otherDb) ); + htmlPrintf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d\" TARGET=\"_blank\">%s:%d-%d</A> link to same window size in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, newQs, newQe,aliasQName, newQs, newQe, trackHubSkipHubName(otherDb) ); printTrackHtml(tdb); } void genericChainClick(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start, char *otherDb) /* Handle click in chain track, at least the basics. */ { boolean doSnake = cartOrTdbBoolean(cart, tdb, "doSnake" , FALSE) && cfgOptionBooleanDefault("canSnake", TRUE); if (doSnake) return doSnakeChainClick(tdb, item, otherDb); struct twoBitFile *otherTbf = getOtherTwoBitUrl(tdb); char *thisOrg = hOrganism(database); char *otherOrg = NULL; @@ -4145,59 +4153,65 @@ atoi(words[0])); } } if (subChain->qStrand == '-') reverseIntRange(&qStart, &qEnd, subChain->qSize); qSeq = otherChromSeq(otherTbf, otherDb, subChain->qName, qStart, qEnd); if (subChain->qStrand == '-') reverseComplement(qSeq->dna, qSeq->size); subChain->score = chainCalcScoreSubChain(subChain, scoreScheme, gapCalc, qSeq, tSeq); subSetScore = subChain->score; } chainFree(&toFree); -printf("<B>%s position:</B> <A HREF=\"%s?%s&db=%s&position=%s:%d-%d\">%s:%d-%d</A>" - " size: %d <BR>\n", - trackHubSkipHubName(thisOrg), hgTracksName(), cartSidUrlString(cart), database, - chain->tName, chain->tStart+1, chain->tEnd, chain->tName, chain->tStart+1, chain->tEnd, - chain->tEnd-chain->tStart); +htmlPrintf("<B>%s position:</B> ", trackHubSkipHubName(thisOrg)); +printf("<A HREF=\"%s?%s&db=", hgTracksName(), cartSidUrlString(cart)); +htmlPrintf("%s&position=%s:%d-%d\">%s:%d-%d</A> size: %d <BR>\n", + database, chain->tName, chain->tStart+1, chain->tEnd, + chain->tName, chain->tStart+1, chain->tEnd, chain->tEnd-chain->tStart); printf("<B>Strand:</B> %c<BR>\n", chain->qStrand); qChainRangePlusStrand(chain, &qs, &qe); if (sameWord(otherDb, "seq")) { - printf("<B>%s position:</B> %s:%d-%d size: %d<BR>\n", + htmlPrintf("<B>%s position:</B> %s:%d-%d size: %d<BR>\n", otherOrg, chain->qName, qs, qe, chain->qEnd - chain->qStart); } else { /* prints link to other db browser only if db exists and is active */ /* else just print position with no link for the other db */ - printf("<B>%s position: </B>", otherOrg); + htmlPrintf("<B>%s position: </B>", otherOrg); if (otherIsActive) - printf(" <A target=\"_blank\" href=\"%s?db=%s&position=%s%%3A%d-%d\">", - hgTracksName(), otherDb, chain->qName, qs, qe); + { + printf(" <A target=\"_blank\" href=\"%s?db=", hgTracksName()); + htmlPrintf("%s&position=%s%%3A%d-%d\">", otherDb, chain->qName, qs, qe); + } else if (hubUrl != NULL) - printf(" <A target=\"_blank\" href=\"%s?genome=%s&hubUrl=%s&position=%s%%3A%d-%d\">", - hgTracksName(), otherDb, hubUrl, chain->qName, qs, qe); - printf("%s:%d-%d", chain->qName, qs, qe); + { + printf(" <A target=\"_blank\" href=\"%s?genome=", hgTracksName()); + htmlPrintf("%s", otherDb); + printf("&hubUrl=%s&position=", hubUrl); + htmlPrintf("%s%%3A%d-%d\">", chain->qName, qs, qe); + } + htmlPrintf("%s:%d-%d", chain->qName, qs, qe); if (otherIsActive || hubUrl) printf("</A>"); printf(" size: %d<BR>\n", chain->qEnd - chain->qStart); } -printf("<B>Chain ID:</B> %s<BR>\n", item); +htmlPrintf("<B>Chain ID:</B> %s<BR>\n", item); printf("<B>Score:</B> %1.0f\n", chain->score); if (nullSubset) printf("<B>Score within browser window:</B> N/A (no aligned bases)<BR>\n"); else if (otherIsActive && subChain != chain) printf("<B> Approximate Score within browser window:</B> %1.0f<BR>\n", subSetScore); else printf("<BR>\n"); boolean normScoreAvailable = chainDbNormScoreAvailable(tdb); // The normalized score lives in the chain table, so for a quickLifted track it has to be // read from the assembly the chain came from. Against the assembly on screen the table // name either does not resolve, or resolves to a same-named table there and returns @@ -4227,31 +4241,31 @@ if ((row = sqlNextRow(sr)) != NULL) { double normScore = atof(row[0]); int basesAligned = chain->score / normScore; printf("<B>Normalized Score:</B> %1.0f (aligned bases: %d)", normScore, basesAligned); } sqlFreeResult(&sr); printf("<BR>\n"); } if (lifted) hFreeConn(&normConn); if (quickLiftIsLifted(tdb) && !quickLiftIsOwnChainTrack(tdb)) // A lifted chain is only worked out over the window being viewed, so the whole chain's // extent is not knowable here and the usual sentence would be wrong. - printf("<BR>This chain comes from %s and is mapped onto %s as the browser draws it, so " + htmlPrintf("<BR>This chain comes from %s and is mapped onto %s as the browser draws it, so " "the fields above describe the part of it around the window rather than the " "whole chain.<BR>\n", trackDbSetting(tdb, "quickLiftDb"), trackHubSkipHubName(database)); else printf("<BR>Fields above refer to entire chain or gap, not just the part inside the window.<BR>\n"); printf("<BR>\n"); chainWinSize = min(winEnd-winStart, chain->tEnd - chain->tStart); /* Show alignment if the database exists and */ /* if there is a chromInfo table for that database and the sequence */ /* file exists. This means that alignments can be shown on the archive */ /* server (or in other cases) if there is a database with a chromInfo table, */ /* the sequences are available and there is an entry added to dbDb for */ /* the otherDb. */ if (otherTbf != NULL || @@ -4325,42 +4339,42 @@ struct dnaSeq *loadGenomePart(char *db, char *chrom, int start, int end) /* Load genomic dna from given database and position. */ { char nibFile[512]; findNib(db, chrom, nibFile); return hFetchSeq(nibFile, chrom, start, end); } void printLabeledNumber(char *org, char *label, long long number) /* Print label: in bold face, and number with commas. */ { char *space = " "; if (org == NULL) org = space = ""; -printf("<B>%s%s%s:</B> ", org, space, label); +htmlPrintf("<B>%s%s%s:</B> ", org, space, label); printLongWithCommas(stdout, number); printf("<BR>\n"); } void printLabeledPercent(char *org, char *label, long p, long q) /* Print label: in bold, then p, and then 100 * p/q */ { char *space = " "; if (org == NULL) org = space = ""; -printf("<B>%s%s%s:</B> ", org, space, label); +htmlPrintf("<B>%s%s%s:</B> ", org, space, label); printLongWithCommas(stdout, p); if (q != 0) printf(" (%3.1f%%)", 100.0 * p / q); printf("<BR>\n"); } static struct netAlign *bigNetLoadOne(struct trackDb *tdb, char *chrom, int start, unsigned level, boolean *retClipped) /* Load the record from a bigNet file at the given level that covers start. * Returns NULL if there isn't one. Sets *retClipped when a quickLifted row would * only lift with its ends pulled in, so the extent reported is the visible part * rather than the whole item. */ { char *fileName = hReplaceGbdb(trackDbSetting(tdb, "bigDataUrl")); char *quickLiftFile = trackDbSetting(tdb, "quickLiftUrl"); @@ -4574,49 +4588,49 @@ if (chain != NULL) { /* print link to browser for otherDb only if otherDb is active */ if (hDbIsActive(otherDb)) chainToOtherBrowser(chain, otherDb, otherOrgBrowser, NULL); chainFree(&chain); } htmlHorizontalLine(); } else if (net->chainId != 0) { /* Only an isBig track with no chain track to follow gets here. */ if (isLifted) { char *sourceDb = trackDbSetting(tdb, "quickLiftDb"); - printf("<BR>This net was lifted from %s, so its chains are not on this assembly " + htmlPrintf("<BR>This net was lifted from %s, so its chains are not on this assembly " "and the alignment cannot be shown here.<BR>\n", isEmpty(sourceDb) ? "another assembly" : sourceDb); } else { /* A hub whose type line names a chain track this assembly does not have. Say so * rather than dropping the whole section without a word. */ htmlPrintf("<BR>This track's type line names the chain track %s, which is not on " "this assembly, so the alignment cannot be shown here.<BR>\n", emptyForNull(namedChainTrack)); } htmlHorizontalLine(); } -printf("<B>Type:</B> %s<BR>\n", net->type); +htmlPrintf("<B>Type:</B> %s<BR>\n", net->type); printf("<B>Level:</B> %d<BR>\n", (net->level+1)/2); -printf("<B>%s position:</B> %s:%d-%d<BR>\n", +htmlPrintf("<B>%s position:</B> %s:%d-%d<BR>\n", org, net->tName, net->tStart+1, net->tEnd); -printf("<B>%s position:</B> %s:%d-%d<BR>\n", +htmlPrintf("<B>%s position:</B> %s:%d-%d<BR>\n", otherOrg, net->qName, net->qStart+1, net->qEnd); printf("<B>Strand:</B> %c<BR>\n", net->strand[0]); printLabeledNumber(NULL, "Score", net->score); if (net->chainId) { printf("<B>Chain ID:</B> %u<BR>\n", net->chainId); printLabeledNumber(NULL, "Bases aligning", net->ali); if (net->qOver >= 0) printLabeledNumber(otherOrg, "parent overlap", net->qOver); if (net->qFar >= 0) printLabeledNumber(otherOrg, "parent distance", net->qFar); if (net->qDup >= 0) printLabeledNumber(otherOrg, "bases duplicated", net->qDup); } if (net->tN >= 0) @@ -5194,39 +5208,39 @@ otherIsActive = TRUE; otherDb = genome->name; } } } chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree); char position[128]; char *ourPos, *otherPos; int seqStart = cartInt(cart, "l"); int seqEnd = cartInt(cart, "r"); char *chromName = cartString(cart, "c"); safef(position, 128, "%s:%d-%d", chromName, seqStart, seqEnd); ourPos = cloneString(addCommasToPos(database, position)); -printf("<B>%s position:</B> %s<BR>", trackHubSkipHubName(database), ourPos); +htmlPrintf("<B>%s position:</B> %s<BR>", trackHubSkipHubName(database), ourPos); int qs,qe; qChainRangePlusStrand(subChain, &qs, &qe); safef(position, 128, "%s:%d-%d", subChain->qName, qs-1, qe); otherPos = cloneString(addCommasToPos(otherDb, position)); -printf("<B>%s position: </B>", trackHubSkipHubName(otherDb)); +htmlPrintf("<B>%s position: </B>", trackHubSkipHubName(otherDb)); linkToOtherBrowser(otherDb, subChain->qName, qs-1, qe); -printf("%s</A><BR><BR>", otherPos); +htmlPrintf("%s</A><BR><BR>", otherPos); chainWinSize = min(winEnd-winStart, chain->tEnd - chain->tStart); if (otherTbf != NULL || (!startsWith("big", tdb->type) && sqlDatabaseExists(otherDb) && chromSeqFileExists(otherDb, chain->qName))) { if (chainWinSize < 1000000) { printf("View "); hgcAnchorSomewhere("htcChainAli", item, tdb->track, chain->tName); printf("DNA sequence alignment of whole window.</A><BR><BR>"); } else { printf("Zoom so that browser window covers 1,000,000 bases or less " @@ -5259,115 +5273,123 @@ case QUICKTYPE_MISMATCH: mismatches++; break; } } // If the click came from a specific difference (not one of the "identical" // regions), the matching row is shown in bold in the tables below. if (clickStart >= 0) printf("<BR>The item you clicked on is shown in <B>bold</B> in the tables below.<BR>\n"); if (deletions) { printf("<BR><B>Deletions in Window:</B><BR>"); printf("<TABLE border=\"1\"> <TR>\n"); - printf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Bases</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); + htmlPrintf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Bases</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); for(hr = regions; hr; hr = hr->next) { if (hr->type != QUICKTYPE_DEL) continue; char *ourPos, *otherPos; snprintf(position, 128, "%s:%ld-%ld", hr->chrom, hr->chromStart, hr->chromEnd); ourPos = cloneString(addCommasToPos(database, position)); snprintf(position, 128, "%s:%ld-%ld", hr->oChrom, hr->oChromStart, hr->oChromEnd); otherPos = cloneString(addCommasToPos(database, position)); char *hilite = (clickStart >= 0 && hr->chromStart == clickStart && hr->chromEnd == clickEnd) ? " style='font-weight:bold'" : ""; - printf("<TR%s><TD>%s</TD><TD>%s</TD><TD>%.*s</TD><TD>", hilite, ourPos, otherPos, hr->otherBaseCount, hr->otherBases); + printf("<TR%s>", hilite); + htmlPrintf("<TD>%s</TD><TD>%s</TD>", ourPos, otherPos); + printf("<TD>%.*s</TD><TD>", hr->otherBaseCount, hr->otherBases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment</A></TD></TR>"); } printf("</TABLE>"); } if (insertions) { printf("<BR><B>Insertions in Window:</B><BR>"); printf("<TABLE border=\"1\"> <TR>\n"); - printf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Bases</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); + htmlPrintf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Bases</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); for(hr = regions; hr; hr = hr->next) { if (hr->type != QUICKTYPE_INSERT) continue; char *ourPos, *otherPos; snprintf(position, 128, "%s:%ld-%ld", hr->chrom, hr->chromStart, hr->chromEnd); ourPos = cloneString(addCommasToPos(database, position)); snprintf(position, 128, "%s:%ld-%ld", hr->oChrom, hr->oChromStart, hr->oChromEnd); otherPos = cloneString(addCommasToPos(database, position)); char *hilite = (clickStart >= 0 && hr->chromStart == clickStart && hr->chromEnd == clickEnd) ? " style='font-weight:bold'" : ""; - printf("<TR%s><TD>%s</TD><TD>%s</TD><TD>%.*s</TD><TD>", hilite, ourPos, otherPos, hr->baseCount, hr->bases); + printf("<TR%s>", hilite); + htmlPrintf("<TD>%s</TD><TD>%s</TD>", ourPos, otherPos); + printf("<TD>%.*s</TD><TD>", hr->baseCount, hr->bases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment</A></TD></TR>"); } printf("</TABLE>"); } if (doubles) { printf("<BR><B>Double Gaps in Window:</B><BR>"); printf("<TABLE border=\"1\"> <TR>\n"); - printf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD># Bases in %s</TD><TD>#Bases in %s</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb), trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); + htmlPrintf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD># Bases in %s</TD><TD>#Bases in %s</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb), trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); for(hr = regions; hr; hr = hr->next) { if (hr->type != QUICKTYPE_DOUBLE) continue; char *ourPos, *otherPos; snprintf(position, 128, "%s:%ld-%ld", hr->chrom, hr->chromStart, hr->chromEnd); ourPos = cloneString(addCommasToPos(database, position)); snprintf(position, 128, "%s:%ld-%ld", hr->oChrom, hr->oChromStart, hr->oChromEnd); otherPos = cloneString(addCommasToPos(database, position)); char *hilite = (clickStart >= 0 && hr->chromStart == clickStart && hr->chromEnd == clickEnd) ? " style='font-weight:bold'" : ""; - printf("<TR%s><TD>%s</TD><TD>%s</TD><TD>%d</TD><TD>%d</TD><TD>", hilite, ourPos, otherPos, hr->baseCount, hr->otherBaseCount); + printf("<TR%s>", hilite); + htmlPrintf("<TD>%s</TD><TD>%s</TD>", ourPos, otherPos); + printf("<TD>%d</TD><TD>%d</TD><TD>", hr->baseCount, hr->otherBaseCount); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment</A></TD></TR>"); } printf("</TABLE>"); } if (mismatches) { printf("<BR><B>Mismatches in Window:</B><BR>"); printf("<TABLE border=\"1\"> <TR>\n"); - printf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Change</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); + htmlPrintf("<TR><TD>%s Position</TD><TD>%s Position</TD><TD>Change</TD><TD>Alignment</TD><TR>", trackHubSkipHubName(database), trackHubSkipHubName(otherDb)); for(hr = regions; hr; hr = hr->next) { if (hr->type != QUICKTYPE_MISMATCH) continue; char *ourPos, *otherPos; snprintf(position, 128, "%s:%ld-%ld", hr->chrom, hr->chromStart, hr->chromEnd); ourPos = cloneString(addCommasToPos(database, position)); snprintf(position, 128, "%s:%ld-%ld", hr->oChrom, hr->oChromStart, hr->oChromEnd); otherPos = cloneString(addCommasToPos(database, position)); char *hilite = (clickStart >= 0 && hr->chromStart == clickStart && hr->chromEnd == clickEnd) ? " style='font-weight:bold'" : ""; - printf("<TR%s><TD>%s</TD><TD>%s</TD><TD>%.*s -> %.*s</TD><TD>", hilite, ourPos, otherPos, hr->otherBaseCount, hr->otherBases, hr->baseCount, hr->bases); + printf("<TR%s>", hilite); + htmlPrintf("<TD>%s</TD><TD>%s</TD>", ourPos, otherPos); + printf("<TD>%.*s -> %.*s</TD><TD>", hr->otherBaseCount, hr->otherBases, hr->baseCount, hr->bases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment</A></TD></TR>"); } printf("</TABLE>"); } } void genericClickHandlerPlus( struct trackDb *tdb, char *item, char *itemForUrl, char *plus) /* Put up generic track info, with additional text appended after item. */ { char *dupe, *type, *words[16], *headerItem; int wordCount; int start = cartInt(cart, "o"); int end = cartInt(cart, "t");