Personal blog written from scratch using Node.js, Bootstrap, and MySQL. https://jrtechs.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
8.1 KiB

  1. const pandoc = require('node-pandoc');
  2. const utils = require('../utils/utils.js');
  3. const sql = require('../utils/sql');
  4. const argsFull = '-S --base-header-level=1 --toc --toc-depth=3 -N --normalize -s --mathjax -t html5';
  5. const argsPreview = '-S --normalize -s --mathjax -t html5';
  6. module.exports=
  7. {
  8. /**
  9. * Renders the entire blog post based on the sql data pulled
  10. * from the database.
  11. *
  12. * @param post sql data which has title, date, and header img location
  13. * @param blocks number of blocks to display for a preview or -1 for
  14. * all the blocks
  15. * @returns {Promise} async call which renders the entire blog post.
  16. */
  17. generateBlogPost: function(post, blocks)
  18. {
  19. return new Promise(function(resolve, reject)
  20. {
  21. Promise.all([module.exports.generateBlogPostHeader(post),
  22. module.exports.generateBlogPostBody(post, blocks),
  23. module.exports.generateBlogPostFooter()]).then(function(content)
  24. {
  25. resolve(content.join(''));
  26. }).catch(function(error)
  27. {
  28. reject(error);
  29. })
  30. });
  31. },
  32. /**
  33. * Renders the header of the blog post which contains the header image, and date
  34. * published.
  35. *
  36. * @param post sql data
  37. * @returns {string}
  38. */
  39. generateBlogPostHeader: function(post)
  40. {
  41. var htmlHead = "<div class=\"blogPost\">";
  42. //image
  43. if(!(post.picture_url === "n/a"))
  44. {
  45. htmlHead +="<img src=\"/blogContent/headerImages/" + post.picture_url +
  46. "\" alt=\"\" style=\"width:100%; height:10%\">";
  47. }
  48. htmlHead += "<div class=\"p-4\"><div class=\"\">";
  49. //title
  50. htmlHead += "<h3><b>" + post.name + "</b></h3>";
  51. //date
  52. htmlHead += "<h5><span class=\"w3-opacity\">" +
  53. post.published.toDateString() + "</span></h5>";
  54. htmlHead +="</div>" + "<div class=\"\">";
  55. return htmlHead;
  56. },
  57. /**
  58. * Method which renders the body of the blog post. This is responsible for getting
  59. * the contents of the markdown/latex file and rendering it into beautiful html.
  60. *
  61. * @param post stuff from the SQL table
  62. * @param blocks
  63. * @returns {Promise}
  64. */
  65. generateBlogPostBody: function(post, blocks)
  66. {
  67. return new Promise(function(resolve, reject)
  68. {
  69. sql.getCategory(post.category_id).then(function(category)
  70. {
  71. resolve(module.exports.generateBlogPost(post.url, category[0].url, blocks));
  72. // const pathName = "blogContent/posts/" + category[0].url + "/"
  73. // + post.url + ".md";
  74. // var markDown = utils.getFileContents(pathName).toString();
  75. // markDown = markDown.split("(media/").join("(" + "../blogContent/posts/"
  76. // + category[0].url + "/media/");
  77. //
  78. // module.exports.convertToHTML(markDown, blocks).then(function(result)
  79. // {
  80. //
  81. // result = result.split("<figcaption>").join("<figcaption style=\"visibility: hidden;\">");
  82. //
  83. // //this line prevents older versions of pandoc from including invalid cdm scripts
  84. // result = result.split("<script src=\"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML-full\" type=\"text/javascript\"></script>").join("");
  85. //
  86. // if(blocks == -1)
  87. // resolve(result);
  88. //
  89. // const htmlBlocks = result.split("<p>");
  90. // var html = "";
  91. // for(var i = 0; i < blocks; i++)
  92. // {
  93. // html += "<p>" + htmlBlocks[i];
  94. // }
  95. //
  96. // html += " <div style=\"\">\n" +
  97. // " <p class='text-center'><button class=\"btn btn-secondary btn-lg " +
  98. // "w3-padding-large w3-white w3-border\" onclick=\"location.href='" +
  99. // "http://jrtechs.net/" + category[0].url + "/" + post.url +
  100. // "'\"><b>READ MORE &raquo;</b></button></p>\n" +
  101. // " </div>\n";
  102. //
  103. // resolve(html);
  104. //
  105. // }).catch(function(error)
  106. // {
  107. // reject(error);
  108. // })
  109. });
  110. })
  111. },
  112. generateBlogPostComponent: function(categoryURL, postURL, blocks)
  113. {
  114. return new Promise(function(resolve, reject)
  115. {
  116. const pathName = "blogContent/posts/" + categoryURL + "/"
  117. + postURL + ".md";
  118. var markDown = utils.getFileContents(pathName).toString();
  119. markDown = markDown.split("(media/").join("(" + "../blogContent/posts/"
  120. + categoryURL + "/media/");
  121. module.exports.convertToHTML(markDown, blocks).then(function(result)
  122. {
  123. result = result.split("<figcaption>").join("<figcaption style=\"visibility: hidden;\">");
  124. //this line prevents older versions of pandoc from including invalid cdm scripts
  125. result = result.split("<script src=\"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML-full\" type=\"text/javascript\"></script>").join("");
  126. if(blocks == -1)
  127. resolve(result);
  128. const htmlBlocks = result.split("<p>");
  129. var html = "";
  130. for(var i = 0; i < blocks; i++)
  131. {
  132. html += "<p>" + htmlBlocks[i];
  133. }
  134. html += " <div style=\"\">\n" +
  135. " <p class='text-center'><button class=\"btn btn-secondary btn-lg " +
  136. "w3-padding-large w3-white w3-border\" onclick=\"location.href='" +
  137. "http://jrtechs.net/" + categoryURL + "/" + postURL +
  138. "'\"><b>READ MORE &raquo;</b></button></p>\n" +
  139. " </div>\n";
  140. resolve(html);
  141. }).catch(function(error)
  142. {
  143. reject(error);
  144. })
  145. })
  146. },
  147. /** Method to return the footer of the html blog post.
  148. *
  149. * @returns {string}
  150. */
  151. generateBlogPostFooter: function()
  152. {
  153. return "</div></div></div><br><br>";
  154. },
  155. /**
  156. * Converts markdown into html.
  157. *
  158. * @param markdownContents
  159. * @param type
  160. * @returns {Promise}
  161. */
  162. convertToHTML: function(markdownContents, type)
  163. {
  164. return new Promise(function(resolve, reject)
  165. {
  166. // Set your callback function
  167. callback = function (err, html)
  168. {
  169. if (err)
  170. {
  171. reject(err);
  172. }
  173. html = html.split("<img").join("<img style=\"max-width: 100%;\" ");
  174. html = html.split("<code>").join("<code class='hljs cpp'>");
  175. resolve(html);
  176. };
  177. if(type == -1)
  178. {
  179. pandoc(markdownContents, argsFull, callback);
  180. }
  181. else
  182. {
  183. pandoc(markdownContents, argsPreview, callback);
  184. }
  185. });
  186. },
  187. }