diff --git a/.github/workflows/build-github-pages.yaml b/.github/workflows/build-github-pages.yaml new file mode 100644 index 0000000..1258456 --- /dev/null +++ b/.github/workflows/build-github-pages.yaml @@ -0,0 +1,28 @@ +# https://github.com/marketplace/actions/deploy-to-github-pages +name: Build and Deploy to Github Pages + +on: + push: + branches: + - main + +permissions: + contents: write + +jobs: + build-and-deploy: + concurrency: ci-${{ github.ref }} # Recommended if you intend to make multiple deployments in quick succession. + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. + run: | + npm ci + npm run build + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: dist # The folder the action should deploy. \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md index 27ea9ea..d0e7ac0 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ # Web Thermodynamics -This is a simple example of how to run CoolProp Javascript wrapper with units handled by mathjs. + +This is an example of how to run CoolProp Javascript wrapper with units handled by mathjs, including a code editor. [![interface](interface.png)](https://dvd101x.github.io/web-thermodynamics/ ) # To-Do -- [ ] Migrate to codemirror 6 with a build tool like Vite +- [x] Migrate to codemirror 6 with a build tool like Vite - [ ] Migrate the language definition to CM6 -- [ ] Scroll outputs into view and highlight them -- [ ] Not only text outputs (allow for latex) +- [x] Scroll outputs into view and highlight them +- [x] Not only text outputs (allow for latex) - [ ] More efficient math evaluation (only update state when inputs change) - [ ] Evaluate expression by expression (not necessarly block by block) -- [ ] Use Alpinejs to reduce code +- [x] Use Alpinejs to reduce code +- [ ] Dynamic autocomplete # Basic example @@ -226,12 +228,12 @@ cond_COP = Q_h/W_comp # # Final results -print('Compressor power : $0 \t$1\t$2', W_comp to [W, BTU/h, TR], 4) -print('Condenser heat out : $0 \t$1\t$2', Q_h to [W, BTU/h, TR], 4) -print('Evaporator heat in : $0 \t$1\t$2', Q_c to [W, BTU/h, TR], 4) +print('Compressor power : $1 \t$2\t$3', W_comp to [W, BTU/h, TR], 4) +print('Condenser heat out : $1 \t$2\t$3', Q_h to [W, BTU/h, TR], 4) +print('Evaporator heat in : $1 \t$2\t$3', Q_c to [W, BTU/h, TR], 4) -print('COP(cooling) : $0', [evap_COP], 3) -print('COP(heating) : $0', [cond_COP], 3) +print('COP(cooling) : $1', [evap_COP], 3) +print('COP(heating) : $1', [cond_COP], 3) ``` Shall return: @@ -253,7 +255,7 @@ COP(heating) : 3.57 Here is a similar project [Engineering-Solver](https://github.com/dvd101x/Engineering-Solver) that includes additional features: * Saves in the browser (you can continue where you left off) -* 9 workspaces, so you can try different things +* 20 workspaces, so you can try different things * Uses a webworker to avoid freezing during big calculaitons * A few more examples focused on the many features of mathjs @@ -265,7 +267,7 @@ Uses the following js libraries * [Mathjs](https://mathjs.org/) * [CoolProp](http://www.coolprop.org/) * Editing - * [CodeMirror 5](https://codemirror.net/5/) + * [CodeMirror](https://codemirror.net/) * Rendering results * [Markdown-it](https://github.com/markdown-it/markdown-it) * [markdown-it-katex](https://github.com/waylonflinn/markdown-it-katex) diff --git a/fluidProperties.js b/fluidProperties.js index cfa2a94..0dc8fdb 100644 --- a/fluidProperties.js +++ b/fluidProperties.js @@ -1,3 +1,5 @@ +import {number, unit} from 'mathjs' + // List of units from coolprop const propUnit = { '': '', @@ -253,12 +255,12 @@ function calcPropUnits(prop) { } } -// This is created only bacuse math.number(value,'') is not valid as '' can't be the unit -toValue = (v, u) => u ? math.number(v, u) : math.number(v) -// This is crate only becous math.unit(value,'') is not valid as '' can't be the unit -toUnit = (v, u) => u ? math.unit(v, u) : math.unit(v) +// This is created only because number(value,'') is not valid as '' can't be the unit +const toValue = (v, u) => u ? number(v, u) : number(v) +// This is crate only because unit(value,'') is not valid as '' can't be the unit +const toUnit = (v, u) => u ? unit(v, u) : unit(v) -function props(desiredProperty, fluidName, fluidProperties) { +export function props(desiredProperty, fluidName, fluidProperties) { const calcPropUnit = calcPropUnits(desiredProperty) let prop = Object.keys(fluidProperties).slice(0,2) let value = Object.values(fluidProperties).slice(0,2) @@ -280,7 +282,7 @@ function props(desiredProperty, fluidName, fluidProperties) { return toUnit(calcValue, calcPropUnit) } -function HAprops(calcProp, fluidProperties) { +export function HAprops(calcProp, fluidProperties) { const calcPropUnit = HApropUnit[calcProp] const arrayProperties = Object.entries(fluidProperties) @@ -304,8 +306,8 @@ function HAprops(calcProp, fluidProperties) { return toUnit(calcValue, calcPropUnit) } -function phase(fluid, fluidProperties) { +export function phase(fluid, fluidProperties) { return phases[props('Phase', fluid, fluidProperties)] -} +} \ No newline at end of file diff --git a/getExpressions.js b/getExpressions.js new file mode 100644 index 0000000..e61ed19 --- /dev/null +++ b/getExpressions.js @@ -0,0 +1,59 @@ +import { parse } from 'mathjs' + +/** + * Extracts parsable expressions from a multiline string. + * + * @param {string} str - The multiline string containing expressions. + * @returns {Array<{from: number, to: number, source: string}>} An array of objects, + * where each object represents a parsable expression and contains: + * - from: The starting line number of the expression within the original string. + * - to: The ending line number of the expression within the original string. + * - source: The actual string content of the expression. + */ +export default function getExpressions(str) { + const lines = str.split('\n'); + let nextLineToParse = 0; + const result = []; + + for (let lineID = 0; lineID < lines.length; lineID++) { + const linesToTest = lines.slice(nextLineToParse, lineID + 1).join('\n'); + if (canBeParsed(linesToTest)) { + if (!isEmptyString(linesToTest)) { + result.push({ from: nextLineToParse, to: lineID, source: linesToTest }); + } + // Start the next parsing attempt from the line after the successfully parsed expression. + nextLineToParse = lineID + 1; + } + } + // Handle any remaining lines that couldn't be parsed as expressions. + const linesToTest = lines.slice(nextLineToParse).join('\n'); + if (!isEmptyString(linesToTest)) { + result.push({ from: nextLineToParse, to: lines.length - 1, source: linesToTest }); + } + return result; +} + +/** + * Determines whether a given expression can be successfully parsed. + * + * @param {string} expression - The expression to parse. + * @returns {boolean} True if the expression can be parsed, false otherwise. + */ +function canBeParsed(expression) { + try { + parse(expression) + return true + } catch (error) { + return false + } +} + +/** + * Checks if a given string is empty or only contains whitespace characters. + * + * @param {string} str - The string to check. + * @returns {boolean} True if the string is empty or only contains whitespace, false otherwise. + */ +function isEmptyString(str) { + return str.trim() === "" +} \ No newline at end of file diff --git a/index.html b/index.html index be5cbf6..66353c5 100644 --- a/index.html +++ b/index.html @@ -1,125 +1,27 @@ - + - -
- - - -