Add line numbers to pdf (fixes #2300)

This commit is contained in:
Sean Engelhardt 2016-09-06 11:52:27 +02:00
parent 0fddfdd25a
commit cc5ff21005
2 changed files with 86 additions and 28 deletions

View File

@ -49,7 +49,7 @@ angular.module('OpenSlidesApp.core.site', [
{ {
fontSize: 6, fontSize: 6,
width: '30%', width: '30%',
text: gettextCatalog.getString('As of') + date.toLocaleDateString() + " " + date.toLocaleTimeString(), text: gettextCatalog.getString('As of') + " " + date.toLocaleDateString() + " " + date.toLocaleTimeString(),
alignment: 'right' alignment: 'right'
}] }]
}; };
@ -78,9 +78,9 @@ angular.module('OpenSlidesApp.core.site', [
pageSize: 'A4', pageSize: 'A4',
pageMargins: [80, 90, 80, 60], pageMargins: [80, 90, 80, 60],
defaultStyle: { defaultStyle: {
font: defaultFont font: defaultFont,
fontSize: 10
}, },
fontSize: 8,
header: header, header: header,
footer: footer, footer: footer,
content: content, content: content,
@ -152,7 +152,7 @@ angular.module('OpenSlidesApp.core.site', [
* @function * @function
* @param {object} html - html * @param {object} html - html
*/ */
convertHTML = function(html) { convertHTML = function(html, scope) {
var elementStyles = { var elementStyles = {
"b": ["font-weight:bold"], "b": ["font-weight:bold"],
"strong": ["font-weight:bold"], "strong": ["font-weight:bold"],
@ -338,21 +338,59 @@ angular.module('OpenSlidesApp.core.site', [
alreadyConverted.push(st); alreadyConverted.push(st);
break; break;
case "span": case "span":
parseChildren(alreadyConverted, element, currentParagraph, styles); if (scope.lineNumberMode == "inline") {
var lineNumberInline = element.getAttribute("data-line-number"),
lineNumberObjInline = {
text: lineNumberInline,
color: "gray",
fontSize: 5
};
currentParagraph.text.push(lineNumberObjInline);
parseChildren(alreadyConverted, element, currentParagraph, styles);
} else if (scope.lineNumberMode == "outside") {
var lineNumberOutline = element.getAttribute("data-line-number"),
lineNumberObject = {
width: 20,
text: lineNumberOutline,
color: "gray"
},
col = {
columns: [
lineNumberObject,
]
};
currentParagraph = create("text");
col.columns.push(currentParagraph);
parseChildren(col.columns[0], element, currentParagraph, styles);
alreadyConverted.push(col);
} else {
parseChildren(alreadyConverted, element, currentParagraph, styles);
}
break; break;
case "br": case "br":
currentParagraph = create("text"); //in case of inline-line-numbers and the os-line-break class ignore the break
alreadyConverted.push(currentParagraph); if (!(scope.lineNumberMode == "inline" && element.getAttribute("class") == "os-line-break")) {
currentParagraph = create("text");
alreadyConverted.push(currentParagraph);
}
break; break;
case "li": case "li":
case "div": case "div":
currentParagraph = create("text");
var stackDiv = create("stack");
stackDiv.stack.push(currentParagraph);
ComputeStyle(stackDiv, styles);
parseChildren(stackDiv.stack, element, currentParagraph);
alreadyConverted.push(stackDiv);
break;
case "p": case "p":
currentParagraph = create("text"); currentParagraph = create("text");
var stack = create("stack"); currentParagraph.margin = [0,5];
stack.stack.push(currentParagraph); var stackP = create("stack");
ComputeStyle(stack, styles); stackP.stack.push(currentParagraph);
parseChildren(stack.stack, element, currentParagraph); ComputeStyle(stackP, styles);
alreadyConverted.push(stack); parseChildren(stackP.stack, element, currentParagraph);
alreadyConverted.push(stackP);
break; break;
case "img": case "img":
alreadyConverted.push({ alreadyConverted.push({
@ -373,8 +411,9 @@ angular.module('OpenSlidesApp.core.site', [
break; break;
default: default:
var temporary = create("text", element.textContent.replace(/\n/g, "")); var temporary = create("text", element.textContent.replace(/\n/g, ""));
if (styles) if (styles) {
ComputeStyle(temporary, styles); ComputeStyle(temporary, styles);
}
currentParagraph.text.push(temporary); currentParagraph.text.push(temporary);
break; break;
} }
@ -390,7 +429,7 @@ angular.module('OpenSlidesApp.core.site', [
var html = $(htmlText.replace(/\t/g, "").replace(/\n/g, "")); var html = $(htmlText.replace(/\t/g, "").replace(/\n/g, ""));
var emptyParagraph = create("text"); var emptyParagraph = create("text");
slice(html).forEach(function(element) { slice(html).forEach(function(element) {
ParseElement(converted, element, emptyParagraph); ParseElement(converted, element);
}); });
}, },
content = []; content = [];

View File

@ -17,7 +17,17 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
* @param {object} $scope - Current $scope * @param {object} $scope - Current $scope
*/ */
var textContent = function(motion, $scope) { var textContent = function(motion, $scope) {
return converter.convertHTML(motion.getText($scope.version)); if ($scope.lineNumberMode == "inline" || $scope.lineNumberMode == "outside") {
/* in order to distinguish between the line-number-types we need to pass the scope
* to the convertHTML function.
* We should avoid this, since this completly breaks compatibilty for every
* other project that might want to use this HTML to PDF parser.
* https://github.com/OpenSlides/OpenSlides/issues/2361
*/
return converter.convertHTML($scope.lineBrokenText, $scope);
} else {
return converter.convertHTML(motion.getText($scope.version), $scope);
}
}, },
/** /**
* Generate text of reason * Generate text of reason
@ -26,7 +36,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
* @param {object} $scope - Current $scope * @param {object} $scope - Current $scope
*/ */
reasonContent = function(motion, $scope) { reasonContent = function(motion, $scope) {
return converter.convertHTML(motion.getReason($scope.version)); return converter.convertHTML(motion.getReason($scope.version), $scope);
}, },
/** /**
* Generate header text of motion * Generate header text of motion
@ -162,15 +172,25 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
* @param {object} User - Current user * @param {object} User - Current user
*/ */
getContent = function(motion, $scope, User) { getContent = function(motion, $scope, User) {
return [ if (reasonContent(motion, $scope).length === 0 ) {
motionHeader(motion, $scope), return [
signment(motion, $scope, User), motionHeader(motion, $scope),
polls(motion, $scope), signment(motion, $scope, User),
titleSection(motion, $scope), polls(motion, $scope),
textContent(motion, $scope), titleSection(motion, $scope),
reason(motion, $scope), textContent(motion, $scope),
reasonContent(motion, $scope) ];
]; } else {
return [
motionHeader(motion, $scope),
signment(motion, $scope, User),
polls(motion, $scope),
titleSection(motion, $scope),
textContent(motion, $scope),
reason(motion, $scope),
reasonContent(motion, $scope)
];
}
}; };
return { return {
getContent: getContent getContent: getContent
@ -840,9 +860,8 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
} }
$scope.amendments = Motion.filter({parent_id: motion.id}); $scope.amendments = Motion.filter({parent_id: motion.id});
$scope.makePDF = function(){ $scope.makePDF = function() {
var content = motion.getText($scope.version) + motion.getReason($scope.version), var id = motion.identifier,
id = motion.identifier,
slice = Function.prototype.call.bind([].slice), slice = Function.prototype.call.bind([].slice),
map = Function.prototype.call.bind([].map), map = Function.prototype.call.bind([].map),
image_sources = map($(content).find("img"), function(element) { image_sources = map($(content).find("img"), function(element) {