1c4bcbc2eSAndreas Gohr<?php 2c4bcbc2eSAndreas Gohr 3c4bcbc2eSAndreas Gohrnamespace dokuwiki\Parsing\ParserMode; 4c4bcbc2eSAndreas Gohr 5c4bcbc2eSAndreas Gohruse dokuwiki\Parsing\Handler; 6c4bcbc2eSAndreas Gohr 7c4bcbc2eSAndreas Gohr/** 8c4bcbc2eSAndreas Gohr * GFM hard line break: two-or-more trailing spaces, or a single 9c4bcbc2eSAndreas Gohr * backslash, immediately before a non-final newline. 10c4bcbc2eSAndreas Gohr * 11c4bcbc2eSAndreas Gohr * Both delimiter forms land in one mode because they share semantics 12c4bcbc2eSAndreas Gohr * (emit linebreak), share the block-boundary rule (no break at the 13c4bcbc2eSAndreas Gohr * end of a paragraph or other block), and share the next-line 14c4bcbc2eSAndreas Gohr * leading-whitespace consumption (GFM strips it). Keeping all hard- 15c4bcbc2eSAndreas Gohr * break logic in one pattern is cheaper than two and matches GFM 16c4bcbc2eSAndreas Gohr * spec section 6.7 directly. 17c4bcbc2eSAndreas Gohr * 18c4bcbc2eSAndreas Gohr * Bypass inside code spans and fenced blocks falls out for free: 19c4bcbc2eSAndreas Gohr * those are whole-span PROTECTED / FORMATTING modes that capture 20d331a839SAndreas Gohr * their body in one regex match, so SUBSTITUTION patterns never see 21c4bcbc2eSAndreas Gohr * the inner text — same mechanism that exempts GfmEscape from 22c4bcbc2eSAndreas Gohr * code spans. 23c4bcbc2eSAndreas Gohr * 24*65dd2042SAndreas Gohr * Coexists with DokuWiki's Linebreak mode (also at sort 140). The two 25*65dd2042SAndreas Gohr * delimiter shapes are disjoint: GfmLinebreak takes a single `\` (or 26*65dd2042SAndreas Gohr * two+ spaces) before a non-final newline, DW Linebreak takes `\\` 27*65dd2042SAndreas Gohr * before a space, tab, or newline. 28c4bcbc2eSAndreas Gohr */ 29c4bcbc2eSAndreas Gohrclass GfmLinebreak extends AbstractMode 30c4bcbc2eSAndreas Gohr{ 31c4bcbc2eSAndreas Gohr /** @inheritdoc */ 32c4bcbc2eSAndreas Gohr public function getSort() 33c4bcbc2eSAndreas Gohr { 34c4bcbc2eSAndreas Gohr return 140; 35c4bcbc2eSAndreas Gohr } 36c4bcbc2eSAndreas Gohr 37c4bcbc2eSAndreas Gohr /** @inheritdoc */ 38c4bcbc2eSAndreas Gohr public function connectTo($mode) 39c4bcbc2eSAndreas Gohr { 40c4bcbc2eSAndreas Gohr // (?:[ ]{2,}|\\) two+ spaces OR one backslash 41c4bcbc2eSAndreas Gohr // \n the line ending 42c4bcbc2eSAndreas Gohr // (?![ \t]*(?:\n|\z)) not at a paragraph break or EOF 43c4bcbc2eSAndreas Gohr // [ \t]* swallow leading WS of the next line 44c4bcbc2eSAndreas Gohr $this->Lexer->addSpecialPattern( 45c4bcbc2eSAndreas Gohr '(?:[ ]{2,}|\\\\)\n(?![ \t]*(?:\n|\z))[ \t]*', 46c4bcbc2eSAndreas Gohr $mode, 47c4bcbc2eSAndreas Gohr 'gfm_linebreak' 48c4bcbc2eSAndreas Gohr ); 49c4bcbc2eSAndreas Gohr } 50c4bcbc2eSAndreas Gohr 51c4bcbc2eSAndreas Gohr /** @inheritdoc */ 52c4bcbc2eSAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 53c4bcbc2eSAndreas Gohr { 54c4bcbc2eSAndreas Gohr $handler->addCall('linebreak', [], $pos); 55c4bcbc2eSAndreas Gohr return true; 56c4bcbc2eSAndreas Gohr } 57c4bcbc2eSAndreas Gohr} 58