use of org.rstudio.core.client.TextCursor in project rstudio by rstudio.
the class DefaultChunkOptionsPopupPanel method parseChunkHeader.
private void parseChunkHeader(String line, HashMap<String, String> chunkOptions) {
String modeId = display_.getModeId();
Pattern pattern = null;
if (modeId.equals("mode/rmarkdown"))
pattern = RegexUtil.RE_RMARKDOWN_CHUNK_BEGIN;
else if (modeId.equals("mode/sweave"))
pattern = RegexUtil.RE_SWEAVE_CHUNK_BEGIN;
else if (modeId.equals("mode/rhtml"))
pattern = RegexUtil.RE_RHTML_CHUNK_BEGIN;
if (pattern == null)
return;
Match match = pattern.match(line, 0);
if (match == null)
return;
String extracted = match.getGroup(1);
chunkPreamble_ = extractChunkPreamble(extracted, modeId);
String chunkLabel = extractChunkLabel(extracted);
if (!StringUtil.isNullOrEmpty(chunkLabel))
tbChunkLabel_.setText(extractChunkLabel(extracted));
// if we had a chunk label, then we want to navigate our cursor to
// the first comma in the chunk header; otherwise, we start at the
// first space. this is done to accept chunk headers of the form
//
// ```{r message=FALSE}
//
// ie, those with no comma after the engine used
int argsStartIdx = StringUtil.isNullOrEmpty(chunkLabel) ? extracted.indexOf(' ') : extracted.indexOf(',');
String arguments = extracted.substring(argsStartIdx + 1);
TextCursor cursor = new TextCursor(arguments);
// consume commas and whitespace if needed
cursor.consumeUntilRegex("[^\\s,]");
int startIndex = 0;
do {
if (!cursor.fwdToCharacter('=', false))
break;
int equalsIndex = cursor.getIndex();
int endIndex = arguments.length();
if (cursor.fwdToCharacter(',', true) || cursor.fwdToCharacter(' ', true)) {
endIndex = cursor.getIndex();
}
chunkOptions.put(arguments.substring(startIndex, equalsIndex).trim(), arguments.substring(equalsIndex + 1, endIndex).trim());
startIndex = cursor.getIndex() + 1;
} while (cursor.moveToNextCharacter());
}
use of org.rstudio.core.client.TextCursor in project rstudio by rstudio.
the class RMarkdownChunkHeaderParser method parse.
public static final void parse(String line, Map<String, String> options) {
// set up state
Mutable<String> key = new Mutable<String>();
Consumer keyConsumer = new MutableConsumer(key);
Mutable<String> val = new Mutable<String>();
Consumer valConsumer = new MutableConsumer(val);
line = trimBoundary(line);
TextCursor cursor = new TextCursor(line);
// force default R engine
options.put("engine", ensureQuoted("r"));
// consume engine
if (!consumeEngine(cursor, options))
return;
// consume whitespace and commas
if (!cursor.consumeUntilRegex("[^\\s,]"))
return;
// a label soon after
if (!consumeKey(cursor, keyConsumer))
return;
// found, this must have been a label
if (!cursor.consumeUntilRegex("[,=]")) {
options.put("label", ensureQuoted(key.get().trim()));
return;
}
char ch = cursor.peek();
if (ch == ',') {
// found a comma -- this must have been a label
options.put("label", ensureQuoted(key.get().trim()));
} else {
// found an '=' -- this was a key for a chunk option
if (!cursor.consume('='))
return;
// eat whitespace
if (!cursor.consumeUntilRegex("\\S"))
return;
// consume value
if (!consumeValue(cursor, valConsumer))
return;
// set option
options.put(key.get(), val.get());
// move to next comma
if (!cursor.fwdToCharacter(',', false))
return;
}
while (cursor.peek() == ',') {
// eat whitespace and commas
if (!cursor.consumeUntilRegex("[^\\s,]"))
return;
// consume key
if (!consumeKey(cursor, keyConsumer))
return;
// eat whitespace
if (!cursor.consumeUntilRegex("\\S"))
return;
// check '='
if (!cursor.consume('='))
return;
// eat whitespace
if (!cursor.consumeUntilRegex("\\S"))
return;
// consume value
if (!consumeValue(cursor, valConsumer))
return;
// update options
options.put(StringUtil.stringValue(key.get().trim()), val.get().trim());
// find next comma
if (!cursor.consumeUntil(','))
return;
}
return;
}
Aggregations