-
-
Notifications
You must be signed in to change notification settings - Fork 199
Writing a Code Generator
Firas Dib edited this page Jun 25, 2017
·
4 revisions
Your code generator file is just a simple react component. An example can be found below.
Please note that your code generator must handle all the possible cases:
- Non-global match
- Global match
- Non-global substitution
- Global substitution
-
x
-mode (this is when a regex can span multiple lines)
You can experiment with the existing flavors to ensure that yours fulfills all cases.
There are a few helper utils you can use:
-
escapeString
: Takes a string and any arbitrary amount of characters and escapes them in the subject string. Example:escapeString('foo "bar" baz', '"', 'a')
->foo \"b\ar\" b\az
;
The code doesn't have to be perfect, I'd be happy to help you as long as you can get it started yourself.
class MyNewLanguage extends PureComponent {
//
// Proptypes
static propTypes = {
regex: PropTypes.string.isRequired,
flags: PropTypes.string.isRequired,
delimiter: PropTypes.string.isRequired,
testString: PropTypes.string.isRequired,
isSubstituting: PropTypes.bool.isRequired,
isGlobal: PropTypes.bool.isRequired,
substString: PropTypes.string
};
//
// Control
// If you need to manipulate any data, you should preferably do it in a function defined
// on the class body here. This could for example be sanitizing data (escaping quotes, etc).
//
// Render functions
render() {
return (
<Highlight lang="myNewLanguage">
{this._renderCode()}
</Highlight>
);
}
_renderCode() {
const { regex, flags, delimiter, testString, isSubstituting, substString, isGlobal } = this.props;
const codeString = new CodeString();
// CodeString is a basic class that allows you to create a code snippet without having
// to worry about indentation or newlines.
// The only functions are `append`, `indent` and `toString`.
// The implementation can be found on this page.
// Create your code string here
codeString.append(`Use string literals when ${regex} interpolating ${flags} data`);
return codeString.toString();
}
}
export default MyNewLangauge;
class CodeString {
constructor(string = '') {
this.string = string;
this.indentLevel = 0;
}
indent(str, space = 0) {
return ' '.repeat(space) + str;
}
append(str = '', indentLevel) {
this.string += this.indent(`${str}\n`, this.indentLevel);
// If `indentLevel` is defined, it will be set until changed later.
if (indentLevel != null) {
this.indentLevel = indentLevel;
}
}
toString() {
return this.string;
}
}
export default CodeString;
class PHP extends PureComponent {
//
// Proptypes
static propTypes = {
regex: PropTypes.string.isRequired,
flags: PropTypes.string.isRequired,
delimiter: PropTypes.string.isRequired,
testString: PropTypes.string.isRequired,
isSubstituting: PropTypes.bool.isRequired,
isGlobal: PropTypes.bool.isRequired,
substString: PropTypes.string
};
//
// Control
_escapePHPRegex(regex, delimiter) {
let escapedRegex = '';
for (let i = 0, len = regex.length; i < len; i++) {
switch (regex.charAt(i)) {
case '\\':
if (regex.charAt(i + 1) === '\\') {
escapedRegex += '\\\\\\\\';
} else {
escapedRegex += '\\' + regex.charAt(i + 1);
}
i++;
break;
case '\'':
escapedRegex += '\\\'';
break;
default:
escapedRegex += regex.charAt(i);
}
}
return escapedRegex;
}
//
// Render functions
render() {
return (
<Highlight lang="php">
{this._renderCode()}
</Highlight>
);
}
_renderCode() {
const { regex, flags, delimiter, testString, isSubstituting, substString, isGlobal } = this.props;
const codeString = new CodeString();
const subflags = flags.replace('g', '');
codeString.append(`$re = '${delimiter}${this._escapePHPRegex(regex)}${delimiter}${subflags}';`);
codeString.append(`$str = '${escapeString(testString, '\'', '\\')}';`);
if (isSubstituting) {
codeString.append(`$subst = '${escapeString(substString, '\'', '\\')}';`);
codeString.append('');
codeString.append('$result = preg_replace($re, $subst, $str' + (!isGlobal ? ', 1' : '') + ');');
codeString.append('');
codeString.append('echo "The result of the substitution is ".$result;');
} else {
codeString.append('');
if (isGlobal) {
codeString.append('preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);');
} else {
codeString.append('preg_match($re, $str, $matches, PREG_OFFSET_CAPTURE, 0);');
}
codeString.append('');
codeString.append('// Print the entire match result');
codeString.append('var_dump($matches);');
}
return codeString.toString();
}
}
export default PHP;