Skip to content

Commit

Permalink
feat: code examples
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryZhang-ZHY committed Nov 19, 2023
1 parent 5c342d5 commit 991d875
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 58 deletions.
68 changes: 68 additions & 0 deletions docs/.vitepress/components/CodeSampleSelector.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script setup lang="ts">
import {ref} from "vue"
interface Sample {
name: string,
code: string,
}
interface Chapter {
name: string
samples: Sample[]
}
interface Props {
chapters: Chapter[],
}
const {
chapters,
} = defineProps<Props>()
const emit = defineEmits(['select:code'])
const select = ref<HTMLSelectElement | null>(null)
const onSelect = () => {
const selectElement = select.value
if (!selectElement) {
return
}
const code = selectElement.options[selectElement.selectedIndex].value
emit('select:code', code)
}
</script>

<template>
<div>
<span class="description">Examples: </span>
<select ref="select" class="select-box" @change="onSelect">
<option disabled hidden selected>Select an example...</option>
<optgroup :label="chapter.name" v-for="chapter in chapters">
<option v-for="sample in chapter.samples" :label="sample.name" :value="sample.code"/>
</optgroup>
</select>
</div>
</template>

<style scoped>
.description {
font-weight: 400;
font-size: 19px;
}
.select-box {
appearance: menulist-button;
height: 32px;
border: 1px solid #ced4da;
border-radius: 8px;
padding: 4px 4px;
font-size: 18px;
line-height: 1.1;
}
</style>
30 changes: 30 additions & 0 deletions docs/.vitepress/components/Console.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
interface Props {
content?: string
}
const {
content = ''
} = defineProps<Props>()
</script>

<template>
<div class="container" v-html="content"></div>
</template>

<style scoped>
.container {
width: 100%;
min-height: 40%;
margin: 16px 0;
padding: 16px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
font-family: Consolas, serif;
overflow: auto;
}
</style>
26 changes: 16 additions & 10 deletions docs/.vitepress/components/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
<script setup lang="ts">
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import {computed, onMounted, ref} from 'vue'
import {computed, onMounted, ref, watch} from 'vue'
interface Props {
modelValue: string
lang?: string
hideMinimap?: boolean
}
const {
hideMinimap,
lang = 'funkey',
modelValue,
} = defineProps<Props>()
const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue'])
const vModel = computed<string>({
get: () => modelValue,
get: () => props.modelValue,
set: (newVal: string) => {
emits('update:modelValue', newVal)
},
Expand Down Expand Up @@ -102,11 +98,21 @@ onMounted(async () => {
},
})
const model = monacoEditor.createModel(vModel.value, lang)
const model = monacoEditor.createModel(vModel.value, props.lang)
model.onDidChangeContent(() => {
vModel.value = model.getValue()
})
watch(
() => props.modelValue,
(newValue) => {
if (model) {
const value = model.getValue()
if (newValue !== value) {
model.setValue(newValue)
}
}
}
)
monacoEditor.create(root.value, {
model,
theme: 'vs',
Expand All @@ -119,7 +125,7 @@ onMounted(async () => {
tabSize: 2,
automaticLayout: true,
minimap: {
enabled: !hideMinimap,
enabled: !props.hideMinimap,
},
fontSize: 16,
})
Expand Down
71 changes: 23 additions & 48 deletions docs/.vitepress/components/Playground.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
<script setup lang="ts">
import {F_Object, runWithPrint} from '@funkey/interpreter'
import Console from './Console.vue'
import CodeSampleSelector from './CodeSampleSelector.vue'
import Editor from './Editor.vue'
import ToolBar from './ToolBar.vue'
import {onMounted, ref} from 'vue'
import {F_Object, runWithPrint} from '@funkey/interpreter'
import {data as CodeSamples} from "../data/playground/PlaygroundSamples.data";
const code = ref<string>(`for (let i = 1; i < 10; i = i + 1) {
for (let j = 1; j <= i; j = j + 1) {
print(j);
print("*");
print(i);
print("=");
print(j*i);
print(" ");
}
print("\\n");
}`)
const code = ref<string>(`print("Hello World");`)
const output = ref<string>('')
const onCodeUpdate = (e) => {
code.value = e
const onSampleSelected = (codeText: string) => {
code.value = codeText
}
const output = ref<HTMLDivElement | null>(null)
const run = () => {
const buffer: string[] = []
const print = (...args: F_Object[]) => {
Expand All @@ -38,7 +31,7 @@ const run = () => {
currentError = currentError.innerError
}
} finally {
output.value.innerHTML = buffer.join('').replaceAll('\\n', '<br/>')
output.value = buffer.join('').replaceAll('\\n', '<br/>')
}
}
Expand All @@ -49,13 +42,18 @@ onMounted(() => {

<template>
<div id="playground">
<div id="tool-bar">
<button id="btn-run" @click="run">run</button>
</div>

<Editor :model-value="code" :lang="'funkey'" :hide-minimap="false" @update:model-value="onCodeUpdate"/>

<div id="output" ref="output"></div>
<ToolBar>
<template #left>
<CodeSampleSelector :chapters="CodeSamples.chapters" @select:code="onSampleSelected"/>
</template>
<template #right>
<button id="btn-run" @click="run">run</button>
</template>
</ToolBar>

<Editor v-model="code" :lang="'funkey'" :hide-minimap="false"/>

<Console :content="output"></Console>
</div>
</template>

Expand All @@ -68,36 +66,13 @@ onMounted(() => {
margin: 8px auto;
}
#tool-bar {
height: 32px;
display: flex;
flex-direction: row-reverse;
margin-bottom: 8px;
}
#btn-run {
width: 64px;
border-radius: 4px;
background-color: hsl(141, 60%, 38%);
color: white;
font-size: 18px;
}
#output {
width: 100%;
min-height: 40%;
margin: 16px 0;
padding: 16px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
font-family: Consolas, serif;
overflow: auto;
font-weight: 400;
}
</style>
26 changes: 26 additions & 0 deletions docs/.vitepress/components/ToolBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
</script>

<template>
<div class="container">
<div>
<slot name="left"></slot>
</div>
<div>
<slot name="right"></slot>
</div>
</div>
</template>

<style scoped>
.container {
height: 32px;
display: flex;
justify-content: space-between;
margin-bottom: 8px;
padding: 0 4px;
}
</style>
62 changes: 62 additions & 0 deletions docs/.vitepress/data/playground/PlaygroundSamples.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {defineLoader} from 'vitepress'
import {readFile} from 'node:fs/promises'
import {basename, parse} from 'node:path'

interface SampleData {
chapter: string,
name: string,
code: string,
}

interface Sample {
name: string,
code: string,
}

interface Chapter {
name: string
samples: Sample[]
}

export interface Data {
chapters: Chapter[]
}

declare const data: Data
export {data}

export default defineLoader({
watch: ['./samples/**/*.fk'],
async load(watchedFiles): Promise<Data> {
const sampleData = await Promise.all(watchedFiles.map(loadSample))
const chapterMap = new Map<string, Chapter>();
for (const sd of sampleData) {
const key = sd.chapter
if (!chapterMap.has(key)) {
chapterMap.set(key, {
name: key,
samples: []
})
}

const chapter = chapterMap.get(key)!
chapter.samples.push(sd)
}

return {chapters: Array.from(chapterMap.values())}
}
})

async function loadSample(path: string): Promise<SampleData> {
const code = await readFile(path, 'utf-8')

const parsedPath = parse(path)
const sampleName = parsedPath.name
const chapterName = basename(parsedPath.dir)

return {
chapter: chapterName,
name: sampleName,
code
}
}
12 changes: 12 additions & 0 deletions docs/.vitepress/data/playground/samples/function/closure.fk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
let cnt = 0;

let add = fn() {
cnt = cnt + 1;
cnt;
};

print(add());
print("\n");
print(add());
print("\n");
print(add());
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("Hello World");
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
for (let i = 1; i < 10; i = i + 1) {
for (let j = 1; j <= i; j = j + 1) {
print(j);
print("*");
print(i);
print("=");
print(j*i);
print(" ");
}
print("\n");
}

0 comments on commit 991d875

Please sign in to comment.