alignment-xform.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. const Enums = require('../../../doc/enums');
  2. const utils = require('../../../utils/utils');
  3. const BaseXform = require('../base-xform');
  4. const validation = {
  5. horizontalValues: [
  6. 'left',
  7. 'center',
  8. 'right',
  9. 'fill',
  10. 'centerContinuous',
  11. 'distributed',
  12. 'justify',
  13. ].reduce((p, v) => {
  14. p[v] = true;
  15. return p;
  16. }, {}),
  17. horizontal(value) {
  18. return this.horizontalValues[value] ? value : undefined;
  19. },
  20. verticalValues: ['top', 'middle', 'bottom', 'distributed', 'justify'].reduce((p, v) => {
  21. p[v] = true;
  22. return p;
  23. }, {}),
  24. vertical(value) {
  25. if (value === 'middle') return 'center';
  26. return this.verticalValues[value] ? value : undefined;
  27. },
  28. wrapText(value) {
  29. return value ? true : undefined;
  30. },
  31. shrinkToFit(value) {
  32. return value ? true : undefined;
  33. },
  34. textRotation(value) {
  35. switch (value) {
  36. case 'vertical':
  37. return value;
  38. default:
  39. value = utils.validInt(value);
  40. return value >= -90 && value <= 90 ? value : undefined;
  41. }
  42. },
  43. indent(value) {
  44. value = utils.validInt(value);
  45. return Math.max(0, value);
  46. },
  47. readingOrder(value) {
  48. switch (value) {
  49. case 'ltr':
  50. return Enums.ReadingOrder.LeftToRight;
  51. case 'rtl':
  52. return Enums.ReadingOrder.RightToLeft;
  53. default:
  54. return undefined;
  55. }
  56. },
  57. };
  58. const textRotationXform = {
  59. toXml(textRotation) {
  60. textRotation = validation.textRotation(textRotation);
  61. if (textRotation) {
  62. if (textRotation === 'vertical') {
  63. return 255;
  64. }
  65. const tr = Math.round(textRotation);
  66. if (tr >= 0 && tr <= 90) {
  67. return tr;
  68. }
  69. if (tr < 0 && tr >= -90) {
  70. return 90 - tr;
  71. }
  72. }
  73. return undefined;
  74. },
  75. toModel(textRotation) {
  76. const tr = utils.validInt(textRotation);
  77. if (tr !== undefined) {
  78. if (tr === 255) {
  79. return 'vertical';
  80. }
  81. if (tr >= 0 && tr <= 90) {
  82. return tr;
  83. }
  84. if (tr > 90 && tr <= 180) {
  85. return 90 - tr;
  86. }
  87. }
  88. return undefined;
  89. },
  90. };
  91. // Alignment encapsulates translation from style.alignment model to/from xlsx
  92. class AlignmentXform extends BaseXform {
  93. get tag() {
  94. return 'alignment';
  95. }
  96. render(xmlStream, model) {
  97. xmlStream.addRollback();
  98. xmlStream.openNode('alignment');
  99. let isValid = false;
  100. function add(name, value) {
  101. if (value) {
  102. xmlStream.addAttribute(name, value);
  103. isValid = true;
  104. }
  105. }
  106. add('horizontal', validation.horizontal(model.horizontal));
  107. add('vertical', validation.vertical(model.vertical));
  108. add('wrapText', validation.wrapText(model.wrapText) ? '1' : false);
  109. add('shrinkToFit', validation.shrinkToFit(model.shrinkToFit) ? '1' : false);
  110. add('indent', validation.indent(model.indent));
  111. add('textRotation', textRotationXform.toXml(model.textRotation));
  112. add('readingOrder', validation.readingOrder(model.readingOrder));
  113. xmlStream.closeNode();
  114. if (isValid) {
  115. xmlStream.commit();
  116. } else {
  117. xmlStream.rollback();
  118. }
  119. }
  120. parseOpen(node) {
  121. const model = {};
  122. let valid = false;
  123. function add(truthy, name, value) {
  124. if (truthy) {
  125. model[name] = value;
  126. valid = true;
  127. }
  128. }
  129. add(node.attributes.horizontal, 'horizontal', node.attributes.horizontal);
  130. add(
  131. node.attributes.vertical,
  132. 'vertical',
  133. node.attributes.vertical === 'center' ? 'middle' : node.attributes.vertical
  134. );
  135. add(node.attributes.wrapText, 'wrapText', utils.parseBoolean(node.attributes.wrapText));
  136. add(node.attributes.shrinkToFit, 'shrinkToFit', utils.parseBoolean(node.attributes.shrinkToFit));
  137. add(node.attributes.indent, 'indent', parseInt(node.attributes.indent, 10));
  138. add(
  139. node.attributes.textRotation,
  140. 'textRotation',
  141. textRotationXform.toModel(node.attributes.textRotation)
  142. );
  143. add(
  144. node.attributes.readingOrder,
  145. 'readingOrder',
  146. node.attributes.readingOrder === '2' ? 'rtl' : 'ltr'
  147. );
  148. this.model = valid ? model : null;
  149. }
  150. parseText() {}
  151. parseClose() {
  152. return false;
  153. }
  154. }
  155. module.exports = AlignmentXform;