Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a globalPrevCapture that persists into nested parses #66

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ and parsing. The most common field on `state` is `inline`, which all of
the default rules set to true when we are in an inline scope, and false
or undefined when we are in a block scope.

`lookbehind` is the string previously captured at this parsing level, to
**DEPRECATED - use `state.prevCapture` instead.** `lookbehind` is the string previously captured at this parsing level, to
allow for lookbehind. For example, lists check that lookbehind ends with
`/^$|\n *$/` to ensure that lists only match at the beginning of a new
line.
Expand Down
27 changes: 15 additions & 12 deletions simple-markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type ReactElements = React$Node;
type MatchFunction = (
source: string,
state: State,
prevCapture: string
prevCapture: string,
) => ?Capture;

type Parser = (
Expand Down Expand Up @@ -338,11 +338,6 @@ var parserFor = function(rules /*: ParserRules */, defaultState /*: ?State */) {
var result = [];
state = state || latestState;
latestState = state;
// We store the previous capture so that match functions can
// use some limited amount of lookbehind. Lists use this to
// ensure they don't match arbitrary '- ' or '* ' in inline
// text (see the list rule for more information).
var prevCapture = "";
while (source) {
// store the best match, it's rule, and quality:
var ruleType = null;
Expand All @@ -357,13 +352,14 @@ var parserFor = function(rules /*: ParserRules */, defaultState /*: ?State */) {

do {
var currOrder = currRule.order;
var currCapture = currRule.match(source, state, prevCapture);
var prevCaptureStr = state.prevCapture === null ? "" : state.prevCapture[0];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to maintain the legacy behavior here we could add an || i === 0 to the condition, which would reset it at the beginning of each nesting like it used to.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I think I'll do that so we don't break any legacy code, but will encourage state.prevCapture in the future.

var currCapture = currRule.match(source, state, prevCaptureStr);

if (currCapture) {
var currQuality = currRule.quality ? currRule.quality(
currCapture,
state,
prevCapture
prevCaptureStr
) : 0;
// This should always be true the first time because
// the initial quality is NaN (that's why there's the
Expand Down Expand Up @@ -442,8 +438,8 @@ var parserFor = function(rules /*: ParserRules */, defaultState /*: ?State */) {
result.push(parsed);
}

prevCapture = capture[0];
source = source.substring(prevCapture.length);
state.prevCapture = capture;
source = source.substring(state.prevCapture[0].length);
}
return result;
};
Expand All @@ -453,6 +449,12 @@ var parserFor = function(rules /*: ParserRules */, defaultState /*: ?State */) {
if (!latestState.inline && !latestState.disableAutoBlockNewlines) {
source = source + "\n\n";
}
// We store the previous capture so that match functions can
// use some limited amount of lookbehind. Lists use this to
// ensure they don't match arbitrary '- ' or '* ' in inline
// text (see the list rule for more information). This stores
// the full regex capture object, if there is one.
latestState.prevCapture = null;
return nestedParse(preprocess(source), latestState);
};
return outerParse;
Expand Down Expand Up @@ -971,7 +973,7 @@ var defaultRules /* : DefaultRules */ = {
},
list: {
order: currOrder++,
match: function(source, state, prevCapture) {
match: function(source, state) {
// We only want to break into a list if we are at the start of a
// line. This is to avoid parsing "hi * there" with "* there"
// becoming a part of a list.
Expand All @@ -980,7 +982,8 @@ var defaultRules /* : DefaultRules */ = {
// lists can be inline, because they might be inside another list,
// in which case we can parse with inline scope, but need to allow
// nested lists inside this inline scope.
var isStartOfLineCapture = LIST_LOOKBEHIND_R.exec(prevCapture);
var prevCaptureStr = state.prevCapture === null ? "" : state.prevCapture[0];
var isStartOfLineCapture = LIST_LOOKBEHIND_R.exec(prevCaptureStr);
var isListBlock = state._list || !state.inline;

if (isStartOfLineCapture && isListBlock) {
Expand Down
Loading