R/minifyHTML.R

#' HTML Minifier
#'
#' This function takes a text string as input and minifies it according to large number of options.
#' The [blog post](http://perfectionkills.com/experimenting-with-html-minifier/) provides a fuller
#' descriptions of the options.
#' @importFrom V8 JS
#' @param input String
#' @param caseSensitive Treat attributes in case sensitive manner (useful for custom HTML tags)
#' @param collapseBooleanAttributes  [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes)
#' @param collapseInlineTagWhitespace  Don't leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=TRUE`
#' @param collapseWhitespace [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace)
#' @param conservativeCollapse Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true`
#' @param continueOnParseError [Handle parse errors](https://html.spec.whatwg.org/multipage/parsing.html#parse-errors) instead of aborting.
#' @param customAttrAssign Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`)
#' @param customAttrCollapse  Regex that specifies custom attribute to strip newlines from (e.g. `/ng-class/`)
#' @param customAttrSurround Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`)
#' @param customEventAttributes Arrays of regex'es that allow to support custom event attributes for `minifyJS` (e.g. `ng-click`)
#' @param decodeEntities Use direct Unicode characters whenever possible
#' @param html5 Parse input according to HTML5 specifications
#' @param ignoreCustomComments Array of regex'es that allow to ignore certain comments, when matched
#' @param ignoreCustomFragments Array of regex'es that allow to ignore certain fragments, when matched (e.g. `<?php ... ?>`, `{{ ... }}`, etc.)
#' @param includeAutoGeneratedTags Insert tags generated by HTML parser
#' @param keepClosingSlash Keep the trailing slash on singleton elements
#' @param maxLineLength Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points
#' @param minifyCSS Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css))
#' @param minifyJS Minify JavaScript in script elements and event attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2))
#' @param minifyURLs Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl))
#' @param preserveLineBreaks Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break. Must be used in conjunction with `collapseWhitespace=true`
#' @param preventAttributesEscaping Prevents the escaping of the values of attributes
#' @param processConditionalComments Process contents of conditional comments through minifier
#' @param processScripts Array of strings corresponding to types of script elements to process through minifier (e.g. `text/ng-template`, `text/x-handlebars-template`, etc.)
#' @param quoteCharacter Type of quote to use for attribute values (' or ")
#' @param removeAttributeQuotes [Remove quotes around attributes when possible](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes)
#' @param removeComments [Strip HTML comments](http://perfectionkills.com/experimenting-with-html-minifier/#remove_comments)
#' @param removeEmptyAttributes [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes)
#' @param removeEmptyElements [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements)
#' @param removeOptionalTags [Remove optional tags](http://perfectionkills.com/experimenting-with-html-minifier/#remove_optional_tags)
#' @param removeRedundantAttributes [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes)
#' @param removeScriptTypeAttributes Remove `type="text/javascript"` from `script` tags. Other `type` attribute values are left intact
#' @param removeStyleLinkTypeAttributes Remove `type="text/css"` from `style` and `link` tags. Other `type` attribute values are left intact
#' @param removeTagWhitespace Remove space between attributes whenever possible. **Note that this will result in invalid HTML!**
#' @param sortAttributes [Sort attributes by frequency](#sorting-attributes--style-classes)
#' @param sortClassName [Sort style classes by frequency](#sorting-attributes--style-classes)
#' @param trimCustomFragments Trim white space around `ignoreCustomFragments`.
#' @param useShortDoctype [Replaces the `doctype` with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype)
#' @seealso [html-minifer](https://github.com/kangax/html-minifier) github page
#' @examples
#' input = "<!-- foo --><div>baz</div><!-- bar\n\n moo -->"
#' minifyHTML(input)
#' @export
minifyHTML = function(input,
                  caseSensitive = FALSE,
                  collapseBooleanAttributes = TRUE,
                  collapseInlineTagWhitespace = FALSE,
                  collapseWhitespace = TRUE,
                  conservativeCollapse = FALSE,
                  continueOnParseError = FALSE,
                  customAttrAssign = "[]",
                  customAttrCollapse = NULL,
                  customAttrSurround = "[]",
                  customEventAttributes = "[ /^on[a-z]{3,}$/ ]",
                  decodeEntities = TRUE,
                  html5 = TRUE,
                  ignoreCustomComments = "[ /^!/ ]",
                  ignoreCustomFragments = "[ /<%[\\s\\S]*?%>/, /<\\?[,\\s\\S]*?\\?>/ ]",
                  includeAutoGeneratedTags = TRUE,
                  keepClosingSlash = FALSE,
                  maxLineLength = NULL,
                  minifyCSS = TRUE,
                  minifyJS = TRUE,
                  minifyURLs = FALSE,
                  preserveLineBreaks = FALSE,
                  preventAttributesEscaping = FALSE,
                  processConditionalComments = TRUE,
                  processScripts = "[]",
                  quoteCharacter = NULL,
                  removeAttributeQuotes = FALSE,
                  removeComments = TRUE,
                  removeEmptyAttributes = TRUE,
                  removeEmptyElements	= FALSE,
                  removeOptionalTags = FALSE,
                  removeRedundantAttributes = FALSE,
                  removeScriptTypeAttributes = FALSE,
                  removeStyleLinkTypeAttributes = FALSE,
                  removeTagWhitespace = FALSE,
                  sortAttributes = TRUE,
                  sortClassName = TRUE,
                  trimCustomFragments	=TRUE,
                  useShortDoctype = TRUE) {

  ## Drop function name and input
  r_args = as.list(environment())[-1]

  if (!is.null(quoteCharacter)) {
    warning("quoteCharacter not supported")
  }
  r_args["quoteCharacter"] = NULL

  if (is.null(maxLineLength)) {
    r_args["maxLineLength"] = NULL
  } else {
    r_args["maxLineLength"] = as.numeric(maxLineLength)
  }

  if (is.null(customAttrCollapse)) {
    r_args["customAttrCollapse"] = NULL
  }

  ## Rename TRUE to true
  r_args = lapply(r_args, function(arg) {
    if (!is.logical(arg)) return(arg)
    if (arg) "true" else "false"
  })

  js_args = ""
  if (length(args) > 0L) {
    js_args = paste0(names(r_args), ": ", r_args, collapse = ", ")
  }
  js_args = paste0("{", js_args, "}", collapse = " ")
  ctx$call("require('html-minifier').minify", input, V8::JS(js_args))
}
csgillespie/minifyHTML documentation built on June 10, 2019, 10 a.m.