Skip to content

Commit

Permalink
Fix overzealous heredoc highlighting
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Alhadis committed Mar 4, 2016
1 parent 6a70a4e commit 7e5d47a
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 41 deletions.
16 changes: 1 addition & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,4 @@ APL language support in Atom

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



Known Limitations
---------------------------------------------
... which aren't worth fixing:

### Heredocs (GNU APL)
1. Strings with escaped quotes can't be used as terminators:
```apl
text ← ⎕INP 'This won''t work'
```
Obviously, the solution is simple: choose a sane identifier:
```apl
text ← ⎕INP 'EOF'
```
Currently being worked on; check back in a few days. =)
110 changes: 88 additions & 22 deletions grammars/apl.cson
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ foldingStartMarker: '\\{'
foldingStopMarker: '\\}'
patterns: [

{ include: "#main" }
{ include: "#heredocs" }
{ include: "#main" }


# Shebang
Expand Down Expand Up @@ -66,25 +67,6 @@ patterns: [
{ include: "#main" }
]
}


# Heredoc (GNU APL)
{
name: "meta.heredoc.apl"
begin: "^\\s*(?:(?:⎕|[A-Za-z0-9∆⍙_]+[A-Za-z0-9∆⍙_¯]*)\\s*←\\s*)?.*?⎕INP\\s+(?:('|\")(.+?)\\1).*$"
end: "^\\2$"
beginCaptures:
0:
name: "meta.heredoc.apl"
patterns: [{include: "#main"}]
endCaptures:
0: {name: "constant.other.apl"}
contentName: "text.embedded.html.basic"
patterns: [
{ include: "text.html.basic" }
{ include: "#embedded-apl" }
]
}
]


Expand All @@ -100,8 +82,8 @@ repository:
{ include: "#int" }
{ include: "#name" }
{ include: "#lambda" }
{ include: "#symbols" }
{ include: "#sysvars" }
{ include: "#symbols" }
]
}

Expand Down Expand Up @@ -332,8 +314,92 @@ repository:
3: {name: "punctuation.assignment.switch.apl"}
patterns: [{include: "#main"}]
}]


# Heredocs (GNU APL)
heredocs:
patterns: [{

# HTML
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")((?i).*?HTML?.*?)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
contentName: "text.embedded.html.basic"
patterns: [
{ include: "text.html.basic" }
{ include: "#embedded-apl" }
]

}, {

# XML
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:XML|XSLT|SVG|RSS).*?)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
contentName: "text.embedded.xml"
patterns: [
{ include: "text.xml" }
{ include: "#embedded-apl" }
]

}, {

# CSS
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:CSS|stylesheet).*?)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
contentName: "source.embedded.css"
patterns: [
{ include: "source.css" }
{ include: "#embedded-apl" }
]

}, {

# JavaScript
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:JS(?!ON)|(?:ECMA|J|Java).?Script).*?)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
contentName: "source.embedded.js"
patterns: [
{ include: "source.js" }
{ include: "#embedded-apl" }
]

}, {

# JSON
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")((?i).*?(?:JSON).*?)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
contentName: "source.embedded.json"
patterns: [
{ include: "source.json" }
{ include: "#embedded-apl" }
]
}, {

# Raw text
name: "meta.heredoc.apl"
begin: "^.*?⎕INP\\s+('|\")(?i)((?:Raw|Plain)?\\s*Te?xt)\\1.*$"
end: "^.*?\\2.*?$"
beginCaptures: {0: {patterns: [{include: "#main"}]}}
endCaptures: {0: {name: "constant.other.apl"}}
patterns: [{ include: "#embedded-apl" }]
}]




# Embedded APL sequences (for GNU APL heredocs)
"embedded-apl":
patterns: [{
Expand Down
8 changes: 4 additions & 4 deletions tests/gnu-web.apl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ yZ←⊃ HTML∆Ol I1, I2, I3, I4
We first give an example of ⎕INP in the style of PHP and another,
more compact, example further down below.
yBODY '<?apl' '?>' ⎕INP 'END-OF-⎕INP' php style
yBODY '<?apl' '?>' ⎕INP 'END-OF-HTML' PHP-style

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

</DIV>

END-OF-⎕INP
END-OF-HTML


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

HTML∆emit HTML∆Document

Expand Down
79 changes: 79 additions & 0 deletions tests/heredocs.apl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
HTML
text ⎕INP "END-OF-HTML"
<header id="top">
Heading
</header>
END-OF-HTML


aaa text ⎕INP "END-OF-XHTML"
<div id="top">
Heading
</div>
END-OF-XHTML



aatext ⎕INP "END-OF-HTML"
<header id="top">Heading</header>
========== END-OF-HTML ===============





XML
tree ⎕INP "END-OF-XML"
<?xml version="1.0" encoding="utf-8"?>
<svg><!-- Fancy lines, etc --></svg>
END-OF-XML

svg ⎕INP "SVG"
<?xml version="1.0" encoding="utf-8"?>
<svg><!-- Fancy lines, etc --></svg>
End of SVG



JavaScript
js ⎕INP "ENDJS"
"use strict";
let light = "shine";
function fn(){
return Math.max(...[5, 6, 8]);
}
JSON.stringify({});
const $ = s => document.querySelector(s);
ENDJS


JSON
json ⎕INP "JSON"
{
"name": "language-apl",
"version": "0.0.1",
"description": "APL language support for Atom",
"keywords": ["APL", "Dyalog"],
"repository": "https://github.com/Alhadis/language-apl",
"license": "ISC",
"engines": {
"atom": "*"
},
"dependencies": {}
}
JSON


CSS
styles ⎕INP "END-CSS"
html{
background: #f00;
}
END-CSS



Plain text
text ⎕INP "Plain Text"
Z←Z←81 9⍴1 ◊ F1←0
Plain Text

0 comments on commit 7e5d47a

Please sign in to comment.