@@ -24,20 +24,54 @@ def render(context)
2424 Pygments . highlight ( code , :lexer => @lang )
2525 end
2626
27- # Select lines according to labels in code. Currently we use "begin code" and "end code" as
28- # labels.
27+ # Trim the code block so as to have the same indention, regardless of their positions in the
28+ # code file.
29+ def trim_codeblock ( lines )
30+ # Select the minimum indention of the current code block.
31+ min_start_spaces = lines
32+ . select { |l | l . strip . size !=0 }
33+ . map { |l | l [ /\A */ ] . size }
34+ . min
35+
36+ lines . map { |l | l [ min_start_spaces .. -1 ] }
37+ end
38+
39+ # Select lines according to labels in code. Currently we use "$example on$" and "$example off$"
40+ # as labels. Note that code blocks identified by the labels should not overlap.
2941 def select_lines ( code )
3042 lines = code . each_line . to_a
31- start = lines . each_with_index . select { |l , i | l . include? "$example on$" } . last . last
32- endline = lines . each_with_index . select { |l , i | l . include? "$example off$" } . last . last
33- length = lines . count
34-
35- if start > 0 or endline < length - 1
36- raise "Wrong positions of begin and end tags." if start > endline
37- range = Range . new ( start , endline )
38- code = lines [ range ] . join
43+
44+ # Select the array of start labels from code.
45+ startIndices = lines
46+ . each_with_index
47+ . select { |l , i | l . include? "$example on$" }
48+ . map { |l , i | i }
49+
50+ # Select the array of end labels from code.
51+ endIndices = lines
52+ . each_with_index
53+ . select { |l , i | l . include? "$example off$" }
54+ . map { |l , i | i }
55+
56+ raise "Start indices amount is not equal to end indices amount, please check the code." \
57+ unless startIndices . size == endIndices . size
58+
59+ raise "No code is selected by include_example, please check the code." \
60+ if startIndices . size == 0
61+
62+ # Select and join code blocks together, with a space line between each of two continuous
63+ # blocks.
64+ lastIndex = -1
65+ result = ""
66+ startIndices . zip ( endIndices ) . each do |start , endline |
67+ raise "Overlapping between two example code blocks are not allowed." if start <= lastIndex
68+ raise "$example on$ should not be in the same line with $example off$." if start == endline
69+ lastIndex = endline
70+ range = Range . new ( start + 1 , endline - 1 )
71+ result += trim_codeblock ( lines [ range ] ) . join
72+ result += "\n "
3973 end
40- code
74+ result
4175 end
4276 end
4377end
0 commit comments