book-source 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/StructuredDocument.js +79 -34
- package/lib/documentParts.js +24 -16
- package/package.json +1 -1
|
@@ -52,7 +52,7 @@ StructuredDocument.prototype.render = function( renderer ) {
|
|
|
52
52
|
title: this.title
|
|
53
53
|
} ;
|
|
54
54
|
|
|
55
|
-
var output = this.renderParts( renderer , this.parts , [] ) ;
|
|
55
|
+
var output = this.renderParts( renderer , this.parts , [] , [ {} ] ) ;
|
|
56
56
|
|
|
57
57
|
if ( renderer.document ) {
|
|
58
58
|
output = renderer.document( meta , output ) ;
|
|
@@ -98,14 +98,20 @@ FRAGMENT.structure = {
|
|
|
98
98
|
}
|
|
99
99
|
} ;
|
|
100
100
|
|
|
101
|
-
StructuredDocument.prototype.renderParts = function( renderer , parts , partStack ) {
|
|
101
|
+
StructuredDocument.prototype.renderParts = function( renderer , parts , partStack , userlandStack ) {
|
|
102
102
|
var fragment = FRAGMENT[ renderer.type || 'string' ] ,
|
|
103
103
|
output = fragment.new() ,
|
|
104
104
|
index = 0 ;
|
|
105
105
|
|
|
106
106
|
for ( let part of parts ) {
|
|
107
|
+
let preFn = 'pre_' + part.type ;
|
|
108
|
+
let postFn = part.type ;
|
|
107
109
|
let partsOutput = fragment.new() ;
|
|
108
110
|
|
|
111
|
+
if ( renderer[ preFn ] ) {
|
|
112
|
+
renderer[ preFn ]( part , partStack , userlandStack , index ) ;
|
|
113
|
+
}
|
|
114
|
+
|
|
109
115
|
if ( part.parts ) {
|
|
110
116
|
if ( renderer.group?.[ part.type ] ) {
|
|
111
117
|
// Some renderer have to group child parts an apply things to each group,
|
|
@@ -116,29 +122,38 @@ StructuredDocument.prototype.renderParts = function( renderer , parts , partStac
|
|
|
116
122
|
for ( let group of groupList ) {
|
|
117
123
|
if ( renderer.group[ part.type ][ group.type ] ) {
|
|
118
124
|
partStack.push( part ) ;
|
|
119
|
-
|
|
125
|
+
userlandStack.push( {} ) ;
|
|
126
|
+
|
|
127
|
+
let groupOutput = this.renderParts( renderer , group.parts , partStack , userlandStack ) ;
|
|
128
|
+
|
|
120
129
|
partStack.pop() ;
|
|
130
|
+
userlandStack.pop() ;
|
|
131
|
+
|
|
121
132
|
partsOutput = fragment.concat(
|
|
122
133
|
partsOutput ,
|
|
123
|
-
renderer.group[ part.type ][ group.type ]( part , groupOutput , partStack )
|
|
134
|
+
renderer.group[ part.type ][ group.type ]( part , groupOutput , partStack , userlandStack )
|
|
124
135
|
) ;
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
else {
|
|
129
140
|
partStack.push( part ) ;
|
|
141
|
+
userlandStack.push( {} ) ;
|
|
142
|
+
|
|
130
143
|
partsOutput = fragment.concat(
|
|
131
144
|
partsOutput ,
|
|
132
|
-
this.renderParts( renderer , part.parts ,
|
|
145
|
+
this.renderParts( renderer , part.parts , partStack , userlandStack )
|
|
133
146
|
) ;
|
|
147
|
+
|
|
134
148
|
partStack.pop() ;
|
|
149
|
+
userlandStack.pop() ;
|
|
135
150
|
}
|
|
136
151
|
}
|
|
137
152
|
|
|
138
|
-
if ( renderer[
|
|
153
|
+
if ( renderer[ postFn ] ) {
|
|
139
154
|
output = fragment.append(
|
|
140
155
|
output ,
|
|
141
|
-
renderer[
|
|
156
|
+
renderer[ postFn ]( part , partsOutput , partStack , userlandStack , index )
|
|
142
157
|
) ;
|
|
143
158
|
}
|
|
144
159
|
|
|
@@ -1324,8 +1339,7 @@ function parseInlineChildrenOfParent( str , ctx , parent , blockEnd , trim = fal
|
|
|
1324
1339
|
// Try to parse non-block content
|
|
1325
1340
|
function parseInline( str , ctx , blockEnd , trim = false ) {
|
|
1326
1341
|
//console.log( "parseInline() -- remaining:" , ctx.i , str.slice( ctx.i ) ) ;
|
|
1327
|
-
var isSpace , scanEnd
|
|
1328
|
-
lastWasSpace = WHITE_SPACES.has( str[ ctx.i - 1 ] ) ;
|
|
1342
|
+
var isSpace , scanEnd ;
|
|
1329
1343
|
|
|
1330
1344
|
scanEnd = blockEnd = blockEnd ?? searchEndOfLine( str , ctx.i ) ;
|
|
1331
1345
|
|
|
@@ -1344,6 +1358,19 @@ function parseInline( str , ctx , blockEnd , trim = false ) {
|
|
|
1344
1358
|
scanEnd = last + 1 ;
|
|
1345
1359
|
}
|
|
1346
1360
|
|
|
1361
|
+
parseNestedInline( str , ctx , scanEnd , true ) ;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
function parseNestedInline( str , ctx , scanEnd , topLevel = false ) {
|
|
1367
|
+
var isSpace ,
|
|
1368
|
+
lastWasSpace = WHITE_SPACES.has( str[ ctx.i - 1 ] ) ;
|
|
1369
|
+
|
|
1370
|
+
//console.log( "parseInline() -- remaining:" , ctx.i , str.slice( ctx.i ) ) ;
|
|
1371
|
+
|
|
1372
|
+
if ( ! topLevel ) { stack( ctx ) ; }
|
|
1373
|
+
|
|
1347
1374
|
ctx.iStartOfInlineChunk = ctx.i ;
|
|
1348
1375
|
|
|
1349
1376
|
for ( ; ctx.i < scanEnd ; ctx.i ++ ) {
|
|
@@ -1388,8 +1415,10 @@ function parseInline( str , ctx , blockEnd , trim = false ) {
|
|
|
1388
1415
|
|
|
1389
1416
|
addInlineTextChunk( str , ctx ) ;
|
|
1390
1417
|
|
|
1391
|
-
ctx.i =
|
|
1418
|
+
ctx.i = scanEnd ;
|
|
1392
1419
|
if ( str[ ctx.i ] === '\n' ) { ctx.i ++ ; }
|
|
1420
|
+
|
|
1421
|
+
if ( ! topLevel ) { unstack( ctx ) ; }
|
|
1393
1422
|
}
|
|
1394
1423
|
|
|
1395
1424
|
|
|
@@ -1467,44 +1496,48 @@ function parseEscape( str , ctx ) {
|
|
|
1467
1496
|
|
|
1468
1497
|
|
|
1469
1498
|
|
|
1470
|
-
function parseEmphasisText( str , ctx ,
|
|
1499
|
+
function parseEmphasisText( str , ctx , scanEnd ) {
|
|
1471
1500
|
//console.error( "parseStyledText()" ) ;
|
|
1472
1501
|
var streak = countStreak( str , ctx.i , '*' ) ;
|
|
1473
1502
|
if ( streak > 3 ) { return ; }
|
|
1474
|
-
var end = searchSwitchCloser( str , ctx.i + streak , '*' , streak , true , false ,
|
|
1503
|
+
var end = searchSwitchCloser( str , ctx.i + streak , '*' , streak , true , false , scanEnd ) ;
|
|
1475
1504
|
if ( end < 0 ) { return ; }
|
|
1476
1505
|
|
|
1477
|
-
|
|
1506
|
+
ctx.parts.push( new documentParts.EmphasisText( streak ) ) ;
|
|
1507
|
+
|
|
1508
|
+
ctx.i += streak ;
|
|
1509
|
+
parseNestedInline( str , ctx , end + 1 - streak ) ;
|
|
1478
1510
|
|
|
1479
|
-
ctx.parts.push( new documentParts.EmphasisText( text , streak ) ) ;
|
|
1480
1511
|
ctx.i = end ;
|
|
1481
1512
|
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1482
1513
|
}
|
|
1483
1514
|
|
|
1484
1515
|
|
|
1485
1516
|
|
|
1486
|
-
function parseDecoratedText( str , ctx ,
|
|
1517
|
+
function parseDecoratedText( str , ctx , scanEnd ) {
|
|
1487
1518
|
//console.error( "parseStyledText()" ) ;
|
|
1488
1519
|
var streak = countStreak( str , ctx.i , '_' ) ;
|
|
1489
1520
|
if ( streak > 2 ) { return ; }
|
|
1490
|
-
var end = searchSwitchCloser( str , ctx.i + streak , '_' , streak , true , false ,
|
|
1521
|
+
var end = searchSwitchCloser( str , ctx.i + streak , '_' , streak , true , false , scanEnd ) ;
|
|
1491
1522
|
if ( end < 0 ) { return ; }
|
|
1492
1523
|
|
|
1493
|
-
|
|
1524
|
+
ctx.parts.push( new documentParts.DecoratedText( streak ) ) ;
|
|
1525
|
+
|
|
1526
|
+
ctx.i += streak ;
|
|
1527
|
+
parseNestedInline( str , ctx , end + 1 - streak ) ;
|
|
1494
1528
|
|
|
1495
|
-
ctx.parts.push( new documentParts.DecoratedText( text , streak ) ) ;
|
|
1496
1529
|
ctx.i = end ;
|
|
1497
1530
|
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1498
1531
|
}
|
|
1499
1532
|
|
|
1500
1533
|
|
|
1501
1534
|
|
|
1502
|
-
function parseCode( str , ctx ,
|
|
1535
|
+
function parseCode( str , ctx , scanEnd ) {
|
|
1503
1536
|
//console.error( "parseStyledText()" ) ;
|
|
1504
1537
|
var streak = countStreak( str , ctx.i , '`' ) ;
|
|
1505
1538
|
// Markdown supports inline code inside two pairs of backquote, to allow backquote in code, hence streak can be 2.
|
|
1506
1539
|
if ( streak > 2 ) { return ; }
|
|
1507
|
-
var end = searchSwitchCloser( str , ctx.i + streak , '`' , streak , false , false ,
|
|
1540
|
+
var end = searchSwitchCloser( str , ctx.i + streak , '`' , streak , false , false , scanEnd ) ;
|
|
1508
1541
|
if ( end < 0 ) { return ; }
|
|
1509
1542
|
|
|
1510
1543
|
var sliceStart = ctx.i + streak ,
|
|
@@ -1526,27 +1559,39 @@ const STYLE_DATA_MARK = {
|
|
|
1526
1559
|
text: true , href: true , style: true , extra: false
|
|
1527
1560
|
} ;
|
|
1528
1561
|
|
|
1529
|
-
function parseStyledText( str , ctx ,
|
|
1562
|
+
function parseStyledText( str , ctx , scanEnd ) {
|
|
1530
1563
|
//console.error( "parseStyledText()" ) ;
|
|
1531
|
-
var end = searchCloser( str , ctx.i + 1 , '[' , ']' , false ,
|
|
1564
|
+
var end = searchCloser( str , ctx.i + 1 , '[' , ']' , false , scanEnd ) ;
|
|
1532
1565
|
if ( end < 0 ) { return ; }
|
|
1533
1566
|
|
|
1534
|
-
var text = str.slice( ctx.i + 1 , end ) ;
|
|
1567
|
+
//var text = str.slice( ctx.i + 1 , end ) ;
|
|
1535
1568
|
|
|
1569
|
+
var start = ctx.i + 1 ;
|
|
1536
1570
|
ctx.i = end ;
|
|
1537
|
-
var data = parseDataMark( str , ctx , STYLE_DATA_MARK ,
|
|
1571
|
+
var data = parseDataMark( str , ctx , STYLE_DATA_MARK , scanEnd ) ;
|
|
1538
1572
|
if ( ! data ) { return ; }
|
|
1539
1573
|
|
|
1574
|
+
var fullMarkupEnd = ctx.i ;
|
|
1575
|
+
|
|
1540
1576
|
var href = data.href?.[ 0 ] ,
|
|
1541
1577
|
style = data.style?.[ 0 ] ,
|
|
1542
1578
|
title = data.text?.[ 0 ] ;
|
|
1543
1579
|
|
|
1544
1580
|
if ( href ) {
|
|
1545
|
-
ctx.parts.push( new documentParts.Link(
|
|
1581
|
+
ctx.parts.push( new documentParts.Link( href , style , title ) ) ;
|
|
1546
1582
|
}
|
|
1547
1583
|
else if ( style || title ) {
|
|
1548
|
-
ctx.parts.push( new documentParts.StyledText(
|
|
1584
|
+
ctx.parts.push( new documentParts.StyledText( style , title ) ) ;
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
return ;
|
|
1549
1588
|
}
|
|
1589
|
+
|
|
1590
|
+
ctx.i = start ;
|
|
1591
|
+
parseNestedInline( str , ctx , end ) ;
|
|
1592
|
+
|
|
1593
|
+
ctx.i = fullMarkupEnd ;
|
|
1594
|
+
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1550
1595
|
}
|
|
1551
1596
|
|
|
1552
1597
|
|
|
@@ -1555,16 +1600,16 @@ const IMAGE_DATA_MARK = {
|
|
|
1555
1600
|
text: true , href: true , style: false , extra: false
|
|
1556
1601
|
} ;
|
|
1557
1602
|
|
|
1558
|
-
function parseImage( str , ctx ,
|
|
1603
|
+
function parseImage( str , ctx , scanEnd ) {
|
|
1559
1604
|
//console.error( "parseStyledText()" ) ;
|
|
1560
|
-
var end = searchCloser( str , ctx.i + 2 , '[' , ']' , false ,
|
|
1605
|
+
var end = searchCloser( str , ctx.i + 2 , '[' , ']' , false , scanEnd ) ;
|
|
1561
1606
|
if ( end < 0 ) { return ; }
|
|
1562
1607
|
|
|
1563
1608
|
var text = str.slice( ctx.i + 2 , end ) ;
|
|
1564
1609
|
|
|
1565
1610
|
ctx.i = end ;
|
|
1566
1611
|
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1567
|
-
var data = parseDataMark( str , ctx , IMAGE_DATA_MARK ,
|
|
1612
|
+
var data = parseDataMark( str , ctx , IMAGE_DATA_MARK , scanEnd ) ;
|
|
1568
1613
|
if ( ! data ) { return ; }
|
|
1569
1614
|
|
|
1570
1615
|
var href = data.href?.[ 0 ] ;
|
|
@@ -1579,13 +1624,13 @@ function parseImage( str , ctx , blockEnd ) {
|
|
|
1579
1624
|
|
|
1580
1625
|
|
|
1581
1626
|
|
|
1582
|
-
function parseDataMark( str , ctx , allow ,
|
|
1627
|
+
function parseDataMark( str , ctx , allow , scanEnd , forTextElement = true ) {
|
|
1583
1628
|
var end ,
|
|
1584
1629
|
data = {} ;
|
|
1585
1630
|
|
|
1586
1631
|
for ( ;; ) {
|
|
1587
1632
|
if ( str[ ctx.i + 1 ] === '[' && allow.text ) {
|
|
1588
|
-
end = searchCloser( str , ctx.i + 2 , '[' , ']' , false ,
|
|
1633
|
+
end = searchCloser( str , ctx.i + 2 , '[' , ']' , false , scanEnd ) ;
|
|
1589
1634
|
if ( end < 0 ) { return ; }
|
|
1590
1635
|
if ( ! data.text ) { data.text = [] ; }
|
|
1591
1636
|
data.text.push( str.slice( ctx.i + 2 , end ) ) ;
|
|
@@ -1593,7 +1638,7 @@ function parseDataMark( str , ctx , allow , blockEnd , forTextElement = true ) {
|
|
|
1593
1638
|
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1594
1639
|
}
|
|
1595
1640
|
else if ( str[ ctx.i + 1 ] === '(' && allow.href ) {
|
|
1596
|
-
end = searchCloser( str , ctx.i + 2 , '(' , ')' , true ,
|
|
1641
|
+
end = searchCloser( str , ctx.i + 2 , '(' , ')' , true , scanEnd ) ;
|
|
1597
1642
|
if ( end < 0 ) { return ; }
|
|
1598
1643
|
if ( ! data.href ) { data.href = [] ; }
|
|
1599
1644
|
data.href.push( str.slice( ctx.i + 2 , end ) ) ;
|
|
@@ -1601,7 +1646,7 @@ function parseDataMark( str , ctx , allow , blockEnd , forTextElement = true ) {
|
|
|
1601
1646
|
ctx.iStartOfInlineChunk = ctx.i + 1 ;
|
|
1602
1647
|
}
|
|
1603
1648
|
else if ( str[ ctx.i + 1 ] === '<' && allow.style ) {
|
|
1604
|
-
end = searchCloser( str , ctx.i + 2 , '<' , '>' , true ,
|
|
1649
|
+
end = searchCloser( str , ctx.i + 2 , '<' , '>' , true , scanEnd ) ;
|
|
1605
1650
|
if ( end < 0 ) { return ; }
|
|
1606
1651
|
if ( ! data.style ) { data.style = [] ; }
|
|
1607
1652
|
//data.style.push( str.slice( ctx.i + 2 , end ) ) ;
|
|
@@ -1613,7 +1658,7 @@ function parseDataMark( str , ctx , allow , blockEnd , forTextElement = true ) {
|
|
|
1613
1658
|
}
|
|
1614
1659
|
/*
|
|
1615
1660
|
else if ( str[ ctx.i + 1 ] === '{' && allow.extra ) {
|
|
1616
|
-
end = searchCloser( str , ctx.i + 2 , '{' , '}' , false ,
|
|
1661
|
+
end = searchCloser( str , ctx.i + 2 , '{' , '}' , false , scanEnd ) ;
|
|
1617
1662
|
if ( end < 0 ) { return ; }
|
|
1618
1663
|
if ( ! data.extra ) { data.extra = [] ; }
|
|
1619
1664
|
data.extra.push( str.slice( ctx.i + 2 , end ) ) ;
|
package/lib/documentParts.js
CHANGED
|
@@ -33,15 +33,13 @@ module.exports = documentParts ;
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
function Part() {
|
|
37
|
-
}
|
|
36
|
+
function Part() {}
|
|
38
37
|
|
|
39
38
|
documentParts.Part = Part ;
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
function InlinePart() {
|
|
44
|
-
}
|
|
42
|
+
function InlinePart() {}
|
|
45
43
|
|
|
46
44
|
InlinePart.prototype = Object.create( Part.prototype ) ;
|
|
47
45
|
InlinePart.prototype.constructor = InlinePart ;
|
|
@@ -49,6 +47,16 @@ documentParts.InlinePart = InlinePart ;
|
|
|
49
47
|
|
|
50
48
|
|
|
51
49
|
|
|
50
|
+
function InlineContainerPart() {
|
|
51
|
+
this.parts = [] ;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
InlineContainerPart.prototype = Object.create( Part.prototype ) ;
|
|
55
|
+
InlineContainerPart.prototype.constructor = InlineContainerPart ;
|
|
56
|
+
documentParts.InlineContainerPart = InlineContainerPart ;
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
52
60
|
function InlineTextPart( text ) {
|
|
53
61
|
this.text = text ;
|
|
54
62
|
}
|
|
@@ -82,26 +90,26 @@ documentParts.Text = Text ;
|
|
|
82
90
|
|
|
83
91
|
|
|
84
92
|
|
|
85
|
-
function EmphasisText(
|
|
93
|
+
function EmphasisText( level ) {
|
|
86
94
|
this.type = 'emphasisText' ;
|
|
87
95
|
this.level = level ;
|
|
88
|
-
|
|
96
|
+
InlineContainerPart.call( this ) ;
|
|
89
97
|
}
|
|
90
98
|
|
|
91
|
-
EmphasisText.prototype = Object.create(
|
|
99
|
+
EmphasisText.prototype = Object.create( InlineContainerPart.prototype ) ;
|
|
92
100
|
EmphasisText.prototype.constructor = EmphasisText ;
|
|
93
101
|
documentParts.EmphasisText = EmphasisText ;
|
|
94
102
|
|
|
95
103
|
|
|
96
104
|
|
|
97
|
-
function DecoratedText(
|
|
105
|
+
function DecoratedText( level ) {
|
|
98
106
|
this.type = 'decoratedText' ;
|
|
99
107
|
this.level = level ;
|
|
100
108
|
this.underline = true ;
|
|
101
|
-
|
|
109
|
+
InlineContainerPart.call( this ) ;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
DecoratedText.prototype = Object.create(
|
|
112
|
+
DecoratedText.prototype = Object.create( InlineContainerPart.prototype ) ;
|
|
105
113
|
DecoratedText.prototype.constructor = DecoratedText ;
|
|
106
114
|
documentParts.DecoratedText = DecoratedText ;
|
|
107
115
|
|
|
@@ -118,28 +126,28 @@ documentParts.Code = Code ;
|
|
|
118
126
|
|
|
119
127
|
|
|
120
128
|
|
|
121
|
-
function Link(
|
|
129
|
+
function Link( href , style , title ) {
|
|
122
130
|
this.type = 'link' ;
|
|
123
131
|
this.href = href ;
|
|
124
132
|
this.style = style || undefined ;
|
|
125
|
-
|
|
133
|
+
InlineContainerPart.call( this ) ;
|
|
126
134
|
this.title = title || undefined ;
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
Link.prototype = Object.create(
|
|
137
|
+
Link.prototype = Object.create( InlineContainerPart.prototype ) ;
|
|
130
138
|
Link.prototype.constructor = Link ;
|
|
131
139
|
documentParts.Link = Link ;
|
|
132
140
|
|
|
133
141
|
|
|
134
142
|
|
|
135
|
-
function StyledText(
|
|
143
|
+
function StyledText( style , title ) {
|
|
136
144
|
this.type = 'styledText' ;
|
|
137
145
|
this.style = style || undefined ;
|
|
138
|
-
|
|
146
|
+
InlineContainerPart.call( this ) ;
|
|
139
147
|
this.title = title || undefined ;
|
|
140
148
|
}
|
|
141
149
|
|
|
142
|
-
StyledText.prototype = Object.create(
|
|
150
|
+
StyledText.prototype = Object.create( InlineContainerPart.prototype ) ;
|
|
143
151
|
StyledText.prototype.constructor = StyledText ;
|
|
144
152
|
documentParts.StyledText = StyledText ;
|
|
145
153
|
|