717a40d56723cebacd7cbb8c240f9c2e72a4160a
braney
  Fri Aug 21 10:01:12 2026 -0700
hubCheck: name the parts of a description page we do not print, refs #38126

Now that a hub description is filtered on the way in, a hub author could
find out about it from a page that comes out looking wrong.  Warn instead,
one line per thing removed, up to ten, then a count of the rest.

Only things a reader would notice are named: an element dropped with its
contents, an event attribute, a link with a scheme we do not print, a style
value holding url() or expression.  A class attribute or an unlisted style
property goes quietly.  Over the 5390 pages of the public hubs, 118 draw at
least one of these warnings.

diff --git src/hg/utils/hubCheck/hubCheck.c src/hg/utils/hubCheck/hubCheck.c
index 62a42691728..c083c766477 100644
--- src/hg/utils/hubCheck/hubCheck.c
+++ src/hg/utils/hubCheck/hubCheck.c
@@ -963,30 +963,45 @@
     safef(setting, sizeof setting, "filter.%s", field);
     if (trackDbSettingClosestToHome(tdb, setting) != NULL)
         continue;
     safef(setting, sizeof setting, "%sFilter", field);
     if (trackDbSettingClosestToHome(tdb, setting) != NULL)
         continue;
     warn("track \"%s\" has a filterByRange/filterLimits setting for field '%s' "
          "but no 'filter.%s' (the default range), so this filter is not shown. "
          "Add 'filter.%s min:max' to enable it.",
          trackHubSkipHubName(tdb->track), field, field, field);
     }
 hashFree(&seen);
 slFreeList(&rangeSettings);
 }
 
+static void hubCheckDescriptionRemovals(struct trackHubGenome *genome, struct trackDb *tdb)
+/* Tell the hub author about the parts of a description page that the Browser will not
+ * print, so that they hear it from us instead of from a page that comes out wrong. */
+{
+struct slName *removed = trackHubDescriptionRemovals(genome->trackDbFile, tdb);
+struct slName *el = removed;
+int count = 0;
+for (;  el != NULL && count < 10;  el = el->next, ++count)
+    warn("warning: on the '%s' description page the Browser %s", tdb->track, el->name);
+if (el != NULL)
+    warn("warning: the '%s' description page has %d more parts the Browser will not print",
+         tdb->track, slCount(el));
+slFreeList(&removed);
+}
+
 int hubCheckTrack(struct trackHub *hub, struct trackHubGenome *genome, struct trackDb *tdb,
                         struct trackHubCheckOptions *options, struct dyString *errors)
 /* Check track settings and optionally, files */
 {
 int retVal = 0;
 int trackDbErrorCount = 0;
 
 if (options->checkSettings && options->settings)
     {
     //verbose(3, "Found %d settings to check to spec\n", slCount(settings));
     verbose(3, "Checking track: %s\n", tdb->shortLabel);
     verbose(3, "Found %d settings to check to spec\n", hashNumEntries(tdb->settingsHash));
     struct hashEl *hel;
     struct hashCookie cookie = hashFirst(tdb->settingsHash);
     while ((hel = hashNext(&cookie)) != NULL)
@@ -1055,30 +1070,32 @@
     // consistent messaging on command line interface vs web interface
     if (!foundTypeError && options->checkFiles)
         hubCheckBigDataUrl(hub, genome, tdb);
 
 
     checkViewLimitsSettings(tdb);
 
     checkOrphanedRangeFilters(tdb);
 
     if (!sameString(tdb->track, "cytoBandIdeo"))
         {
         trackHubAddDescription(genome->trackDbFile, tdb);
         if (!tdb->html)
             warn("warning: missing description page for track. Add 'html %s.html' line to the '%s' track stanza. ",
                  tdb->track, tdb->track);
+        else
+            hubCheckDescriptionRemovals(genome, tdb);
         }
 
     if (!trackIsContainer && sameString(trackDbRequiredSetting(tdb, "type"), "bigWig"))
         {
         char *autoScaleSetting = trackDbLocalSetting(tdb, "autoScale");
         if (autoScaleSetting && !sameString(autoScaleSetting, "off") && !sameString(autoScaleSetting, "on"))
             {
             errAbort("track \"%s\" uses 'autoScale %s', but individual bigWig tracks only accept "
                     "'autoScale on' or 'autoScale off'. If you're trying to set 'autoScale group', "
                     "that setting belongs in the parent composite stanza instead.",
                     trackHubSkipHubName(tdb->track), autoScaleSetting);
             }
         }
     }
 errCatchEnd(errCatch);