tags:

views:

77

answers:

1

I tried to generate the actions block dynamically in the code below (from static version here http://stackoverflow.com/questions/3326484/extending-build-markup-with-repeat-refinement/) but It doesn't work why ?

build-markup: func [
    {Return markup text replacing <%tags%> with their evaluated results.} 
    content [string! file! url!] 
    /repeat block-fields block-values
    /quiet "Do not show errors in the output." 
    /local out eval value
][

  out: make string! 126 

  either not repeat [
      content: either string? content [copy content] [read content] 

      eval: func [val /local tmp] [
          either error? set/any 'tmp try [do val] [
              if not quiet [
                  tmp: disarm :tmp 
                  append out reform ["***ERROR" tmp/id "in:" val]
              ]
          ] [
              if not unset? get/any 'tmp [append out :tmp]
          ]
      ] 
      parse/all content [
          any [
              end break 
              | "<%" [copy value to "%>" 2 skip | copy value to end] (eval value) 
              | copy value [to "<%" | to end] (append out value)
          ]
      ]
    ][          

        actions: copy []

        n: length? block-fields
        repeat i n [
          append actions compose/only [
            set in system/words (to-lit-word pick (block-fields) (i)) get pick (block-fields) (i)
          ]
        ]
        append actions compose/only [
            append out build-markup content
        ]
        foreach :block-fields block-values actions        
    ] 
    out
]

template1: {    <td><%a%></td><td><%b%></td>
}
template2: {  <tr>
<%build-markup/repeat template1 [a b] [1 2 3 4]%>
  </tr>
}
template3: {<table>
<%build-markup/repeat template2 [a b] [1 2 3 4 5 6]%>
</table>}
build-markup template3

Output error:

>> build-markup template3
== {<table>
***ERROR no-value in: build-markup/repeat template2 [a b] [1 2 3 4 5 6]
</table>}
>>
+1  A: 

It looks like a binding problem.

I changed this line:

either error? set/any 'tmp try [do val] [

to

either error? set/any 'tmp e: try [do val] [

e holds the error,

>> e
** Script Error: i has no value
** Where: build-markup
** Near: i n [
endo64
Oh my if it's binding I'm lost :) Now what should I do ?
Rebol Tutorial
I don't know, sorry, I don't have too much time. But just realized that you have /repeat refinement and you use repeat function also. This may lead to a problem.
endo64
You're right :) By the way I really think refinement syntax is bad : refinement should be somehow typed.
Rebol Tutorial
thanks Endo64 for your remark, I badly needed this function and it works now.
Rebol Tutorial
You are welcome, I didn't know that this was the only problem in your function :)>> f: func [/repeat] [repeat i 10 [print i]]>> f** Script Error: i has no valueThe strange thing is, protect-system cannot protect the words from being refinement.>> protect-system>> f: func [/repeat] [probe repeat]>> fnone== none ;repeat is gone..
endo64
If you have an editor that is Rebol syntax aware, it will color the keywords for you and then these issues are more clearly obvious .. that you are using system words as variables.
Graham Chiu
@Endo I didn't know about protect-system seems interesting. @Graham good suggestion.
Rebol Tutorial