Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
25 changes: 25 additions & 0 deletions action.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ public function register($controller) {
*
*/
public function handle($event, $param) {
if ($this->isSubParser()) {
return;
}

refnotes_parser_core::getInstance()->exitParsingContext($event->data);

/* We need a new instance of mangler for each event because we can trigger it recursively
Expand All @@ -68,6 +72,27 @@ public function handle($event, $param) {

$mangler->process();
}

private function isSubParser() {
if (!class_exists('dokuwiki\Parsing\ModeRegistry')) return false;

$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
foreach ($trace as $i => $frame) {
$func = $frame['function'] ?? '';
if ($func === 'withSubParser' || $func === 'acquireSubParser') {
return true;
}
$class = $frame['class'] ?? '';
if (($class === 'dokuwiki\Parsing\Parser' || $class === 'Doku_Parser') && $func === 'parse') {
$caller = $trace[$i + 1] ?? array();
$callerFunc = $caller['function'] ?? '';
if ($callerFunc !== 'p_get_instructions' && $callerFunc !== 'getInstructions') {
return true;
}
}
}
return false;
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
39 changes: 32 additions & 7 deletions bibtex.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ private function addBibtexMode($mode) {
$this->addMode($mode->getName(), $mode);
}

/**
* Override addMode to avoid DokuWiki Mort dependency injection
* which expects a DokuWiki ModeRegistry and Handler.
*/
public function addMode($name, \dokuwiki\Parsing\ParserMode\AbstractMode $Mode) {
$Mode->setLexer($this->lexer);
$this->modes[$name] = $Mode;
}

/**
*
*/
Expand Down Expand Up @@ -83,26 +92,35 @@ class refnotes_bibtex_lexer extends \dokuwiki\Parsing\Lexer\Lexer {
*/
public function parse($text) {
$lastMode = '';
// Offset tracking is required by DokuWiki Mort Lexer which doesn't slice the input string
$offset = 0;

// Reset the mode stack for DokuWiki Mort lexer
$this->modeStack = new \dokuwiki\Parsing\Lexer\StateStack('base');

while (is_array($parsed = $this->reduce($text))) {
while (is_array($parsed = $this->reduce($text, $offset))) {
list($unmatched, $matched, $mode) = $parsed;
$matchPos = $offset + strlen($unmatched);

if (!$this->dispatchTokens($unmatched, $matched, $mode, 0, 0)) {
if (!$this->dispatchTokens($unmatched, $matched, $mode, $offset, $matchPos)) {
return false;
}

$newOffset = $matchPos + strlen($matched);

if (empty($unmatched) && empty($matched) && ($lastMode == $this->modeStack->getCurrent())) {
return false;
}

$lastMode = $this->modeStack->getCurrent();
$offset = $newOffset;
}

if (!$parsed) {
return false;
}

return $this->invokeHandler($text, DOKU_LEXER_UNMATCHED, 0);
return $this->invokeHandler(substr($text, $offset), DOKU_LEXER_UNMATCHED, $offset);
}

/**
Expand Down Expand Up @@ -141,6 +159,13 @@ public function __construct() {
$this->exitPattern = array();
}

/**
* Required by AbstractMode but not used by refnotes custom parser.
*/
public function handle($match, $state, $pos, Doku_Handler $handler) {
return false;
}

/**
*
*/
Expand Down Expand Up @@ -218,7 +243,7 @@ public function __construct($type) {

list($open, $close) = ($type == 'parented') ? array('\(', '\)') : array('{', '}');

$this->entryPattern[] = '^@\w+\s*' . $open . '(?=.*' . $close . ')';
$this->entryPattern[] = '@\w+\s*' . $open . '(?=.*' . $close . ')';
$this->exitPattern[] = '\s*(?:' . $close . '|(?=@))';

$this->allowedModes = array('field');
Expand All @@ -234,7 +259,7 @@ class refnotes_bibtex_field_mode extends refnotes_bibtex_mode {
public function __construct() {
parent::__construct();

$this->entryPattern[] = '^\s*\w[\w-]+\s*=\s*';
$this->entryPattern[] = '\s*\w[\w-]+\s*=\s*';
$this->exitPattern[] = '\s*(?:,|(?=[\)}@]))';

$this->allowedModes = array('integer_value', 'string_value_quoted', 'string_value_braced', 'concatenation');
Expand All @@ -250,7 +275,7 @@ class refnotes_bibtex_integer_value_mode extends refnotes_bibtex_mode {
public function __construct() {
parent::__construct();

$this->specialPattern[] = '^\d+';
$this->specialPattern[] = '\G\d+';
}
}

Expand All @@ -268,7 +293,7 @@ public function __construct($type) {

list($open, $close, $exit) = ($type == 'quoted') ? array('"', '"', '"') : array('{', '}', '(?:}|(?=@))');

$this->entryPattern[] = '^' . $open . '(?=.*' . $close . ')';
$this->entryPattern[] = $open . '(?=.*' . $close . ')';
$this->exitPattern[] = $exit;

$this->allowedModes = array('nested_braces_' . $type);
Expand Down
28 changes: 27 additions & 1 deletion core.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,39 @@ public function enterParsingContext() {
public function exitParsingContext($handler) {
$this->handler = $handler;

unset($this->context[count($this->context) - 1]);
// Fail-safe: NEVER pop the base context, guaranteeing we always have a context to fallback to.
if (count($this->context) > 1) {
unset($this->context[count($this->context) - 1]);
}
}

/**
*
*/
public function getInstructions($text) {
if (method_exists($this->handler, 'getModeRegistry')) {
$registry = $this->handler->getModeRegistry();
$calls = $registry->withSubParser(
array(),
array(),
function ($subParser) use ($text) {
$subParser->getHandler()->reset();
$subParser->parse($text);
return $subParser->getHandler()->calls;
}
);

$filtered = array();
if (is_array($calls)) {
foreach ($calls as $call) {
if ($call[0] == 'document_start' || $call[0] == 'document_end') continue;
if ($call[0] == 'p_open' || $call[0] == 'p_close') continue;
$filtered[] = $call;
}
}
return $filtered;
}

$this->callWriter = new refnotes_nested_call_writer($this->handler->getCallWriter(), $this->handler);

$this->callWriter->connect();
Expand Down
18 changes: 16 additions & 2 deletions database.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,24 @@ private function normalizeKeyText($text) {
private function loadPages() {
global $conf;

if (file_exists($conf['indexdir'] . '/page.idx')) {
require_once(DOKU_INC . 'inc/indexer.php');
$pageIndex = array();

if (class_exists('\dokuwiki\Search\Indexer')) {
$indexer = new \dokuwiki\Search\Indexer();
if (method_exists($indexer, 'getAllPages')) {
$pageIndex = $indexer->getAllPages();
} elseif (method_exists($indexer, 'getPages')) {
$pageIndex = $indexer->getPages();
}
} elseif (file_exists($conf['indexdir'] . '/page.idx')) {
if (file_exists(DOKU_INC . 'inc/indexer.php')) {
require_once(DOKU_INC . 'inc/indexer.php');
}

$pageIndex = idx_getIndex('page', '');
}

if (!empty($pageIndex)) {
$namespace = refnotes_configuration::getSetting('reference-db-namespace');
$namespacePattern = '/^' . trim($namespace, ':') . ':/';
$cache = new refnotes_reference_database_cache();
Expand Down