A templating language that looks like Lisp and compiles to HTML
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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)