5e8e0ed53c05f2ef9b51ce897440bae308367f47 chmalee Wed Feb 9 14:45:54 2022 -0800 Add csv output option to table browser to support opening files in Excel, refs #27623. Also change the output filename message to hint that Excel can auto-recognize .csv extensions and behave appropriately. Lastly, fix output dropdown selection to properly warn on update when using GTF output option or a snp table. diff --git src/hg/hgTables/hic.c src/hg/hgTables/hic.c index 1905826..ab36720 100644 --- src/hg/hgTables/hic.c +++ src/hg/hgTables/hic.c @@ -112,64 +112,72 @@ assert(numPt < numBufEnd); } int hicCompare(const void *elem1, const void *elem2) /* Simple comparison function for sorting hic data in interact structures, * since it is not always returned in sorted order. */ { const struct interact *first = *((struct interact **)elem1); const struct interact *second = *((struct interact **)elem2); int dif = strcmp(first->chrom, second->chrom); if (dif == 0) dif = first->chromStart - second->chromStart; return dif; } -void hicTabOut(char *db, char *table, struct sqlConnection *conn, char *fields, FILE *f) +void hicTabOut(char *db, char *table, struct sqlConnection *conn, char *fields, FILE *f, char outSep) /* Print out selected fields from hic. If fields is NULL, then print out all fields. */ { if (f == NULL) f = stdout; /* Convert comma separated list of fields to array. */ int fieldCount = chopByChar(fields, ',', NULL, 0); char **fieldArray; AllocArray(fieldArray, fieldCount); chopByChar(fields, ',', fieldArray, fieldCount); /* Get list of all fields in hic and turn it into a hash of column indexes keyed by * column name. */ struct hash *fieldHash = hashNew(0); struct slName *field, *fieldList = hicGetFields(); int i; for (field = fieldList, i=0; field != NULL; field = field->next, ++i) { hashAddInt(fieldHash, field->name, i); } /* Create an array of column indexes corresponding to the selected field list. */ int *columnArray; AllocArray(columnArray, fieldCount); for (i=0; i<fieldCount; ++i) { columnArray[i] = hashIntVal(fieldHash, fieldArray[i]); } /* Output row of labels */ -fprintf(f, "#%s", fieldArray[0]); +fprintf(f, "#"); +if (outSep == ',') fputc('"', f); +fprintf(f, "%s", fieldArray[0]); +if (outSep == ',') fputc('"', f); for (i=1; i<fieldCount; ++i) - fprintf(f, "\t%s", fieldArray[i]); + { + fputc(outSep, f); + if (outSep == ',') fputc('"', f); + fprintf(f, "%s", fieldArray[i]); + if (outSep == ',') fputc('"', f); + } fprintf(f, "\n"); struct asObject *as = interactAsObj(); struct asFilter *filter = NULL; if (anyFilter()) { filter = asFilterFromCart(cart, db, table, as); if (filter) { fprintf(f, "# Filtering on %d columns\n", slCount(filter->columnList)); } } /* Loop through outputting each region */ @@ -190,33 +198,40 @@ struct interact *results = NULL, *result = NULL; int res = hicUiFetchResolutionAsInt(cart, tdb, fileInfo, region->end-region->start); char *errMsg = hicLoadData(fileInfo, res, norm, region->chrom, region->start, region->end, region->chrom, region->start, region->end, &results); if (errMsg != NULL) warn("%s", errMsg); slSort(&results, &hicCompare); char *row[INTERACT_NUM_COLS]; char numBuf[HIC_NUM_BUF_SIZE]; for (result = results; result != NULL && (maxOut > 0); result = result->next) { hicRecordToRow(result, numBuf, row); if (asFilterOnRow(filter, row)) { int i; + if (outSep == ',') fputc('"', f); fprintf(f, "%s", row[columnArray[0]]); + if (outSep == ',') fputc('"', f); for (i=1; i<fieldCount; ++i) - fprintf(f, "\t%s", row[columnArray[i]]); + { + fputc(outSep, f); + if (outSep == ',') fputc('"', f); + fprintf(f, "%s", row[columnArray[i]]); + if (outSep == ',') fputc('"', f); + } fprintf(f, "\n"); maxOut --; } } } freeMem(fileName); if (maxOut == 0) errAbort("Reached output limit of %d data values, please make region smaller,\n\tor set a higher output line limit with the filter settings.", bigFileMaxOutput()); /* Clean up and exit. */ hashFree(&fieldHash); freeMem(fieldArray); freeMem(columnArray); }