@@ -4,42 +4,79 @@ function isQuizNode(node) {
44 return ( / ^ [ ( \[ ] [ x ] [ ) \] ] / ) . test ( node . text || node ) ;
55}
66
7- function isQuiz ( nodes ) {
8- if ( nodes . length < 3 ) {
9- return false ;
10- }
7+ function isTableQuestion ( nodes ) {
8+ var block = questionBlock ( nodes ) ;
9+ return (
10+ block . length === 1 &&
11+ block [ 0 ] . type === 'table' &&
12+ _ . all ( block [ 0 ] . cells [ 0 ] . slice ( 1 ) , isQuizNode )
13+ ) ;
14+ }
1115
12- // Support having a first paragraph block
13- // before our series of questions
14- var quizNodes = nodes . slice ( nodes [ 0 ] . type === 'paragraph' ? 1 : 0 ) ;
16+ function isListQuestion ( nodes ) {
17+ var block = questionBlock ( nodes ) ;
18+ // Counter of when we go in and out of lists
19+ var inlist = 0 ;
20+ // Number of lists we found
21+ var lists = 0 ;
22+ // Elements found outside a list
23+ var outsiders = 0 ;
24+ // Ensure that we have nothing except lists
25+ _ . each ( block , function ( node ) {
26+ if ( node . type === 'list_start' ) {
27+ inlist ++ ;
28+ } else if ( node . type === 'list_end' ) {
29+ inlist -- ;
30+ lists ++ ;
31+ } else if ( inlist === 0 ) {
32+ // Found non list_start or list_end whilst outside a list
33+ outsiders ++ ;
34+ }
35+ } ) ;
36+ return lists > 0 && outsiders === 0 ;
37+ }
1538
16- // No questions
17- if ( ! _ . some ( quizNodes , { type : 'blockquote_start' } ) ) {
18- return false ;
19- }
39+ function isQuestion ( nodes ) {
40+ return isListQuestion ( nodes ) || isTableQuestion ( nodes ) ;
41+ }
2042
21- // Check if section has list of questions
22- // or table of questions
23- var listIdx = _ . findIndex ( quizNodes , { type : 'list_item_start' } ) ;
24- var tableIdx = _ . findIndex ( quizNodes , { type : 'table' } ) ;
25-
26-
27- if (
28- // List of questions
29- listIdx !== - 1 && isQuizNode ( quizNodes [ listIdx + 1 ] ) ||
30-
31- // Table of questions
32- (
33- tableIdx !== - 1 &&
34- // Last entry
35- tableIdx === nodes . length - 1 &&
36- _ . every ( quizNodes [ tableIdx ] . cells [ 0 ] . slice ( 1 ) , isQuizNode )
37- )
38- ) {
39- return true ;
43+ // Remove (optional) paragraph header node and blockquote
44+ function questionBlock ( nodes ) {
45+ return nodes . slice (
46+ nodes [ 0 ] . type === 'paragraph' ? 1 : 0 ,
47+ _ . findIndex ( nodes , { type : 'blockquote_start' } )
48+ ) ;
49+ }
50+
51+ function splitQuestions ( nodes ) {
52+ // Represents nodes in current question
53+ var buffer = [ ] ;
54+ return _ . reduce ( nodes , function ( accu , node ) {
55+ // Add node to buffer
56+ buffer . push ( node ) ;
57+
58+ // Flush buffer once we hit the end of a question
59+ if ( node . type === 'blockquote_end' ) {
60+ accu . push ( buffer ) ;
61+ // Clear buffer
62+ buffer = [ ] ;
63+ }
64+
65+ return accu ;
66+ } , [ ] ) ;
67+ }
68+
69+ function isQuiz ( nodes ) {
70+ // Extract potential questions
71+ var questions = splitQuestions ( nodes ) ;
72+
73+ // Nothing that looks like questions
74+ if ( questions . length === 0 ) {
75+ return false ;
4076 }
4177
42- return false ;
78+ // Ensure all questions are correctly structured
79+ return _ . all ( questions , isQuestion ) ;
4380}
4481
4582module . exports = isQuiz ;
0 commit comments