Vùng chứa văn bản trong MathML

Giờ bạn đã có cái nhìn rõ hơn về MathML, chúng ta sẽ chuyển trọng tâm sang các vùng chứa văn bản (biến, số, toán tử, ...) được dùng làm khối xây dựng của các công thức MathML.

Ký tự Unicode cho toán học

Các công thức toán học chứa nhiều ký tự đặc biệt, ví dụ các chữ cái Hy Lạp (ví dụ: Δ), chữ fraktur (ví dụ: 𝔄), chữ double-struck (ví dụ: ℂ), toán tử nhị phân (ví dụ: ≠), mũi tên (ví dụ: ⇒), ký hiệu tích phân (ví dụ: ∮), ký hiệu tổng (ví dụ: ∑), ký hiệu logic (ví dụ: ∀), ký hiệu ngoặc (ví dụ: ⌊) và còn nhiều nữa. Bài viết trên Wikipedia Mathematical operators and symbols in Unicode cung cấp một cái nhìn tổng quan tốt về các ký tự được dùng.

Vì hầu hết các ký tự này không thuộc khối Unicode Basic Latin, bạn nên chỉ định mã hóa ký tự của tài liệu và phục vụ nó với web fonts phù hợp. Sau đây là một mẫu cơ bản dùng mã hóa UTF-8 và phông Latin Modern Math:

html
<!doctype html>
<html lang="vi">
  <head>
    <meta charset="utf-8" />
    <title>Trang của tôi với các ký tự toán học</title>
    <link
      rel="stylesheet"
      href="https://fred-wang.github.io/MathFonts/LatinModern/mathfonts.css" />
  </head>
  <body>
    <p>∀A∊𝔰𝔩(n,𝔽),TrA=0</p>
  </body>
</html>
css
p {
  font-family: "Latin Modern Math", math;
}

Một chút ngữ nghĩa

Chúng ta đã thấy trong bài bắt đầu với MathML rằng văn bản trong các công thức MathML được bao trong các phần tử vùng chứa cụ thể như <mn> hoặc <mo>. Nói rộng hơn, mọi văn bản trong công thức MathML đều phải nằm trong các phần tử vùng chứa như vậy, được gọi là các phần tử token. Ngoài ra, MathML cung cấp nhiều phần tử token để phân biệt các ý nghĩa khác nhau của nội dung văn bản:

  • Phần tử <mi> biểu diễn một "định danh", có thể là tên ký hiệu hoặc văn bản tùy ý. Ví dụ: <mi>x</mi> (biến), <mi>cos</mi> (tên hàm) và <mi>π</mi> (hằng ký hiệu).
  • Phần tử <mn> biểu diễn một "hằng số số học" hoặc dữ liệu khác nên được hiển thị như một hằng số số học. Ví dụ: <mn>2</mn> (số nguyên), <mn>0.123</mn> (số thập phân) hoặc <mn>0xFFEF</mn> (giá trị thập lục phân).
  • Phần tử <mo> biểu diễn một toán tử hoặc bất kỳ thứ gì nên được hiển thị như một toán tử. Ví dụ <mo>+</mo> (phép toán nhị phân), <mo>≤</mo> (quan hệ nhị phân), <mo>∑</mo> (ký hiệu tổng) hoặc <mo>[</mo> (ký hiệu ngoặc).
  • Phần tử <mtext> được dùng để biểu diễn văn bản tùy ý. Ví dụ các từ ngắn trong công thức như <mtext>if<mtext> hoặc <mtext>maps to</mtext>.

Đến lượt bạn: Nhận ra các phần tử token

Bên dưới là một ví dụ phức tạp hơn, cho biết giá trị tuyệt đối của một số thực bằng chính số đó nếu và chỉ nếu nó không âm. Chúng tôi muốn bạn thử nhận ra các phần tử token khác nhau và chúng được dùng để làm gì. Mỗi khi bạn bấm vào văn bản tương ứng, nó sẽ được tô sáng và một thông báo xác nhận sẽ hiện ra.

Cuối cùng, hãy đọc mã nguồn MathML để kiểm tra xem nó có khớp với kỳ vọng của bạn hay không:

xml
<math display="block">
  <mrow>
    <mrow>
      <mo>|</mo>
      <mi>x</mi>
      <mo>|</mo>
    </mrow>
    <mo>=</mo>
    <mi>x</mi>
  </mrow>
  <mtext>&nbsp;nếu và chỉ nếu&nbsp;</mtext>
  <mrow>
    <mi>x</mi>
    <mo>≥</mo>
    <mn>0</mn>
  </mrow>
</math>

Note: Đôi khi rất khó quyết định nên dùng phần tử token nào cho một nội dung văn bản cụ thể. Trên thực tế, việc chọn sai phần tử thường không gây ra vấn đề lớn vì các phần tử token nhìn chung được các trình duyệt hiển thị giống nhau (cho cả hiển thị trực quan lẫn công nghệ hỗ trợ). Tuy nhiên, các phần tử <mi><mo> có những đặc điểm phân biệt riêng mà bạn nên biết. Chúng được giải thích trong các phần tiếp theo.

Tự động nghiêng <mi>

Một quy ước kiểu chữ trong toán học là dùng chữ nghiêng cho biến. Để hỗ trợ điều đó, các phần tử <mi> chỉ có một ký tự có thể được tự động hiển thị nghiêng. Điều này áp dụng cho tất cả các chữ cái trong bảng chữ cái latin và greek. Hãy so sánh cách hiển thị của hai phần tử <mi> trong công thức sau:

html
<math>
  <mi>sin</mi>
  <mi>x</mi>
</math>

Note: Bảng này từ MathML Core cung cấp danh sách đầy đủ các ký tự chịu tác động của việc nghiêng, cùng với các ký tự nghiêng tương ứng.

Hủy nghiêng tự động của <mi>

Để bỏ phép biến đổi nghiêng mặc định này, bạn có thể gắn thuộc tính mathvariant="normal" vào phần tử <mi>. Hãy so sánh cách hiển thị của các chữ gamma in hoa trong công thức sau:

html
<math>
  <mi>Γ</mi>
  <mi mathvariant="normal">Γ</mi>
</math>

Note: Dù bạn có thể áp dụng biến đổi này, thông thường bạn sẽ chỉ dùng Mathematical Alphanumeric Symbols mong muốn.

Thuộc tính toán tử của <mo>

MathML chứa một operator dictionary xác định các thuộc tính mặc định của phần tử <mo> tùy theo nội dung và vị trí của nó trong vùng chứa (prefix, infix hoặc postfix). Hãy xét một ví dụ cụ thể:

html
<table>
  <tbody>
    <tr>
      <td>Phép cộng tiền tố</td>
      <td>
        <math>
          <mo>+</mo>
          <mi>i</mi>
        </math>
      </td>
    </tr>
    <tr>
      <td>Phép cộng trung tố</td>
      <td>
        <math>
          <mi>j</mi>
          <mo>+</mo>
          <mi>i</mi>
        </math>
      </td>
    </tr>
    <tr>
      <td>Tổng tiền tố</td>
      <td>
        <math>
          <mo>∑</mo>
          <mi>i</mi>
        </math>
      </td>
    </tr>
  </tbody>
</table>

Ví dụ này sẽ được hiển thị tương tự như ảnh chụp bên dưới. Hãy quan sát khoảng cách giữa các phần tử <mi>i</mi> và phần tử <mo> đứng trước nó: không có khoảng cách cho dấu cộng tiền tố, có khoảng cách cho dấu cộng trung tố và khoảng cách nhỏ hơn cho ký hiệu tổng tiền tố.

Ảnh chụp công thức MathML với khoảng cách toán tử khác nhau

Toán tử có nhiều thuộc tính khác mà chúng ta sẽ xem kỹ hơn sau. Trước mắt, hãy nhớ dùng vùng chứa <mo> cho các ký tự nằm trong operator dictionary và nhóm các biểu thức con đúng cách bằng các phần tử <mrow> để hỗ trợ bộ hiển thị MathML.

Nhận ra sự khác biệt

Bây giờ khi đã quen hơn với các đặc điểm đặc biệt của <mi><mo>, chúng tôi muốn bạn viết lại phần tử <p> trong ví dụ ở đầu trang bằng MathML thật sự. Hãy so sánh cách hiển thị trong trình duyệt của bạn và giải thích sự khác nhau so với phiên bản chỉ có văn bản.

html
<!doctype html>
<html lang="vi">
  <head>
    <meta charset="utf-8" />
    <title>Trang của tôi với các ký tự toán học</title>
    <link
      rel="stylesheet"
      href="https://fred-wang.github.io/MathFonts/LatinModern/mathfonts.css" />
  </head>
  <body>
    <p class="text">∀A∊𝔰𝔩(n,𝔽),TrA=0</p>
    <p>
      <math>
        <mo>∀</mo>
        <mrow>
          <mi>A</mi>
          <mo>∊</mo>
          <mrow>
            <mi>𝔰𝔩</mi>
            <mrow>
              <mo>(</mo>
              <mi>n</mi>
              <mo>,</mo>
              <mi>𝔽</mi>
              <mo>)</mo>
            </mrow>
          </mrow>
        </mrow>
        <mo>,</mo>
        <mrow>
          <mrow>
            <mi>Tr</mi>
            <mi>A</mi>
          </mrow>
          <mo>=</mo>
          <mn>0</mn>
        </mrow>
      </math>
    </p>
    <input id="showSolution" type="button" value="Hiển thị lời giải" />
    <div id="solution"></div>
  </body>
</html>

Note: Một khác biệt rõ ràng là mã nguồn trở nên dài dòng hơn nhiều với MathML. Hãy nhớ rằng bài hướng dẫn này nhằm học ngôn ngữ này, nhưng trên thực tế nội dung MathML thường không được viết tay. Xem trang Authoring MathML để biết thêm thông tin.

Nhận ra các toán tử co giãn

Operator dictionary xác định một thuộc tính mặc định stretchy cùng với stretch axis tương ứng cho một số toán tử. Ví dụ, một toán tử có thể co giãn theo chiều dọc mặc định để bao phủ chiều cao tối đa của các phần tử anh em không co giãn bên trong vùng chứa <mrow>. Bằng cách chỉnh một bài tập trước, bạn có thể làm cho các toán tử co giãn theo chiều dọc. Bạn có tìm ra chúng không?

Như thường lệ, bạn được khuyến khích đọc mã nguồn sau khi hoàn thành:

xml
<math display="block">
  <mrow>
    <mrow>
      <mo>|</mo>
      <mfrac>
        <mn>1</mn>
        <mi>x</mi>
      </mfrac>
      <mo>|</mo>
    </mrow>
    <mo>=</mo>
    <mfrac>
      <mn>1</mn>
      <mrow>
        <mo>|</mo>
        <mi>x</mi>
        <mo>|</mo>
      </mrow>
    </mfrac>
    <mo>=</mo>
    <mfrac>
      <mn>1</mn>
      <mi>x</mi>
    </mfrac>
  </mrow>
  <mtext>&nbsp;nếu và chỉ nếu&nbsp;</mtext>
  <mrow>
    <mi>x</mi>
    <mo>≥</mo>
    <mn>0</mn>
  </mrow>
</math>

Warning: Các phông toán học đặc biệt thường được yêu cầu để việc co giãn này hoạt động; ví dụ trước dựa vào web fonts.

Tóm tắt

Trong bài viết này, chúng ta đã tìm hiểu một vài phần tử token được dùng làm vùng chứa văn bản cùng với ngữ nghĩa khác nhau của chúng, cụ thể là <mi> (định danh), <mn> (số), <mo> (toán tử), <mtext> (văn bản tổng quát). Chúng ta đã xem các ký tự Unicode đặc biệt thường gặp trong công thức toán và có cái nhìn tổng quan về một số hành vi quan sát được của các phần tử <mi><mo>. Trong bài tiếp theo, chúng ta sẽ xem cách dựa vào các phần tử token để xây dựng những biểu thức phức tạp hơn nhiều như phân số và căn.

Xem thêm