Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#31 2016-03-15 00:47:51

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 5,229
Website GitHub

Re: Prism for html preview in write tab

sacripant wrote #298225:

Meanwhile, it’s a good idea to make your first plugin for txp 4.6 :)

Not quite a plugin, but something to try out. Paste the following into the Additional js code box of the “Write Tab Customize” plugin:

<style>
#main_content .text .microcode-wrapper {
  position: relative;
  height:auto;
  margin-bottom
}
#main_content .text .microcode-wrapper .code-input,
#main_content .text .microcode-wrapper .code-output {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100%;
  padding: 1rem;
  background: transparent;
  white-space: pre-wrap;
  font-family: Consolas,Menlo,Monaco,monospace;
  font-size: 14px;
  line-height: 1.5em;
  word-wrap: break-word;
}
#main_content .text .microcode-wrapper .code-input {
  opacity: 0.7;
  margin: 0;
  color: #999;
  resize: none;
}
#main_content .text .microcode-wrapper .code-output {
  pointer-events: none;
  border-color: transparent;
  z-index: 3;
  margin: 0;
  overflow-y: auto;
  line-height: 1.5;
}
#main_content .text .microcode-wrapper .code-output code {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 1rem;
  display: block;
  color: #666;
  font-size: 14px;
  font-family: Consolas,Menlo,Monaco,monospace;
  word-wrap: break-word;
  white-space: pre-wrap;
}
</style>
<script>
;var MicroCode = (function(){
	return {
		init: function(inputSel, outputSel){
			this.focusInput(inputSel);
			this.resizeOutput(outputSel, $(inputSel).outerHeight() );
			this.listenForInput(inputSel, outputSel);
			this.renderOutput(outputSel, $(inputSel)[0].value);
			this.listenerForScroll(inputSel, outputSel);
			this.listenerForResize(inputSel, outputSel);
		},

		listenForInput: function(inputSel, outputSel){
			var self = this;

			$(inputSel).on('input keydown', function(key){
				var input = this,
					selStartPos = input.selectionStart,
					inputVal = input.value;

				if(key.keyCode === 9){
					input.value = inputVal.substring(0, selStartPos) + "    " + inputVal.substring(selStartPos, input.value.length);
					input.selectionStart = selStartPos + 4;
					input.selectionEnd = selStartPos + 4;
					key.preventDefault();
				}

				self.renderOutput(outputSel, this.value);
			});

			Prism.highlightAll();
		},

		listenerForScroll: function(inputSel, outputSel){
			$(inputSel).on('scroll', function(){
				console.log(this.scrollTop);
				$(outputSel)[0].scrollTop = this.scrollTop;
			});
		},

		listenerForResize: function(inputSel, outputSel){
		  var self = this;
			$(inputSel).on('autosize:resized', function() {
				self.resizeOutput(outputSel, $(inputSel).outerHeight() );
			});
		},

		resizeOutput: function(outputSel, value){
		  $(outputSel).add($(outputSel).parent()).height(value);
		},

		renderOutput: function(outputSel, value){
			$('code', outputSel)
				.html(value
				.replace(/&/g, "&amp;")
				.replace(/</g, "&lt;")
				.replace(/>/g, "&gt;") + "\n");

			Prism.highlightAll();
		},

		focusInput: function(inputSel){
			var input = $(inputSel);

			input.focus();

			input[0].selectionStart = input[0].value.length;
			input[0].selectionEnd = input[0].value.length;
		}
	}
})();

$(function() {
  var MicroCodeSyntax = 'textile';
  var $Textareas = $('#body').add('#excerpt');

  // add wrapper and input class
  $Textareas.addClass('code-input').wrap('<div class="microcode-wrapper"></div>');

  // add styled code output container
  $('<pre class="body-output code-output language-' + MicroCodeSyntax + '"><code class="language-' + MicroCodeSyntax + '"></code></pre>').insertAfter('#body');
  $('<pre class="excerpt-output code-output language-' + MicroCodeSyntax + '"><code class="language-' + MicroCodeSyntax + '"></code></pre>').insertAfter('#excerpt');

  // initiate MicroCode syntax highlighting
  MicroCode.init('#body', '.body-output');
  MicroCode.init('#excerpt', '.excerpt-output');

});
</script>

And you should have live textile highlighted textareas for the body and excerpt fields (v4.6 only) using the bundled prism syntax highlighter. By changing the var MicroCodeSyntax = 'textile'; to markdown it should also do markdown syntax highlighting.

There are advantages …

  • You edit directly in the textarea, not in an editor that has to pass the code back to the textarea, so saving works fine.
  • It’s comparatively lean and responds to changing textarea widths and heights (as far as I’ve tested).

… and disadvantages to this method …

  • It works by fading back the textarea text and overlaying a div directly over the textarea with the syntax highlighting. Hence the font, font-size, padding, line-spacing and widths of the overlay and the textarea must therefore be styled identically. You type as it were through the overlay into the textarea. Occasionally you’ll see that they don’t tally, e.g. when text is italicised, or when for some reason wrapping goes awry.
  • Not sure how well it works in old browsers.

The biggest disadvantage is that prism textile highlighter doesn’t seem to properly highlight certain situations, that do, however, crop up fairly often, for example:

  • hyphens and underscores in file names or in date sequences, e.g. 21-23 May / 13-14 June register as strikethrough or italic. Both occur frequently in links or file_download links.
  • Highlighting in an ordered or unordered list doesn’t appear to work at all
  • And probably more.

If this is due to some setting in prismjs I’m not aware of, do let me know.

Problem solutions and problems with those solutions:

  • Reducing the opacity of the textarea further helps reduce the overlap effect, but the blinking cursor fades with it. Are there ways around that.
  • If someone more knowledgeable were able to make the prism textile syntax parser more robust, it could be quite usable.

Note: if you make own changes to the code, make sure the &amp;, &lt; and &gt; in the RenderOutput function haven’t been encoded by bot_wtc.

BTW: All code optimisations welcome.


TXP Builders – finely-crafted code, design and txp

Offline

#32 2016-03-15 20:54:00

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 5,229
Website GitHub

Re: Prism for html preview in write tab

This is a screenshot using the standard css that comes with prism:

It also shows the problems:

  • Syntax highlighting works fine in a paragraph, but not in the same text in the bullet points beneath it. Why?
  • Hyphens in the link address are not ignored and show the del styling
  • Underscores in the link address are not ignored and show as italic
  • If you look carefully, you can see the faded straight text beneath the italicised text.

TXP Builders – finely-crafted code, design and txp

Offline

#33 2016-03-15 21:19:46

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 5,229
Website GitHub

Re: Prism for html preview in write tab

And this is a screenshot of the same but using markdown syntax:

Some things work better in markdown, like the syntax highlighting in bullet points but underscores in.


TXP Builders – finely-crafted code, design and txp

Offline

Board footer

Powered by FluxBB