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

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