Skip to content

Commit

Permalink
Additional fixes to eval workflow (#255)
Browse files Browse the repository at this point in the history
* added an eval toggle (jd_code_eval)

* added variable to capture and aggregate scripts

* bringing back the printing
  • Loading branch information
tlienart authored Oct 8, 2019
1 parent 6ca011c commit 5245abb
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 26 deletions.
7 changes: 7 additions & 0 deletions src/converter/md.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ function convert_md(mds::String, pre_lxdefs::Vector{LxDef}=Vector{LxDef}();
lxcontext = LxContext(lxcoms, lxdefs, braces)
hstring = convert_inter_html(inter_html, mblocks, lxcontext)

#> if there's code, assemble it so that can be shown or loaded in one shot
codes = LOCAL_PAGE_VARS["jd_code_scope"].first.codes
if !isempty(codes)
set_var!(LOCAL_PAGE_VARS, "jd_code",
strip(prod(c*"\n" for c in codes)))
end

# Return the string + judoc variables
return hstring, jd_vars
end
Expand Down
48 changes: 32 additions & 16 deletions src/converter/md_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function convert_block(β::AbstractBlock, lxcontext::LxContext)::AS
β isa HTML_SPCH && return ifelse(isempty.r), β.ss, β.r)
# Return relevant interpolated string based on case
βn = β.name
βn MD_HEADER && return convert_header(β)
βn MD_HEADER && return convert_header(β)
βn == :CODE_INLINE && return html_code_inline(content(β) |> htmlesc)
βn == :CODE_BLOCK_LANG && return convert_code_block.ss)
βn == :CODE_BLOCK_IND && return convert_indented_code_block.ss)
Expand Down Expand Up @@ -131,19 +131,26 @@ const MESSAGE_FILE_GEN = "# This file was generated by JuDoc, do not modify it.
"""Convenience function to increment the eval' code block counter"""
increment_code_head() = (LOCAL_PAGE_VARS["jd_code_head"].first[] += 1)

"""Convenience function to mark `jd_code_eval` as true (subsequent blocks will be evaled)"""
toggle_jd_code_eval() = (LOCAL_PAGE_VARS["jd_code_eval"].first[] = true)

"""
$SIGNATURES
Helper function to eval a code block, write it where appropriate, and finally return
a resolved block that can be displayed in the html.
"""
function eval_and_resolve_code(code::AS, rpath::AS; eval::Bool=true)::String
function eval_and_resolve_code(code::AS, rpath::AS;
eval::Bool=true, nopush::Bool=false)::String
# Here we have a julia code block that was provided with a script path
# It will consequently be
# 1. written to script file unless it's already there
# 2. eval with redirect (unless file+output already there)
# 3. inserted after cleaning out lines (see resolve_lx_input)

# start by adding it to code scope
nopush || push!(LOCAL_PAGE_VARS["jd_code_scope"].first, rpath, code)

# form the path
path = resolve_assets_rpath(rpath; canonical=true, code=true)

Expand All @@ -164,7 +171,7 @@ function eval_and_resolve_code(code::AS, rpath::AS; eval::Bool=true)::String
end

write(path, MESSAGE_FILE_GEN * code)
print(rpad("\r→ evaluating code [...] ($(CUR_PATH[]), $rpath)", 79)*"\r")
print(rpad("\r→ evaluating code [...] ($(CUR_PATH[]), $rpath)", 79))
# - execute the code while redirecting stdout to file
Logging.disable_logging(Logging.LogLevel(3_000))
open(out_path, "w") do outf # for stdout
Expand Down Expand Up @@ -208,9 +215,17 @@ function convert_code_block(ss::SubString)::String
# path currently has an indicative `:` we don't care about
rpath = rpath[2:end]

# extract handles of relevant local page variables
reeval = LOCAL_PAGE_VARS["reeval"].first # full page re-eval
eval = LOCAL_PAGE_VARS["jd_code_eval"].first[] # eval toggle from given point
freeze = LOCAL_PAGE_VARS["freezecode"].first
scope = LOCAL_PAGE_VARS["jd_code_scope"].first
head = increment_code_head()

# In the case of forced re-eval, we don't care about the
# code scope just force-reeval everything sequentially
if FORCE_REEVAL[] || LOCAL_PAGE_VARS["reeval"].first
if FORCE_REEVAL[] || reeval || eval
length(scope.codes) head && purgefrom!(scope, head)
return eval_and_resolve_code(code, rpath)
end

Expand All @@ -219,48 +234,49 @@ function convert_code_block(ss::SubString)::String
# the case then there will be a check to see if the relevant
# files exist, if they don't exist the code *will* be eval'ed
# (see `eval_and_resolve_code`)
if FULL_PASS[] || LOCAL_PAGE_VARS["freezecode"].first
if FULL_PASS[] || freeze
length(scope.codes) head && purgefrom!(scope, head)
return eval_and_resolve_code(code, rpath, eval=false)
end

# Here we're either in
# A. full pass but with forced-reeval
# B. local pass with non-frozen code

# handle for dictionary of eval'ed code blocks (scope)
code_scope = LOCAL_PAGE_VARS["jd_code_scope"].first

# check if the page we're looking at is in scope
if CUR_PATH[] != CUR_PATH_WITH_EVAL[]
# we're necessarily at the first code block of the page.
# need to re-instantiate a code scope; note that if we
# are here then necessarily a def_LOCAL_PAGE_VARS was
# called, so LOCAL_PAGE_VARS["jd_code_head"] points to 1
reset!(code_scope, rpath, code)
reset!(scope)
# keep track that the page is now in scope
CUR_PATH_WITH_EVAL[] = CUR_PATH[]
# flag rest of page as to be eval-ed (might be stale)
toggle_jd_code_eval()
# eval and resolve code
return eval_and_resolve_code(code, rpath)
end

# we're in scope, compare the code block with the
# current code scope and act appropriately
head = increment_code_head()
ncodes = length(code_scope.codes)
ncodes = length(scope.codes)

# there is only one case where we might not add and eval
# --> if c ≤ length(code_dict) -- code block may be among seen ones
# --> code == code_dict[rpath] -- the content matches exactly
if (head ncodes)
if (code_scope.rpaths[head] == rpath && code == code_scope.codes[head])
if (scope.rpaths[head] == rpath && code == scope.codes[head])
# resolve with no eval (the function will check if the files are
# present and if they're not, there will be an evaluation)
return eval_and_resolve_code(code, rpath; eval=false)
return eval_and_resolve_code(code, rpath; eval=false, nopush=true)
else
# all further blocks are stale
purgeafter!(code_scope, head-1)
# purge subsequent code blocks as stale
purgefrom!(scope, head)
# flag rest of page as to be eval-ed (stale)
toggle_jd_code_eval()
end
end
push!(code_scope, rpath, code)
return eval_and_resolve_code(code, rpath)
end

Expand Down
21 changes: 11 additions & 10 deletions src/jd_vars.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ DEVNOTE: marked as constant for perf reasons but can be modified since Dict.
"""
const GLOBAL_PAGE_VARS = PageVars()


"""
$(SIGNATURES)
Expand Down Expand Up @@ -50,16 +49,16 @@ function push!(cs::CodeScope, rpath::SubString, code::SubString)::Nothing
end

"""Convenience function to (re)start a code scope."""
function reset!(cs::CodeScope, rpath::SubString, code::SubString)::Nothing
cs.rpaths = [rpath]
cs.codes = [code]
function reset!(cs::CodeScope)::Nothing
cs.rpaths = []
cs.codes = []
return nothing
end

"""Convenience function to clear arrays beyond an index"""
function purgeafter!(cs::CodeScope, head::Int)::Nothing
cs.rpaths = cs.rpaths[1:head]
cs.codes = cs.codes[1:head]
"""Convenience function to purge code scope from head"""
function purgefrom!(cs::CodeScope, head::Int)
cs.rpaths = cs.rpaths[1:head-1]
cs.codes = cs.codes[1:head-1]
return nothing
end

Expand Down Expand Up @@ -126,8 +125,10 @@ is processed.

# Internal vars for code blocks
LOCAL_PAGE_VARS["jd_code_scope"] = code_scope
LOCAL_PAGE_VARS["jd_code_head"] = Pair(Ref(0), (Ref{Int},))
LOCAL_PAGE_VARS["reeval"] = Pair(false, (Bool,)) # whether to always re-evals all on pg
LOCAL_PAGE_VARS["jd_code_head"] = Pair(Ref(0), (Ref{Int},))
LOCAL_PAGE_VARS["jd_code_eval"] = Pair(Ref(false), (Ref{Bool},)) # toggle reeval
LOCAL_PAGE_VARS["reeval"] = Pair(false, (Bool,)) # always reeval on pg
LOCAL_PAGE_VARS["jd_code"] = Pair("", (String,)) # just the script

# If there are GLOBAL vars that are defined, they take precedence
local_keys = keys(LOCAL_PAGE_VARS)
Expand Down
16 changes: 16 additions & 0 deletions test/global/eval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ end
<pre><code>8</code></pre>
""")

@test J.LOCAL_PAGE_VARS["jd_code"].first == """
a = 5
println(a)
a += 3
println(a)"""

h = raw"""
@def hascode = true
@def reeval = true
Expand Down Expand Up @@ -174,4 +181,13 @@ end
println(a)</code></pre>
<pre><code>9</code></pre>
""")
@test J.LOCAL_PAGE_VARS["jd_code"].first == """
a = 5
println(a)
a += 1
println(a)
a += 3
println(a)"""
end

0 comments on commit 5245abb

Please sign in to comment.