Estevao Soares dos Santos преди 8 години
родител
ревизия
0bc7bd1bd8

+ 4 - 2
README.md

@@ -198,7 +198,7 @@ var defaultOptions = showdown.getDefaultOptions();
 
  * **noHeaderId**: (boolean) [default false] Disable the automatic generation of header ids. Setting to true overrides **prefixHeaderId**
 
- * **customizedHeaderId**: (boolean) [default false] Use text in curly braces as header id.
+ * **customizedHeaderId**: (boolean) [default false] Use text in curly braces as header id. (since v1.7.0)
    Example:
    ```
    ## Sample header {real-id}     will use real-id as id
@@ -328,7 +328,9 @@ var defaultOptions = showdown.getDefaultOptions();
 
    NOTE: Prior to version 1.6.1, emails would always be obfuscated through dec and hex encoding.
 
- * **openLinksInNewWindow**: (boolean) [default false] Open all links in new windows (by adding the attribute `target="_blank"` to `<a>` tags)
+ * **openLinksInNewWindow**: (boolean) [default false] Open all links in new windows (by adding the attribute `target="_blank"` to `<a>` tags) (since v1.7.0)
+
+ * **backslashEscapesHTMLTags**: (boolean) [default false] Support for HTML Tag escaping. ex: `\<div>foo\</div>` (since v1.7.2)
 
 **NOTE**: Please note that until version 1.6.0, all of these options are ***DISABLED*** by default in the cli tool.
  

+ 32 - 9
dist/showdown.js

@@ -1,4 +1,4 @@
-;/*! showdown 02-06-2017 */
+;/*! showdown 04-08-2017 */
 (function(){
 /**
  * Created by Tivie on 13-07-2015.
@@ -127,6 +127,11 @@ function getDefaultOpts (simple) {
       defaultValue: false,
       description: 'Open all links in new windows',
       type: 'boolean'
+    },
+    backslashEscapesHTMLTags: {
+      defaultValue: false,
+      description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
+      type: 'boolean'
     }
   };
   if (simple === false) {
@@ -1426,8 +1431,12 @@ showdown.subParser('anchors', function (text, options, globals) {
       if (!showdown.helper.isString(options.ghMentionsLink)) {
         throw new Error('ghMentionsLink option must be a string');
       }
-      var lnk = options.ghMentionsLink.replace(/\{u}/g, username);
-      return st + '<a href="' + lnk + '">' + mentions + '</a>';
+      var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
+          target = '';
+      if (options.openLinksInNewWindow) {
+        target = ' target="¨E95Eblank"';
+      }
+      return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
     });
   }
 
@@ -1940,14 +1949,26 @@ showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
         return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
       };
 
+  if (options.backslashEscapesHTMLTags) {
+    // encode backslash escaped HTML tags
+    text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
+      return '&lt;' + inside + '&gt;';
+    });
+  }
+
+  // hash HTML Blocks
   for (var i = 0; i < blockTags.length; ++i) {
 
     var opTagPos,
-        rgx1     = new RegExp('^ {0,3}<' + blockTags[i] + '\\b[^>]*>', 'im'),
+        rgx1     = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
         patLeft  = '<' + blockTags[i] + '\\b[^>]*>',
         patRight = '</' + blockTags[i] + '>';
     // 1. Look for the first position of the first opening HTML tag in the text
     while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
+
+      // if the HTML tag is \ escaped, we need to escape it and break
+
+
       //2. Split the text in that position
       var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
       //3. Match recursively
@@ -2443,16 +2464,14 @@ showdown.subParser('lists', function (text, options, globals) {
         item = showdown.subParser('lists')(item, options, globals);
         item = item.replace(/\n$/, ''); // chomp(item)
         item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
+
         // Colapse double linebreaks
         item = item.replace(/\n\n+/g, '\n\n');
-        // replace double linebreaks with a placeholder
-        item = item.replace(/\n\n/g, '¨B');
         if (isParagraphed) {
           item = showdown.subParser('paragraphs')(item, options, globals);
         } else {
           item = showdown.subParser('spanGamut')(item, options, globals);
         }
-        item = item.replace(/¨B/g, '\n\n');
       }
 
       // now we need to remove the marker (¨A)
@@ -2684,7 +2703,10 @@ showdown.subParser('spanGamut', function (text, options, globals) {
   // Do hard breaks
   if (options.simpleLineBreaks) {
     // GFM style hard breaks
-    text = text.replace(/\n/g, '<br />\n');
+    // only add line breaks if the text does not contain a block (special case for lists)
+    if (!/\n\n¨K/.test(text)) {
+      text = text.replace(/\n+/g, '<br />\n');
+    }
   } else {
     // Vanilla hard breaks
     text = text.replace(/  +\n/g, '<br />\n');
@@ -2780,7 +2802,8 @@ showdown.subParser('tables', function (text, options, globals) {
   function parseHeaders (header, style) {
     var id = '';
     header = header.trim();
-    if (options.tableHeaderId) {
+    // support both tablesHeaderId and tableHeaderId due to error in documention so we don't break backwards compatibility
+    if (options.tablesHeaderId || options.tableHeaderId) {
       id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
     }
     header = showdown.subParser('spanGamut')(header, options, globals);

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
dist/showdown.js.map


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/showdown.min.js


Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
dist/showdown.min.js.map


+ 5 - 0
src/options.js

@@ -125,6 +125,11 @@ function getDefaultOpts (simple) {
       defaultValue: false,
       description: 'Open all links in new windows',
       type: 'boolean'
+    },
+    backslashEscapesHTMLTags: {
+      defaultValue: false,
+      description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
+      type: 'boolean'
     }
   };
   if (simple === false) {

+ 6 - 2
src/subParsers/anchors.js

@@ -82,8 +82,12 @@ showdown.subParser('anchors', function (text, options, globals) {
       if (!showdown.helper.isString(options.ghMentionsLink)) {
         throw new Error('ghMentionsLink option must be a string');
       }
-      var lnk = options.ghMentionsLink.replace(/\{u}/g, username);
-      return st + '<a href="' + lnk + '">' + mentions + '</a>';
+      var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
+          target = '';
+      if (options.openLinksInNewWindow) {
+        target = ' target="¨E95Eblank"';
+      }
+      return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
     });
   }
 

+ 13 - 1
src/subParsers/hashHTMLBlocks.js

@@ -48,14 +48,26 @@ showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
         return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
       };
 
+  if (options.backslashEscapesHTMLTags) {
+    // encode backslash escaped HTML tags
+    text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
+      return '&lt;' + inside + '&gt;';
+    });
+  }
+
+  // hash HTML Blocks
   for (var i = 0; i < blockTags.length; ++i) {
 
     var opTagPos,
-        rgx1     = new RegExp('^ {0,3}<' + blockTags[i] + '\\b[^>]*>', 'im'),
+        rgx1     = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
         patLeft  = '<' + blockTags[i] + '\\b[^>]*>',
         patRight = '</' + blockTags[i] + '>';
     // 1. Look for the first position of the first opening HTML tag in the text
     while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
+
+      // if the HTML tag is \ escaped, we need to escape it and break
+
+
       //2. Split the text in that position
       var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
       //3. Match recursively

+ 1 - 3
src/subParsers/lists.js

@@ -93,16 +93,14 @@ showdown.subParser('lists', function (text, options, globals) {
         item = showdown.subParser('lists')(item, options, globals);
         item = item.replace(/\n$/, ''); // chomp(item)
         item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
+
         // Colapse double linebreaks
         item = item.replace(/\n\n+/g, '\n\n');
-        // replace double linebreaks with a placeholder
-        item = item.replace(/\n\n/g, '¨B');
         if (isParagraphed) {
           item = showdown.subParser('paragraphs')(item, options, globals);
         } else {
           item = showdown.subParser('spanGamut')(item, options, globals);
         }
-        item = item.replace(/¨B/g, '\n\n');
       }
 
       // now we need to remove the marker (¨A)

+ 4 - 1
src/subParsers/spanGamut.js

@@ -32,7 +32,10 @@ showdown.subParser('spanGamut', function (text, options, globals) {
   // Do hard breaks
   if (options.simpleLineBreaks) {
     // GFM style hard breaks
-    text = text.replace(/\n/g, '<br />\n');
+    // only add line breaks if the text does not contain a block (special case for lists)
+    if (!/\n\n¨K/.test(text)) {
+      text = text.replace(/\n+/g, '<br />\n');
+    }
   } else {
     // Vanilla hard breaks
     text = text.replace(/  +\n/g, '<br />\n');

+ 2 - 1
src/subParsers/tables.js

@@ -22,7 +22,8 @@ showdown.subParser('tables', function (text, options, globals) {
   function parseHeaders (header, style) {
     var id = '';
     header = header.trim();
-    if (options.tableHeaderId) {
+    // support both tablesHeaderId and tableHeaderId due to error in documention so we don't break backwards compatibility
+    if (options.tablesHeaderId || options.tableHeaderId) {
       id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
     }
     header = showdown.subParser('spanGamut')(header, options, globals);

+ 1 - 0
test/features/#374.escape-html-tags.html

@@ -0,0 +1 @@
+<p>&lt;div&gt;foo&lt;/div&gt;</p>

+ 1 - 0
test/features/#374.escape-html-tags.md

@@ -0,0 +1 @@
+\<div>foo\</div>

+ 14 - 0
test/issues/#397.unordered-list-strange-behavior.html

@@ -0,0 +1,14 @@
+<ul>
+    <li><p><strong>Customer</strong> – Opens the Customer List. Refer to the document “Customer Management”.</p>
+        <ul>
+            <li>Customer List</li>
+            <li>New Customer</li>
+            <li>Customer Prices</li>
+            <li>Appointments</li></ul></li>
+    <li><p><strong>Designer</strong> - Opens the Designer List. Refer to the document “Designer Commissions”.</p>
+        <ul>
+            <li>Designer List</li>
+            <li>New Designer</li>
+            <li>Designer Payment List</li>
+            <li>New Designer Payment</li></ul></li>
+</ul>

+ 11 - 0
test/issues/#397.unordered-list-strange-behavior.md

@@ -0,0 +1,11 @@
+- **Customer** – Opens the Customer List. Refer to the document “Customer Management”.
+    - Customer List
+    - New Customer
+    - Customer Prices
+    - Appointments
+
+- **Designer** - Opens the Designer List. Refer to the document “Designer Commissions”.
+    - Designer List
+    - New Designer
+    - Designer Payment List
+    - New Designer Payment

+ 3 - 1
test/node/testsuite.features.js

@@ -80,6 +80,8 @@ describe('makeHtml() features testsuite', function () {
         converter = new showdown.Converter({customizedHeaderId: true});
       } else if (testsuite[i].name === '#378.simplifiedAutoLinks-with-excludeTrailingPunctuationFromURLs') {
         converter = new showdown.Converter({simplifiedAutoLink: true, excludeTrailingPunctuationFromURLs: true});
+      } else if (testsuite[i].name === '#374.escape-html-tags') {
+        converter = new showdown.Converter({backslashEscapesHTMLTags: true});
       } else if (testsuite[i].name === '#379.openLinksInNewWindow-breaks-em-markdup') {
         converter = new showdown.Converter({openLinksInNewWindow: true});
       } else {
@@ -95,7 +97,7 @@ describe('makeHtml() features testsuite', function () {
         suite = tableSuite;
     for (var i = 0; i < suite.length; ++i) {
       if (suite[i].name === 'basic-with-header-ids') {
-        converter = new showdown.Converter({tables: true, tableHeaderId: true});
+        converter = new showdown.Converter({tables: true, tablesHeaderId: true});
       } else if (suite[i].name === '#179.parse-md-in-table-ths') {
         converter = new showdown.Converter({tables: true, strikethrough: true});
       } else {

Някои файлове не бяха показани, защото твърде много файлове са промени