Skip to content

Commit 7e5d47a

Browse files
committed
Fix overzealous heredoc highlighting
As the example Sudoku program demonstrates, the behaviour of heredocs in GNU APL isn't synonymous with those of other languages. If used inside a function, the heredoc won't start to collect lines until the function is called - at which point, it begins collecting whatever's under the call. Although this is useful, it also makes it impossible for a heredoc to be used in a function without screwing the document's highlighting. Instead of removing heredoc formatting altogether, this commit allows authors to "opt-in" based on whether the terminator contains the language's name: text ← ⎕INP "END-OF-HTML" <h1> Heading </h1> <a href="somewhere.htm"> Link </a> END-OF-HTML Only a handful of languages are recognised in this way: anything else is regarded as APL code. Authors can enable highlighting for the following: ╔══════════════╦═══════════════════════════════════════════════╗ ║ Language ║ Activated by ║ ╟──────────────╫───────────────────────────────────────────────╢ ║ HTML ║ HTML, HTM ║ ║ XML ║ XML, XSLT, SVG, RSS ║ ║ CSS ║ CSS, Stylesheet ║ ║ JavaScript ║ JS, ECMAScript, JavaScript, JScript ║ ║ JSON ║ JSON ║ ║ Plain text ║ Raw Text, Plain Text, Raw, Plain ║ ╚══════════════╩═══════════════════════════════════════════════╝ The matching is performed case-insensitively, and will also work against substrings in addition to complete matches (raw text is the exception): text ← ⎕INP "HTML" text ← ⎕INP "EndHTMLDocument" text ← ⎕INP "CSS" In addition to these changes, a few pattern-matching bugs were fixed: * Heredocs needed leading whitespace before they would highlight * The closing line was expected to have no other characters except the terminating string (whitespace included). GNU APL actually places no such restriction, though it discards anything sharing the terminator sequence's line.
1 parent 6a70a4e commit 7e5d47a

4 files changed

Lines changed: 172 additions & 41 deletions

File tree

README.md

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,4 @@ APL language support in Atom
33

44
This package adds Atom support for everybody's favourite array-wrangling crypto-language.
55

6-
7-
8-
Known Limitations
9-
---------------------------------------------
10-
... which aren't worth fixing:
11-
12-
### Heredocs (GNU APL)
13-
1. Strings with escaped quotes can't be used as terminators:
14-
```apl
15-
text ← ⎕INP 'This won''t work'
16-
```
17-
Obviously, the solution is simple: choose a sane identifier:
18-
```apl
19-
text ← ⎕INP 'EOF'
20-
```
6+
Currently being worked on; check back in a few days. =)

grammars/apl.cson

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ foldingStartMarker: '\\{'
66
foldingStopMarker: '\\}'
77
patterns: [
88

9-
{ include: "#main" }
9+
{ include: "#heredocs" }
10+
{ include: "#main" }
1011

1112

1213
# Shebang
@@ -66,25 +67,6 @@ patterns: [
6667
{ include: "#main" }
6768
]
6869
}
69-
70-
71-
# Heredoc (GNU APL)
72-
{
73-
name: "meta.heredoc.apl"
74-
begin: "^\\s*(?:(?:⎕|[A-Za-z0-9∆⍙_]+[A-Za-z0-9∆⍙_¯]*)\\s*←\\s*)?.*?⎕INP\\s+(?:('|\")(.+?)\\1).*$"
75-
end: "^\\2$"
76-
beginCaptures:
77-
0:
78-
name: "meta.heredoc.apl"
79-
patterns: [{include: "#main"}]
80-
endCaptures:
81-
0: {name: "constant.other.apl"}
82-
contentName: "text.embedded.html.basic"
83-
patterns: [
84-
{ include: "text.html.basic" }
85-
{ include: "#embedded-apl" }
86-
]
87-
}
8870
]
8971

9072

@@ -100,8 +82,8 @@ repository:
10082
{ include: "#int" }
10183
{ include: "#name" }
10284
{ include: "#lambda" }
103-
{ include: "#symbols" }
10485
{ include: "#sysvars" }
86+
{ include: "#symbols" }
10587
]
10688
}
10789

@@ -332,8 +314,92 @@ repository:
332314
3: {name: "punctuation.assignment.switch.apl"}
333315
patterns: [{include: "#main"}]
334316
}]
317+
318+
319+
# Heredocs (GNU APL)
320+
heredocs:
321+
patterns: [{
322+
323+
# HTML
324+
name: "meta.heredoc.apl"
325+
begin: "^.*?⎕INP\\s+('|\")((?i).*?HTML?.*?)\\1.*$"
326+
end: "^.*?\\2.*?$"
327+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
328+
endCaptures: {0: {name: "constant.other.apl"}}
329+
contentName: "text.embedded.html.basic"
330+
patterns: [
331+
{ include: "text.html.basic" }
332+
{ include: "#embedded-apl" }
333+
]
334+
335+
}, {
336+
337+
# XML
338+
name: "meta.heredoc.apl"
339+
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:XML|XSLT|SVG|RSS).*?)\\1.*$"
340+
end: "^.*?\\2.*?$"
341+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
342+
endCaptures: {0: {name: "constant.other.apl"}}
343+
contentName: "text.embedded.xml"
344+
patterns: [
345+
{ include: "text.xml" }
346+
{ include: "#embedded-apl" }
347+
]
348+
349+
}, {
350+
351+
# CSS
352+
name: "meta.heredoc.apl"
353+
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:CSS|stylesheet).*?)\\1.*$"
354+
end: "^.*?\\2.*?$"
355+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
356+
endCaptures: {0: {name: "constant.other.apl"}}
357+
contentName: "source.embedded.css"
358+
patterns: [
359+
{ include: "source.css" }
360+
{ include: "#embedded-apl" }
361+
]
362+
363+
}, {
364+
365+
# JavaScript
366+
name: "meta.heredoc.apl"
367+
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:JS(?!ON)|(?:ECMA|J|Java).?Script).*?)\\1.*$"
368+
end: "^.*?\\2.*?$"
369+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
370+
endCaptures: {0: {name: "constant.other.apl"}}
371+
contentName: "source.embedded.js"
372+
patterns: [
373+
{ include: "source.js" }
374+
{ include: "#embedded-apl" }
375+
]
376+
377+
}, {
378+
379+
# JSON
380+
name: "meta.heredoc.apl"
381+
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:JSON).*?)\\1.*$"
382+
end: "^.*?\\2.*?$"
383+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
384+
endCaptures: {0: {name: "constant.other.apl"}}
385+
contentName: "source.embedded.json"
386+
patterns: [
387+
{ include: "source.json" }
388+
{ include: "#embedded-apl" }
389+
]
390+
}, {
391+
392+
# Raw text
393+
name: "meta.heredoc.apl"
394+
begin: "^.*?⎕INP\\s+('|\")(?i)((?:Raw|Plain)?\\s*Te?xt)\\1.*$"
395+
end: "^.*?\\2.*?$"
396+
beginCaptures: {0: {patterns: [{include: "#main"}]}}
397+
endCaptures: {0: {name: "constant.other.apl"}}
398+
patterns: [{ include: "#embedded-apl" }]
399+
}]
335400

336-
401+
402+
337403
# Embedded APL sequences (for GNU APL heredocs)
338404
"embedded-apl":
339405
patterns: [{

tests/gnu-web.apl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ yZ←⊃ HTML∆Ol I1, I2, I3, I4
126126
We first give an example of ⎕INP in the style of PHP and another,
127127
more compact, example further down below.
128128
129-
yBODY '<?apl' '?>' ⎕INP 'END-OF-⎕INP' php style
129+
yBODY '<?apl' '?>' ⎕INP 'END-OF-HTML' PHP-style
130130

131131
<DIV class="c1">
132132
<?apl HTML∆H1[''] xTITLE ?>
@@ -275,7 +275,7 @@ the creation of an own hosting account would be an overkill.
275275

276276
</DIV>
277277

278-
END-OF-⎕INP
278+
END-OF-HTML
279279

280280

281281
the text above used an 'escape style' similar to PHP
@@ -286,7 +286,7 @@ END-OF-⎕INP
286286
preferred style, for example the more compact { ... } style
287287
as shown in the following example:
288288
289-
yBODYyBODY, (,¨'{}') ⎕INP 'END-OF-⎕INP' more compact style
289+
yBODYyBODY, (,¨'{}') ⎕INP 'END-OF-HTML' more compact style
290290
<DIV class="c7">
291291
Return to {HTML∆x2y "http://www.gnu.org/home.html" HTML∆A "GNU's home page"}.
292292
<P>
@@ -309,7 +309,7 @@ Copyright (C) 2014 Free Software Foundation, Inc.,
309309
Verbatim copying and distribution of this entire article is
310310
permitted in any medium, provided this notice is preserved.<P>
311311
</DIV>
312-
END-OF-⎕INP
312+
END-OF-HTML
313313

314314
HTML∆emit HTML∆Document
315315

tests/heredocs.apl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
HTML
2+
text ⎕INP "END-OF-HTML"
3+
<header id="top">
4+
Heading
5+
</header>
6+
END-OF-HTML
7+
8+
9+
aaa text ⎕INP "END-OF-XHTML"
10+
<div id="top">
11+
Heading
12+
</div>
13+
END-OF-XHTML
14+
15+
16+
17+
aatext ⎕INP "END-OF-HTML"
18+
<header id="top">Heading</header>
19+
========== END-OF-HTML ===============
20+
21+
22+
23+
24+
25+
XML
26+
tree ⎕INP "END-OF-XML"
27+
<?xml version="1.0" encoding="utf-8"?>
28+
<svg><!-- Fancy lines, etc --></svg>
29+
END-OF-XML
30+
31+
svg ⎕INP "SVG"
32+
<?xml version="1.0" encoding="utf-8"?>
33+
<svg><!-- Fancy lines, etc --></svg>
34+
End of SVG
35+
36+
37+
38+
JavaScript
39+
js ⎕INP "ENDJS"
40+
"use strict";
41+
let light = "shine";
42+
function fn(){
43+
return Math.max(...[5, 6, 8]);
44+
}
45+
JSON.stringify({});
46+
const $ = s => document.querySelector(s);
47+
ENDJS
48+
49+
50+
JSON
51+
json ⎕INP "JSON"
52+
{
53+
"name": "language-apl",
54+
"version": "0.0.1",
55+
"description": "APL language support for Atom",
56+
"keywords": ["APL", "Dyalog"],
57+
"repository": "https://github.com/Alhadis/language-apl",
58+
"license": "ISC",
59+
"engines": {
60+
"atom": "*"
61+
},
62+
"dependencies": {}
63+
}
64+
JSON
65+
66+
67+
CSS
68+
styles ⎕INP "END-CSS"
69+
html{
70+
background: #f00;
71+
}
72+
END-CSS
73+
74+
75+
76+
Plain text
77+
text ⎕INP "Plain Text"
78+
Z←Z←81 9⍴1 ◊ F1←0
79+
Plain Text

0 commit comments

Comments
 (0)