Compare commits

..

3 Commits

Author SHA1 Message Date
Martin Berg Alstad
e91dee5059 Updated link to source code to point to gitea
All checks were successful
Deploy / Build (push) Successful in 3m47s
Deploy / Deploy (push) Successful in 55s
2024-09-29 11:40:17 +02:00
Martin Berg Alstad
0d62eb876a Removed node and pnpm setups. Updated checkout to v4
All checks were successful
Deploy / Build (push) Successful in 3m0s
Deploy / Deploy (push) Successful in 52s
2024-09-29 11:27:37 +02:00
Martin Berg Alstad
af1c2f8bb2 Rewritten github actions script to gitea actions
Some checks failed
Deploy / Build (push) Failing after 2m54s
Deploy / Deploy (push) Has been skipped
2024-09-29 11:10:37 +02:00
9 changed files with 2064 additions and 1654 deletions

View File

@ -0,0 +1,45 @@
name: Deploy
on:
pull_request:
branches:
- master
push:
branches:
- master
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Install dependencies
run: echo y | npm exec -- pnpm install
- name: Build project
run: npm exec -- pnpm build
- name: Upload production-ready build files
uses: actions/upload-artifact@v3
with:
name: dist
path: ./dist
deploy:
name: Deploy
needs: build
runs-on: host
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: dist
path: ./dist
# Deploy to local repo
- name: Move files to server
run: |
rm -rf /var/www/martials.no/*
cp -r dist/* /var/www/martials.no

View File

@ -1,59 +0,0 @@
name: Deploy
on:
pull_request:
push:
branches:
- master
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: pnpm install
- name: Build project
run: pnpm build
- name: Upload production-ready build files
uses: actions/upload-artifact@v3
with:
name: production-files
path: ./dist
deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: production-files
path: ./dist
# Deploy to local repo
- name: Deploy
uses: s0/git-publish-subdir-action@develop
env:
REPO: self
BRANCH: build
FOLDER: dist
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -11,22 +11,22 @@
}, },
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.17",
"postcss": "^8.4.39", "postcss": "^8.4.35",
"prettier": "3.3.3", "prettier": "3.2.5",
"prettier-plugin-tailwindcss": "^0.6.5", "prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.4.6", "tailwindcss": "^3.4.1",
"typescript": "^5.5.3", "typescript": "^5.3.3",
"vite": "^5.3.4", "vite": "^5.1.4",
"vite-plugin-solid": "^2.10.2" "vite-plugin-solid": "^2.10.1"
}, },
"dependencies": { "dependencies": {
"@solidjs/router": "^0.14.1", "@solidjs/router": "^0.12.4",
"@types/diff": "^5.2.1", "@types/diff": "^5.0.9",
"diff": "^5.2.0", "diff": "^5.2.0",
"solid-headless": "^0.13.1", "solid-headless": "^0.13.1",
"solid-heroicons": "^3.2.4", "solid-heroicons": "^3.2.4",
"solid-js": "^1.8.18", "solid-js": "^1.8.15",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
} }
} }

3454
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ import { Link } from "./link"
const Footer: Component<SimpleProps> = ({ className }) => ( const Footer: Component<SimpleProps> = ({ className }) => (
<footer class={`container absolute bottom-0 py-5 text-center ${className}`}> <footer class={`container absolute bottom-0 py-5 text-center ${className}`}>
<p> <p>
Kildekode <Link to={"https://github.com/h600878/martials.no"}>GitHub</Link> Kildekode <Link to={"https://git.martials.no/martials/old.martials.no"}>Gitea</Link>
</p> </p>
</footer> </footer>
) )

View File

@ -3,7 +3,7 @@ import { For } from "solid-js/web"
import { type Component } from "solid-js" import { type Component } from "solid-js"
interface TruthTableProps extends SimpleProps { interface TruthTableProps extends SimpleProps {
table?: TruthMatrix table?: Table
header?: string[] header?: string[]
} }
@ -20,7 +20,8 @@ const TruthTable: Component<TruthTableProps> = ({ table, header, className, styl
<th <th
scope={"col"} scope={"col"}
class={ class={
`sticky top-0 bg-default-bg text-center outline outline-2 outline-offset-[-1px] outline-gray-500 [position:-webkit-sticky;]` /*TODO sticky header at the top of the screen */ `sticky top-0 bg-default-bg text-center outline
outline-2 outline-offset-[-1px] outline-gray-500 [position:-webkit-sticky;]` /*TODO sticky header at the top of the screen */
} }
> >
<p class={"w-max px-2"}>{exp}</p> <p class={"w-max px-2"}>{exp}</p>
@ -36,7 +37,8 @@ const TruthTable: Component<TruthTableProps> = ({ table, header, className, styl
<For each={row}> <For each={row}>
{(value) => ( {(value) => (
<td <td
class={`border border-gray-500 text-center last:underline ${value ? "bg-green-700" : "bg-red-700"}`} class={`border border-gray-500 text-center last:underline
${value ? "bg-green-700" : "bg-red-700"}`}
> >
<p>{value ? "T" : "F"}</p> <p>{value ? "T" : "F"}</p>
</td> </td>

View File

@ -25,20 +25,18 @@ type Option = {
} }
const fetchUrls = [ const fetchUrls = [
"http://localhost:8000/simplify/table/", "http://localhost:8080/simplify/table/",
"https://api.martials.no/simplify-truths/v2/simplify/table/" "https://api.martials.no/simplify-truths/simplify/table/"
] ]
// TODO move some code to new components // TODO move some code to new components
// TODO option to ignore case
// TODO more user friendly options
const TruthTablePage: Component = () => { const TruthTablePage: Component = () => {
const [searchParams, setSearchParams] = useSearchParams() const [searchParams, setSearchParams] = useSearchParams()
let inputElement!: HTMLInputElement let inputElement: HTMLInputElement | undefined = undefined
let simplifyDefault = searchParams.simplify === undefined || searchParams.simplify === "true", let simplifyDefault = searchParams.simplify === undefined || searchParams.simplify === "true",
inputContent = !!searchParams.exp, inputContent = !!searchParams.exp,
hideIntermediate = searchParams.hideIntermediateSteps === "true" hideIntermediate = searchParams.hideIntermediate === "true"
const [simplifyEnabled, setSimplifyEnabled] = createSignal(simplifyDefault) const [simplifyEnabled, setSimplifyEnabled] = createSignal(simplifyDefault)
const [fetchResult, setFetchResult] = createSignal<FetchResult | null>(null) const [fetchResult, setFetchResult] = createSignal<FetchResult | null>(null)
@ -77,14 +75,14 @@ const TruthTablePage: Component = () => {
simplify: simplifyEnabled(), simplify: simplifyEnabled(),
hide: hideValues().value, hide: hideValues().value,
sort: sortValues().value, sort: sortValues().value,
hideIntermediateSteps: hideIntermediates() hideIntermediate: hideIntermediates()
}) })
void getFetchResult(exp) getFetchResult(exp)
} }
} }
async function getFetchResult(exp: string | null): Promise<void> { function getFetchResult(exp: string | null): void {
setFetchResult(null) setFetchResult(null)
if (exp && exp !== "") { if (exp && exp !== "") {
@ -92,30 +90,18 @@ const TruthTablePage: Component = () => {
setError(null) setError(null)
setIsLoaded(false) setIsLoaded(false)
try { fetch(`${fetchUrls[useLocalhost() ? 0 : 1]}${encodeURIComponent(exp)}?
const response = simplify=${simplifyEnabled()}&hide=${hideValues().value}&sort=${sortValues().value}&caseSensitive=false&
await fetch(`${fetchUrls[useLocalhost() ? 0 : 1]}${encodeURIComponent(exp)}? hideIntermediate=${hideIntermediates()}`)
simplify=${simplifyEnabled()}&hide=${hideValues().value}&sort=${sortValues().value}&ignoreCase=false& .then((res) => res.json())
hideIntermediateSteps=${hideIntermediates()}`) .then((res) => {
if (res.status !== "OK" && !res.ok) {
const body = await response.json() return setError({ title: "Input error", message: res.message })
if (!response.ok) { }
setError({ return setFetchResult(res)
title: "Input error",
message: body.message
})
} else {
const fetchResult: FetchResult = body
setFetchResult(fetchResult)
}
} catch (e: any) {
setError({
title: "Error",
message: e.message
}) })
} finally { .catch((err) => setError({ title: "Fetch error", message: err.toString() }))
setIsLoaded(true) .finally(() => setIsLoaded(true))
}
} }
} }
@ -134,7 +120,7 @@ hideIntermediateSteps=${hideIntermediates()}`)
setSortValues(sortOptions.find((o) => o.value === sort) ?? sortOptions[0]) setSortValues(sortOptions.find((o) => o.value === sort) ?? sortOptions[0])
} }
void getFetchResult(exp) getFetchResult(exp)
} }
// Focuses searchbar on load // Focuses searchbar on load
@ -300,12 +286,12 @@ hideIntermediateSteps=${hideIntermediates()}`)
/> />
</Show> </Show>
<Show when={simplifyEnabled() && (fetchResult()?.operations?.length ?? 0) > 0} keyed> <Show when={simplifyEnabled() && (fetchResult()?.orderOperations?.length ?? 0) > 0} keyed>
<ShowMeHow fetchResult={fetchResult} /> <ShowMeHow fetchResult={fetchResult} />
</Show> </Show>
</div> </div>
<Show when={isLoaded() && error() === null && fetchResult()?.truthTable} keyed> <Show when={isLoaded() && error() === null} keyed>
<Show when={simplifyEnabled()} keyed> <Show when={simplifyEnabled()} keyed>
<InfoBox <InfoBox
className={"mx-auto w-fit pb-1 text-center text-lg"} className={"mx-auto w-fit pb-1 text-center text-lg"}
@ -319,8 +305,8 @@ hideIntermediateSteps=${hideIntermediates()}`)
<div class={"m-2 flex justify-center"}> <div class={"m-2 flex justify-center"}>
<div id={"table"} class={"h-[45rem] overflow-auto"}> <div id={"table"} class={"h-[45rem] overflow-auto"}>
<TruthTable <TruthTable
header={fetchResult()!.truthTable!.header} header={fetchResult()?.header ?? undefined}
table={fetchResult()!.truthTable!.truthMatrix} table={fetchResult()?.table?.truthMatrix}
id={tableId} id={tableId}
/> />
</div> </div>
@ -368,7 +354,7 @@ const ShowMeHow: Component<ShowMeHowProps> = ({ fetchResult }) => (
<MyDisclosure title={"Show me how it's done"}> <MyDisclosure title={"Show me how it's done"}>
<table class={"table"}> <table class={"table"}>
<tbody> <tbody>
<For each={fetchResult()?.operations}>{operationRow()}</For> <For each={fetchResult()?.orderOperations}>{orderOperationRow()}</For>
</tbody> </tbody>
</table> </table>
</MyDisclosure> </MyDisclosure>
@ -386,8 +372,7 @@ const HowTo: Component = () => (
Parentheses is also allowed. Parentheses is also allowed.
</p> </p>
<p> <p>
API docs can be found{" "} API docs can be found <Link to={"https://api.martials.no/simplify-truths"}>here</Link>.
<Link to={"https://api.martials.no/simplify-truths/v2/openapi"}>here</Link>.
</p> </p>
</MyDisclosure> </MyDisclosure>
@ -395,7 +380,7 @@ const HowTo: Component = () => (
</MyDisclosureContainer> </MyDisclosureContainer>
) )
const operationRow = () => (operation: Operation, index: Accessor<number>) => ( const orderOperationRow = () => (operation: OrderOfOperation, index: Accessor<number>) => (
<tr class={"border-b border-dotted border-gray-500"}> <tr class={"border-b border-dotted border-gray-500"}>
<td>{index() + 1}:</td> <td>{index() + 1}:</td>
<td class={"px-2"}> <td class={"px-2"}>
@ -452,7 +437,7 @@ const KeywordsDisclosure: Component = () => (
</tr> </tr>
<tr> <tr>
<td class={"pr-2"}>Implication:</td> <td class={"pr-2"}>Implication:</td>
<td>{"=>"}</td> <td>{"->"}</td>
<td class={"px-2"}>IMPLICATION</td> <td class={"px-2"}>IMPLICATION</td>
<td>IMP</td> <td>IMP</td>
</tr> </tr>

53
src/types/types.d.ts vendored
View File

@ -37,51 +37,34 @@ interface CardProps extends LinkProps {
title?: string title?: string
} }
type AtomicExpression = { type Expression = {
atomic: string leading: string
left: Expression | null
operator: Operator | null
right: Expression | null
trailing: string
atomic: string | null
} }
type NotExpression = { type Operator = "AND" | "OR" | "NOT" | "IMPLICATION"
not: Expression
}
type BinaryExpression = { type Table = boolean[][]
left: Expression
operator: BinaryOperator
right: Expression
}
type Expression = AtomicExpression | NotExpression | BinaryExpression type OrderOfOperation = {
type BinaryOperator = "AND" | "OR" | "IMPLICATION"
type Law =
| "ELIMINATION_OF_IMPLICATION"
| "DE_MORGANS_LAWS"
| "ABSORPTION_LAW"
| "ASSOCIATIVE_LAW"
| "DISTRIBUTIVE_LAW"
| "DOUBLE_NEGATION_ELIMINATION"
| "COMMUTATIVE_LAW"
type TruthMatrix = boolean[][]
type Operation = {
before: string before: string
after: string after: string
law: Law law: string
}
type Table = {
header: string[]
truthMatrix: TruthMatrix
} }
type FetchResult = { type FetchResult = {
version: string status: string
version: string | null
before: string before: string
after: string after: string
operations: Operation[] orderOperations: OrderOfOperation[] | null
expression: Expression | null expression: Expression | null
truthTable?: Table | null header: string[] | null
table: {
truthMatrix: Table
} | null
} }

View File

@ -7,8 +7,8 @@ export function replaceOperators(expression: string): string {
return expression return expression
.replaceAll(/\//g, "|") .replaceAll(/\//g, "|")
.replaceAll(/¬/g, "!") .replaceAll(/¬/g, "!")
.replaceAll(/\s(OR|)\s/gi, " | ") .replaceAll(/\sOR\s/gi, " | ")
.replaceAll(/\s(AND|⋀)\s/gi, " & ") .replaceAll(/\sAND\s/gi, " & ")
.replaceAll(/\s(IMPLICATION|IMP|->)\s/gi, " => ") .replaceAll(/\s(IMPLICATION|IMP)\s/gi, " -> ")
.replaceAll(/\sNOT\s/gi, " !") .replaceAll(/\sNOT\s/gi, " !")
} }