Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Convert to HTML all ordered list styles types #433

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/docx/numbering-xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ function readAbstractNum(element) {
levels[levelIndex] = {
isOrdered: numFmt !== "bullet",
level: levelIndex,
paragraphStyleId: paragraphStyleId
paragraphStyleId: paragraphStyleId,
listStyleType: numFmt !== "bullet" ? numFmt : undefined
};
});

Expand Down
37 changes: 31 additions & 6 deletions lib/options-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,60 @@ var defaultStyleMap = exports._defaultStyleMap = [
"p[style-name='heading 4'] => h4:fresh",
"p[style-name='heading 5'] => h5:fresh",
"p[style-name='heading 6'] => h6:fresh",

"r[style-name='Strong'] => strong",

"p[style-name='footnote text'] => p:fresh",
"r[style-name='footnote reference'] =>",
"p[style-name='endnote text'] => p:fresh",
"r[style-name='endnote reference'] =>",
"p[style-name='annotation text'] => p:fresh",
"r[style-name='annotation reference'] =>",

// LibreOffice
"p[style-name='Footnote'] => p:fresh",
"r[style-name='Footnote anchor'] =>",
"p[style-name='Endnote'] => p:fresh",
"r[style-name='Endnote anchor'] =>",

"p:unordered-list(1) => ul > li:fresh",
"p:unordered-list(2) => ul|ol > li > ul > li:fresh",
"p:unordered-list(3) => ul|ol > li > ul|ol > li > ul > li:fresh",
"p:unordered-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ul > li:fresh",
"p:unordered-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ul > li:fresh",

"p:ordered-list(1) => ol > li:fresh",
"p:ordered-lower-letter-list(1) => ol > li[style='list-style-type:lower-alpha;']:fresh",
"p:ordered-upper-letter-list(1) => ol > li[style='list-style-type:upper-alpha;']:fresh",
"p:ordered-lower-roman-list(1) => ol > li[style='list-style-type:lower-roman;']:fresh",
"p:ordered-upper-roman-list(1) => ol > li[style='list-style-type:upper-roman;']:fresh",

"p:ordered-list(2) => ul|ol > li > ol > li:fresh",
"p:ordered-lower-letter-list(2) => ul|ol > li > ol > li[style='list-style-type:lower-alpha;']:fresh",
"p:ordered-upper-letter-list(2) => ul|ol > li > ol > li[style='list-style-type:upper-alpha;']:fresh",
"p:ordered-lower-roman-list(2) => ul|ol > li > ol > li[style='list-style-type:lower-roman;']:fresh",
"p:ordered-upper-roman-list(2) => ul|ol > li > ol > li[style='list-style-type:upper-roman;']:fresh",

"p:ordered-list(3) => ul|ol > li > ul|ol > li > ol > li:fresh",
"p:ordered-lower-letter-list(3) => ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-alpha;']:fresh",
"p:ordered-upper-letter-list(3) => ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-alpha;']:fresh",
"p:ordered-lower-roman-list(3) => ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-roman;']:fresh",
"p:ordered-upper-roman-list(3) => ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-roman;']:fresh",

"p:ordered-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li:fresh",
"p:ordered-lower-letter-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-alpha;']:fresh",
"p:ordered-upper-letter-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-alpha;']:fresh",
"p:ordered-lower-roman-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-roman;']:fresh",
"p:ordered-upper-roman-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-roman;']:fresh",

"p:ordered-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li:fresh",

"p:ordered-lower-letter-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-alpha;']:fresh",
"p:ordered-upper-letter-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-alpha;']:fresh",
"p:ordered-lower-roman-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:lower-roman;']:fresh",
"p:ordered-upper-letter-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li[style='list-style-type:upper-roman;']:fresh",

"r[style-name='Hyperlink'] =>",

"p[style-name='Normal'] => p:fresh"
];

Expand Down
9 changes: 7 additions & 2 deletions lib/style-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ function documentMatcherRule() {


var listTypeRule = lop.rules.firstOf("list type",
identifierToConstant("ordered-list", {isOrdered: true}),
identifierToConstant("ordered-list", {isOrdered: true, listStyleType: 'decimal'}),
identifierToConstant("ordered-lower-letter-list", {isOrdered: true, listStyleType: 'lowerLetter'}),
identifierToConstant("ordered-upper-letter-list", {isOrdered: true, listStyleType: 'upperLetter'}),
identifierToConstant("ordered-lower-roman-list", {isOrdered: true, listStyleType: 'lowerRoman'}),
identifierToConstant("ordered-upper-roman-list", {isOrdered: true, listStyleType: 'upperRoman'}),
identifierToConstant("unordered-list", {isOrdered: false})
);
var listRule = sequence(
Expand All @@ -112,7 +116,8 @@ function documentMatcherRule() {
return {
list: {
isOrdered: listType.isOrdered,
levelIndex: levelNumber - 1
levelIndex: levelNumber - 1,
listStyleType: listType.listStyleType
}
};
});
Expand Down
8 changes: 5 additions & 3 deletions lib/styles/document-matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ function Matcher(elementType, options) {
if (options.list) {
this._listIndex = options.list.levelIndex;
this._listIsOrdered = options.list.isOrdered;
this._listStyleType = options.list.listStyleType;
}
}

Matcher.prototype.matches = function(element) {
return element.type === this._elementType &&
(this._styleId === undefined || element.styleId === this._styleId) &&
(this._styleName === undefined || (element.styleName && this._styleName.operator(this._styleName.operand, element.styleName))) &&
(this._listIndex === undefined || isList(element, this._listIndex, this._listIsOrdered)) &&
(this._listIndex === undefined || isList(element, this._listIndex, this._listIsOrdered, this._listStyleType)) &&
(this._breakType === undefined || this._breakType === element.breakType);
};

Expand All @@ -71,10 +72,11 @@ BreakMatcher.prototype.matches = function(element) {
(this._breakType === undefined || element.breakType === this._breakType);
};

function isList(element, levelIndex, isOrdered) {
function isList(element, levelIndex, isOrdered, listStyleType) {
return element.numbering &&
element.numbering.level == levelIndex &&
element.numbering.isOrdered == isOrdered;
element.numbering.isOrdered == isOrdered &&
element.numbering.listStyleType == listStyleType;
}

function equalTo(value) {
Expand Down
30 changes: 29 additions & 1 deletion test/style-reader.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,35 @@ test("styleReader.readDocumentMatcher", {
"reads p:ordered-list(1) as ordered list with index of 0": function() {
assertDocumentMatcher(
"p:ordered-list(1)",
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0}})
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0, listStyleType: 'decimal'}})
);
},

"reads p:ordered-lower-letter-list(1) as ordered list with index of 0": function() {
assertDocumentMatcher(
"p:ordered-lower-letter-list(1)",
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0, listStyleType: 'lowerLetter'}})
);
},

"reads p:ordered-upper-letter-list(1) as ordered list with index of 0": function() {
assertDocumentMatcher(
"p:ordered-upper-letter-list(1)",
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0, listStyleType: 'upperLetter'}})
);
},

"reads p:ordered-lower-roman-list(1) as ordered list with index of 0": function() {
assertDocumentMatcher(
"p:ordered-lower-roman-list(1)",
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0, listStyleType: 'lowerRoman'}})
);
},

"reads p:ordered-upper-roman-list(1) as ordered list with index of 0": function() {
assertDocumentMatcher(
"p:ordered-upper-roman-list(1)",
documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 0, listStyleType: 'upperRoman'}})
);
},

Expand Down
36 changes: 34 additions & 2 deletions test/styles/document-matchers.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,41 @@ test("paragraph style name only matches paragraphs with that style name", functi
});

test("ordered-list(index) matches an ordered list with specified level index", function() {
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1}});
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1, listStyleType: 'decimal'}});
assert.ok(!matcher.matches(new Paragraph()));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true}})));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true, listStyleType: 'decimal'}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
});

test("ordered-lower-letter-list(index) matches an ordered list with specified level index", function() {
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1, listStyleType: 'lowerLetter'}});
assert.ok(!matcher.matches(new Paragraph()));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true, listStyleType: 'lowerLetter'}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
});

test("ordered-upper-letter-list(index) matches an ordered list with specified level index", function() {
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1, listStyleType: 'upperLetter'}});
assert.ok(!matcher.matches(new Paragraph()));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true, listStyleType: 'upperLetter'}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
});

test("ordered-lower-roman-list(index) matches an ordered list with specified level index", function() {
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1, listStyleType: 'lowerRoman'}});
assert.ok(!matcher.matches(new Paragraph()));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true, listStyleType: 'lowerRoman'}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
});

test("ordered-upper-roman-list(index) matches an ordered list with specified level index", function() {
var matcher = documentMatchers.paragraph({list: {isOrdered: true, levelIndex: 1, listStyleType: 'upperRoman'}});
assert.ok(!matcher.matches(new Paragraph()));
assert.ok(matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: true, listStyleType: 'upperRoman'}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 0, isOrdered: true}})));
assert.ok(!matcher.matches(new Paragraph([], {numbering: {level: 1, isOrdered: false}})));
});
Expand Down