 
         @holders = {} if clearHolders
         text
+
+
+    # mark line
+    markLine: (start, end = -1) ->
+        if @line
+            end = if end < 0 then start else end
+            return '<span class="line" data-start="' + start + '" data-end="' + end + '" />'
+
+        ''
+
+    
+    # mark lines
+    markLines: (lines, start) ->
+        i = -1
+
+        if @line then lines.map (line) =>
+            i += 1
+            start = start + i
+            (@markLine start) + line
+        else lines
+
+
+    # optimize lines
+    optimizeLines: (html) ->
+        last = 0
+
+        if @line then html.replace /<span class="line" data\-start="([0-9]+)" data\-end="([0-9]+)" \/>/, (matches...) ->
+            current = parseInt matches[1]
+            if current != last
+                replace = '<span class="line" data-start="' + last + '" data-end="' + matches[2] + '" />'
+            else
+                replace = matches[0]
+
+            last = 1 + parseInt matches[2]
+            replace
+        else html
 
 
     # parse inline




    parseHr: -> '<hr>'


    parseNormal: (lines) ->

        @call 'afterOptimizeBlocks', blocks, lines


    parseCode: (lines, parts, start) ->
        [blank, lang] = parts
        lang = trim lang
        count = blank.length
