angular.module("sideBySide").factory("markdownReader", () -> # Read markdown poem # # For sample input, see: # source/documents/tests/services/reader/markdown.js.coffee # # @param source [String] Markdown poem # @return [Object] Poem object (source) -> # Read meta information from markdown block # # @param block [string] Meta block # @param inlineLexer [Object] Inline markdown lexer # @return [Object] Meta properties readMeta = (text, inlineLexer) -> meta = {} for line in text.split("\n") lexed = inlineLexer.output(line) match = /([^:]*):(.*)/.exec(lexed) meta[match[1].trim()] = match[2].trim() meta # Read and remove one section from start of lexed blocks # # @param lexed [Array] Lexed blocks # @return [Array] Section readSection = (lexed, separators) -> items = [] while lexed.length > 0 break if lexed[0]["type"] in separators items.push(lexed.shift()) items # Read content from lexed blocks # # @param lexed [Array] Lexed blocks # @param separators [Array] Section separators # @return [Array] Content readContent = (lexed, separators) -> content = [] while lexed.length > 0 heading = if lexed[0]["type"] in separators \ then lexed.shift().text or "" \ else "" text = readSection(lexed, separators) text.links = lexed.links content.push({ section: heading text: marked.parser(text) }) content marked.setOptions({ smartypants: true }) lexed = marked.lexer(source) meta = lexed.shift() meta = readMeta(meta.text, new marked.InlineLexer(lexed.links)) separators = if meta.Separator \ then [meta.Separator] else ['heading', 'hr'] { meta: meta content: readContent(lexed, separators) } )