yamlscript

delon 2024-12-26T14:02:29.639009Z

I’m currently toying around with processing a Jekyll site with YS as a way to finally write some real YS code. Is there a way to quote a text file (e.g. an Liquid template file) as a YAML string from YAML or YS (ideally without having to modify the file)? I’m trying to avoid YS processing template literals as YAML. Most of the content files can be loaded without incident, but the layout files blow up.

Ingy döt Net 2024-12-26T14:16:30.653779Z

$ cat jekyll.yaml 
from: 
file: |
  {% if page.show_sidebar %}
    <div class="sidebar">
      sidebar content
    </div>
  {% endif %}
$ ys -l jekyll.yaml -e '.file:print'
{% if page.show_sidebar %}
  <div class="sidebar">
    sidebar content
  </div>
{% endif %}

Ingy döt Net 2024-12-26T14:18:28.176669Z

Quoting files as strings (like heredocs in come langs) is one of the things YAML (and thus YS) is great at. Just use | and then indent the file content appropriately.

Ingy döt Net 2024-12-26T14:20:50.782809Z

In YAML, this is called a "literal" style scalar. There are 5 scalar styles: plain (unquoted), single quoted, double quoted, literal and folded.

Ingy döt Net 2024-12-26T14:50:48.053059Z

Note, that in YS you can interpolate variables an d expressions in double quoted and literal strings. This makes literal strings excellent you simple templating:

$ cat interpolate.ys 
!yamlscript/v0

say: "Hello $(ENV.USER:uc1). 2 + 2 = $(2 + 2)."

say: |

  Have you seen this cool new program?

  
$(FILE:slurp)
It's written in YAMLScript v$VERSION
$ ys interpolate.ys 
Hello Ingy. 2 + 2 = 4.

Have you seen this cool new program?

!yamlscript/v0 say: "Hello $(ENV.USER:uc1). 2 + 2 = $(2 + 2)." say: | Have you seen this cool new program?
$(FILE:slurp)
  
It's written in YAMLScript v$VERSION
It's written in YAMLScript v0.1.87

$ 

Ingy döt Net 2024-12-26T14:54:39.578509Z

https://gist.github.com/ingydotnet/9ece4af186c6a6dcfd589c446dab9b38 was generated by this YS program: https://github.com/ingydotnet/yamlscript-vs-rosetta/blob/main/bin/ys-vs-rc which uses that kind of templating with literals quite a bit.

Ingy döt Net 2024-12-26T14:59:38.397289Z

Note that you can avoid the interpoation easily by switching to "data mode" (with ::)

$ cat interpolate2.ys 
!yamlscript/v0

say: |
  Hello
  $(ENV.USER:uc1)

say:: |
  Hello
  $(ENV.USER:uc1)
$ ys interpolate2.ys 
Hello
Ingy

Hello
$(ENV.USER:uc1)

👍 1
Ingy döt Net 2024-12-26T15:00:17.976579Z

Make sense, @delon?

delon 2024-12-26T15:04:48.944559Z

That does! I’m out and about at the moment, but I’ll try it out when I get home.

👍 1
delon 2024-12-26T16:05:32.962389Z

The :: data mode is helpful. I was wondering what that was.

delon 2024-12-26T16:10:38.266769Z

@ingy Also, do you know if anyone has started on a yamlscript mode for Emacs?

Ingy döt Net 2024-12-26T16:17:01.073359Z

Not to my knowledge. Just looking for syntax highlighting?

delon 2024-12-26T16:17:21.623089Z

Yeah for now

Ingy döt Net 2024-12-26T16:18:09.782649Z

I've noticed PowerShell does a pretty good job in vscode 😂

delon 2024-12-26T16:18:17.936519Z

Hehe

delon 2024-12-26T16:18:27.418889Z

I could see that

Ingy döt Net 2024-12-26T16:18:39.624949Z

YAML mode is meh for YS

delon 2024-12-26T16:18:45.705869Z

Yeah

delon 2024-12-26T16:18:50.817079Z

I’m noticing that too

Ingy döt Net 2024-12-26T16:19:06.683429Z

Does emacs work with LSP servers?

delon 2024-12-26T16:19:13.804489Z

Yes

Ingy döt Net 2024-12-26T16:19:31.416029Z

oh cool. then I plan to have one soon

delon 2024-12-26T16:19:52.882859Z

Ok, cool

delon 2024-12-26T16:20:02.177349Z

I’m trying out powershell for now

Ingy döt Net 2024-12-26T16:20:03.419199Z

do you have any experience with how they work?

Ingy döt Net 2024-12-26T16:20:09.575059Z

LSP...

delon 2024-12-26T16:20:37.914899Z

Not much, though I do have an interest in the subject

Ingy döt Net 2024-12-26T16:21:26.652439Z

the YS compiler has access to input position (line,col) and produces an AST internally so I think it shouldn't be that hard. Maybe we can collab on it.

Ingy döt Net 2024-12-26T16:22:13.452919Z

It would also work well for plain YAML (which is also YS)

delon 2024-12-26T16:23:01.046449Z

That’d be cool

delon 2024-12-26T16:23:23.940119Z

We’ll see how my time goes. But I’d love to collab on this sort of thing

Ingy döt Net 2024-12-26T16:23:47.305829Z

It's sorely missed I know..

delon 2024-12-26T16:23:58.361459Z

I have sometime now, but it may dry up soon

Ingy döt Net 2024-12-26T16:24:07.533419Z

aye

Ingy döt Net 2024-12-26T16:24:33.109059Z

Let me know if you need help with your jekyll thing

delon 2024-12-26T16:24:42.041499Z

For me it’s not really too bad, but I’m a weirdo that likes making my own programming languages 🤓

delon 2024-12-26T16:24:50.879159Z

Yes

Ingy döt Net 2024-12-26T16:25:16.302819Z

I might even have time to pair this afternoon if you wanna

delon 2024-12-26T16:25:17.493789Z

layouts =:
  "%":
    default: |
      $(slurp("./_layouts/default.html"))

delon 2024-12-26T16:25:42.369289Z

We’ll see I have a meeting kind of late afternoon

Ingy döt Net 2024-12-26T16:26:01.422489Z

I have a meeting in 5 mins, but free after

delon 2024-12-26T16:26:44.636189Z

Ok, I’ve got a couple of things to take care but that may work

Ingy döt Net 2024-12-26T16:57:19.126859Z

@delon given: https://gist.github.com/ingydotnet/ecfb144b1d86ae32f749e1fc53e7bece

$ ys layouts1.ys 
Runtime error:
Could not resolve symbol: default
$ ys layouts2.ys 
'%':
  default: |+
    
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>{{ page.title }}</title>
        <link rel="stylesheet" href="/css/style.css">
      </head>
      <body>
        <nav>
          <a href="/">Home</a>
          <a href="/blog/">Blog</a>
        </nav>
        <h1>{{ page.title }}</h1>
        <section>
          {{ content }}
        </section>
        <footer>
          &copy; to me
        </footer>
      </body>
    </html>


$ ys layouts3.ys 
'%':
  default: |
    
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>{{ page.title }}</title>
        <link rel="stylesheet" href="/css/style.css">
      </head>
      <body>
        <nav>
          <a href="/">Home</a>
          <a href="/blog/">Blog</a>
        </nav>
        <h1>{{ page.title }}</h1>
        <section>
          {{ content }}
        </section>
        <footer>
          &copy; to me
        </footer>
      </body>
    </html>

$ 

Ingy döt Net 2024-12-26T17:07:42.135619Z

I think that's where you were going. 1. You need the !yamlscript/v0 at the top 2. That starts you in "code mode" (where unquoted scalars are ys exprs) 3. :: switches the following value node to "data mode" (where unquoted scalars are normal YAML (strings usually)) 4. no need to slurp in the context of a literal scalar unless you are using the slurp as part of a bigger string. 5. slurp(file) can be written in various other syntax forms like: a. (slurp file) b. slurp: file c. slurp file: d. file.slurp() e. file:slurp f. !:slurp file 6. Prefer single quoted strings 'foo' over double quoted "foo" unless using interpolation, escaping or embedded single quotes "foo\n'$bar'"

Ingy döt Net 2024-12-26T17:11:10.764299Z

Also interpolation syntax has 4 distinct forms:

"foo $(slurp(file)) bar"
"foo $slurp(file) bar"
"foo $file bar"
"foo${file}bar"

Ingy döt Net 2024-12-26T17:11:49.431109Z

@danielmartincraig you might enjoy this stuff ^^

delon 2024-12-26T22:17:21.851419Z

Sorry, I missed you today, I got a bit behind on things so my time disappeared on me 😅. But thanks for the feedback that looks like what I needed. I’ll dig into it a little more between tomorrow and next week.

✅ 1