Skip to content

Commit 70a7265

Browse files
Fix tabbed Literate CoffeeScript (#4345)
* failing test case * add markdown parser for literate coffeescript this should help to handle ligitimate markdown with indentation correctly * Update generated code * Update package.json * Add `marked` dependency to browser version of CoffeeScript * Update invertLiterate to use a randomly-generated token that we check for uniqueness, rather than a magic number that we hope might not occur in the code * Fix typos
1 parent b35bb20 commit 70a7265

File tree

6 files changed

+176
-37
lines changed

6 files changed

+176
-37
lines changed

Cakefile

+8
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ task 'build:parser', 'rebuild the Jison parser (run build first)', ->
140140

141141
task 'build:browser', 'rebuild the merged script for inclusion in the browser', ->
142142
code = ''
143+
for {name, src} in [{name: 'marked', src: 'lib/marked.js'}]
144+
code += """
145+
require['#{name}'] = (function() {
146+
var exports = {}, module = {exports: exports};
147+
#{fs.readFileSync "node_modules/#{name}/#{src}"}
148+
return module.exports;
149+
})();
150+
"""
143151
for name in ['helpers', 'rewriter', 'lexer', 'parser', 'scope', 'nodes', 'sourcemap', 'coffee-script', 'browser']
144152
code += """
145153
require['./#{name}'] = (function() {

extras/coffee-script.js

+8-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/coffee-script/helpers.js

+20-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@
4444
"highlight.js": "~9.7.0",
4545
"underscore": "~1.8.3",
4646
"docco": "~0.7.0"
47+
},
48+
"dependencies": {
49+
"marked": "~0.3.6"
4750
}
4851
}

src/helpers.coffee

+29-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
# the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
33
# arrays, count characters, that sort of thing.
44

5+
marked = require 'marked'
6+
# marked.setOptions
7+
# renderer: new marked.Renderer()
8+
# gfm: true
9+
# tables: true
10+
# breaks: false
11+
# pedantic: false
12+
# sanitize: true
13+
# smartLists: true
14+
# smartypants: false
15+
516
# Peek at the beginning of a given string to see if it matches a sequence.
617
exports.starts = (string, literal, start) ->
718
literal is string.substr start, literal.length
@@ -67,19 +78,25 @@ exports.some = Array::some ? (fn) ->
6778
return true for e in this when fn e
6879
false
6980

70-
# Simple function for inverting Literate CoffeeScript code by putting the
71-
# documentation in comments, producing a string of CoffeeScript code that
72-
# can be compiled "normally".
81+
# Simple function for extracting code from Literate CoffeeScript by stripping
82+
# out all non-code blocks, producing a string of CoffeeScript code that can
83+
# be compiled normally.”
7384
exports.invertLiterate = (code) ->
74-
maybe_code = true
75-
lines = for line in code.split('\n')
76-
if maybe_code and /^([ ]{4}|[ ]{0,3}\t)/.test line
77-
line
78-
else if maybe_code = /^\s*$/.test line
79-
line
80-
else
81-
'# ' + line
82-
lines.join '\n'
85+
# Create a placeholder for tabs, that isn’t used anywhere in `code`, and then
86+
# re-insert the tabs after code extraction.
87+
generateRandomToken = ->
88+
"#{Math.random() * Date.now()}"
89+
while token is undefined or code.indexOf(token) isnt -1
90+
token = generateRandomToken()
91+
92+
code = code.replace "\t", token
93+
# Parse as markdown, discard everything except code blocks.
94+
out = ""
95+
for item in marked.lexer code, {}
96+
out += "#{item.text}\n" if item.type is 'code'
97+
# Put the tabs back in.
98+
out.replace token, "\t"
99+
out
83100

84101
# Merge two jison-style location data objects together.
85102
# If `last` is not provided, this will simply return `first`.

test/literate.litcoffee

+108
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,111 @@ Tabs work too:
5555

5656
test "tabbed code", ->
5757
ok yes
58+
59+
---
60+
61+
# keep track of whether code blocks are executed or not
62+
executed = false
63+
64+
<p>
65+
66+
executed = true # should not execute, this is just HTML para, not code!
67+
68+
</p>
69+
70+
test "should ignore indented sections inside HTML", ->
71+
eq executed, false
72+
73+
---
74+
75+
* A list item with a code block:
76+
77+
test "basic literate CoffeeScript parsing", ->
78+
ok yes
79+
80+
---
81+
82+
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
83+
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
84+
viverra nec, fringilla in, laoreet vitae, risus.
85+
86+
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
87+
Suspendisse id sem consectetuer libero luctus adipiscing.
88+
89+
---
90+
91+
1. This is a list item with two paragraphs. Lorem ipsum dolor
92+
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
93+
mi posuere lectus.
94+
95+
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
96+
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
97+
sit amet velit.
98+
99+
2. Suspendisse id sem consectetuer libero luctus adipiscing.
100+
101+
---
102+
103+
1. This is a list item with two paragraphs. Lorem ipsum dolor
104+
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
105+
mi posuere lectus.
106+
107+
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
108+
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
109+
sit amet velit.
110+
111+
2. Suspendisse id sem consectetuer libero luctus adipiscing.
112+
113+
---
114+
115+
* A list item with a blockquote:
116+
117+
> This is a blockquote
118+
> inside a list item.
119+
120+
---
121+
122+
This next one probably passes because a string is inoffensive in compiled js, also, can't get `marked` to parse it correctly, and not sure if empty line is permitted between title and reference
123+
124+
This is [an example][id] reference-style link.
125+
[id]: http://example.com/
126+
127+
"Optional Title Here"
128+
129+
---
130+
131+
executed = no
132+
133+
1986. What a great season.
134+
executed = yes
135+
136+
and test...
137+
138+
test "should recognise indented code blocks in lists", ->
139+
ok executed
140+
141+
---
142+
143+
executed = no
144+
145+
1986. What a great season.
146+
147+
executed = yes
148+
149+
and test...
150+
151+
test "should recognise indented code blocks in lists with empty line as separator", ->
152+
ok executed
153+
154+
---
155+
156+
executed = no
157+
158+
1986\. What a great season.
159+
executed = yes
160+
161+
and test...
162+
163+
test "should ignore indented code in escaped list like number", ->
164+
eq executed, no
165+

0 commit comments

Comments
 (0)