Cursor

A Cursor is essentially a fancy string wrapper that remembers your current position as you parse it. It contains a set of highly-optimized methods making it easy to parse characters, match regular expressions, and more.

Supported Encodings

As of now, only UTF-8 (and, by extension, ASCII) encoding is supported.

Usage

Instantiating a new Cursor is as simple as:

use League\CommonMark\Parser\Cursor;

$cursor = new Cursor('Hello World!');

Or, if you’re creating a custom block parser or inline parser, a pre-configured Cursor will be provided to you with (with the Cursor already set to the current position trying to be parsed).

Methods

You can then call any of the following methods to parse the string within that Cursor:

Method Purpose
getPosition() Returns the current position/index of the Cursor within the string
getColumn() Returns the current column (used when handling tabbed indentation)
getIndent() Returns the current amount of indentation
isIndented() Returns whether the cursor is indented to INDENT_LEVEL
getCharacter(int $index) Returns the character at the given absolute position
getCurrentCharacter() Returns the character at the current position
peek() Returns the next character without changing the current position of the cursor
peek(int $offset) Returns the character $offset chars away without changing the current position of the cursor
getNextNonSpacePosition() Returns the position of the next character which is not a space or tab
getNextNonSpaceCharacter() Returns the next character which isn’t a space (or tab)
advance() Moves the cursor forward by 1 character
advanceBy(int $characters) Moves the cursor forward by $characters characters
advanceBy(int $characters, true) Moves the cursor forward by $characters characters, handling tabs as columns
advanceBySpaceOrTab() Advances forward one character (and returns true) if it’s a space or tab; returns false otherwise
advanceToNextNonSpaceOrTab() Advances forward past all spaces and tabs found, returning the number of such characters found
advanceToNextNonSpaceOrNewline() Advances forward past all spaces and newlines found, returning the number of such characters found
advanceToEnd() Advances the position to the very end of the string, returning the number of such characters passed
match(string $regex) Attempts to match the given $regex against the remainder; returns null if matching fails, otherwise it advances past and returns the matched text
matchInPlace(string $regex) Like match(), but matches at the cursor’s position within the whole line instead of copying the remainder; see below
getPreviousText() Returns the text that was just advanced through during the last advance__() or match() operation
getRemainder() Returns the contents of the string from the current position through the end of the string
isBlank() Returns whether the remainder is blank (we’re at the end or only space characters remain)
isAtEnd() Returns whether the cursor has reached the end of the string
saveState() Encapsulates the current state of the cursor into an array in case you need to restoreState() later
restoreState($state) Pass the result of saveState() back into here to restore the original state of the Cursor
getLine() Returns the entire string (not taking the position into account)

Regular Expression Matching

The Cursor offers two ways to match a regular expression at the current position. They differ in what the pattern is matched against:

matchInPlace() has two advantages:

One exception: when the cursor has partially consumed a tab, no position within the line can represent it, so matchInPlace() falls back to matching a copy of the remainder with the leftover tab expanded into spaces. \G still anchors at the cursor there, but the text before the cursor is not visible to the pattern in that state.

To migrate a pattern from match() to matchInPlace(), replace its leading ^ (or \A) with \G, and double-check that any \b or lookbehind still means what you want now that it can see the preceding text:

$cursor->match('/^#+/');         // anchors at the cursor
$cursor->matchInPlace('/\G#+/'); // equivalent, without copying the remainder

Edit this page