A templating language that looks like Lisp and compiles to HTML
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.

oslo.js 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/env node
  2. const fs = require('fs')
  3. const path = require('path')
  4. const args = require('minimist')(process.argv.slice(2))
  5. const oslo = require('../src/index')
  6. class OsloCLI {
  7. constructor(opts) {
  8. this.context = {}
  9. this.eval(opts)
  10. }
  11. eval(opts) {
  12. if (opts.l) {
  13. this.context = JSON.parse(fs.readFileSync(this.absolutePath(opts.l)))
  14. }
  15. let output
  16. if (opts.f && opts.f !== true) {
  17. output = this.file(path.join(process.cwd(), opts.f))
  18. } else if (opts.d && opts.d !== true) {
  19. if (!opts.o) {
  20. console.log(
  21. 'Output directory required. Invoke oslo with `-o path/to/output/directory`',
  22. )
  23. process.exit()
  24. }
  25. output = this.directory(
  26. this.absolutePath(opts.d),
  27. this.absolutePath(opts.o),
  28. )
  29. } else if (opts.e && opts.e !== true) {
  30. output = this.inline(opts.e)
  31. } else {
  32. this.printUsage()
  33. process.exit()
  34. }
  35. if (output.error) {
  36. this.error(output.error)
  37. }
  38. if (opts.o) {
  39. this.output(opts, output)
  40. } else {
  41. process.stdout.write(output)
  42. process.stdout.write('\n')
  43. }
  44. }
  45. file(file) {
  46. const contents = fs.readFileSync(file).toString()
  47. return oslo(contents, this.context)
  48. }
  49. directory(directory) {
  50. let files = {}
  51. fs.readdirSync(directory).forEach(item => {
  52. const absolutePath = this.absolutePath(item, directory)
  53. if (fs.lstatSync(absolutePath).isDirectory()) {
  54. files = Object.assign(files, this.directory(absolutePath))
  55. } else {
  56. let output = this.file(absolutePath)
  57. files[absolutePath] = output
  58. }
  59. })
  60. return files
  61. }
  62. inline(source) {
  63. return oslo(source.toString(), this.context)
  64. }
  65. absolutePath(file, root = null) {
  66. if (!root) {
  67. root = process.cwd()
  68. }
  69. return path.join(root, file)
  70. }
  71. output(opts, output) {
  72. const absoluteOutputPath = this.absolutePath(opts.o)
  73. if (opts.f || opts.e) {
  74. fs.writeFile(absoluteOutputPath, output, function(err) {
  75. if (err) throw err
  76. })
  77. } else if (opts.d) {
  78. const absoluteInputPath = this.absolutePath(opts.d)
  79. Object.keys(output).forEach(function(file) {
  80. const absoluteOutputFilePath = file
  81. .replace(absoluteInputPath, absoluteOutputPath)
  82. .replace(/\.oslo$/, '.html')
  83. const parentDirectory = path.dirname(absoluteOutputFilePath)
  84. if (!fs.existsSync(parentDirectory)) {
  85. fs.mkdirSync(parentDirectory)
  86. }
  87. fs.writeFile(absoluteOutputFilePath, output[file], function(err) {
  88. if (err) throw err
  89. console.log(
  90. `Writing to ${absoluteOutputFilePath.replace(process.cwd(), '')}`,
  91. )
  92. })
  93. })
  94. }
  95. }
  96. printUsage() {
  97. console.log(
  98. `USAGE
  99. -d The path to a directory. The directory will be recursively scanned. An
  100. output directory is required with this option.
  101. oslo -d templates
  102. -e Pass oslo code directly.
  103. oslo -e '(div "Hello world")'
  104. -f The path to a single file.
  105. oslo -f index.oslo
  106. -l The path to a json file to use as context for compilation
  107. oslo -f index.oslo -l data.json
  108. -o Where to direct the output. If no path is provided, output will be directed
  109. to stdout. When used with -f, the argument should be the path to a file.
  110. When used with -d, the argument should be the path to a directory, which
  111. will be created if it does not already exist.
  112. oslo -f index.oslo -o index.html
  113. oslo -d templates -o html`,
  114. )
  115. }
  116. error(err) {
  117. console.log(err.message)
  118. process.exit()
  119. }
  120. }
  121. new OsloCLI(args)