src/common/support.js/getSupportInfo
function getSupportInfo(version, opts) {
  opts = Object.assign(
    {
      plugins: [],
      pluginsLoaded: false,
      showUnreleased: false,
      showDeprecated: false,
      showInternal: false
    },
    opts
  );

  if (!version) {
    version = currentVersion;
  }

  const plugins = opts.pluginsLoaded ? opts.plugins : loadPlugins(opts.plugins);

  const options = util
    .arrayify(
      Object.assign(
        plugins.reduce(
          (currentOptions, plugin) =>
            Object.assign(currentOptions, plugin.options),
          {}
        ),
        supportOptions
      ),
      "name"
    )
    .sort((a, b) => (a.name === b.name ? 0 : a.name < b.name ? -1 : 1))
    .filter(filterSince)
    .filter(filterDeprecated)
    .map(mapDeprecated)
    .map(mapInternal)
    .map(option => {
      const newOption = Object.assign({}, option);

      if (Array.isArray(newOption.default)) {
        newOption.default =
          newOption.default.length === 1
            ? newOption.default[0].value
            : newOption.default
                .filter(filterSince)
                .sort((info1, info2) =>
                  semver.compare(info2.since, info1.since)
                )[0].value;
      }

      if (Array.isArray(newOption.choices)) {
        newOption.choices = newOption.choices
          .filter(filterSince)
          .filter(filterDeprecated)
          .map(mapDeprecated);
      }

      return newOption;
    })
    .map(option => {
      const filteredPlugins = plugins.filter(
        plugin => plugin.defaultOptions && plugin.defaultOptions[option.name]
      );
      const pluginDefaults = filteredPlugins.reduce((reduced, plugin) => {
        reduced[plugin.name] = plugin.defaultOptions[option.name];
        return reduced;
      }, {});
      return Object.assign(option, { pluginDefaults });
    });

  const usePostCssParser = semver.lt(version, "1.7.1");

  const languages = plugins
    .reduce((all, plugin) => all.concat(plugin.languages), [])
    .filter(
      language =>
        language.since
          ? semver.gte(version, language.since)
          : language.since !== null
    )
    .map(language => {
      // Prevent breaking changes
      if (language.name === "Markdown") {
        return Object.assign({}, language, {
          parsers: ["markdown"]
        });
      }
      if (language.name === "TypeScript") {
        return Object.assign({}, language, {
          parsers: ["typescript"]
        });
      }

      if (usePostCssParser && language.group === "CSS") {
        return Object.assign({}, language, {
          parsers: ["postcss"]
        });
      }
      return language;
    });

  return { languages, options };

  function filterSince(object) {
    return (
      opts.showUnreleased ||
      !("since" in object) ||
      (object.since && semver.gte(version, object.since))
    );
  }
  function filterDeprecated(object) {
    return (
      opts.showDeprecated ||
      !("deprecated" in object) ||
      (object.deprecated && semver.lt(version, object.deprecated))
    );
  }
  function mapDeprecated(object) {
    if (!object.deprecated || opts.showDeprecated) {
      return object;
    }
    const newObject = Object.assign({}, object);
    delete newObject.deprecated;
    delete newObject.redirect;
    return newObject;
  }
  function mapInternal(object) {
    if (opts.showInternal) {
      return object;
    }
    const newObject = Object.assign({}, object);
    delete newObject.cliName;
    delete newObject.cliCategory;
    delete newObject.cliDescription;
    return newObject;
  }
}