08d6980eaab706037ad30a1ca266386121d1b4af
[nit.git] / src / examples / nitlight_as_a_service.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # This is an example of a client of the frontend without command-line processing.
16 #
17 # It offers a simple nitcorn web server that offers a textarea and nitpick and nitlignt it.
18 module nitlight_as_a_service
19
20 import frontend
21 import highlight
22 import nitcorn
23 import nitcorn::log
24
25 # Fully process a content as a nit source file.
26 fun hightlightcode(hl: HighlightVisitor, content: String): SourceFile
27 do
28 # Prepare a stand-alone tool context
29 var tc = new ToolContext
30 tc.nit_dir = tc.locate_nit_dir # still use the common lib to have core
31 tc.keep_going = true # no exit, obviously
32 tc.opt_warn.value = -1 # no output, obviously
33
34 # Prepare an stand-alone model and model builder.
35 # Unfortunately, models are enclosing and append-only.
36 # There is no way (yet?) to have a shared module `core` with
37 # isolated and throwable user modules.
38 var model = new Model
39 var mb = new ModelBuilder(model, tc)
40
41 # Parse the code
42 var source = new SourceFile.from_string("", content)
43 var lexer = new Lexer(source)
44 var parser = new Parser(lexer)
45 var tree = parser.parse
46
47 # Check syntax error
48 var eof = tree.n_eof
49 if eof isa AError then
50 mb.error(eof, eof.message)
51 hl.hightlight_source(source)
52 return source
53 end
54 var amodule = tree.n_base.as(not null)
55
56 # Load the AST as a module in the model
57 # Then process it
58 mb.load_rt_module(null, amodule, "")
59 mb.run_phases
60
61 # Highlight the processed module
62 hl.enter_visit(amodule)
63 return source
64 end
65
66 # Nitcorn service to hightlight code
67 #
68 # It's a single stand-alone page that has to form to itself.
69 class HighlightAction
70 super Action
71
72 redef fun answer(http_request, turi)
73 do
74 var code = http_request.post_args.get_or_null("code")
75
76 var hl = new HighlightVisitor
77 var page = "<doctype html><html><head>{hl.head_content}<style>{hl.css_content} textarea \{width:100%;\}</style></head><body>"
78 # Add the form+textarea
79 page += """
80 <form action="#light" method=post><textarea name=code rows=10>{{{code or else ""}}}</textarea><br><input type=submit></form>
81 """
82
83 if code != null then
84 # There is code? Process it
85 var source = hightlightcode(hl, code)
86
87 # Inject highlight
88 page += "<pre id=light><code>"
89 page += hl.html.write_to_string
90 page += "</code></pre><hr>"
91 page += "<ul>"
92
93 # List messages
94 for m in source.messages do
95 page += "<li>{m.location.as(not null)}: {m.text}</li>"
96 end
97 page += "</ul>"
98 end
99
100 page += hl.foot_content
101
102 var response = new HttpResponse(200)
103 response.header["Content-Type"] = "text/html"
104 response.body = page
105 return response
106 end
107 end
108
109 var host = "localhost:8080"
110 if args.length > 0 then host = args.first
111
112 var vh = new VirtualHost(host)
113 vh.routes.add new Route("/", new HighlightAction)
114 var factory = new HttpFactory.and_libevent
115 factory.config.virtual_hosts.add vh
116 factory.run