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.4KB

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