# All files / src/lib/markdown-it/plugins markdown-it-icons.ts

100% Statements 61/61
100% Branches 29/29
100% Functions 10/10
100% Lines 59/59

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    17x
    17x
    17x

    17x

    9x

    17x
    7x

    17x
    6x

    6x
    1x

    5x

    17x
    3x

    3x
    1x

    2x
    2x
    2x
    2x

    17x
    11x
    11x

    1x
    1x

    1x
    1x

    1x
    1x

    3x
    3x

    11x

    17x
    13x

    17x

    17x
    44x
    44x
    44x

    44x
    7x
    37x
    6x
    31x
    3x
    28x
    11x
    17x
    4x

    13x

    17x
    5x

    5x
    4x

    5x
    5x

    17x

    40x

    17x
     // import the necessary packages
    const octicons = require('@primer/octicons');
    const cheerio = require('cheerio');
    const markdownItRegExp = require('markdown-it-regexp');

    // regular expression to match the icon patterns
    const ICON_REGEXP
      = /:(fa[brs]|fa-brands|fa-solid|glyphicon|octicon|octiconlight|mi[forst]|bi)-([a-z-]+)~?([a-z-]+)?:/;

    // function to get the octicon icons
    function getOcticonIcon(iconName: string) {
      return octicons[iconName] ?? null;
    }

    // handler function for glyphicon icons
    const handleGlyphicon = (iconFontName: string) =>
      `<span aria-hidden="true" class="glyphicon glyphicon-${iconFontName}"></span>`;

    // handler function for octicon icons
    const handleOcticon = (iconFontName: string, iconClass?: string) => {
      const octiconIcon = getOcticonIcon(iconFontName);
      // ensure octicons are valid
      if (octiconIcon === null) {
        return '<span aria-hidden="true"></span>';
      }
      return iconClass ? octiconIcon.toSVG({ class: iconClass }) : octiconIcon.toSVG();
    };

    // handler function for light octicon icons
    const handleOcticonLight = (iconFontName: string, iconClass?: string) => {
      const octiconIcon = getOcticonIcon(iconFontName);
      // ensure octicons are valid
      if (octiconIcon === null) {
        return '<span aria-hidden="true"></span>';
      }
      const octiconIconHtml = iconClass ? octiconIcon.toSVG({ class: iconClass }) : octiconIcon.toSVG();
      const $ = cheerio.load(octiconIconHtml);
      $('svg').attr('style', 'color: #fff');
      return $.html();
    };

    // handler function for material icons
    const handleMaterialIcon = (iconFontType: string, iconFontName: string) => {
      let materialIconsClass = 'material-icons';
      switch (iconFontType) {
      case 'mio':
        materialIconsClass += '-outlined';
        break;
      case 'mir':
        materialIconsClass += '-round';
        break;
      case 'mis':
        materialIconsClass += '-sharp';
        break;
      case 'mit':
        materialIconsClass += '-two-tone';
        break;
      default:
      // .material-icons generates 'Filled' style icons; hence, no suffix is needed for 'mif'.
      }
      // Use .align-middle by default to vertically-align the icon with its surrounding text (if any).
      // Also, replace dashes (-) with underscores (_) to format the icon name properly.
      return `<span aria-hidden="true" class="${materialIconsClass} align-middle">`
        + `${iconFontName.split('-').join('_')}</span>`;
    };

    // handler function for font awesome icons
    const handleFontAwesome = (iconFontType: string, iconFontName: string) =>
      `<span aria-hidden="true" class="${iconFontType} fa-${iconFontName}"></span>`;

    // Handler function for Bootstrap Icons
    const handleBootstrapIcon = (iconFontName: string) => `<i class="bi-${iconFontName}"></i>`;

    // function to get the respective icon html based on the icon font type
    const getIconHtml = (match: string[]) => {
      const iconFontType = match[1];
      const iconFontName = match[2];
      const iconClass = match[3];

      if (iconFontType === 'glyphicon') {
        return handleGlyphicon(iconFontName);
      } else if (iconFontType === 'octicon') {
        return handleOcticon(iconFontName, iconClass);
      } else if (iconFontType === 'octiconlight') {
        return handleOcticonLight(iconFontName, iconClass);
      } else if (iconFontType.startsWith('mi')) {
        return handleMaterialIcon(iconFontType, iconFontName);
      } else if (iconFontType === 'bi') {
        return handleBootstrapIcon(iconFontName);
      }
      return handleFontAwesome(iconFontType, iconFontName);
    };

    // function to process the icon string and get the icon html
    const processIconString = (iconStr: string) => {
      let icon = iconStr;

      if (!iconStr.startsWith(':') && !iconStr.endsWith(':')) {
        icon = `:${iconStr}:`;
      }

      const match = icon.match(ICON_REGEXP);
      return match ? getIconHtml(match) : null;
    };

    // create a markdown-it plugin to process the icon strings in the markdown
    /**
     * A Markdown-It plugin that replaces icon syntax matching `ICON_REGEXP` with corresponding HTML.
     *
     * This plugin uses a regular expression to detect icon patterns in Markdown content,
     * and transforms them into HTML using the `getIconHtml` function.
     */
    const markdownItIconsPlugin = markdownItRegExp(
      ICON_REGEXP,
      (match: string[]) => getIconHtml(match),
    );

    export { markdownItIconsPlugin, processIconString };