index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import init, { setup_panic_hook, Numbat, FormatType } from "./pkg/numbat_wasm.js";
  2. async function fetch_exchange_rates() {
  3. try {
  4. const response = await fetch("https://numbat.dev/ecb-exchange-rates.php");
  5. if (!response.ok) {
  6. return;
  7. }
  8. const xml_content = await response.text();
  9. numbat.set_exchange_rates(xml_content);
  10. } catch (error) {
  11. console.error("Failed to load currency exchange rates from the European Central Bank");
  12. return;
  13. }
  14. }
  15. function create_numbat_instance() {
  16. return Numbat.new(true, true, FormatType.JqueryTerminal);
  17. }
  18. function updateUrlQuery(query) {
  19. let url = new URL(window.location);
  20. if (query == null) {
  21. url.searchParams.delete('q');
  22. } else {
  23. url.searchParams.set('q', query);
  24. }
  25. history.replaceState(null, null, url);
  26. }
  27. function interpret(input) {
  28. // Skip empty lines or comments
  29. var input_trimmed = input.trim();
  30. if (input_trimmed === "" || (input_trimmed[0] === "#" && input_trimmed.indexOf("\n") == -1)) {
  31. return;
  32. }
  33. if (input_trimmed == "clear") {
  34. this.clear();
  35. var output = "";
  36. } else if (input_trimmed == "reset") {
  37. numbat = create_numbat_instance();
  38. numbat.interpret("use units::currencies");
  39. combined_input = "";
  40. updateUrlQuery(null);
  41. this.clear();
  42. } else if (input_trimmed == "list" || input_trimmed == "ls") {
  43. output = numbat.print_environment();
  44. } else if (input_trimmed == "list functions" || input_trimmed == "ls functions") {
  45. output = numbat.print_functions();
  46. } else if (input_trimmed == "list dimensions" || input_trimmed == "ls dimensions") {
  47. output = numbat.print_dimensions();
  48. } else if (input_trimmed == "list variables" || input_trimmed == "ls variables") {
  49. output = numbat.print_variables();
  50. } else if (input_trimmed == "list units" || input_trimmed == "ls units") {
  51. output = numbat.print_units();
  52. } else if (input_trimmed == "help" || input_trimmed == "?") {
  53. output = numbat.help();
  54. } else {
  55. var result = {is_error: false};
  56. if (input_trimmed.startsWith("info ")) {
  57. var keyword = input_trimmed.substring(4).trim();
  58. output = numbat.print_info(keyword);
  59. } else {
  60. result = numbat.interpret(input);
  61. output = result.output;
  62. }
  63. if (!result.is_error) {
  64. combined_input += input.trim() + "⏎";
  65. updateUrlQuery(combined_input);
  66. }
  67. }
  68. return output;
  69. }
  70. function setup() {
  71. $(document).ready(function() {
  72. var term = $('#terminal').terminal(interpret, {
  73. greetings: false,
  74. name: "terminal",
  75. height: 550,
  76. prompt: "[[;;;prompt]>>> ]",
  77. checkArity: false,
  78. historySize: 200,
  79. historyFilter(line) {
  80. return line.trim() !== "";
  81. },
  82. completion(inp, cb) {
  83. cb(numbat.get_completions_for(inp));
  84. }
  85. });
  86. // evaluate expression in query string if supplied (via opensearch)
  87. if (location.search) {
  88. var queryParams = new URLSearchParams(location.search);
  89. if (queryParams.has("q")) {
  90. // feed in the query line by line, as if the user typed it in
  91. for (const line of queryParams.get("q").split("⏎")) {
  92. if (line.trim().length > 0) {
  93. term.exec(line.trim() + "\n");
  94. }
  95. }
  96. }
  97. }
  98. });
  99. }
  100. var numbat;
  101. var combined_input = "";
  102. async function main() {
  103. await init();
  104. setup_panic_hook();
  105. numbat = create_numbat_instance();
  106. combined_input = "";
  107. // Load KeyboardEvent polyfill for old browsers
  108. keyboardeventKeyPolyfill.polyfill();
  109. fetch_exchange_rates().then(setup);
  110. }
  111. main();