0.2.41 • Published 8 months ago

codemirror-lang-nuformula v0.2.41

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

公式編輯 CodeMirror 6 language package template

日期:2023-07-21
規劃:Chien Lo
版本號:0.2

Structure 資料夾結構拆分

src/
├── autocomplete.ts ──────────────────── 關鍵字輸入 code mirror 外掛
├── constant.ts ──────────────────────── 常數宣告
├── evaluation-lib.ts ────────────────── 定義可用運算子方法
├── evaluation.ts ────────────────────── 實踐公式計算類型 
├── highlight.ts ─────────────────────── 文法高亮 code mirror 外掛
├── index.ts ─────────────────────────── 套件入口檔
├── item-widget.ts ───────────────────── 替換表單元件 code mirror 外掛
├── linter.ts ────────────────────────── 文法檢查 code mirror 外掛
├── syntax.grammar ───────────────────── lexer 文法規範
└── syntax.grammar.d.ts ──────────────── 封裝 lexer 文法規範

安裝方式

npm i codemirror-lang-nuformula

注:此套件僅為插件,需另外配置 code-mirror

使用範例

Vue3

<script setup lang="ts">
import { EditorState } from "@codemirror/state";
import { EditorView, keymap } from "@codemirror/view";
import { defaultKeymap } from "@codemirror/commands";
import { bracketMatching } from "@codemirror/language";
import {
  nuformula,
  nuformulaHighlightStyle,
  nuformulaLinter,
  nuformulaItemWidget,
  nuformulaAutocomplete,
  formatFormItems,
} from "codemirror-lang-nuformula";
import { ref, onMounted, reactive, computed } from "vue";

const props = defineProps({
  // 公式綁定數值
  value: { default: "=", type: String },
  // 是否禁用元件
  disabled: { default: false, type: Boolean },
  // 表單元件
  formItems: { default: () => ({}), type: Object }
});

const emit = defineEmits(["change"]);

// 編輯器 DOM
const editor = ref();
// 公式字串
const value = ref(props.value);
// 是否禁用
const disabled = ref(props.disabled);
// 錯誤訊息
const formulaError = ref("");

// 格式化表單元件
const formattedFormItems = formatFormItems(props.formItems);

/**
 * 取得當前公式
 *
 * @returns {string}
 */
function getFormula(): string {
  if (cm.view === undefined) return "=";
  return `=${cm.view.state.doc.toString().replace(/^=./, "")}`;
}

/**
 * 當更新編輯器
 * 
 * @param {object} error - 錯誤訊息
 */
const handleEditorUpdate = (error: { [key: string]: any }): void => {
  formulaError.value = error?.message ?? "";
  emit("change", getFormula());
};

const cm = reactive({
  view: undefined as EditorView | undefined,
});

// 初始 code mirror state
const state = EditorState.create({
  doc: value.value.replace(/^\=/, ""),
  extensions: [
    // 使用基本設配置
    keymap.of(defaultKeymap),
    // 是否禁用
    EditorState.readOnly.of(disabled.value),
    // 括號配對插件
    bracketMatching(),
    // 公式編輯語法
    nuformula(),
    // 配置語法標示
    nuformulaHighlightStyle(),
    // linter 插件
    nuformulaLinter(formattedFormItems, handleEditorUpdate),
    // 表單項目標記插件
    nuformulaItemWidget(formattedFormItems),
    // 自動選字插件
    nuformulaAutocomplete(formattedFormItems),
  ],
});

onMounted(() => {
  // 初始 code mirror view
  cm.view = new EditorView({
    state: state,
    parent: editor.value,
  });
});
</script>

Vue2

<template>
  <div class="formula-editor">
    <div ref="editor"></div>
    <div>{{ formulaError }}</div>
  </div>
</template>

<script>
import { EditorState } from "@codemirror/state";
import { EditorView, keymap } from "@codemirror/view";
import { defaultKeymap } from "@codemirror/commands";
import { bracketMatching } from "@codemirror/language";
import {
  funcName,
  nuformula,
  nuformulaHighlightStyle,
  nuformulaLinter,
  nuformulaItemWidget,
  nuformulaAutocomplete,
  formatFormItems,
} from "codemirror-lang-nuformula";
import { isEmptyValue } from "@/utils";

export default {
  name: "FormulaEditor",
  provide() {
    return {
      // 可用表單元件
      formItems: this.formattedFormItems,
      // 可用函式運算子
      functions: Object.keys(funcName),
    };
  },
  props: {
    // 公式綁定數值
    value: { default: "=", type: String },
    // 是否禁用元件
    disabled: { default: false, type: Boolean },
    // 表單元件
    formItems: { default: () => ({}), type: Object }
  },
  data() {
    return {
      // code mirror state
      state: null,
      // code mirror view
      view: null,
      // 錯誤訊息
      formulaError: "",
    };
  },
  computed: {
    // 格式化表單元件
    formattedFormItems() {
      return formatFormItems(this.formItems);
    },
  },
  created() {
    // 初始編輯器
    this.initEditor();
  },
  mounted() {
    // 掛載編輯器
    this.mountEditor();
  },
  methods: {
    /**
     * 初始編輯器
     */
    initEditor() {
      // 初始 code mirror state
      this.state = EditorState.create({
        doc: this.value.replace(/^\=/, ""),
        extensions: [
          // 使用基本設配置
          keymap.of(defaultKeymap),
          // 是否禁用
          EditorState.readOnly.of(this.disabled),
          // 括號配對插件
          bracketMatching(),
          // 公式編輯語法
          nuformula(),
          // 配置語法標示
          nuformulaHighlightStyle(),
          // linter 插件
          nuformulaLinter(this.formattedFormItems, this.handleEditorUpdate),
          // 表單項目標記插件
          nuformulaItemWidget(this.formattedFormItems),
          // 自動選字插件
          nuformulaAutocomplete(this.formattedFormItems),
        ],
      });
    },
    /**
     * 掛載編輯器
     */
    mountEditor() {
      // 初始 code mirror view
      this.view = new EditorView({
        state: this.state,
        parent: this.$refs.editor,
      });
    },
    /**
     * 當觸發錯誤資訊
     *
     * @param {object} error - 錯誤資訊
     */
    handleEditorUpdate(error) {
      this.formulaError = isEmptyValue(error) ? "" : error.message;
      this.$emit("change", this.getFormula())
    },
    /**
     * 取得當前公式
     *
     * @returns {string}
     */
    getFormula() {
      return `=${this.view.state.doc.toString().replace(/^=./, "")}`;
    },
  },
};
</script>

編輯器插件

詳見 文件連結

公式函式庫

詳見 文件連結

開發指南

詳見 文件連結

0.2.41

8 months ago

0.2.40

8 months ago

0.2.39

8 months ago

0.2.38

8 months ago

0.2.37

9 months ago

0.2.36

9 months ago

0.2.35

9 months ago

0.2.34

9 months ago

0.2.33

9 months ago

0.2.32

9 months ago

0.2.31

9 months ago

0.2.30

9 months ago

0.2.29

9 months ago

0.2.28

9 months ago

0.2.27

9 months ago

0.2.26

9 months ago

0.2.25

9 months ago

0.2.24

9 months ago

0.2.23

9 months ago

0.2.22

9 months ago

0.2.21

9 months ago

0.2.20

9 months ago

0.2.18

9 months ago

0.2.17

9 months ago

0.2.16

9 months ago

0.2.15

9 months ago

0.2.14

10 months ago

0.2.13

10 months ago

0.2.11

10 months ago

0.2.10

10 months ago

0.2.9

10 months ago

0.2.8

10 months ago

0.2.7

10 months ago

0.2.6

10 months ago

0.2.5

10 months ago

0.2.4

10 months ago

0.2.3

10 months ago

0.2.2

10 months ago

0.2.1

10 months ago

0.2.0

10 months ago

0.1.51

10 months ago

0.1.50

10 months ago

0.1.49

10 months ago

0.1.48

10 months ago

0.1.47

10 months ago

0.1.46

10 months ago

0.1.45

10 months ago

0.1.44

10 months ago

0.1.43

10 months ago

0.1.42

10 months ago

0.1.41

10 months ago

0.1.40

10 months ago

0.1.39

10 months ago

0.1.38

10 months ago

0.1.37

10 months ago

0.1.36

10 months ago

0.1.35

10 months ago

0.1.34

10 months ago

0.1.33

10 months ago

0.1.32

10 months ago

0.1.31

10 months ago

0.1.30

10 months ago

0.1.29

10 months ago

0.1.28

10 months ago

0.1.27

10 months ago

0.1.26

10 months ago

0.1.25

10 months ago

0.1.24

10 months ago

0.1.23

10 months ago

0.1.22

10 months ago

0.1.21

10 months ago

0.1.20

10 months ago

0.1.18

10 months ago

0.1.17

10 months ago

0.1.16

10 months ago

0.1.14

10 months ago

0.1.13

10 months ago

0.1.12

10 months ago

0.1.11

10 months ago

0.1.10

10 months ago

0.1.9

10 months ago

0.1.8

10 months ago

0.1.7

10 months ago

0.1.6

10 months ago

0.1.5

10 months ago

0.1.4

10 months ago

0.1.3

10 months ago

0.1.1

10 months ago

0.1.0

10 months ago