通过重复细化扩展构建标记

发布于 2024-09-10 22:38:34 字数 1681 浏览 1 评论 0原文

我尝试使用之前的答案向构建标记函数添加重复细化: 如何绑定到 foreach 上下文?

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
][

  either not repeat [
      content: either string? content [copy content] [read content] 
      out: make string! 126 
      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)
          ]
      ]
    ][        
        probe :block-fields
        foreach :block-fields block-values [
          print get pick :block-fields 1
          print get pick :block-fields 2
        ]
    ] 
    out
]

c: [a b]
template: "<%a%> <%b%>"
build-markup/repeat template :c [1 2 3 4]

输出不是我想要的:

>> c: [a b]
== [a b]
>> template: "<%a%> <%b%>"
== "<%a%> <%b%>"
>> build-markup/repeat template :c [1 2 3 4]
[a b]
1
1 a b
1
1 a b

而我会预料到

1
2
3
4

那么我应该如何纠正?

I tried to add a repeat refinement to build-markup function using the previous answer:
How to bind to foreach context?

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
][

  either not repeat [
      content: either string? content [copy content] [read content] 
      out: make string! 126 
      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)
          ]
      ]
    ][        
        probe :block-fields
        foreach :block-fields block-values [
          print get pick :block-fields 1
          print get pick :block-fields 2
        ]
    ] 
    out
]

c: [a b]
template: "<%a%> <%b%>"
build-markup/repeat template :c [1 2 3 4]

Output is not what I want:

>> c: [a b]
== [a b]
>> template: "<%a%> <%b%>"
== "<%a%> <%b%>"
>> build-markup/repeat template :c [1 2 3 4]
[a b]
1
1 a b
1
1 a b

whereas I would have expected

1
2
3
4

So how should I correct ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

总以为 2024-09-17 22:38:34

For:

words: [num]
vals: [1 2 3]

当您使用 foreach :words 时,您正在创建一个新的上下文,重复块将绑定到该上下文。 :wordsword! 内容实际上并未绑定到这个新上下文。您获得的值表明 'a 全局设置为 1,'b 设置为 [ab]。为了解决

>> num: 9                 
== 9
>> words: [num]           
== [num]
>> foreach :words vals [
[    probe get 'num         
[    probe get first :words 
[    ]                      
1
9
2
9
3
9
== 9

这个问题,请尝试想象一下,对于循环的每次迭代,执行的块都被'bind绑定到循环上下文。您可以像这样抢占绑定:(

foreach :words vals probe compose/only [
    probe get first (words)
]

出于说明目的而保留探针)

For:

words: [num]
vals: [1 2 3]

When you use foreach :words, you are creating a new context for which the repeat block will be bound to. The word! contents of :words are not actually bound to this new context. The values you are getting suggest 'a is globally set to 1 and 'b is set to [a b]. To illustrate:

>> num: 9                 
== 9
>> words: [num]           
== [num]
>> foreach :words vals [
[    probe get 'num         
[    probe get first :words 
[    ]                      
1
9
2
9
3
9
== 9

To work around this, try to picture that for each iteration of the loop, the block that is executed is 'bind-ed to the loop context. You can preempt the bind like this:

foreach :words vals probe compose/only [
    probe get first (words)
]

(probe left in for illustrative purposes)

極樂鬼 2024-09-17 22:38:34

似乎有效:

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: compose/only [
            set in system/words (to-lit-word pick (block-fields) 1) get pick (block-fields) 1
            set in system/words (to-lit-word pick (block-fields) 2) get pick (block-fields) 2
            probe get in system/words (to-lit-word pick (block-fields) 1)
            probe get in system/words (to-lit-word pick (block-fields) 2)
            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

输出:

== {<table>
  <tr>
    <td>1</td><td>2</td>
    <td>3</td><td>4</td>

  </tr>
  <tr>
    <td>1</td><td>2</td>
    <td>3</td><td>4</...
>

>

seems to work:

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: compose/only [
            set in system/words (to-lit-word pick (block-fields) 1) get pick (block-fields) 1
            set in system/words (to-lit-word pick (block-fields) 2) get pick (block-fields) 2
            probe get in system/words (to-lit-word pick (block-fields) 1)
            probe get in system/words (to-lit-word pick (block-fields) 2)
            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:

== {<table>
  <tr>
    <td>1</td><td>2</td>
    <td>3</td><td>4</td>

  </tr>
  <tr>
    <td>1</td><td>2</td>
    <td>3</td><td>4</...
>

>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文