hiveExtractor.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Licensed to Cloudera, Inc. under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. Cloudera, Inc. licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. const program = require('commander');
  17. const EPub = require('epub');
  18. const Topic = require('./Topic');
  19. const libxml = require('libxmljs');
  20. const outputPath = './desktop/core/src/desktop/static/desktop/docs/hive/';
  21. const mako = './desktop/core/src/desktop/templates/sql_doc_index.mako';
  22. const jsonHandler = require('./jsonHandler');
  23. // Handle command line arguments
  24. program
  25. .version('1.0')
  26. .option('-e, --epub [path]', 'the path to the Hive epub file')
  27. .parse(process.argv);
  28. const epub = new EPub(program.epub);
  29. const convertToPre = (element, fragments) => {
  30. switch (element.name()) {
  31. case 'div':
  32. element.childNodes().forEach(node => {
  33. convertToPre(node, fragments);
  34. });
  35. break;
  36. case 'text':
  37. if (fragments.length === 1) {
  38. fragments.push(element.text().replace(/^\n/, ''));
  39. } else {
  40. fragments.push(element.text());
  41. }
  42. break;
  43. case 'code':
  44. if (
  45. element.attr('class') &&
  46. element
  47. .attr('class')
  48. .value()
  49. .indexOf('value') !== -1
  50. ) {
  51. fragments.push('<span class="hue-doc-varname">');
  52. element.childNodes().forEach(node => {
  53. convertToPre(node, fragments);
  54. });
  55. fragments.push('</span>');
  56. break;
  57. }
  58. default:
  59. element.childNodes().forEach(node => {
  60. convertToPre(node, fragments);
  61. });
  62. }
  63. };
  64. const adaptElement = element => {
  65. if (
  66. element.attr('class') &&
  67. element
  68. .attr('class')
  69. .value()
  70. .indexOf('syntaxhighlighter') !== -1
  71. ) {
  72. const fragments = ['<div class="hue-doc-codeblock">'];
  73. element.childNodes().forEach(childNode => {
  74. convertToPre(childNode, fragments);
  75. });
  76. fragments.push('</div>');
  77. const replacement = fragments.join('');
  78. element.replace(libxml.parseHtmlFragment(replacement).root());
  79. } else if (element.attr('class')) {
  80. element.attr('class').remove();
  81. }
  82. element.childNodes().forEach(adaptElement);
  83. };
  84. epub.on('end', () => {
  85. const rootTopics = [];
  86. const lastTopicPerLevel = {};
  87. const promises = [];
  88. epub.flow.forEach(chapter => {
  89. promises.push(
  90. new Promise((resolve, reject) => {
  91. const topic = new Topic('/', chapter.id);
  92. topic.fragment = {
  93. title: {
  94. text: () => chapter.title.replace(/LanguageManual\s(.+)/, '$1')
  95. }
  96. };
  97. epub.getChapter(chapter.id, (error, text) => {
  98. try {
  99. const contents = libxml.parseHtmlFragment('<div>' + text + '</div>');
  100. topic.domXml = contents.root();
  101. adaptElement(topic.domXml);
  102. resolve();
  103. } catch (error) {
  104. reject();
  105. }
  106. });
  107. if (lastTopicPerLevel[chapter.level - 1]) {
  108. lastTopicPerLevel[chapter.level - 1].children.push(topic);
  109. }
  110. if (chapter.level === 0) {
  111. rootTopics.push(topic);
  112. }
  113. lastTopicPerLevel[chapter.level] = topic;
  114. })
  115. );
  116. });
  117. Promise.all(promises).then(() => {
  118. const rootTopic = rootTopics[0];
  119. rootTopic.children.forEach(childTopic => {
  120. rootTopics.push(childTopic);
  121. });
  122. rootTopic.children = [];
  123. jsonHandler
  124. .saveTopics(rootTopics, outputPath, mako, false)
  125. .then(() => {
  126. console.log('Done.');
  127. })
  128. .catch(() => {
  129. console.log('Fail.');
  130. });
  131. });
  132. });
  133. epub.parse();