Skip to content

Commit

Permalink
Move toRegExp to index.js
Browse files Browse the repository at this point in the history
  • Loading branch information
slevithan committed Oct 25, 2024
1 parent 1823317 commit dea1102
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 44 deletions.
10 changes: 5 additions & 5 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ function showOutput(el) {
outputEl.classList.remove('error');
let output = '';
try {
// Don't actually run `toRegExp` in case the selected `target` includes features that don't
// work in the user's browser
// Use `compile` but display output as if `toRegExp` was called. This avoids erroring when the
// selected `target` includes features that don't work in the user's browser
const re = compile(input, flags, {
allowBestEffort: optionAllowBestEffortValue,
maxRecursionDepth: optionMaxRecursionDepthValue === '' ? null : +optionMaxRecursionDepthValue,
optimize: optionOptimizeValue,
target: optionTargetValue,
});
output = `/${regexize(re.pattern)}/${re.flags}`;
output = `/${getRegExpLiteralPattern(re.pattern)}/${re.flags}`;
} catch (e) {
outputEl.classList.add('error');
output = `Error: ${e.message}`;
Expand All @@ -47,8 +47,8 @@ function escapeHtml(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;');
}

function regexize(str) {
return str === '' ? '(?:)' : str.replace(/\\?./gsu, m => m === '/' ? '\\/' : m);
function getRegExpLiteralPattern(str) {
return str ? str.replace(/\\?./gsu, m => m === '/' ? '\\/' : m) : '(?:)';
}

function setFlagI(checked) {
Expand Down
2 changes: 1 addition & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h1>
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c2/GitHub_Invertocat_Logo.svg" width="25" height="25" alt="GitHub">
</a>
</h1>
<p>This is a basic REPL for testing the output of <a href="https://github.com/slevithan/oniguruma-to-es">Oniguruma-To-ES</a>, an <a href="https://github.com/kkos/oniguruma">Oniguruma</a> to JavaScript RegExp transpiler.</p>
<p>This is a basic REPL for testing the output of <a href="https://github.com/slevithan/oniguruma-to-es">Oniguruma-To-ES</a>, an Oniguruma to JavaScript RegExp transpiler. See <a href="https://github.com/kkos/oniguruma/blob/master/doc/RE">Oniguruma syntax</a>.</p>

<h2>Try it</h2>
<p><textarea id="input" spellcheck="false" oninput="showOutput(this); autoGrow(this)"></textarea></p>
Expand Down
26 changes: 13 additions & 13 deletions dist/index.min.js

Large diffs are not rendered by default.

19 changes: 4 additions & 15 deletions src/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {EsVersion, Target} from './utils.js';
}} CompileOptions
*/
/**
Transpiles a regex pattern and flags from Oniguruma to native JS.
Transpiles an Oniguruma regex pattern and flags to native JS.
@param {string} pattern Oniguruma regex pattern.
@param {import('./tokenize.js').OnigurumaFlags} [flags] Oniguruma flags. Flag m is equivalent to JS's flag s.
@param {CompileOptions} [options]
Expand All @@ -27,7 +27,9 @@ Transpiles a regex pattern and flags from Oniguruma to native JS.
function compile(pattern, flags, options) {
const opts = getOptions(options);
const tokenized = tokenize(pattern, flags);
const onigurumaAst = parse(tokenized, {optimize: opts.optimize});
const onigurumaAst = parse(tokenized, {
optimize: opts.optimize,
});
const regexAst = transform(onigurumaAst, {
allowBestEffort: opts.allowBestEffort,
bestEffortTarget: opts.target,
Expand Down Expand Up @@ -66,20 +68,7 @@ function getOptions(options) {
};
}

/**
Transpiles a regex pattern and flags from Oniguruma to a native JS RegExp.
@param {string} pattern Oniguruma regex pattern.
@param {import('./tokenize.js').OnigurumaFlags} [flags] Oniguruma flags. Flag m is equivalent to JS's flag s.
@param {CompileOptions} [options]
@returns {RegExp}
*/
function toRegExp(pattern, flags, options) {
const result = compile(pattern, flags, options);
return new RegExp(result.pattern, result.flags);
}

export {
compile,
getOptions,
toRegExp,
};
31 changes: 21 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import {transform} from './transform.js';
import {compile, toRegExp} from './compile.js';
import {compile} from './compile.js';
import {parse} from './parse.js';
import {tokenize} from './tokenize.js';

// The transformation and error checking for Oniguruma's unique syntax and behavior differences
// compared to native JS RegExp is layered into all steps of the compilation process:
// 1. Tokenizer: Understands Oniguruma syntax (many large and small differences from JS).
// 1. Tokenizer: Understands Oniguruma syntax, with many large and small differences from JS.
// 2. Parser: Builds an Oniguruma AST from the tokens with understanding of Oniguruma differences.
// 3. Transformer: Converts the Oniguruma AST to a `regex` AST that preserves all Oniguruma
// behavior. This is true even in cases of non-JS features that are supported by both `regex`
// and Oniguruma but with subtly different behavior (subroutines, flag x).
// 4. Generator: Converts the `regex` AST to a `regex` pattern.
// 5. `regex`: Components of the `regex` libray are used to transpile several remaining features
// that aren't native to JS RegExp (atomic groups, possessive quantifiers, recursion). `regex`
// uses a strict superset of JS RegExp syntax, so using it this way allows this library to
// benefit from not reinventing the wheel for features that `regex` already knows how to
// transpile to JS.
// behavior. This is true even in cases of non-native-JS features that are supported by both
// `regex` and Oniguruma but with subtly different behavior in each (subroutines, flag x).
// 4. Generator: Converts the `regex` AST to a `regex` pattern, flags, and options.
// 5. Compiler: Components of the `regex` libray are used to transpile several remaining features
// that aren't native to JS (atomic groups, possessive quantifiers, recursion). `regex` uses a
// strict superset of JS RegExp syntax, so using it allows this library to benefit from not
// reinventing the wheel for complex features that `regex` already knows how to transpile to JS.

/**
Generates an Oniguruma AST from an Oniguruma pattern and flags.
Expand All @@ -37,6 +36,18 @@ function toRegexAst(pattern, flags) {
return transform(toOnigurumaAst(pattern, flags));
}

/**
Transpiles an Oniguruma regex pattern and flags to a native JS RegExp.
@param {string} pattern Oniguruma regex pattern.
@param {import('./tokenize.js').OnigurumaFlags} [flags] Oniguruma flags. Flag m is equivalent to JS's flag s.
@param {CompileOptions} [options]
@returns {RegExp}
*/
function toRegExp(pattern, flags, options) {
const result = compile(pattern, flags, options);
return new RegExp(result.pattern, result.flags);
}

export {
compile,
toOnigurumaAst,
Expand Down

0 comments on commit dea1102

Please sign in to comment.