tc39 / proposal-string-dedent

TC39 Proposal to remove common leading indentation from multiline template strings
https://tc39.es/proposal-string-dedent/
MIT License
625 stars 17 forks source link

Use case: Regexp with commenting #4

Open jridgewell opened 4 years ago

jridgewell commented 4 years ago

Depends on us adding (?# comment ) syntax, but we could finally have a decent way to document regexes:

const re = String.dedent(({ raw } => {
  // Obviously a bit more complicated
  return raw.map(r => r.replace(/\n/g, '')).join('');
});

const regex = RegExp(re`
  complicated_regex(?# comments )
  more complicatedregex(?# describing this line)
  \n(?# and newline escapes will just work! )
`, 'g');

The current way requires either string concatting or array joining, eg https://github.com/ampproject/error-tracker/blob/bcaf006cc73a3aac4ab2d66511e5a18644635894/utils/stacktrace/unminify.js#L30-L44. And, you have to remember to double escape everything, which is a pain. Being able to write in "regex" mode and have it represented properly would be very nice.

thetiby commented 4 years ago

Interesting. Here's a hacky way to do it at this time:

const cdnJsRegex = new RegExp(String.raw`${''/* 
    Require the CDN URL origin at the beginning. 
  */}^(https://cdn\.ampproject\.org)${''/* 
    Allow, but don't require, RTV. 
  */}(?:/rtv/(\d{2}\d{13,}))?${''/* 
    Require text "/v" followed by digits 
  */}(/(?:amp4ads-v|v)\d+${''/* 
    Allow, but don't require, an extension under the v0 directory. 
  */}(?:/(.+?))?)${''/*
    Allow, but don't require, "-module" and "-nomodule". 
  */}(-(?:module|nomodule))?${''/*
    Require ".js" or ".mjs" extension, optionally followed by ".br". 
  */}(\.(m)?js)(\.br)?$${''/*
*/}`);

Alternatively, here's the original version, "enhanced":

// [...]

function _(templateString) { return String.raw(templateString).trim() } // for hoisting reasons


Just for reference, here's the actual original, in case the link dies:
```js
const cdnJsRegex = new RegExp(
  // Require the CDN URL origin at the beginning.
  '^(https://cdn\\.ampproject\\.org)' +
  // Allow, but don't require, RTV.
  '(?:/rtv/(\\d{2}\\d{13,}))?' +
  // Require text "/v" followed by digits
  '(/(?:amp4ads-v|v)\\d+' +
  // Allow, but don't require, an extension under the v0 directory.
  '(?:/(.+?))?)' +
  // Allow, but don't require, "-module" and "-nomodule".
  '(-(?:module|nomodule))?' +
  // Require ".js" or ".mjs" extension, optionally followed by ".br".
  '(\\.(m)?js)(\\.br)?$'
);
tophf commented 2 years ago

Reminds me of babel-plugin-transform-modern-regexp syntax:

re`/

  # A regular expression for date.

  (?<year>\d{4})-    # year part of a date
  (?<month>\d{2})-   # month part of a date
  (?<day>\d{2})      # day part of a date

/x`;