compile.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * Module dependencies.
  3. */
  4. var fs = require('fs')
  5. var dox = require('dox')
  6. var jade = require('jade')
  7. var marked = require('marked')
  8. var hljs = require('highlight.js')
  9. var assert = require('assert')
  10. fs.readFile(__dirname + '/../lib/ref.js', 'utf8', function (err, data) {
  11. if (err) throw err
  12. // don't depend on dox for parsing the Markdown (raw: true)
  13. var docs = dox.parseComments(data, { raw: true })
  14. var base = 0
  15. var sections = []
  16. docs.forEach(function (doc, i) {
  17. doc.tags.forEach(function (t) {
  18. if (t.type === 'section') {
  19. sections.push(docs.slice(base, i))
  20. base = i
  21. }
  22. if (t.type === 'name') {
  23. doc.name = t.string
  24. }
  25. if (t.type === 'type') {
  26. doc.type = t.types[0]
  27. }
  28. })
  29. if (!doc.name) {
  30. doc.name = doc.ctx && doc.ctx.name
  31. }
  32. if (!doc.type) {
  33. doc.type = doc.ctx && doc.ctx.type || 'property'
  34. }
  35. })
  36. sections.push(docs.slice(base))
  37. assert.equal(sections.length, 3)
  38. // get the 3 sections
  39. var exports = sections[0]
  40. var types = sections[1]
  41. var extensions = sections[2]
  42. // move NULL_POINTER from "types" to "exports"
  43. var null_pointer = types.pop()
  44. assert.equal(null_pointer.name, 'NULL_POINTER')
  45. exports.push(null_pointer)
  46. // extract the "return" and "param" types
  47. exports.forEach(function (doc) {
  48. doc.tags.forEach(function (t) {
  49. if (t.description) {
  50. // parse the Markdown descriptions
  51. t.description = markdown(t.description).trim()
  52. // remove the surrounding <p> tags
  53. t.description = t.description.substring(3, t.description.length - 4)
  54. }
  55. })
  56. doc.returnType = doc.tags.filter(function (t) {
  57. return t.type == 'return'
  58. })[0]
  59. doc.paramTypes = doc.tags.filter(function (t) {
  60. return t.type == 'param'
  61. })
  62. })
  63. // sort
  64. exports = exports.sort(sort)
  65. extensions = extensions.sort(sort)
  66. // parse and highlight the Markdown descriptions
  67. ;[exports, types, extensions].forEach(function (docs) {
  68. docs.forEach(function (doc) {
  69. var desc = doc.description
  70. desc.full = markdown(desc.full)
  71. desc.summary = markdown(desc.summary)
  72. desc.body = markdown(desc.body)
  73. })
  74. })
  75. // get a reference to the ref export doc object for every Buffer extension doc
  76. extensions.forEach(function (doc) {
  77. doc.ref = exports.filter(function (ref) {
  78. return ref.name === doc.name
  79. })[0]
  80. })
  81. fs.readFile(__dirname + '/index.jade', 'utf8', function (err, template) {
  82. if (err) throw err
  83. template = jade.compile(template)
  84. var html = template({
  85. exports: sections[0]
  86. , types: sections[1]
  87. , extensions: sections[2]
  88. , package: require('../package.json')
  89. , markdown: markdown
  90. , highlight: highlight
  91. })
  92. fs.writeFile(__dirname + '/index.html', html, function (err) {
  93. if (err) throw err
  94. })
  95. })
  96. })
  97. /**
  98. * Sorts an array of dox objects by doc.name. If the first letter is an '_' then
  99. * it is considered "private" and gets sorted at the bottom.
  100. */
  101. function sort (a, b) {
  102. var aname = a.name
  103. var bname = b.name
  104. var aprivate = a.isPrivate
  105. var bprivate = b.isPrivate
  106. if (aprivate && !bprivate) {
  107. return 1
  108. }
  109. if (bprivate && !aprivate) {
  110. return -1
  111. }
  112. return aname > bname ? 1 : -1
  113. }
  114. /**
  115. * Parses Markdown into highlighted HTML.
  116. */
  117. function markdown (code) {
  118. if (!code) return code
  119. return marked(code, {
  120. gfm: true
  121. , highlight: highlight
  122. })
  123. }
  124. /**
  125. * Add syntax highlighting HTML to the given `code` block.
  126. * `lang` defaults to "javascript" if no valid name is given.
  127. */
  128. function highlight (code, lang) {
  129. if (!hljs.LANGUAGES.hasOwnProperty(lang)) {
  130. lang = 'javascript'
  131. }
  132. return hljs.highlight(lang, code).value
  133. }