diff --git a/plugin/markdown/markdown.js b/plugin/markdown/markdown.js index 61d698795e0f95d1b635e3f8f7e1196c79ab2ee0..fccc442034ece6939feeaee3ce7d700d4a27465e 100755 --- a/plugin/markdown/markdown.js +++ b/plugin/markdown/markdown.js @@ -28,6 +28,7 @@ var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$', DEFAULT_NOTES_SEPARATOR = 'note:'; + DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '{\\\.\s*?([^}]+?)}'; /** @@ -218,7 +219,6 @@ xhr.onreadystatechange = function() { if( xhr.readyState === 4 ) { if ( xhr.status >= 200 && xhr.status < 300 ) { - section.outerHTML = slidify( xhr.responseText, { separator: section.getAttribute( 'data-separator' ), verticalSeparator: section.getAttribute( 'data-vertical' ), @@ -268,6 +268,57 @@ } + /** + * Check if a node value has the attributes pattern. + * If yes, extract it and add that value as one or several attributes + * the the terget element. + * + * You need Cache Killer on Chrome to see the effect on any FOM transformation + * directly on refresh (F5) + * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277 + */ + function addAttributeInElement( node, elementTarget, separator ){ + var mardownClassesInElementsRegex = new RegExp( separator, 'mg' ); + var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' ); + var nodeValue = node.nodeValue; + if ( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) { + + var classes = matches[1]; + nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex ); + node.nodeValue = nodeValue; + + while( matchesClass = mardownClassRegex.exec( classes ) ) { + elementTarget.setAttribute(matchesClass[1], matchesClass[2]); + } + } + } + + /** + * Add attributes to the parent element of a text node, + * or the element of an attribute node. + */ + function addAttributes( element, separator ) + { + if ( element.childNodes.length > 0 ) { + + for ( var i = 0; i < element.childNodes.length; i++ ) { + addAttributes( element.childNodes[i], separator ); + } + } + var nodeValue; + var elementTarget; + // From http://stackoverflow.com/questions/9178174/find-all-text-nodes + if ( element.nodeType == Node.TEXT_NODE && /\S/.test(element.nodeValue) ) { + addAttributeInElement( element, element.parentNode, separator ); + } + if ( element.nodeType == Node.ELEMENT_NODE && element.attributes.length > 0 ) { + for ( iattr=0; iattr<element.attributes.length; iattr++ ){ + var attr = element.attributes[iattr]; + addAttributeInElement(attr, element, separator ) + } + } + } + /** * Converts any current data-markdown slides in the * DOM to HTML. @@ -289,6 +340,9 @@ var markdown = getMarkdownFromSlide( section ); section.innerHTML = marked( markdown ); + addAttributes( section, section.getAttribute( 'data-element-attributes' ) || + section.parentNode.getAttribute( 'data-element-attributes' ) || + DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR ); // If there were notes, we need to re-add them after // having overwritten the section's HTML diff --git a/test/red-curtain-50x50.jpg b/test/red-curtain-50x50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ddfe7a637d747dedc7c7c71a01431e7e76e0eb6f Binary files /dev/null and b/test/red-curtain-50x50.jpg differ diff --git a/test/test-element-attributes-markdown.html b/test/test-element-attributes-markdown.html new file mode 100644 index 0000000000000000000000000000000000000000..e547d161da004c5d56dfe7c45f5281ae0ae4349a --- /dev/null +++ b/test/test-element-attributes-markdown.html @@ -0,0 +1,84 @@ +<!doctype html> +<html lang="en"> + + <head> + <meta charset="utf-8"> + + <title>reveal.js - Test Markdown</title> + + <link rel="stylesheet" href="../css/reveal.min.css"> + <link rel="stylesheet" href="qunit-1.12.0.css"> + </head> + + <body style="overflow: auto;"> + + <div id="qunit"></div> + <div id="qunit-fixture"></div> + + <div class="reveal" style="display: none;"> + + <div class="slides"> + + <!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> --> + + <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes --> + <section data-markdown data-separator="^\n---\n$" + data-vertical="^\n--\n$" + data-element-attributes="{_\s*?([^}]+?)}"> + <script type="text/template"> + ## Slide 1.1 {_class="fragment fade-out" data-fragment-index="1"} + + -- + + ## Slide 1.2 {_class="fragment shrink"} + + Paragraph 1 {_class="fragment grow"} + + Paragraph 2 {_class="fragment grow"} + + - list item 1 {_class="fragment roll-in"} + - list item 2 {_class="fragment roll-in"} + - list item 3 {_class="fragment roll-in"} + + + --- + + ## Slide 2 + + + Paragraph 1.2 + multi-line {_class="fragment highlight-red"} + + Paragraph 2.2 {_class="fragment highlight-red"} + + Paragraph 2.3 {_class="fragment highlight-red"} + + Paragraph 2.4 {_class="fragment highlight-red"} + + - list item 1 {_class="fragment highlight-green"} + - list item 2 {_class="fragment highlight-green"} + - list item 3 {_class="fragment highlight-green"} + - list item 4 {_class="fragment highlight-green"} + - list item 5 {_class="fragment highlight-green"} + +Test + + + + </script> + </section> + + </div> + + </div> + + <script src="../lib/js/head.min.js"></script> + <script src="../js/reveal.min.js"></script> + <script src="../plugin/markdown/marked.js"></script> + <script src="../plugin/markdown/markdown.js"></script> + <script src="qunit-1.12.0.js"></script> + + <script src="test-element-attributes-markdown.js"></script> + + </body> +</html> diff --git a/test/test-element-attributes-markdown.js b/test/test-element-attributes-markdown.js new file mode 100644 index 0000000000000000000000000000000000000000..e79806c63ed86376d36aa5f5ce8523bc9b0c1895 --- /dev/null +++ b/test/test-element-attributes-markdown.js @@ -0,0 +1,38 @@ + + +Reveal.addEventListener( 'ready', function() { + + QUnit.module( 'Markdown' ); + + test( 'Vertical separator', function() { + strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' ); + }); + + + test( 'Attributes on vertical slides header', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' ); + strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' ); + }); + + test( 'Attributes on vertical slides paragraphs', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' ); + }); + + test( 'Attributes on vertical slides list items', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' ); + }); + + test( 'Attributes on horizontal slides paragraphs', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' ); + }); + test( 'Attributes on horizontal slides list items', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' ); + }); + test( 'Attributes on horizontal slides list items', function() { + strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' ); + }); + +} ); + +Reveal.initialize(); +