Class: PointBlank::Parsing::EmphInline

Inherits:
NullInline
  • Object
show all
Defined in:
lib/mmmd/blankshell.rb

Overview

Emphasis and strong emphasis inline parser

Constant Summary collapse

INFIX_TOKENS =
/^[^\p{S}\p{P}\p{Zs}_]_++[^\p{S}\p{P}\p{Zs}_]$/

Class Method Summary collapse

Methods inherited from NullInline

build, check_contents, check_unescaped, construct_literal, construct_text, find_unescaped, forward_walk, iterate_tokens

Class Method Details

.break_into_elements(token_inner, token, left, right, matched) ⇒ Object

Break token string into elements

Parameters:

  • token_inner (String)
  • token (String)
  • left (Boolean)
  • right (Boolean)
  • matched (Boolean)


1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
# File 'lib/mmmd/blankshell.rb', line 1390

def self.break_into_elements(token_inner, token, left, right, matched)
  return token_inner[0] unless matched

  star_token = token_inner.match?(/^\*+$/)
  infix_token = token.match(INFIX_TOKENS)
  return token_inner if !star_token && infix_token

  if left && right
    [token_inner, self, :open, :close]
  elsif left
    [token_inner, self, :open]
  elsif right
    [token_inner, self, :close]
  else
    token_inner
  end
end

.build_emph(children, strong) ⇒ ::PointBlank::DOM::DOMObject

Build strong or normal emphasis depending on the boolean flag

Parameters:

Returns:



1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
# File 'lib/mmmd/blankshell.rb', line 1452

def self.build_emph(children, strong)
  obj = if strong
          ::PointBlank::DOM::InlineStrong
        else
          ::PointBlank::DOM::InlineEmphasis
        end.new
  tokens = children.map do |child|
    child.is_a?(Array) ? child.first : child
  end
  scanner = StackScanner.new(obj, init_tokens: tokens)
  scanner.scan
  obj
end

.extract_left(bfr) ⇒ String

Extract left-flanking token from before the tokenized string

Parameters:

Returns:

  • (String)


1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
# File 'lib/mmmd/blankshell.rb', line 1336

def self.extract_left(bfr)
  case bfr
  when String
    bfr[-1]
  when ::PointBlank::DOM::DOMObject
    "."
  when Array
    bfr.first[-1]
  end
end

.extract_right(afr) ⇒ String

Extract right-flanking token from after the tokenized string

Parameters:

Returns:

  • (String)


1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
# File 'lib/mmmd/blankshell.rb', line 1350

def self.extract_right(afr)
  case afr
  when String
    afr[0]
  when ::PointBlank::DOM::DOMObject
    "."
  when Array
    afr.first[0]
  end
end

.left_token?(bfr, _token, afr) ⇒ Boolean

Is this token, given these surrounding characters, left-flanking?

Parameters:

  • bfr (String)
  • token (String)
  • afr (String)

Returns:

  • (Boolean)


1364
1365
1366
1367
1368
1369
1370
# File 'lib/mmmd/blankshell.rb', line 1364

def self.left_token?(bfr, _token, afr)
  bfr_white = bfr.match?(/[\p{Zs}\n\r]/) || bfr.empty?
  afr_white = afr.match?(/[\p{Zs}\n\r]/) || afr.empty?
  bfr_symbol = bfr.match?(/[\p{P}\p{S}]/)
  afr_symbol = afr.match?(/[\p{P}\p{S}]/)
  !afr_white && (!afr_symbol || (afr_symbol && (bfr_symbol || bfr_white)))
end

.reverse_walk(backlog, **_doc) ⇒ Object



1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
# File 'lib/mmmd/blankshell.rb', line 1409

def self.reverse_walk(backlog, **_doc)
  until backlog.last.first.empty?
    capture = []
    before = []
    closer = backlog.last
    star = closer.first.match?(/^\*+$/)
    open = true
    backlog[..-2].reverse_each do |blk|
      open = false if blk.is_a?(Array) && blk[2] == :open &&
                      blk.first.match?(/^\*+$/) == star &&
                      blk[1] == self &&
                      ((blk.first.length + closer.first.length) % 3 != 0 ||
                         ((blk.first.length % 3).zero? &&
                          (closer.first.length % 3).zero?))
      (open ? capture : before).prepend(blk)
      next unless blk.is_a?(Array) && !open

      return backlog unless closer[1].check_contents(capture)
    end
    return backlog if open

    opener = before[-1]
    strong = if closer.first.length > 1 && opener.first.length > 1
               # Strong emphasis
               closer[0] = closer.first[2..]
               opener[0] = opener.first[2..]
               true
             else
               # Emphasis
               closer[0] = closer.first[1..]
               opener[0] = opener.first[1..]
               false
             end
    before = before[..-2] if opener.first.empty?
    backlog = before + [build_emph(capture, strong)] + [closer]
  end
  backlog
end

.right_token?(bfr, _token, afr) ⇒ Boolean

Is this token, given these surrounding characters, reft-flanking?

Parameters:

  • bfr (String)
  • token (String)
  • afr (String)

Returns:

  • (Boolean)


1376
1377
1378
1379
1380
1381
1382
# File 'lib/mmmd/blankshell.rb', line 1376

def self.right_token?(bfr, _token, afr)
  bfr_white = bfr.match?(/[\p{Z}\n\r]/) || bfr.empty?
  afr_white = afr.match?(/[\p{Z}\n\r]/) || afr.empty?
  bfr_symbol = bfr.match?(/[\p{P}\p{S}]/)
  afr_symbol = afr.match?(/[\p{P}\p{S}]/)
  !bfr_white && (!bfr_symbol || (bfr_symbol && (afr_symbol || afr_white)))
end

.tokenize(string, before, after) ⇒ Object



1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
# File 'lib/mmmd/blankshell.rb', line 1319

def self.tokenize(string, before, after)
  bfrb = extract_left(before)
  afra = extract_right(after)
  iterate_tokens(string, /(?:_++|\*++)/) do |bfr, text, matched|
    token, afr = text.match(/^(_++|\*++)(.?)/)[1..2]
    bfr = bfr[-1] || bfrb || ""
    afr = afr.empty? ? afra || "" : afr
    left = left_token?(bfr, token, afr)
    right = right_token?(bfr, token, afr)
    break_into_elements(token, [bfr[-1] || "", token, afr].join(''),
                        left, right, matched)
  end
end