I started using Sass (actually, scssphp, since I'm a PHP troglodyte) and I'm loving it. It makes CSS much cleaner; just having variables makes everything easier. The only catch is whether it would work with the non-standard CSS I use with my CSS parser for behaviors. The good news is that it does, with one caveat.

Continue reading ‘Using parsecss with Sass’ »

John McLear wanted to use sendkeys to help automate tests on the wicked cool Etherpad (a browser-based collaborative editor) but noted that it wouldn't quite work right. He did the debugging and it turns out that Etherpad uses a content-editable <iframe> and sendkeys would only use the parent document. He and colleagues implemented the necessary changes in bililiteRange and now it works with <iframe>s.

bililiteRange is now at version 1.2.

Thanks, John!

One of the nice things about my sendkeys plugin is the fact that it's easy to add new "special keys." I have a macro to create a link in Notepad++: it takes the selection, wraps it in <a href=""></a> and places the insertion point between the quotes so I can start typing the link.

I added two things to sendkeys to make that possible: {selection}, which remembers the original selected text and inserts it, and {mark}, which records the location of the insertion point and sets the selection there after the string is inserted. Thus, '<a href="{mark}">{selection}</a>' accomplishes the same thing and I can use it in my home-grown text editors.

<input class=text /> <input type=button class=test value="Try It" />
$('input.test').click(function(){ $('input.text').sendkeys('<a href="{mark}">{selection}</a>'); });

I use the WordPress HTML editor exclusively, with the Text Control plugin with no formatting, so the posts contain exactly the markup I want. The editor comes with "Quick Tag" buttons, that let you insert HTML tags with one click, and allows you to add custom buttons. So, for all my code samples, I want to have a <pre> button, I just create a javascript file (say, called quicktags.custom.js):

QTags.addButton('pre', 'pre', '<pre>', '</pre>\n');

And include it with the following PHP either in a plugin or my theme functions.php:

if(is_admin()){
	// it's an admin page. Add the custom editor buttons
	wp_register_script('customeditor', plugins_url('quicktags.custom.js', __FILE__), array('quicktags')); // this script depends on 'quicktags'
	wp_enqueue_script('customeditor');
}

And now I have a button that inserts <pre></pre> pairs. But there's much more you can do.

Continue reading ‘Custom Buttons in the WordPress HTML Editor’ »
Updated 2013-12-09 to use much simpler code

One thing that is nice about Prism is that it provides hooks to extend the syntax highlighting, so it is straightforward to create a plugin that adds features like my line numbering, so I can do things like:

<pre><code class="language-javascript" data-linenumber=4>
function foo(arg){
  console.log('You said: '+arg);
}</code></pre>

Download the code.

Download the CSS (the linenumbering parts are at the bottom).

See an example (working together with the line highlighting plugin)(note that Chrome requires an explicit line-height on the <pre> to work). Continue reading ‘Line Numbering Plugin for Prism’ »

I've been looking for a good Javascript-based syntax highlighter, and it looks like Prism is it. It fulfills just about all my criteria: works on code blocks whether inline or in block elements, is HTML5-friendly, uses classes on spans rather than hard-coded styles, and is easy to extend. It's what is running on the website now.

But it's not actually perfect; it mucks about with class names more than I would like (though it isn't really a problem), and it uses a different name for HTML--class="language-markup" rather than class="language-html". That is easy to fix; just do Prism.languages.html = Prism.languages.markup and you're done. The biggest downside (though not one that affects me in real life; it just seems inelegant) is that it flattens the text to analyze it (it uses var code = element.textContent.trim();. It ought to be possible to use my range routines to wrap elements without flattening them.

Be that as it may, it works well; see just about any post on the blog.

Plugins for other languages:

Plus I added a Prism.languages.markup.jquery= /\$|jQuery/ so I could mark it up separately.

I've thought about creating my own syntax highlighter. I've been using Chili, but there are some odd bugs that pop up here and there and it doesn't seem to play well with Chrome. And it hasn't been updated in 2 years.

One thing I did want was line numbering, but that's been a bugaboo of syntax highighlighters for a long time—you want the numbers but do not want them copied when code is selected. Firefox copies the numbers when using <li> elements, and tables or inserted text will also copy everything. The answer seems to be using :before to insert the line numbers, since that text won't be copied in any modern browser (IE 8 and below don't support :before, but we won't worry about that).

The issue then is how to tell CSS about the lines. We want to wrap them in <span>s, as so:

<pre>
<span class=line>This is a <em>text</em></span>
<span class=line>This is the second line</span>
</pre>

And number everything with CSS:

pre.test1 {
	counter-reset: linecounter;
}
pre.test1 span.line{
	counter-increment: linecounter;
}
pre.test1 span.line:before{
	content: counter(linecounter);
	width: 2em;
	display: inline-block;
	border-right: 1px solid black;
}

And this is the result, exactly as desired.

This is a text
This is the second line

The keys in the CSS are lines 1 and 4 that set up the counter (change line 1 to linecounter 4 to start the numbering at 5 (counter-increment increments before displaying)) (change linecounter to anything you want as long as its consistent). Line 7 displays the value of the counter in the :before pseudoelement, and lines 8-10 are just old-fashioned styling to make it prettier. You of course would want to add some padding, margin, odd/even backgrounds etc., but that's old hat.

Continue reading ‘Line Numbering in <pre> Elements’ »

I wanted to use the CSS pseudoelement :before for manipulating input elements. I had <input class="before-test"/>, and I wanted to use CSS to add a label before the element on small screens only (on a larger screen I would have a table with the label as the <th> element). So

<style>
  .before-test:before { content: "label: "; }
</style>

ought to work, right?

No.

:before,despite its name, doesn't insert its content before the element specified. It inserts the content as the first child of the element specified. In other words, it works like jQuery's prepend, not like before. See Smashing Magazine's article for more details.

So the correct way to do this is:

<div class="before-test"><input/></div>

With the selector targeting the enclosing element.

Continue reading ‘Understanding :before and :after’ »

Michael Tyson had a cool idea: instead of the search results page showing an excerpt of the first words of the post, show an excerpt that contains the search terms and highlight them (say, by making them bold). I thought his method was too complex—it requires replacing your theme's search.php with a custom page, and it shows the context of every occurrence of the search terms. I thought it would be more straightforward to use the existing search page, which should be using the_excerpt to show an extract of the found page, and use the existing filters to change the text. Also, there's no need to show every occurrence of the search terms; the first ones should be fine.

Continue reading ‘Contextual Search Results in WordPress’ »

I wanted a way to highlight search terms on the search results page (the way search engines do), by surrounding the text with <span class=whatever></span>, but simply doing preg_replace($re, '<span class=whatever>$0</span>', $text) replaces things inside any HTML tags as well. There are some solutions on the web, but the simplest one I found involves generating a new regular expression. I'd like something I can pass in the regular expression to match and the replacement text, something exactly equivalent to preg_replace.

What I came up with:

function preg_replace_text ($pattern, $replacement, $subject){
	// only replace text that is not inside tags. Assumes $subject is valid HTML and surrounded by tags
	// the (?<=>) is a lookbehind assertion to make sure the match starts with a >
	return preg_replace_callback('/(?<=>)[^<]*/', function($matches) use ($pattern, $replacement) {
		return preg_replace($pattern, $replacement, $matches[0]);
	}, $subject);
}

Hope this is useful to someone.