diff --git a/src/reader/markdown.jl b/src/reader/markdown.jl index 6a462b3..acdd13c 100644 --- a/src/reader/markdown.jl +++ b/src/reader/markdown.jl @@ -49,29 +49,24 @@ end function parse_markdown_body(document_body, code_start, code_end, offset) lines = split(document_body, '\n') - state = "doc" - - docno = 1 - codeno = 1 + state = :doc + doc_no = 0 + code_no = 0 content = "" start_line = offset options = Dict() - optionString = "" + option_string = "" chunks = WeaveChunk[] - for (lineno, line) in enumerate(lines) + for (line_no, line) in enumerate(lines) m = match(code_start, line) - if !isnothing(m) && state == "doc" - state = "code" - if m.captures[1] == nothing - optionString = "" - else - optionString = strip(m.captures[1]) - end + if !isnothing(m) && state === :doc + state = :code + option_string = isnothing(m[:options]) ? "" : strip(m[:options]) options = Dict{Symbol,Any}() - if length(optionString) > 0 - expr = Meta.parse(optionString) + if !isempty(option_string) + expr = Meta.parse(option_string) Base.Meta.isexpr(expr, :(=)) && (options[expr.args[1]] = expr.args[2]) Base.Meta.isexpr(expr, :toplevel) && map(pushopt, fill(options, length(expr.args)), expr.args) @@ -79,42 +74,27 @@ function parse_markdown_body(document_body, code_start, code_end, offset) haskey(options, :label) && (options[:name] = options[:label]) haskey(options, :name) || (options[:name] = nothing) - if !isempty(strip(content)) - chunk = DocChunk(content, docno, start_line) - docno += 1 - push!(chunks, chunk) - end + isempty(strip(content)) || push!(chunks, DocChunk(content, doc_no += 1, start_line)) + start_line = line_no + offset content = "" - start_line = lineno + offset - continue end - if occursin(code_end, line) && state == "code" - chunk = CodeChunk(content, codeno, start_line, optionString, options) + if occursin(code_end, line) && state === :code + push!(chunks, CodeChunk(content, code_no += 1, start_line, option_string, options)) - codeno += 1 - start_line = lineno + offset + start_line = line_no + offset content = "" - state = "doc" - push!(chunks, chunk) + state = :doc continue end - if lineno == 1 - content *= line - else - content *= "\n" * line - end + content *= isone(line_no) ? line : string('\n', line) end # Remember the last chunk - if strip(content) != "" - chunk = DocChunk(content, docno, start_line) - # chunk = Dict{Symbol,Any}(:type => "doc", :content => content, - # :number => docno, :start_line => start_line) - push!(chunks, chunk) - end + isempty(strip(content)) || push!(chunks, DocChunk(content, doc_no += 1, start_line)) + return chunks end diff --git a/src/reader/notebook.jl b/src/reader/notebook.jl index 9d5bbbc..5c4dd5e 100644 --- a/src/reader/notebook.jl +++ b/src/reader/notebook.jl @@ -1,22 +1,21 @@ +using JSON + + function parse_notebook(document_body) nb = JSON.parse(document_body) - chunks = WeaveChunk[] + code_no = 0 + doc_no = 0 + + # TODO: handle some of options ? options = Dict{Symbol,Any}() opt_string = "" - docno = 1 - codeno = 1 - for cell in nb["cells"] - srctext = "\n" * join(cell["source"], "") - - if cell["cell_type"] == "code" - chunk = CodeChunk(rstrip(srctext), codeno, 0, opt_string, options) - push!(chunks, chunk) - codeno += 1 + chunks = map(nb["cells"]) do cell + text = string('\n', join(cell["source"]), '\n') + return if cell["cell_type"] == "code" + CodeChunk(text, code_no += 1, 0, opt_string, options) else - chunk = DocChunk(srctext * "\n", docno, 0; notebook = true) - push!(chunks, chunk) - docno += 1 + DocChunk(text, doc_no += 1, 0; notebook = true) end end diff --git a/src/reader/reader.jl b/src/reader/reader.jl index e1f757d..90d7aa3 100644 --- a/src/reader/reader.jl +++ b/src/reader/reader.jl @@ -1,4 +1,4 @@ -using JSON, YAML +using YAML function WeaveDoc(source, informat = nothing) diff --git a/src/reader/script.jl b/src/reader/script.jl index 1e1678e..ab8910f 100644 --- a/src/reader/script.jl +++ b/src/reader/script.jl @@ -1,59 +1,47 @@ function parse_script(document_body) - lines = split(document_body, "\n") + lines = split(document_body, '\n') doc_line = r"(^#'.*)|(^#%%.*)|(^# %%.*)" doc_start = r"(^#')|(^#%%)|(^# %%)" opt_line = r"(^#\+.*$)|(^#%%\+.*$)|(^# %%\+.*$)" opt_start = r"(^#\+)|(^#%%\+)|(^# %%\+)" - read = "" - docno = 1 - codeno = 1 content = "" + state = :code + doc_no = 0 + code_no = 0 start_line = 1 + options = Dict{Symbol,Any}() - optionString = "" + option_string = "" chunks = WeaveChunk[] - state = "code" - for lineno = 1:length(lines) - line = lines[lineno] - if (m = match(doc_line, line)) != nothing && (m = match(opt_line, line)) == nothing + for (line_no, line) in enumerate(lines) + if (m = match(doc_line, line)) !== nothing && (m = match(opt_line, line)) === nothing line = replace(line, doc_start => "", count = 1) - if startswith(line, " ") - line = replace(line, " " => "", count = 1) + startswith(line, ' ') && (line = line[2:end]) + if state === :code && !isempty(strip(content)) + push!(chunks, CodeChunk(string('\n', strip(content)), code_no += 1, start_line, option_string, options)) + content = "" + start_line = line_no end - if state == "code" && strip(read) != "" - chunk = - CodeChunk("\n" * strip(read), codeno, start_line, optionString, options) - push!(chunks, chunk) - codeno += 1 - read = "" - start_line = lineno + state = :doc + elseif (m = match(opt_line, line)) !== nothing + start_line = line_no + if state === :code && !isempty(strip(content)) + push!(chunks, CodeChunk(string('\n', strip(content)), code_no += 1, start_line, option_string, options)) + content = "" end - state = "doc" - elseif (m = match(opt_line, line)) != nothing - start_line = lineno - if state == "code" && strip(read) != "" - chunk = - CodeChunk("\n" * strip(read), codeno, start_line, optionString, options) - push!(chunks, chunk) - read = "" - codeno += 1 - end - if state == "doc" && strip(read) != "" - (docno > 1) && (read = "\n" * read) # Add whitespace to doc chunk. Needed for markdown output - chunk = DocChunk(read, docno, start_line) - push!(chunks, chunk) - read = "" - docno += 1 + if state === :doc && !isempty(strip(content)) + iszero(doc_no) || (content = string('\n', content)) # Add whitespace to doc chunk. Needed for markdown output + push!(chunks, DocChunk(content, doc_no += 1, start_line)) + content = "" end - optionString = replace(line, opt_start => "", count = 1) - # Get options + option_string = replace(line, opt_start => "", count = 1) options = Dict{Symbol,Any}() - if length(optionString) > 0 - expr = Meta.parse(optionString) + if !isempty(option_string) + expr = Meta.parse(option_string) Base.Meta.isexpr(expr, :(=)) && (options[expr.args[1]] = expr.args[2]) Base.Meta.isexpr(expr, :toplevel) && map(pushopt, fill(options, length(expr.args)), expr.args) @@ -61,29 +49,25 @@ function parse_script(document_body) haskey(options, :label) && (options[:name] = options[:label]) haskey(options, :name) || (options[:name] = nothing) - state = "code" + state = :code continue - elseif state == "doc" # && strip(line) != "" && strip(read) != "" - state = "code" - (docno > 1) && (read = "\n" * read) # Add whitespace to doc chunk. Needed for markdown output - chunk = DocChunk(read, docno, start_line) - push!(chunks, chunk) + elseif state === :doc # && strip(line) != "" && strip(content) != "" + state = :code + iszero(doc_no) || (content = string('\n', content)) # Add whitespace to doc chunk. Needed for markdown output + push!(chunks, DocChunk(content, doc_no += 1, start_line)) + content = "" + options = Dict{Symbol,Any}() - start_line = lineno - read = "" - docno += 1 + start_line = line_no end - read *= line * "\n" + content *= string(line, '\n') end # Handle the last chunk - if state == "code" - chunk = CodeChunk("\n" * strip(read), codeno, start_line, optionString, options) - push!(chunks, chunk) - else - chunk = DocChunk(read, docno, start_line) - push!(chunks, chunk) - end + chunk = state === :code ? + CodeChunk(string('\n', strip(content)), code_no, start_line, option_string, options) : + DocChunk(content, doc_no, start_line) + push!(chunks, chunk) return Dict(), chunks end diff --git a/src/types.jl b/src/types.jl index 6854d8b..d6c8281 100644 --- a/src/types.jl +++ b/src/types.jl @@ -37,7 +37,7 @@ mutable struct CodeChunk <: WeaveChunk result::Vector{ChunkOutput} function CodeChunk(content, number, start_line, optionstring, options) new( - rstrip(content) * "\n", + string(rstrip(content), '\n'), # normalize end of chunk number, 0, start_line,