-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
macros.cr
106 lines (104 loc) · 2.16 KB
/
macros.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
module ECR
# Defines a `to_s(io)` method whose body is the ECR contained
# in *filename*, translated to Crystal code.
#
# ```text
# # greeting.ecr
# Hello <%= @name %>!
# ```
#
# ```
# require "ecr/macros"
#
# class Greeting
# def initialize(@name : String)
# end
#
# ECR.def_to_s "greeting.ecr"
# end
#
# Greeting.new("World").to_s # => "Hello World!"
# ```
#
# The macro basically translates the text inside the given file
# to Crystal code that appends to the IO:
#
# ```
# class Greeting
# def to_s(io)
# io << "Hello "
# io << @name
# io << '!'
# end
# end
# ```
macro def_to_s(filename)
def to_s(__io__ : IO) : Nil
ECR.embed {{filename}}, "__io__"
end
end
# Embeds an ECR file *filename* into the program and appends the content to
# an IO in the variable *io_name*.
#
# The generated code is the result of translating the contents of
# the ECR file to Crystal, a program that appends to an IO.
#
# ```text
# # greeting.ecr
# Hello <%= name %>!
# ```
#
# ```
# require "ecr/macros"
#
# name = "World"
#
# io = IO::Memory.new
# ECR.embed "greeting.ecr", io
# io.to_s # => "Hello World!"
# ```
#
# The `ECR.embed` line basically generates this Crystal code:
#
# ```
# io << "Hello "
# io << name
# io << '!'
# ```
macro embed(filename, io_name)
\{{ run("ecr/process", {{filename}}, {{io_name.id.stringify}}) }}
end
# Embeds an ECR file *filename* into the program and renders it to a string.
#
# The generated code is the result of translating the contents of
# the ECR file to Crystal, a program that appends to an IO and returns a string.
#
# ```text
# # greeting.ecr
# Hello <%= name %>!
# ```
#
# ```
# require "ecr/macros"
#
# name = "World"
#
# rendered = ECR.render "greeting.ecr"
# rendered # => "Hello World!"
# ```
#
# The `ECR.render` basically generates this Crystal code:
#
# ```
# String.build do |io|
# io << "Hello "
# io << name
# io << '!'
# end
# ```
macro render(filename)
::String.build do |%io|
::ECR.embed({{filename}}, %io)
end
end
end