mirror of
https://github.com/vale981/highlight-lisp
synced 2025-03-04 17:01:38 -05:00
adding paren matching =]
This commit is contained in:
parent
1c2e649858
commit
93216f5e8a
8 changed files with 120 additions and 1 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
test/*
|
||||||
|
|
12
README.md
12
README.md
|
@ -45,6 +45,18 @@ var code = document.getElementById('my-code-element');
|
||||||
HighlightLisp.highlight_element(code);
|
HighlightLisp.highlight_element(code);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Paren matching
|
||||||
|
--------------
|
||||||
|
|
||||||
|
You can now enable paren matching (on mouse hover):
|
||||||
|
|
||||||
|
```js
|
||||||
|
HighlightLisp.paren_match();
|
||||||
|
```
|
||||||
|
|
||||||
|
This will go through all highlighted blocks of code and add mouseover/mouseout
|
||||||
|
event listeners to all ('s and )'s that highlight the matching paren on hover.
|
||||||
|
|
||||||
What gets highlighted
|
What gets highlighted
|
||||||
---------------------
|
---------------------
|
||||||
- **Functions**
|
- **Functions**
|
||||||
|
|
|
@ -420,6 +420,99 @@ var highlight_lisp = function() {
|
||||||
this.highlight_element(code);
|
this.highlight_element(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If called, enables paren matching (hovering over a paren will add the
|
||||||
|
* "active" class to both the highlighted and the matching paren)
|
||||||
|
*/
|
||||||
|
this.paren_match = function(options)
|
||||||
|
{
|
||||||
|
options || (options = {});
|
||||||
|
|
||||||
|
if(!('querySelector' in document))
|
||||||
|
{
|
||||||
|
console.error('HighlightLisp.paren_match: browser does not support querySelector/matches');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matches = function(element, selector)
|
||||||
|
{
|
||||||
|
if(!element) return;
|
||||||
|
var domatch;
|
||||||
|
var tests = ['matches', 'msMatchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector'];
|
||||||
|
for(var i = 0; i < tests.length; i++)
|
||||||
|
{
|
||||||
|
if(!(tests[i] in element)) continue;
|
||||||
|
domatch = element[tests[i]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return domatch.call(element, selector);
|
||||||
|
};
|
||||||
|
|
||||||
|
var is_paren = function(el)
|
||||||
|
{
|
||||||
|
return matches(el, 'code > .list, code span:not(.comment):not(.string) .list');
|
||||||
|
};
|
||||||
|
|
||||||
|
var find_match = function(paren)
|
||||||
|
{
|
||||||
|
// grab all non-commented/stringed parens
|
||||||
|
var children = paren.parentElement.querySelectorAll('code > span.list, code span:not(.comment):not(.string) .list');
|
||||||
|
// turn them into a real array
|
||||||
|
children = Array.prototype.slice.call(children);
|
||||||
|
|
||||||
|
var is_opening = function(el) { return el.innerHTML == '('; };
|
||||||
|
|
||||||
|
// tracks when to start counting parens
|
||||||
|
var count = false;
|
||||||
|
// tests if this is an opening or closing paren
|
||||||
|
var opening = is_opening(paren);
|
||||||
|
// if this is a closing paren, reverse the children so we can search
|
||||||
|
// backwards just by going forwards
|
||||||
|
if(!opening) children.reverse();
|
||||||
|
|
||||||
|
for(var i = 0; i < children.length; i++)
|
||||||
|
{
|
||||||
|
var child = children[i];
|
||||||
|
var open = is_opening(child);
|
||||||
|
// mark the first occurance of the paren, and start counting
|
||||||
|
// from there
|
||||||
|
if(child === paren)
|
||||||
|
{
|
||||||
|
count = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(count === false) continue;
|
||||||
|
if(opening == open) count++;
|
||||||
|
else count--;
|
||||||
|
if(count === 0) return child;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var add_class = function(el, classname, add)
|
||||||
|
{
|
||||||
|
if(!el) return;
|
||||||
|
el.className = el.className.replace(new RegExp(classname, 'g'), '');
|
||||||
|
if(add) el.className += ' '+classname;
|
||||||
|
};
|
||||||
|
|
||||||
|
var codes = document.getElementsByClassName('hl-highlighted');
|
||||||
|
for(var i = 0; i < codes.length; i++)
|
||||||
|
{
|
||||||
|
var code = codes[i];
|
||||||
|
var listener = function(add, e)
|
||||||
|
{
|
||||||
|
var hovered = e.target;
|
||||||
|
if(!is_paren(hovered)) return;
|
||||||
|
var match = find_match(hovered);
|
||||||
|
add_class(hovered, 'active', add);
|
||||||
|
add_class(match, 'active', add);
|
||||||
|
};
|
||||||
|
code.addEventListener('mouseover', listener.bind(this, true));
|
||||||
|
code.addEventListener('mouseout', listener.bind(this, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "highlight-lisp",
|
"name": "highlight-lisp",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "An HTML syntax highlighter for Common Lisp",
|
"description": "An HTML syntax highlighter for Common Lisp",
|
||||||
"author": "Andrew Lyon <orthecreedence@gmail.com>",
|
"author": "Andrew Lyon <orthecreedence@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
@ -26,3 +26,6 @@ code.hl-highlighted .comment *,
|
||||||
code.hl-highlighted .comment .string
|
code.hl-highlighted .comment .string
|
||||||
code.hl-highlighted .comment .string * {color: #777 !important;}
|
code.hl-highlighted .comment .string * {color: #777 !important;}
|
||||||
code.hl-highlighted .string .comment {color: #b5bd88 !important;}
|
code.hl-highlighted .string .comment {color: #b5bd88 !important;}
|
||||||
|
|
||||||
|
code.hl-highlighted .list.active {display: inline-block; color: #333; background: #aaa;}
|
||||||
|
|
||||||
|
|
|
@ -26,3 +26,6 @@ code.hl-highlighted .comment *,
|
||||||
code.hl-highlighted .comment .string
|
code.hl-highlighted .comment .string
|
||||||
code.hl-highlighted .comment .string * {color: #aaa !important;}
|
code.hl-highlighted .comment .string * {color: #aaa !important;}
|
||||||
code.hl-highlighted .string .comment {color: #d14 !important;}
|
code.hl-highlighted .string .comment {color: #d14 !important;}
|
||||||
|
|
||||||
|
code.hl-highlighted .list.active {display: inline-block; background: #aefff7;}
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,6 @@ code.hl-highlighted .nil {color: #f00;}
|
||||||
|
|
||||||
code.hl-highlighted .comment, code.hl-highlighted .comment *, code.hl-highlighted .comment .string {color: #aaa !important;}
|
code.hl-highlighted .comment, code.hl-highlighted .comment *, code.hl-highlighted .comment .string {color: #aaa !important;}
|
||||||
code.hl-highlighted .string, code.hl-highlighted .string * {color: #088 !important;}
|
code.hl-highlighted .string, code.hl-highlighted .string * {color: #088 !important;}
|
||||||
|
|
||||||
|
code.hl-highlighted .list.active {display: inline-block; background: #aefff7;}
|
||||||
|
|
||||||
|
|
|
@ -26,3 +26,6 @@ code.hl-highlighted .comment *,
|
||||||
code.hl-highlighted .comment .string
|
code.hl-highlighted .comment .string
|
||||||
code.hl-highlighted .comment .string * {color: #777 !important;}
|
code.hl-highlighted .comment .string * {color: #777 !important;}
|
||||||
code.hl-highlighted .string .comment {color: #db7d8e !important;}
|
code.hl-highlighted .string .comment {color: #db7d8e !important;}
|
||||||
|
|
||||||
|
code.hl-highlighted .list.active {display: inline-block; color: #333; background: #aaa;}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue