ass.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. 'use strict';
  2. import xml2js = require('xml2js');
  3. /**
  4. * Converts an input buffer to a SubStation Alpha subtitle.
  5. */
  6. export default function(input: string|Buffer, done: (err: Error, subtitle?: string) => void) {
  7. xml2js.parseString(input.toString(), {
  8. explicitArray: false,
  9. explicitRoot: false
  10. }, (err: Error, xml: ISubtitle) => {
  11. if (err) return done(err);
  12. try {
  13. done(null, script(xml) + '\n' +
  14. style(xml.styles) + '\n' +
  15. event(xml.events));
  16. } catch (err) {
  17. done(err);
  18. }
  19. });
  20. }
  21. /**
  22. * Converts the event block.
  23. */
  24. function event(block: ISubtitleEvent): string {
  25. var format = 'Layer,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text';
  26. return '[Events]\n' +
  27. 'Format: ' + format + '\n' +
  28. [].concat(block.event).map(style => ('Dialogue: 0,' +
  29. style.$.start + ',' +
  30. style.$.end + ',' +
  31. style.$.style + ',' +
  32. style.$.name + ',' +
  33. style.$.margin_l + ',' +
  34. style.$.margin_r + ',' +
  35. style.$.margin_v + ',' +
  36. style.$.effect + ',' +
  37. style.$.text)).join('\n') + '\n';
  38. }
  39. /**
  40. * Converts the script block.
  41. */
  42. function script(block: ISubtitle): string {
  43. return '[Script Info]\n' +
  44. 'Title: ' + block.$.title + '\n' +
  45. 'ScriptType: v4.00+\n' +
  46. 'WrapStyle: ' + block.$.wrap_style + '\n' +
  47. 'PlayResX: ' + block.$.play_res_x + '\n' +
  48. 'PlayResY: ' + block.$.play_res_y + '\n' +
  49. 'Subtitle ID: ' + block.$.id + '\n' +
  50. 'Language: ' + block.$.lang_string + '\n' +
  51. 'Created: ' + block.$.created + '\n';
  52. }
  53. /**
  54. * Converts the style block.
  55. */
  56. function style(block: ISubtitleStyle): string {
  57. var format = 'Name,Fontname,Fontsize,PrimaryColour,SecondaryColour,' +
  58. 'OutlineColour,BackColour,Bold,Italic,Underline,StrikeOut,ScaleX,' +
  59. 'ScaleY,Spacing,Angle,BorderStyle,Outline,Shadow,Alignment,' +
  60. 'MarginL,MarginR,MarginV,Encoding';
  61. return '[V4+ Styles]\n' +
  62. 'Format: ' + format + '\n' +
  63. [].concat(block.style).map(style => 'Style: ' +
  64. style.$.name + ',' +
  65. style.$.font_name + ',' +
  66. style.$.font_size + ',' +
  67. style.$.primary_colour + ',' +
  68. style.$.secondary_colour + ',' +
  69. style.$.outline_colour + ',' +
  70. style.$.back_colour + ',' +
  71. style.$.bold + ',' +
  72. style.$.italic + ',' +
  73. style.$.underline + ',' +
  74. style.$.strikeout + ',' +
  75. style.$.scale_x + ',' +
  76. style.$.scale_y + ',' +
  77. style.$.spacing + ',' +
  78. style.$.angle + ',' +
  79. style.$.border_style + ',' +
  80. style.$.outline + ',' +
  81. style.$.shadow + ',' +
  82. style.$.alignment + ',' +
  83. style.$.margin_l + ',' +
  84. style.$.margin_r + ',' +
  85. style.$.margin_v + ',' +
  86. style.$.encoding).join('\n') + '\n';
  87. }