// 特殊字符、常规符号及其代码对照表

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>特殊字符、常规符号及其代码对照表</title>
    <style>
      /* 可视对照表基础样式 */
      .glyph-table {
        border-collapse: collapse;
        width: 100%;
        margin-top: 1rem;
      }
      .glyph-table th,
      .glyph-table td {
        border: 1px solid #ccc;
        padding: 6px;
        text-align: center;
      }
      .glyph-table th {
        background: #f0f0f0;
      }
      .font-sample {
        font-size: 28px;
      }
      .controls {
        margin: 8px 0;
      }
      .placeholder {
        color: #888;
        font-family: monospace;
      }
    </style>
  </head>
  <body>
    <div class="controls">
      <label
        >范围:
        <input id="start" type="number" value="32" min="1" style="width:80px" />
<input id="end" type="number" value="255" min="1" style="width:80px"
      /></label>
      <button id="regen">重新生成</button>
      <span style="margin-left:1rem;color:#666"
        >提示:显示效果依赖系统/浏览器是否安装相应字体。</span
      >
    </div>

    <!-- 可视对照表 -->
    <div id="visual"></div>

    <script>
      // 用于对比的字体(常见 Windows 字体名)
      const fonts = [
        "Webdings",
        "Wingdings",
        "Wingdings 2",
        "Wingdings 3",
        "Symbol",
        "Arial"
      ];

      function escapePipe(s) {
        return String(s).replace(/\|/g, "\\|");
      }

      function visibleFor(i, glyph) {
        // 将空白与不可见字符可视化
        if (glyph === " ") return "␣";
        if (glyph === "\t") return "\\t";
        if (glyph === "\n") return "\\n";
        // 不间断空格
        if (glyph === "\u00A0") return "⍽";
        // 控制字符范围(无法精确判定类别时使用占位符)
        if (i < 32 || (i >= 127 && i <= 159)) return "[控制字符]";
        return glyph;
      }

      function uPlus(i) {
        return "U+" + i.toString(16).toUpperCase().padStart(4, "0");
      }

      function build(start = 32, end = 255) {
        start = Math.max(1, Math.floor(start));
        end = Math.max(start, Math.floor(end));

        // 构建可视 HTML 表格
        const container = document.getElementById("visual");
        container.innerHTML = "";

        const table = document.createElement("table");
        table.className = "glyph-table";

        const thead = document.createElement("thead");
        const headRow = document.createElement("tr");
        // 表头(中文)
        ["十进制", "十六进制", "Unicode", "实体"].forEach((h) => {
          const th = document.createElement("th");
          th.textContent = h;
          headRow.appendChild(th);
        });
        fonts.forEach((f) => {
          const th = document.createElement("th");
          th.textContent = f;
          headRow.appendChild(th);
        });
        thead.appendChild(headRow);
        table.appendChild(thead);

        const tbody = document.createElement("tbody");
        for (let i = start; i <= end; i++) {
          const tr = document.createElement("tr");
          const codeTd = document.createElement("td");
          codeTd.textContent = i;
          tr.appendChild(codeTd);
          const hexTd = document.createElement("td");
          hexTd.textContent =
            "0x" + i.toString(16).toUpperCase().padStart(2, "0");
          tr.appendChild(hexTd);
          const uniTd = document.createElement("td");
          uniTd.textContent = uPlus(i);
          tr.appendChild(uniTd);
          const entTd = document.createElement("td");
          entTd.textContent = "&#" + i + ";";
          tr.appendChild(entTd);

          const glyph = String.fromCharCode(i);
          const visible = visibleFor(i, glyph);
          for (const f of fonts) {
            const td = document.createElement("td");
            const span = document.createElement("span");
            span.className = "font-sample";
            span.style.fontFamily = f + ", Arial, sans-serif";
            // 控制/不可见字符显示占位符,其他显示字符
            if (visible.startsWith("[")) {
              const placeholder = document.createElement("span");
              placeholder.className = "placeholder";
              placeholder.textContent = visible;
              td.appendChild(placeholder);
            } else {
              span.textContent = visible;
              td.appendChild(span);
            }
            tr.appendChild(td);
          }
          tbody.appendChild(tr);
        }
        table.appendChild(tbody);
        container.appendChild(table);
      }

      document.getElementById("regen").addEventListener("click", () => {
        const s = Number(document.getElementById("start").value);
        const e = Number(document.getElementById("end").value);
        build(s, e);
      });

      // 初次渲染
      build();
    </script>
  </body>
</html>

米随随 书于孝感