diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-06-17 14:33:43 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-06-17 14:33:43 +0100 |
| commit | 17577bdd715c65e71d81f762b54b8c27f60f4535 (patch) | |
| tree | 5389d7741881b2d198daf450f915fa9b3527f7e7 | |
| parent | dc31bacddd43e100a2793c76e26d35568262d89a (diff) | |
Support underlines in style map
| -rw-r--r-- | lib/document-matchers.js | 1 | ||||
| -rw-r--r-- | lib/document-to-html.js | 15 | ||||
| -rw-r--r-- | lib/html-generator.js | 5 | ||||
| -rw-r--r-- | lib/style-reader.js | 9 | ||||
| -rw-r--r-- | tests/document-to-html.tests.js | 32 | ||||
| -rw-r--r-- | tests/html-generator.tests.js | 9 | ||||
| -rw-r--r-- | tests/mammoth.tests.js | 7 | ||||
| -rw-r--r-- | tests/style-reader.tests.js | 7 |
8 files changed, 81 insertions, 4 deletions
diff --git a/lib/document-matchers.js b/lib/document-matchers.js index 9b01dfd..a4d59be 100644 --- a/lib/document-matchers.js +++ b/lib/document-matchers.js @@ -1,5 +1,6 @@ exports.paragraph = paragraph; exports.run = run; +exports.underline = new Matcher("underline"); function paragraph(options) { diff --git a/lib/document-to-html.js b/lib/document-to-html.js index 220ae2b..264f7c9 100644 --- a/lib/document-to-html.js +++ b/lib/document-to-html.js @@ -122,8 +122,8 @@ function DocumentConversion(options) { if (run.verticalAlignment === documents.verticalAlignment.subscript) { runHtml.open(htmlPaths.element("sub")); } - if (run.isUnderline && options.convertUnderline) { - options.convertUnderline(runHtml); + if (run.isUnderline) { + convertUnderline(runHtml); } convertElements(run.children, runHtml, messages, function(err) { if (err) { @@ -136,6 +136,17 @@ function DocumentConversion(options) { }); } + function convertUnderline(runHtml) { + (options.convertUnderline || defaultConvertUnderline)(runHtml); + } + + function defaultConvertUnderline(runHtml) { + var style = findStyle({type: "underline"}); + if (style) { + runHtml.appendPath(style.to); + } + } + function findStyle(element) { for (var i = 0; i < styleMap.length; i++) { if (styleMap[i].from.matches(element)) { diff --git a/lib/html-generator.js b/lib/html-generator.js index a071a5e..a20a714 100644 --- a/lib/html-generator.js +++ b/lib/html-generator.js @@ -43,6 +43,10 @@ function HtmlGenerator(options) { } } + function appendPath(style) { + style.forEach(open); + } + function stylePartMatchesStackElement(stylePart, stackElement) { return stackElement && stylePart.matchesElement(stackElement); } @@ -86,6 +90,7 @@ function HtmlGenerator(options) { return { satisfyPath: satisfyPath, + appendPath: appendPath, text: text, open: open, close: close, diff --git a/lib/style-reader.js b/lib/style-reader.js index ef379b6..811e06e 100644 --- a/lib/style-reader.js +++ b/lib/style-reader.js @@ -109,7 +109,7 @@ function documentMatcherRule() { ); var matcherSuffixes = lop.rules.zeroOrMore(matcherSuffix); - return sequence( + var paragraphOrRun = sequence( sequence.capture(elementTypeRule), sequence.capture(matcherSuffixes) ).map(function(createMatcher, suffixes) { @@ -119,6 +119,13 @@ function documentMatcherRule() { }); return createMatcher(matcherOptions); }); + + var underline = identifierToConstant("u", documentMatchers.underline); + + return lop.rules.firstOf("element type", + paragraphOrRun, + underline + ); } function readHtmlPath(string) { diff --git a/tests/document-to-html.tests.js b/tests/document-to-html.tests.js index 5a271d0..516f2fe 100644 --- a/tests/document-to-html.tests.js +++ b/tests/document-to-html.tests.js @@ -177,7 +177,7 @@ describe('DocumentConverter', function() { }); }); - test('underline runs can be wrapped in <u> tags', function() { + test('underline runs can be wrapped in <u> tags using convertUnderline option', function() { var run = runOfText("Hello.", {isUnderline: true}); var converter = new DocumentConverter({ convertUnderline: mammoth.underline.element("u") @@ -186,6 +186,36 @@ describe('DocumentConverter', function() { assert.equal(result.value, "<u>Hello.</u>"); }); }); + + test('underline runs can be mapped using style mapping', function() { + var run = runOfText("Hello.", {isUnderline: true}); + var converter = new DocumentConverter({ + styleMap: [ + { + from: documentMatchers.underline, + to: htmlPaths.elements([htmlPaths.element("u")]) + } + ] + }); + return converter.convertToHtml(run).then(function(result) { + assert.equal(result.value, "<u>Hello.</u>"); + }); + }); + + test('style mapping for underline runs does not close parent elements', function() { + var run = runOfText("Hello.", {isUnderline: true, isBold: true}); + var converter = new DocumentConverter({ + styleMap: [ + { + from: documentMatchers.underline, + to: htmlPaths.elements([htmlPaths.element("u")]) + } + ] + }); + return converter.convertToHtml(run).then(function(result) { + assert.equal(result.value, "<strong><u>Hello.</u></strong>"); + }); + }); test('italic runs are wrapped in <em> tags', function() { var run = runOfText("Hello.", {isItalic: true}); diff --git a/tests/html-generator.tests.js b/tests/html-generator.tests.js index f361633..6921b45 100644 --- a/tests/html-generator.tests.js +++ b/tests/html-generator.tests.js @@ -69,4 +69,13 @@ describe('HtmlGenerator', function() { generator.selfClosing({tagName: "br", attributes: {"data-blah": "<"}}); return assert.equal(generator.asString(), '<br data-blah="<" />'); }); + + test('appendPath does not close currently-open elements', function() { + var generator = new HtmlGenerator(); + generator.satisfyPath(htmlPaths.elements(["strong"])); + generator.appendPath(htmlPaths.elements(["em"])); + generator.text("Hello!"); + generator.closeAll(); + return assert.equal(generator.asString(), "<strong><em>Hello!</em></strong>"); + }); }); diff --git a/tests/mammoth.tests.js b/tests/mammoth.tests.js index e016fe1..93fc966 100644 --- a/tests/mammoth.tests.js +++ b/tests/mammoth.tests.js @@ -217,6 +217,13 @@ describe('mammoth', function() { }); }); + test('underline can be configured with style mapping', function() { + var docxPath = path.join(__dirname, "test-data/underline.docx"); + return mammoth.convertToHtml({path: docxPath}, {styleMap: "u => em"}).then(function(result) { + assert.equal(result.value, '<p><strong>The </strong><strong><em>Sunset</em></strong><strong> Tree</strong></p>'); + }); + }); + test('indentation is used if prettyPrint is true', function() { var docxPath = path.join(__dirname, "test-data/single-paragraph.docx"); return mammoth.convertToHtml({path: docxPath}, {prettyPrint: true}).then(function(result) { diff --git a/tests/style-reader.tests.js b/tests/style-reader.tests.js index 7927153..59d7c51 100644 --- a/tests/style-reader.tests.js +++ b/tests/style-reader.tests.js @@ -93,6 +93,13 @@ describe("styleReader.readDocumentMatcher", function() { documentMatchers.run() ); }); + + test("reads underline", function() { + assert.deepEqual( + readDocumentMatcher("u"), + documentMatchers.underline + ); + }); }); describe("styleReader.read", function() { |
