likes
comments
collection
share

开发个 markdown 和 excel 在线表格 格式互相转换的 在线工具

作者站长头像
站长
· 阅读数 21

背景

我经常需要编辑markdown表格,有时需要在markdown和excel(或在线表格)之间来回复制。

所以我需要一个支持markdown和excel(或在线表格)互相转换格式的工具。

我常用网上的在线工具,但是有些工具很卡、有些工具有广告、有些工具甚至有泄露数据的安全风险。所以我自己动手开发了一个工具。

而且,我只想用纯 html js css 实现,不依赖任何库,尽可能减少它的体积。

开发个 markdown 和 excel 在线表格 格式互相转换的 在线工具

理想效果

整个页面分为上下两块:

  • 上半部分为输入区,用户可以输入 markdown 格式的表格,也可以粘贴 excel(在线表格)到输入框中,它可以自动识别是 markdown 格式还是 excel(在线表格)格式。
  • 用户光标点击外部(即监听 textarea 的 change 事件)时,触发更新,上半部分自动格式化为 markdown 格式,下半部分出现表格格式(用 html 展示的)。
  • 如果用户需要 markdown 格式(通常是excel或在线表格转 markdown),此时可以在上半部分复制走。
  • 如果用户需要 excel(在线表格)格式(通常是 markdown 转excel或在线表格),此时可以在下半部分复制走。

开发难点

  1. 如何辨别是 markdown 还是 excel(在线表格)。
  2. 需要开发代码理解 markdown 的语法。
  3. 需要开发代码理解 excel(在线表格)的语法。
  4. 需要自动生成 markdown 语法。
  5. 需要自动生成 excel(在线表格)的 html 文本。

开发实现

如何辨别是 markdown 还是 excel(在线表格)

主要是通过包含|\t的行的数量来比较。如果几乎每行都有|,说明是markdown。如果\t比较多,说明是 excel 或在线表格。

const isMarkdown = (lines) => {
  let verticalBarLineCount = 0;
  let blankLineCount = 0;
  let tabLineCount = 0;
  for (const line of lines) {
    const trimLine = line.trim();
    if (trimLine.length === 0) {
      blankLineCount += 1;
      continue;
    }
    if (trimLine.length > 3 && trimLine[0] === '|' && trimLine.substr(1).includes('|')) {
      verticalBarLineCount += 1;
    }
    if (trimLine.length > 3 && trimLine.includes('\t')) {
      tabLineCount += 1;
    }
  }
  const nonBlankLineCount = lines.length - blankLineCount;
  if (verticalBarLineCount === 0) return false;
  if (verticalBarLineCount >= nonBlankLineCount * 0.8) return true;
  return tabLineCount < verticalBarLineCount;
};

理解 markdown 语法

const content = [];
let gapFlag = false;
for (const line of lines) {
  let text = line.trim();
  if (text[0] === '|') text = text.substr(1);
  if (text[text.length - 1] === '|') text = text.substr(0, text.length - 2);
  if (!gapFlag && judgeGap(line)) {
    gapFlag = true;
    continue;
  }
  const chars = new Set(line);
  if (chars.size === 0) continue;
  if (chars.size === 1 && chars.has(' ')) continue;
  content.push(text.split('|').map(t => t.trim()));
}

理解 excel(在线表格)语法

在 excel(在线表格)复制到 textarea 后,表格的分隔符是\t,换行则是\n

const content = [];
for (const line of lines) {
  content.push(line.split('\t').map(t => t.trim()));
}

自动生成 markdown

const getMarkdown = (content) => {
  let markdown = '';
  let gapFlag = false;
  for (const line of content) {
    markdown += '| ';
    for (const cell of line) {
      markdown += cell + ' | ';
    }
    markdown = markdown.substr(0, markdown.length - 1);
    markdown += '\n';
    if (!gapFlag) {
      gapFlag = true;
      markdown += '| ';
      for (const cell of line) {
        markdown += '--- | ';
      }
      markdown = markdown.substr(0, markdown.length - 1);
      markdown += '\n';
    }
  }
  return markdown;
};

自动生成 excel(在线表格)的 html 文本

const getTable = (content) => {
  let table = '<tbody>';
  let gapFlag = false;
  for (const line of content) {
    table += '<tr>';
    for (const cell of line) {
      table += gapFlag ? '<td>' : '<th>';
      table += cell;
      table += gapFlag ? '</td>' : '</th>';
    }
    table += '</tr>\n';
    gapFlag = true;
  }
  table += '</tbody>';
  return table;
};

待优化事项

  1. 不支持识别\|,这在 markdown 并非表格分割线。
  2. markdown 生成的没有很规整,没有通过增加空格把每个单元格弄成一样长度。

写在最后

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,联系我,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋象棋等游戏,不收费无广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我噢~我有空了会分享做游戏的相关技术,会在这2个专栏里分享:《教你做小游戏》《极致用户体验》

转载自:https://juejin.cn/post/7158850778705166372
评论
请登录