Weave.jl/src/readers.jl

85 lines
2.7 KiB
Julia

pushopt(options::Dict,expr::Expr) = Base.Meta.isexpr(expr,:(=)) && (options[expr.args[1]] = expr.args[2])
const input_formats = @compat Dict{String, Any}(
"noweb" => Dict{Symbol, Any}(
:codestart => r"^<<(.*?)>>=\s*$",
:codeend => r"^@\s*$"
),
"markdown" => Dict{Symbol, Any}(
:codestart => r"(?:^(?:`|~){3,}\s*(?:\{|\{\.|)julia(?:;|\s)(.*)\}\s*$)|(?:^(?:`|~){3,}\s*julia\s*$)",
:codeend => r"^`|~{3,}\s*$"
)
)
function read_document(document, format)
#doctext = readall(open(document))
lines = split(bytestring(open(document) do io
mmap_array(Uint8,(filesize(document),),io)
end), "\n")
codestart = input_formats[format][:codestart]
codeend = input_formats[format][:codeend]
state = "doc"
docno = 1
codeno = 1
content = ""
start_line = 0
options = Dict()
optionstring = ""
parsed = Dict[]
for lineno in 1:length(lines)
line = lines[lineno]
if (m = match(codestart, line)) != nothing && state=="doc"
state = "code"
if m.captures[1] == nothing
optionstring = ""
else
optionstring=strip(m.captures[1])
end
@show optionstring
options = Dict{Symbol,Any}()
if length(optionstring) > 0
expr = parse(optionstring)
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)
end
haskey(options, :label) && (options[:name] = options[:label])
haskey(options, :name) || (options[:name] = nothing)
@show options
chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content,
:number => docno,:start_line => start_line)
docno += 1
start_line = lineno
push!(parsed, chunk)
content = ""
continue
end
if ismatch(codeend, line) && state=="code"
chunk = @compat Dict{Symbol,Any}(:type => "code", :content => content,
:number => codeno, :options => options,
:optionstring => optionstring,
:start_line => start_line)
codeno+=1
start_line = lineno
content = ""
state = "doc"
push!(parsed, chunk)
continue
end
content *= "\n" * line
end
#Remember the last chunk
if content != ""
chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content,
:number => docno, :start_line => start_line)
push!(parsed, chunk)
end
return parsed
end