1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # This is an example of a client of the frontend without command-line processing.
17 # It offers a simple nitcorn web server that offers a textarea and nitpick and nitlignt it.
18 module nitlight_as_a_service
26 # Fully process a content as a nit source file.
27 fun hightlightcode
(hl
: HighlightVisitor, content
: String): HLCode
29 # Prepare a stand-alone tool context
30 var tc
= new ToolContext
31 tc
.nit_dir
= tc
.locate_nit_dir
# still use the common lib to have core
32 tc
.keep_going
= true # no exit, obviously
33 tc
.opt_warn
.value
= -1 # no output, obviously
35 # Prepare an stand-alone model and model builder.
36 # Unfortunately, models are enclosing and append-only.
37 # There is no way (yet?) to have a shared module `core` with
38 # isolated and throwable user modules.
40 var mb
= new ModelBuilder(model
, tc
)
43 var source
= new SourceFile.from_string
("", content
+ "\n")
44 var lexer
= new Lexer(source
)
45 var parser
= new Parser(lexer
)
46 var tree
= parser
.parse
48 var hlcode
= new HLCode(hl
, content
, source
)
52 if eof
isa AError then
53 mb
.error
(eof
, eof
.message
)
54 hl
.hightlight_source
(source
)
57 var amodule
= tree
.n_base
.as(not null)
59 # Load the AST as a module in the model
61 mb
.load_rt_module
(null, amodule
, "")
64 # Highlight the processed module
65 hl
.enter_visit
(amodule
)
69 # A standalone highlighted piece of code
71 # The highlighter used
72 var hl
: HighlightVisitor
77 # The pseudo source-file
78 var source
: SourceFile
80 # JavaScript code to update an existing codemirror editor.
81 fun code_mirror_update
: Template
84 var res
= new Template
86 function nitmessage() {
87 editor.operation(function(){
88 for (var i = 0; i < widgets.length; ++i)
89 editor.removeLineWidget(widgets[i]);
93 for m
in source
.messages
do
95 var l = document.createElement("div");
96 l.className = "lint-error"
97 l.innerHTML = "<span class='glyphicon glyphicon-warning-sign lint-error-icon'></span> {{{m.text.html_escape}}}";
98 var w = editor.addLineWidget({{{m.location.line_start-1}}}, l);
107 # Nitcorn service to hightlight code
109 # It's a single stand-alone page that has to form to itself.
110 class HighlightAction
113 redef fun answer
(http_request
, turi
)
115 var hl
= new HighlightVisitor
116 var page
= new Template
118 # There is code? Process it
119 var code
= http_request
.post_args
.get_or_null
("code")
121 if code
!= null then hlcode
= hightlightcode
(hl
, code
)
123 if http_request
.post_args
.get_or_null
("ajax") == "true" and hlcode
!= null then
124 page
.add hlcode
.code_mirror_update
126 document.getElementById("lightcode").innerHTML = "{{{hl.html.write_to_string.escape_to_c}}}";
130 var response
= new HttpResponse(200)
131 response
.header
["Content-Type"] = "application/javascript"
132 response
.body
= page
.write_to_string
137 <!doctype html><html><head>{{{hl.head_content}}}
138 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.16.0/codemirror.css">
141 textarea {width:100%;}
142 .lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
143 .lint-error-icon {color: red; padding: 0 3px; margin-right: 7px;}
144 </style></head><body>
146 # Add the form+textarea
148 <form action="#light" method=post><textarea id=code name=code rows=10>{{{code or else ""}}}</textarea><br><input type=submit></form>
151 if hlcode
!= null then
153 page
.add
"<pre id=light><code id=lightcode>"
154 page
.add hl
.html
.write_to_string
155 page
.add
"</code></pre><hr>"
159 for m
in hlcode
.source
.messages
do
160 page
.add
"<li>{m.location.as(not null)}: {m.text}</li>"
164 page
.add
"<pre id=light><code id=lightcode></code></pre>"
167 page
.add hl
.foot_content
171 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.16.0/codemirror.min.js"></script>
173 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
178 # Callback to update codemirror messages
179 if hlcode
!= null then
180 page
.add hlcode
.code_mirror_update
182 page
.add
"function nitmessage()\{\}"
188 function updatePage() {
189 $.post("", { ajax: true, code: editor.getValue()}, function(data) {
191 $(".popupable").popover({html:true, placement:'top'});
196 editor.on("change", function() {
197 clearTimeout(waiting);
198 waiting = setTimeout(updatePage, 500);
200 waiting = setTimeout(updatePage, 500);
206 var response
= new HttpResponse(200)
207 response
.header
["Content-Type"] = "text/html"
208 response
.body
= page
.write_to_string
213 var host
= "localhost:8080"
214 if args
.length
> 0 then host
= args
.first
216 var vh
= new VirtualHost(host
)
217 vh
.routes
.add
new Route("/", new HighlightAction)
218 var factory
= new HttpFactory.and_libevent
219 factory
.config
.virtual_hosts
.add vh