Compare commits
209 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b57813c1e8 | ||
|
75746268bb | ||
|
99cbcbf444 | ||
|
70133abe67 | ||
|
166c35b4a7 | ||
|
841fd4a88b | ||
|
7e98f39ee9 | ||
|
b2afb8400a | ||
|
0b9c886c19 | ||
|
11ac18a6f5 | ||
|
7b0890ba24 | ||
|
8b4e949008 | ||
|
c83f29d906 | ||
|
fcc83a2696 | ||
|
61e8466c88 | ||
|
2528537f2e | ||
|
2e4bdb4dc4 | ||
|
20be02ee8c | ||
|
0d914e2321 | ||
|
9d0b738c03 | ||
|
ca8bd83702 | ||
|
5ae44ec6c6 | ||
|
4bed8d523b | ||
|
8da22d184e | ||
|
6fcc975735 | ||
|
f68f45f2c8 | ||
|
7bca165095 | ||
|
8f864361a9 | ||
|
ecde594cd3 | ||
|
398aa189fe | ||
|
f8a3d35aa1 | ||
|
b0149a45a3 | ||
|
d6f438a532 | ||
|
11ed5ffcbe | ||
|
29212f284c | ||
|
5c8d99818b | ||
|
18e85d016a | ||
|
cca4a39d89 | ||
|
37a9ce1b99 | ||
|
28d2b57997 | ||
|
36cfb020d2 | ||
|
5c8cf1b013 | ||
|
3d4d7ecd22 | ||
|
cfeb408332 | ||
|
ece360295a | ||
|
bdd3cd7480 | ||
|
e1741b13d5 | ||
|
c5ee5114fb | ||
|
a727a3a309 | ||
|
06986af907 | ||
|
b970df3c9e | ||
|
fb80000eb8 | ||
|
bb3d4736a6 | ||
|
d3eb2bffdf | ||
|
585c5c75e3 | ||
|
6b34c20542 | ||
|
7e000a0db1 | ||
|
cf0a3d4434 | ||
|
57e29caf9c | ||
|
2fda593fae | ||
|
88ab616a78 | ||
|
dc22fa31a4 | ||
|
a2fa1d4dcf | ||
|
c53fb2a956 | ||
|
1e3b5a81d5 | ||
|
04da7fc198 | ||
|
1cd6cc4da4 | ||
|
20a2572e12 | ||
|
13c4c7e173 | ||
|
80ec1995de | ||
|
a3e75978e6 | ||
|
eb4dd9561c | ||
|
957c8ff803 | ||
|
af3b7108cc | ||
|
872900b076 | ||
|
13b820a339 | ||
|
3c70bd11ef | ||
|
ff7ad4f7b4 | ||
|
06eb95d9c1 | ||
|
b738939001 | ||
|
43825dcac4 | ||
|
4849ee4373 | ||
|
8389cd1a9d | ||
|
3b6955314f | ||
|
17d7ebd16b | ||
|
f71c7b3c67 | ||
|
dc2d92e3fd | ||
|
58ad8a5766 | ||
|
fc430b31ac | ||
|
cfb5d03b92 | ||
|
e5d5ac2efe | ||
|
071cf90549 | ||
|
92d3b9bd5b | ||
|
9c757878ee | ||
|
2656c86158 | ||
|
bae4f782bb | ||
|
1a19e3947a | ||
|
62bab63177 | ||
|
413ec0112a | ||
|
e74bca7eac | ||
|
be474c633a | ||
|
7341dd5fc6 | ||
|
f4c0721401 | ||
|
3c033069f3 | ||
|
e6d7b73beb | ||
|
9b85cdb610 | ||
|
9c43b61387 | ||
|
ae911c29ae | ||
|
174cad050b | ||
|
637dfbf90a | ||
|
89f8e2a79a | ||
|
7a52f5580b | ||
|
9005c304d7 | ||
|
3bd184a3d1 | ||
|
e83622cbae | ||
|
e84079ee73 | ||
|
a2fb445894 | ||
|
cb2c48aa8d | ||
|
f5be988925 | ||
|
d2bb7a9457 | ||
|
bdbeb16c53 | ||
|
c8c32e0f4c | ||
|
d6758fe997 | ||
|
288af48597 | ||
|
0cd0784699 | ||
|
f132e3496a | ||
|
c6a180cd1a | ||
|
d1ef3292ee | ||
|
8ddc9aeebc | ||
|
cfae79975e | ||
|
5b9066eb26 | ||
|
54ce65a04d | ||
|
ddaf56b8af | ||
|
71c127dd67 | ||
|
3eae23c268 | ||
|
235815eb98 | ||
|
5252cbc90d | ||
|
e76d9ec8bf | ||
|
e1b8debcf6 | ||
|
d63bed65a1 | ||
|
e21116b501 | ||
|
e6077a2702 | ||
|
75a03787f8 | ||
|
c78ac2e779 | ||
|
903480a3f9 | ||
|
f5acbf0ab4 | ||
|
cb5def2cb1 | ||
|
d4c6d493d2 | ||
|
77b607e2e2 | ||
|
ccedfba57a | ||
|
75ede91b5d | ||
|
75c92b1ff5 | ||
|
3a8dcdebe8 | ||
|
4005fc172d | ||
|
36b3c596a7 | ||
|
ffe3514b75 | ||
|
3decacd033 | ||
|
09b8344549 | ||
|
8834b6af0d | ||
|
f6c7bb6b98 | ||
|
9e501b2d76 | ||
|
71b8d151d4 | ||
|
fcfe981c9e | ||
|
cd11aa478c | ||
|
6cb32caeb8 | ||
|
d5c0f98b91 | ||
|
fd9c8f4fcc | ||
|
a673af336c | ||
|
209f0cb13b | ||
|
702e974485 | ||
|
fba9e02b92 | ||
|
1bda0c5892 | ||
|
57f54f6ef6 | ||
|
dfee31b4b8 | ||
|
e0705c210b | ||
|
948818c8bc | ||
|
5be2282e9b | ||
|
6da728c217 | ||
|
e7eb77a396 | ||
|
29bda8e8c2 | ||
|
9d76be873e | ||
|
06149a5e99 | ||
|
dd7098fb4a | ||
|
d6b2747171 | ||
|
a782003db4 | ||
|
06915c6aa3 | ||
|
a0dc11d37d | ||
|
db60580191 | ||
|
a30b875e7a | ||
|
80f95f575a | ||
|
87e67e0807 | ||
|
ba4b30d49b | ||
|
483ab6a572 | ||
|
7a2a93fe5a | ||
|
f982de18ee | ||
|
207ea33a4e | ||
|
1961c2445c | ||
|
c9904b3bc5 | ||
|
ebc813d299 | ||
|
ec8fd3c1a8 | ||
|
6f92838e19 | ||
|
913b7150e1 | ||
|
1046e096ed | ||
|
2974676fab | ||
|
c4c2b701b5 | ||
|
98fd0a477a | ||
|
ba219a05bb | ||
|
562f9b1248 | ||
|
f9a23ca0b4 |
38
.github/actions/ctan-upload/action.yaml
vendored
Normal file
38
.github/actions/ctan-upload/action.yaml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: CTAN upload
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
filename:
|
||||||
|
required: true
|
||||||
|
dry-run:
|
||||||
|
required: true
|
||||||
|
uploader:
|
||||||
|
required: true
|
||||||
|
email:
|
||||||
|
required: true
|
||||||
|
version:
|
||||||
|
required: false
|
||||||
|
default: ${{ github.ref_name }}
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Send to CTAN
|
||||||
|
uses: zauguin/ctan-upload@v0.1
|
||||||
|
with:
|
||||||
|
package-name: luamml
|
||||||
|
version: ${{ inputs.version }}
|
||||||
|
author: 'Marcel Krüger, LaTeX Project Team'
|
||||||
|
uploader: ${{ inputs.uploader }}
|
||||||
|
email: ${{ inputs.email }}
|
||||||
|
license: lppl1.3c
|
||||||
|
summary: "Automatically generate MathML from LuaLaTeX math mode material"
|
||||||
|
ctan-path: /macros/luatex/latex/luamml
|
||||||
|
support: https://github.com/latex3/luamml/issues
|
||||||
|
update: true
|
||||||
|
topic: maths,luatex
|
||||||
|
description: |
|
||||||
|
LuaMML is an experimental package to automatically generate a MathML representation of mathematical expessions written in LuaLaTeX documents. These MathML representations can be used for improving accessibility or to ease conversion into new output formats like HTML.
|
||||||
|
filename: ${{ inputs.filename }}
|
||||||
|
dry-run: ${{ inputs.dry-run }}
|
||||||
|
# announcement-filename: ctan.ann
|
||||||
|
note: Uploaded automatically by GitHub Actions.
|
60
.github/tl_packages
vendored
Normal file
60
.github/tl_packages
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
scheme-minimal latex-bin l3build
|
||||||
|
#Proudly generated by the Island of TeX's DEPendency Printer https://gitlab.com/islandoftex/texmf/depp
|
||||||
|
alphalph
|
||||||
|
amsfonts
|
||||||
|
amsmath
|
||||||
|
bigintcalc
|
||||||
|
bitset
|
||||||
|
bookmark
|
||||||
|
booktabs
|
||||||
|
cm
|
||||||
|
colortbl
|
||||||
|
csquotes
|
||||||
|
enumitem
|
||||||
|
etoolbox
|
||||||
|
fancyvrb
|
||||||
|
firstaid
|
||||||
|
fontspec
|
||||||
|
gettitlestring
|
||||||
|
graphics
|
||||||
|
graphics-cfg
|
||||||
|
graphics-def
|
||||||
|
hologo
|
||||||
|
hycolor
|
||||||
|
hypdoc
|
||||||
|
hyperref
|
||||||
|
iftex
|
||||||
|
infwarerr
|
||||||
|
intcalc
|
||||||
|
knuth-lib
|
||||||
|
kvdefinekeys
|
||||||
|
kvoptions
|
||||||
|
kvsetkeys
|
||||||
|
l3backend
|
||||||
|
l3build
|
||||||
|
l3kernel
|
||||||
|
l3packages
|
||||||
|
l3experimental
|
||||||
|
latex
|
||||||
|
latex-fonts
|
||||||
|
latex-lab
|
||||||
|
lm
|
||||||
|
lm-math
|
||||||
|
ltxcmds
|
||||||
|
luacolor
|
||||||
|
lualatex-math
|
||||||
|
pdfescape
|
||||||
|
pdfmanagement-testphase
|
||||||
|
pdftexcmds
|
||||||
|
psnfss
|
||||||
|
refcount
|
||||||
|
rerunfilecheck
|
||||||
|
stringenc
|
||||||
|
symbol
|
||||||
|
tagpdf
|
||||||
|
tools
|
||||||
|
underscore
|
||||||
|
unicode-math
|
||||||
|
uniquecounter
|
||||||
|
url
|
||||||
|
zapfding
|
78
.github/workflows/deploy.yaml
vendored
Normal file
78
.github/workflows/deploy.yaml
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Only triggers for new tags
|
||||||
|
push:
|
||||||
|
tags: "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Mostly the same as the main.yaml workflow, but we only use a single job
|
||||||
|
l3build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Boilerplate
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: sudo apt-get install tidy
|
||||||
|
- name: Install TeX Live
|
||||||
|
uses: zauguin/install-texlive@v3
|
||||||
|
with:
|
||||||
|
# Here we use the same list of packages as in the testing workflow.
|
||||||
|
package_file: .github/tl_packages
|
||||||
|
- name: Run l3build
|
||||||
|
run: l3build ctan -H --show-log-on-error
|
||||||
|
- name: Upload package artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Package
|
||||||
|
path: |
|
||||||
|
build/distrib/ctan/*.zip
|
||||||
|
ctan.ann
|
||||||
|
- name: Validate CTAN package
|
||||||
|
uses: ./.github/actions/ctan-upload
|
||||||
|
with:
|
||||||
|
uploader: Dummy Name
|
||||||
|
email: dryrun@example.com
|
||||||
|
filename: "build/distrib/ctan/luamml-ctan.zip"
|
||||||
|
dry-run: true
|
||||||
|
|
||||||
|
github:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- l3build
|
||||||
|
steps:
|
||||||
|
- name: Download package artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Package
|
||||||
|
- name: Create GitHub release
|
||||||
|
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5
|
||||||
|
id: release
|
||||||
|
with:
|
||||||
|
artifacts: "build/distrib/ctan/*.zip"
|
||||||
|
prerelease: ${{ endsWith(github.ref, '-dev') }}
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# bodyFile: ctan.ann
|
||||||
|
|
||||||
|
ctan-upload:
|
||||||
|
if: "${{ !endsWith(github.ref, '-dev') }}"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: CTAN
|
||||||
|
needs:
|
||||||
|
- l3build
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: .github
|
||||||
|
- name: Download package artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Package
|
||||||
|
- name: Upload CTAN package
|
||||||
|
uses: ./.github/actions/ctan-upload
|
||||||
|
with:
|
||||||
|
uploader: ${{ secrets.CTAN_NAME }}
|
||||||
|
email: ${{ secrets.CTAN_EMAIL }}
|
||||||
|
filename: "build/distrib/ctan/luamml-ctan.zip"
|
||||||
|
dry-run: false
|
53
.github/workflows/main.yaml
vendored
Normal file
53
.github/workflows/main.yaml
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
name: Automated testing
|
||||||
|
|
||||||
|
# Currently we run in two situations:
|
||||||
|
on:
|
||||||
|
# Whenever someone pushes to a branch or tag in our repo
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*"
|
||||||
|
# Whenever a pull request is opened, reopened or gets new commits.
|
||||||
|
pull_request:
|
||||||
|
# This implies that for every push to a local branch in our repo for which a
|
||||||
|
# pull request is open this runs twice. But it's important to ensure that pull
|
||||||
|
# requests get tested even if their branch comes from a fork.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
l3build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
kind: [doc, test]
|
||||||
|
name: "${{ format('{0}', matrix.kind == 'doc' && 'Documentation' || 'Test suite') }}"
|
||||||
|
steps:
|
||||||
|
# Boilerplate
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: sudo apt-get install tidy
|
||||||
|
- name: Install TeX Live
|
||||||
|
uses: zauguin/install-texlive@v3
|
||||||
|
with:
|
||||||
|
# The list of packages to install is in a separate file under .github/tl_packages
|
||||||
|
# to allow reuse.
|
||||||
|
package_file: .github/tl_packages
|
||||||
|
cache_version: 0
|
||||||
|
- name: Run l3build
|
||||||
|
run: ${{ format('l3build {0} -q -H', matrix.kind == 'doc' && 'doc' || 'check --show-log-on-error') }}
|
||||||
|
# Now we create the artifacts: There are two cases where this happens.
|
||||||
|
# 1. If we failed running tests
|
||||||
|
- name: Archive failed test output
|
||||||
|
if: ${{ matrix.kind == 'test' && always() }}
|
||||||
|
uses: zauguin/l3build-failure-artifacts@v1
|
||||||
|
with:
|
||||||
|
name: testfiles-${{ matrix.platform }}
|
||||||
|
# Decide how long to keep the test output artifact:
|
||||||
|
retention-days: 3
|
||||||
|
# 2. If we succeed building documentation
|
||||||
|
- name: Archive documentation
|
||||||
|
if: ${{ matrix.kind == 'doc' && success() }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Documentation
|
||||||
|
path: "**/*.pdf"
|
||||||
|
# Decide how long to keep the test output artifact:
|
||||||
|
retention-days: 21
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/build/
|
||||||
|
*.aux
|
||||||
|
*.log
|
||||||
|
*.pdf
|
||||||
|
*.xml
|
43
CHANGELOG.md
Normal file
43
CHANGELOG.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to the `luamml` package since the
|
||||||
|
2025-02-17 will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
this project uses date-based 'snapshot' version identifiers.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
- Ulrike Fischer, 2025-03-06
|
||||||
|
* add class attribute to math environments
|
||||||
|
* correct columnalign (take label column into account)
|
||||||
|
* add intent :continued-row in split enviroment
|
||||||
|
* add intent :system-of-equations to environments
|
||||||
|
* temporary patch to \common@align@ending to store the environment name
|
||||||
|
* start some debugging functions (variable debugmtable)
|
||||||
|
* correct columnspacing
|
||||||
|
* add intent :pause-medium between columns
|
||||||
|
|
||||||
|
## 2025-02-21
|
||||||
|
|
||||||
|
- Ulrike Fischer, 2025-02-21
|
||||||
|
* change intent :equationlabel to :equation-label and
|
||||||
|
:noequationlabel to :no-equation-label
|
||||||
|
|
||||||
|
|
||||||
|
## 2025-02-17
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Ulrike Fischer, 2025-02-17
|
||||||
|
* moved all patches into latex-lab
|
||||||
|
* added sockets to luamml.dtx
|
||||||
|
* changed handling of tags/labels: empty tags produces a row too and have an intent
|
||||||
|
* corrected small bugs
|
||||||
|
|
||||||
|
- Ulrike Fischer, 2024-11-29
|
||||||
|
luamml-structelemwriter.lua: moved the actualtext for e.g. stretched braces from the structure element to the mc-chunk.
|
||||||
|
|
||||||
|
- Ulrike Fischer, 2024-03-03
|
||||||
|
luamml.dtx: add plug for mbox socket to correctly annotate them in math.
|
||||||
|
|
||||||
|
- Ulrike Fischer, 2024-11-29
|
||||||
|
luamml-structelemwriter.lua: use structnum instead of label when stashing.
|
17
README.md
17
README.md
@ -1,14 +1,17 @@
|
|||||||
# Automated LuaLaTeX math to MathML conversion
|
# LuaMML: Automated LuaLaTeX math to MathML conversion
|
||||||
**Highly experimental! At this point all interfaces may change without prior warning and many features aren't implemented yet. It is not ready for anything beyond simple experiments.**
|
|
||||||
|
|
||||||
This is an attempt to implement automatic conversion of LuaLaTeX inline and display math expressions into MathML code to aid with tagging.
|
This is an attempt to implement automatic conversion of LuaLaTeX inline and display math expressions into MathML code to aid with tagging.
|
||||||
It works best with `unicode-math`, but it can also be used with traditional math fonts if mappings to Unicode are provided.
|
It works best with `unicode-math`, but it can also be used with traditional math fonts if mappings to Unicode are provided.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Run `l3build install` to install `luamml` into your local `texmf` tree.
|
Run `l3build install` to install `luamml` into your local `texmf` tree.
|
||||||
|
|
||||||
## Demo
|
## Usage
|
||||||
Run `lualatex test_tex` to see all equations from [our example file](./test_tex.tex) converted into MathML.
|
Add `\usepackage[tracing]{luamml-demo}` to print MathML to the terminal or `\usepackage[files]{luamml-demo}` to generate separate files with MathML output.
|
||||||
|
Alternatively it can be used with latex-lab to automatically integrate with tagging infrastucture.
|
||||||
|
|
||||||
To test it on your own files, add `\usepackage{luamml}` and `\tracingmathml=2` to your preamble.
|
## License
|
||||||
Also see a [`tagpdf` experiment using this to tag PDF formulas](https://github.com/u-fischer/tagpdf/blob/develop/experiments/exp-mathml-lua.tex).
|
LuaMML may be modified and distributed under the terms of the [LaTeX Project Public License](https://www.latex-project.org/lppl/), version 1.3c or greater.
|
||||||
|
It is written by Marcel Krüger and the LaTeX Project Team.
|
||||||
|
<!-- Also see a [`tagpdf` experiment using this to tag PDF formulas](https://github.com/u-fischer/tagpdf/blob/develop/experiments/exp-mathml-lua.tex). -->
|
||||||
|
|
||||||
|
<!-- If you are very brave you can also try running `pdflatex test_pdf` and afterwards run `./pdfmml.lua test_pdf.lua` to get pdflatex formulas converted. -->
|
||||||
|
16
build.lua
16
build.lua
@ -1,7 +1,15 @@
|
|||||||
module = "luamml"
|
module = "luamml"
|
||||||
|
|
||||||
tdsroot = "lualatex"
|
tdsroot = "lualatex"
|
||||||
installfiles = { "luamml-*.lua", "*.sty" }
|
installfiles = { "luamml-*.lua", "*.sty" }
|
||||||
stdengine = "luatex"
|
sourcefiles = { "luamml-*.lua", "*.sty", "*.dtx" }
|
||||||
checkengines = {"luatex"}
|
typesetsuppfiles = { "*.tex" }
|
||||||
sourcefiles = installfiles
|
typesetsourcefiles = { "*.tex" }
|
||||||
|
stdengine = "luatex"
|
||||||
|
unpackfiles = { "*.dtx" }
|
||||||
|
typesetexe = "lualatex"
|
||||||
|
|
||||||
|
checkconfigs = {
|
||||||
|
'config-lua',
|
||||||
|
'config-pdf',
|
||||||
|
}
|
||||||
|
17
config-lua.lua
Normal file
17
config-lua.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
testfiledir = "testfiles-lua"
|
||||||
|
checkengines = {"luatex"}
|
||||||
|
stdengine = "luatex"
|
||||||
|
checkruns = 3
|
||||||
|
|
||||||
|
test_types = test_types or {}
|
||||||
|
test_types.mml = {
|
||||||
|
test = '.mlt',
|
||||||
|
generated = '.mml',
|
||||||
|
reference = '.mlr',
|
||||||
|
expectation = '.mle',
|
||||||
|
rewrite = function(source, result, engine, errlevels)
|
||||||
|
return os.execute(string.format('tidy -xml -indent -wrap -quiet --output-file "%s" "%s"', result, source))
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
test_order = {'log', 'pdf', 'mml'}
|
33
config-pdf.lua
Normal file
33
config-pdf.lua
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
testfiledir = "testfiles-pdf"
|
||||||
|
checkengines = {"pdftex"}
|
||||||
|
stdengine = "pdftex"
|
||||||
|
checkruns = 3
|
||||||
|
|
||||||
|
test_types = test_types or {}
|
||||||
|
test_types.tml = {
|
||||||
|
test = '.xrt',
|
||||||
|
generated = '.tml',
|
||||||
|
reference = '.txr',
|
||||||
|
expectation = '.xre',
|
||||||
|
rewrite = function(source, result, engine, errlevels)
|
||||||
|
local file = assert(io.open(source,"rb"))
|
||||||
|
local content = string.gsub(file:read("*all") .. "\n","\r\n","\n")
|
||||||
|
file:close()
|
||||||
|
local new_content = content
|
||||||
|
-- local new_content = processor(content,...)
|
||||||
|
local newfile = io.open(result,"w")
|
||||||
|
newfile:write(new_content)
|
||||||
|
newfile:close()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
test_types.mml = {
|
||||||
|
test = '.mlt',
|
||||||
|
generated = '.tml',
|
||||||
|
reference = '.mlr',
|
||||||
|
expectation = '.mle',
|
||||||
|
rewrite = function(source, result, engine, errlevels)
|
||||||
|
return os.execute(string.format('texlua pdfmml.lua "%s" | tidy -xml -indent -wrap -quiet --output-file "%s" -', source, result))
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
test_order = {'log', 'pdf', 'tml', 'mml'}
|
@ -3,11 +3,30 @@ local make_root = require'luamml-convert'.make_root
|
|||||||
local save_result = require'luamml-tex'.save_result
|
local save_result = require'luamml-tex'.save_result
|
||||||
local store_column = require'luamml-table'.store_column
|
local store_column = require'luamml-table'.store_column
|
||||||
local store_tag = require'luamml-table'.store_tag
|
local store_tag = require'luamml-table'.store_tag
|
||||||
|
local store_notag = require'luamml-table'.store_notag
|
||||||
local get_table = require'luamml-table'.get_table
|
local get_table = require'luamml-table'.get_table
|
||||||
|
local set_row_attribute = require'luamml-table'.set_row_attribute
|
||||||
local to_text = require'luamml-lr'
|
local to_text = require'luamml-lr'
|
||||||
|
|
||||||
local properties = node.get_properties_table()
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
|
local math_t = node.id'math'
|
||||||
|
|
||||||
|
local funcid = luatexbase.new_luafunction'__luamml_amsmath_add_last_to_row:'
|
||||||
|
token.set_lua('__luamml_amsmath_add_last_to_row:', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
-- TODO: Error handling etc
|
||||||
|
-- local box = token.scan_int()
|
||||||
|
local nest = tex.nest.top
|
||||||
|
local head, startmath = nest.head, nest.tail
|
||||||
|
repeat
|
||||||
|
startmath = startmath.prev
|
||||||
|
until startmath == head or (startmath.id == math_t and startmath.subtype == 0)
|
||||||
|
if startmath == head then return end
|
||||||
|
assert(startmath.id == node.id"math")
|
||||||
|
store_column(startmath)
|
||||||
|
end
|
||||||
|
|
||||||
local funcid = luatexbase.new_luafunction'__luamml_amsmath_add_box_to_row:'
|
local funcid = luatexbase.new_luafunction'__luamml_amsmath_add_box_to_row:'
|
||||||
token.set_lua('__luamml_amsmath_add_box_to_row:', funcid, 'protected')
|
token.set_lua('__luamml_amsmath_add_box_to_row:', funcid, 'protected')
|
||||||
lua.get_functions_table()[funcid] = function()
|
lua.get_functions_table()[funcid] = function()
|
||||||
@ -15,24 +34,139 @@ lua.get_functions_table()[funcid] = function()
|
|||||||
-- local box = token.scan_int()
|
-- local box = token.scan_int()
|
||||||
local boxnum = 0
|
local boxnum = 0
|
||||||
local startmath = tex.box[boxnum].list
|
local startmath = tex.box[boxnum].list
|
||||||
assert(startmath.id == node.id"math")
|
assert(startmath.id == math_t)
|
||||||
store_column(startmath, true)
|
store_column(startmath)
|
||||||
end
|
end
|
||||||
|
|
||||||
funcid = luatexbase.new_luafunction'__luamml_amsmath_finalize_table:'
|
local funcid = luatexbase.new_luafunction'__luamml_amsmath_set_row_columnalign:n'
|
||||||
token.set_lua('__luamml_amsmath_finalize_table:', funcid)
|
token.set_lua('__luamml_amsmath_set_row_columnalign:n', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
set_row_attribute('columnalign', token.scan_argument())
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This function is used to add a intent :continued-row to
|
||||||
|
-- rows of a split environment.
|
||||||
|
-- we assume that the table is a mtable with mrow with mtd.
|
||||||
|
-- we check row 2..n. If the first cell has only one element and
|
||||||
|
-- for this element 'tex:ignore' has been set, we assume a continued row and
|
||||||
|
-- set the intent on the mrow.
|
||||||
|
local function add_intent_continued_row (table)
|
||||||
|
for index,rowtable in ipairs(table) do
|
||||||
|
if table[index][1] and table[index][1][1] then -- just for safety ...
|
||||||
|
if index > 1 and #table[index][1]==1 and table[index][1][1]['tex:ignore'] then
|
||||||
|
table[index]['intent']=':continued-row'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This function add an intent =":pause-medium" on every second mtd in a table
|
||||||
|
-- currently it is also on the first (after the label) but this could be changed
|
||||||
|
-- used in __luamml_amsmath_finalize_table:n for
|
||||||
|
-- 'align' or 'alignat' or 'flalign' or 'xalignat' or 'xxalignat'
|
||||||
|
local function add_intent_pause (mmltable)
|
||||||
|
for mtrindex,mtrtable in ipairs(mmltable) do
|
||||||
|
for mtdindex,mtdtable in ipairs(mtrtable) do
|
||||||
|
if (mtdindex % 2 == 0) then
|
||||||
|
mtdtable['intent']=':pause-medium'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- debug function for tables
|
||||||
|
-- activate with \directlua{debugmtable=2} or \directlua{debugmtable='split'}
|
||||||
|
local function debug_mtable (mtable,kind)
|
||||||
|
if debugmtable and (debugmtable==2) or (debugmtable==kind) then
|
||||||
|
texio.write_nl('==============')
|
||||||
|
texio.write_nl(kind)
|
||||||
|
texio.write_nl(table.serialize(mtable))
|
||||||
|
texio.write_nl('==============')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local saved
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_amsmath_save_inner_table:n'
|
||||||
|
token.set_lua('__luamml_amsmath_save_inner_table:n', funcid)
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
-- TODO: Error handling etc
|
||||||
|
local kind = token.scan_argument()
|
||||||
|
kind = kind:gsub("*","")
|
||||||
|
local mml_table = get_table()
|
||||||
|
if not mml_table then return end
|
||||||
|
mml_table.displaystyle = true
|
||||||
|
mml_table.class=kind
|
||||||
|
if kind=="split" then
|
||||||
|
add_intent_continued_row (mml_table)
|
||||||
|
end
|
||||||
|
local columns = node.count(node.id'align_record', tex.lists.align_head)//2
|
||||||
|
mml_table.columnalign = kind == 'gathered' and 'center' or string.rep('right left', columns, ' ')
|
||||||
|
local spacing = {}
|
||||||
|
for n in node.traverse_id(node.id'glue', tex.lists.align_head) do
|
||||||
|
spacing[#spacing+1] = n.width == 0 and '0' or string.format('%.3fpt', n.width/65781.76)
|
||||||
|
end
|
||||||
|
mml_table.columnspacing = #spacing > 3 and table.concat(spacing, ' ', 2, #spacing-2) or nil
|
||||||
|
debug_mtable(mml_table,kind)
|
||||||
|
saved = mml_table
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_amsmath_save_smallmatrix:'
|
||||||
|
token.set_lua('__luamml_amsmath_save_smallmatrix:', funcid)
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
-- TODO: Error handling etc
|
||||||
|
local mml_table = get_table()
|
||||||
|
mml_table.align = 'axis'
|
||||||
|
mml_table.class='smallmatrix'
|
||||||
|
mml_table.columnalign = 'center'
|
||||||
|
mml_table.columnspacing = '0.278em'
|
||||||
|
mml_table.rowspacing = string.format('%.3fpt', tex.lineskip.width/65781.76)
|
||||||
|
saved = {[0] = 'mpadded', width = '+0.333em', lspace = '0.167em', mml_table}
|
||||||
|
debug_mtable(mml_table,kind)
|
||||||
|
saved = mml_table
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_amsmath_finalize_inner_table:'
|
||||||
|
token.set_lua('__luamml_amsmath_finalize_inner_table:', funcid)
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
-- TODO: Error handling etc
|
||||||
|
local vcenter = tex.nest.top.tail.nucleus
|
||||||
|
local props = properties[vcenter]
|
||||||
|
if not props then
|
||||||
|
props = {}
|
||||||
|
properties[vcenter] = props
|
||||||
|
end
|
||||||
|
props.mathml_table = assert(saved)
|
||||||
|
saved = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_amsmath_finalize_table:n'
|
||||||
|
token.set_lua('__luamml_amsmath_finalize_table:n', funcid)
|
||||||
lua.get_functions_table()[funcid] = function()
|
lua.get_functions_table()[funcid] = function()
|
||||||
-- TODO: Error handling etc
|
-- TODO: Error handling etc
|
||||||
|
local kind = token.scan_argument()
|
||||||
|
kind = kind:gsub("*","")
|
||||||
local mml_table = get_table()
|
local mml_table = get_table()
|
||||||
if not mml_table then return end
|
if not mml_table then return end
|
||||||
mml_table.displaystyle = true
|
mml_table.displaystyle = true
|
||||||
|
mml_table.class=kind
|
||||||
|
-- this should perhaps be configurable and extendable
|
||||||
|
if kind == 'align' or 'alignat' or 'flalign' or 'xalignat' or 'xxalignat' then
|
||||||
|
mml_table.intent=":system-of-equations"
|
||||||
|
add_intent_pause (mml_table)
|
||||||
|
end
|
||||||
local columns = node.count(node.id'align_record', tex.lists.align_head)//2
|
local columns = node.count(node.id'align_record', tex.lists.align_head)//2
|
||||||
mml_table.columnalign = string.rep('right left', columns, ' ')
|
mml_table.columnalign = kind == 'align' and 'left '..string.rep('right left', columns, ' ') or nil
|
||||||
|
mml_table.width = kind == 'multline' and '100%' or nil
|
||||||
|
-- mml_table.side = kind == 'multline' and 'rightoverlap' or nil
|
||||||
local spacing = {}
|
local spacing = {}
|
||||||
for n in node.traverse_id(node.id'glue', tex.lists.align_head) do
|
for n in node.traverse_id(node.id'glue', tex.lists.align_head) do
|
||||||
spacing[#spacing+1] = n.width == 0 and '0' or '.8em'
|
spacing[#spacing+1] = n.width == 0 and '0' or '.8em'
|
||||||
end
|
end
|
||||||
mml_table.columnspacing = table.concat(spacing, ' ', 2, #spacing-2)
|
mml_table.columnspacing = #spacing > 3 and "0 "..table.concat(spacing, ' ', 2, #spacing-2) or nil
|
||||||
|
debug_mtable(mml_table,kind)
|
||||||
save_result(mml_table, true)
|
save_result(mml_table, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -50,9 +184,9 @@ funcid = luatexbase.new_luafunction'__luamml_amsmath_set_tag:'
|
|||||||
token.set_lua('__luamml_amsmath_set_tag:', funcid, 'protected')
|
token.set_lua('__luamml_amsmath_set_tag:', funcid, 'protected')
|
||||||
lua.get_functions_table()[funcid] = function()
|
lua.get_functions_table()[funcid] = function()
|
||||||
if not last_tag then
|
if not last_tag then
|
||||||
texio.write_nl'WARNING: Tag extraction failed'
|
store_notag({[0] = 'mtd',''})
|
||||||
return
|
else
|
||||||
|
store_tag({[0] = 'mtd', last_tag})
|
||||||
|
last_tag = nil
|
||||||
end
|
end
|
||||||
store_tag({[0] = 'mtd', last_tag})
|
|
||||||
last_tag = nil
|
|
||||||
end
|
end
|
||||||
|
@ -54,7 +54,7 @@ end
|
|||||||
|
|
||||||
local saved_array
|
local saved_array
|
||||||
|
|
||||||
funcid = luatexbase.new_luafunction'__luamml_array_finalize_array:'
|
funcid = luatexbase.new_luafunction'__luamml_array_save_array:'
|
||||||
token.set_lua('__luamml_array_save_array:', funcid)
|
token.set_lua('__luamml_array_save_array:', funcid)
|
||||||
lua.get_functions_table()[funcid] = function()
|
lua.get_functions_table()[funcid] = function()
|
||||||
-- TODO: Error handling etc.
|
-- TODO: Error handling etc.
|
||||||
|
@ -11,7 +11,86 @@ local radical_t, fraction_t, fence_t = node.id'radical', node.id'fraction', node
|
|||||||
|
|
||||||
local math_char_t, sub_box_t, sub_mlist_t = node.id'math_char', node.id'sub_box', node.id'sub_mlist'
|
local math_char_t, sub_box_t, sub_mlist_t = node.id'math_char', node.id'sub_box', node.id'sub_mlist'
|
||||||
|
|
||||||
local noad_sub = node.subtypes'noad'
|
local function invert_table(t)
|
||||||
|
local t_inv = {}
|
||||||
|
for k, v in next, t do
|
||||||
|
t_inv[v] = k
|
||||||
|
end
|
||||||
|
return t_inv
|
||||||
|
end
|
||||||
|
|
||||||
|
local noad_names = node.subtypes'noad'
|
||||||
|
|
||||||
|
--[[ We could determine the noad subtypes dynamically:
|
||||||
|
local noad_sub = invert_table(noad_names)
|
||||||
|
local noad_ord = noad_sub.ord
|
||||||
|
local noad_op = noad_sub.opdisplaylimits
|
||||||
|
local noad_oplimits = noad_sub.oplimits
|
||||||
|
local noad_opnolimits = noad_sub.opnolimits
|
||||||
|
local noad_bin = noad_sub.bin
|
||||||
|
local noad_rel = noad_sub.rel
|
||||||
|
local noad_open = noad_sub.open
|
||||||
|
local noad_close = noad_sub.close
|
||||||
|
local noad_punct = noad_sub.punct
|
||||||
|
local noad_inner = noad_sub.inner
|
||||||
|
local noad_under = noad_sub.under
|
||||||
|
local noad_over = noad_sub.over
|
||||||
|
local noad_vcenter = noad_sub.vcenter
|
||||||
|
-- But the spacing table depends on their specific values anyway, so we just verify the values
|
||||||
|
]]
|
||||||
|
local noad_ord, noad_op, noad_oplimits, noad_opnolimits = 0, 1, 2, 3
|
||||||
|
local noad_bin, noad_rel, noad_open, noad_close, noad_punct = 4, 5, 6, 7, 8
|
||||||
|
local noad_inner, noad_under, noad_over, noad_vcenter = 9, 10, 11, 12
|
||||||
|
|
||||||
|
for i, n in ipairs{'ord', 'opdisplaylimits', 'oplimits', 'opnolimits', 'bin',
|
||||||
|
'rel', 'open', 'close', 'punct', 'inner', 'under', 'over', 'vcenter'} do
|
||||||
|
assert(noad_names[i-1] == n)
|
||||||
|
end
|
||||||
|
-- Attention, the spacing_table is indexed by subtype+1 since 1-based tables are faster in Lua
|
||||||
|
local spacing_table = {
|
||||||
|
{0 , '0.167em', '0.167em', '0.167em', '0.222em', '0.278em', 0 , 0 , 0 , '0.167em', 0 , 0 , 0 , },
|
||||||
|
{'0.167em', '0.167em', '0.167em', '0.167em', nil , '0.278em', 0 , 0 , 0 , '0.167em', '0.167em', '0.167em', '0.167em', },
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
{'0.222em', '0.222em', '0.222em', '0.222em', nil , nil , '0.222em', nil , nil , '0.222em', '0.222em', '0.222em', '0.222em', },
|
||||||
|
{'0.278em', '0.278em', '0.278em', '0.278em', nil , 0 , '0.278em', 0 , 0 , '0.278em', '0.278em', '0.278em', '0.278em', },
|
||||||
|
{0 , 0 , 0 , 0 , nil , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , '0.167em', '0.167em', '0.167em', '0.222em', '0.278em', 0 , 0 , 0 , '0.167em', 0 , 0 , 0 , },
|
||||||
|
{'0.167em', '0.167em', '0.167em', '0.167em', nil , '0.167em', '0.167em', '0.167em', '0.167em', '0.167em', '0.167em', '0.167em', '0.167em', },
|
||||||
|
{'0.167em', '0.167em', '0.167em', '0.167em', '0.222em', '0.278em', '0.167em', 0 , '0.167em', '0.167em', '0.167em', '0.167em', '0.167em', },
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
local spacing_table_script = {
|
||||||
|
{0 , '0.167em', '0.167em', '0.167em', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{'0.167em', '0.167em', '0.167em', '0.167em', nil , 0 , 0 , 0 , 0 , 0 , '0.167em', '0.167em', '0.167em', },
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
{0 , 0 , 0 , 0 , nil , nil , 0 , nil , nil , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , 0 , 0 , 0 , nil , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , 0 , 0 , 0 , nil , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , '0.167em', '0.167em', '0.167em', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , 0 , 0 , 0 , nil , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
{0 , '0.167em', '0.167em', '0.167em', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , },
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
do -- Fill the blanks
|
||||||
|
local st, sts = spacing_table, spacing_table_script
|
||||||
|
|
||||||
|
local st_op, sts_op = st[noad_op+1], sts[noad_op+1]
|
||||||
|
st[noad_oplimits+1], sts[noad_oplimits+1] = st_op, sts_op
|
||||||
|
st[noad_opnolimits+1], sts[noad_opnolimits+1] = st_op, sts_op
|
||||||
|
|
||||||
|
local st_ord, sts_ord = st[noad_ord+1], sts[noad_ord+1]
|
||||||
|
st[noad_under+1], sts[noad_under+1] = st_ord, sts_ord
|
||||||
|
st[noad_over+1], sts[noad_over+1] = st_ord, sts_ord
|
||||||
|
st[noad_vcenter+1], sts[noad_vcenter+1] = st_ord, sts_ord
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local radical_sub = node.subtypes'radical'
|
local radical_sub = node.subtypes'radical'
|
||||||
local fence_sub = node.subtypes'fence'
|
local fence_sub = node.subtypes'fence'
|
||||||
|
|
||||||
@ -25,8 +104,13 @@ local digit_map = {["0"] = true, ["1"] = true,
|
|||||||
["5"] = true, ["6"] = true, ["7"] = true,
|
["5"] = true, ["6"] = true, ["7"] = true,
|
||||||
["8"] = true, ["9"] = true,}
|
["8"] = true, ["9"] = true,}
|
||||||
|
|
||||||
-- Two marker tables. They are used instead of an embellished operator to mark space-like or user provided constructs
|
local always_mo = {["%"] = true, ["&"] = true, ["."] = true, ["/"] = true,
|
||||||
local user_provided, space_like = {}, {}
|
["\\"] = true, ["¬"] = true, ["′"] = true, ["″"] = true, ["‴"] = true,
|
||||||
|
["⁗"] = true, ["‵"] = true, ["‶"] = true, ["‷"] = true, ["|"] = true,
|
||||||
|
["∀"] = true, ["∁"] = true, ["∃"] = true, ["∂"] = true, ["∄"] = true,}
|
||||||
|
|
||||||
|
-- Marker tables replacing the core operator for space like elements
|
||||||
|
local space_like = {}
|
||||||
|
|
||||||
local nodes_to_table
|
local nodes_to_table
|
||||||
|
|
||||||
@ -35,47 +119,71 @@ local function sup_style(s) return s//4*2+4+s%2 end
|
|||||||
|
|
||||||
-- The _to_table functions generally return a second argument which is
|
-- The _to_table functions generally return a second argument which is
|
||||||
-- could be (if it were a <mo>) a core operator of the embellishe operator
|
-- could be (if it were a <mo>) a core operator of the embellishe operator
|
||||||
-- or space_like/user_provided
|
-- or space_like
|
||||||
-- acc_to_table is special since it's return value should
|
-- acc_to_table is special since it's return value should
|
||||||
-- always be considered a core operator
|
-- always be considered a core operator
|
||||||
|
|
||||||
-- We ignore large_... since they aren't used for modern fonts
|
-- We ignore large_... since they aren't used for modern fonts
|
||||||
local function delim_to_table(delim)
|
local function delim_to_table(delim)
|
||||||
if not delim then return end
|
if not delim then return end
|
||||||
local props = properties[delim] props = props and props.mathml_table
|
local props = properties[delim]
|
||||||
if props then return props end
|
local mathml_core = props and props.mathml_core
|
||||||
|
local mathml_table = props and (props.mathml_table or mathml_core)
|
||||||
|
if mathml_table ~= nil then return mathml_table, mathml_core end
|
||||||
|
local mathml_filter = props and props.mathml_filter -- Kind of pointless since the arguments are literals, but present for consistency
|
||||||
local char = delim.small_char
|
local char = delim.small_char
|
||||||
if char == 0 then
|
if char == 0 then
|
||||||
return {[0] = 'mspace', width = string.format("%.3fpt", tex.nulldelimiterspace/65781.76)}, space_like
|
local result = {[0] = 'mspace', width = string.format("%.3fpt", tex.nulldelimiterspace/65781.76)}
|
||||||
|
if mathml_filter then
|
||||||
|
return mathml_filter(result, space_like)
|
||||||
|
else
|
||||||
|
return result, space_like
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local fam = delim.small_fam
|
local fam = delim.small_fam
|
||||||
char = remap_lookup[fam << 21 | char]
|
char = remap_lookup[fam << 21 | char]
|
||||||
local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[char] or nil }
|
local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[char] or nil, lspace = 0, rspace = 0, [':nodes'] = {delim}, [':actual'] = char}
|
||||||
return result, result
|
if mathml_filter then
|
||||||
|
return mathml_filter(result, result)
|
||||||
|
else
|
||||||
|
return result, result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Like kernel_to_table but always a math_char_t. Also creating a mo and potentially remapping to handle combining chars
|
-- Like kernel_to_table but always a math_char_t. Also creating a mo and potentially remapping to handle combining chars.
|
||||||
|
-- No lspace or space is set here since these never appear as core operators in an mrow.
|
||||||
local function acc_to_table(acc, cur_style, stretch)
|
local function acc_to_table(acc, cur_style, stretch)
|
||||||
if not acc then return end
|
if not acc then return end
|
||||||
local props = properties[acc] props = props and props.mathml_table
|
local props = properties[acc]
|
||||||
if props then return props end
|
local mathml_core = props and props.mathml_core
|
||||||
|
local mathml_table = props and (props.mathml_table or mathml_core)
|
||||||
|
if mathml_table ~= nil then return mathml_table, mathml_core end
|
||||||
if acc.id ~= math_char_t then
|
if acc.id ~= math_char_t then
|
||||||
error'confusion'
|
error'confusion'
|
||||||
end
|
end
|
||||||
|
local mathml_filter = props and props.mathml_filter -- Kind of pointless since the arguments are literals, but present for consistency
|
||||||
local fam = acc.fam
|
local fam = acc.fam
|
||||||
local char = remap_lookup[fam << 21 | acc.char]
|
local char = remap_lookup[fam << 21 | acc.char]
|
||||||
char = remap_comb[char] or char
|
char = remap_comb[char] or char
|
||||||
if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy
|
if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy
|
||||||
stretch = nil
|
stretch = nil
|
||||||
end
|
end
|
||||||
return {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch}
|
local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch, [':nodes'] = {acc}, [':actual'] = stretch and char or nil}
|
||||||
|
if mathml_filter then
|
||||||
|
return mathml_filter(result)
|
||||||
|
else
|
||||||
|
return result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function kernel_to_table(kernel, cur_style)
|
local function kernel_to_table(kernel, cur_style, text_families)
|
||||||
if not kernel then return end
|
if not kernel then return end
|
||||||
local props = properties[kernel] props = props and props.mathml_table
|
local props = properties[kernel]
|
||||||
if props then return props, user_provided end
|
local mathml_core = props and props.mathml_core
|
||||||
|
local mathml_table = props and (props.mathml_table or mathml_core)
|
||||||
|
if mathml_table ~= nil then return mathml_table, mathml_core end
|
||||||
|
local mathml_filter = props and props.mathml_filter -- Kind of pointless since the arguments are literals, but present for consistency
|
||||||
local id = kernel.id
|
local id = kernel.id
|
||||||
if id == math_char_t then
|
if id == math_char_t then
|
||||||
local fam = kernel.fam
|
local fam = kernel.fam
|
||||||
@ -84,27 +192,40 @@ local function kernel_to_table(kernel, cur_style)
|
|||||||
local result = {[0] = elem,
|
local result = {[0] = elem,
|
||||||
char,
|
char,
|
||||||
['tex:family'] = fam ~= 0 and fam or nil,
|
['tex:family'] = fam ~= 0 and fam or nil,
|
||||||
mathvariant = utf8.len(char) == 1 and elem == 'mi' and utf8.codepoint(char) < 0x10000 and 'normal' or nil
|
mathvariant = utf8.len(char) == 1 and elem == 'mi' and utf8.codepoint(char) < 0x10000 and 'normal' or nil,
|
||||||
|
[':nodes'] = {kernel},
|
||||||
}
|
}
|
||||||
return result, result
|
if mathml_filter then
|
||||||
elseif id == sub_box_t then
|
return mathml_filter(result, result)
|
||||||
if kernel.list.id == hlist_t then -- We directly give up for vlists
|
else
|
||||||
local result = to_text(kernel.list.head)
|
return result, result
|
||||||
return result, result
|
end
|
||||||
|
elseif id == sub_box_t then
|
||||||
|
local result
|
||||||
|
if kernel.list.id == hlist_t then -- We directly give up for vlists
|
||||||
|
result = to_text(kernel.list.head)
|
||||||
|
else
|
||||||
|
result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':nodes'] = {kernel}}}
|
||||||
|
end
|
||||||
|
if mathml_filter then
|
||||||
|
return mathml_filter(result, result)
|
||||||
else
|
else
|
||||||
local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}}
|
|
||||||
return result, result
|
return result, result
|
||||||
end
|
end
|
||||||
elseif id == sub_mlist_t then
|
elseif id == sub_mlist_t then
|
||||||
return nodes_to_table(kernel.list, cur_style)
|
if mathml_filter then
|
||||||
|
return mathml_filter(nodes_to_table(kernel.list, cur_style, text_families))
|
||||||
|
else
|
||||||
|
return nodes_to_table(kernel.list, cur_style, text_families)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error'confusion'
|
error'confusion'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function do_sub_sup(t, core, n, cur_style)
|
local function do_sub_sup(t, core, n, cur_style, text_families)
|
||||||
local sub = kernel_to_table(n.sub, sub_style(cur_style))
|
local sub = kernel_to_table(n.sub, sub_style(cur_style), text_families)
|
||||||
local sup = kernel_to_table(n.sup, sup_style(cur_style))
|
local sup = kernel_to_table(n.sup, sup_style(cur_style), text_families)
|
||||||
if sub then
|
if sub then
|
||||||
if sup then
|
if sup then
|
||||||
return {[0] = 'msubsup', t, sub, sup}, core
|
return {[0] = 'msubsup', t, sub, sup}, core
|
||||||
@ -125,7 +246,7 @@ local function maybe_to_mn(noad, core)
|
|||||||
local after = noad.next
|
local after = noad.next
|
||||||
if not after then return end
|
if not after then return end
|
||||||
if after.id ~= noad_t then return end
|
if after.id ~= noad_t then return end
|
||||||
if noad_sub[after.subtype] ~= 'ord' then return end
|
if after.subtype ~= noad_ord then return end
|
||||||
after = after.nucleus
|
after = after.nucleus
|
||||||
if not after then return end
|
if not after then return end
|
||||||
if after.id ~= math_char_t then return end
|
if after.id ~= math_char_t then return end
|
||||||
@ -133,70 +254,91 @@ local function maybe_to_mn(noad, core)
|
|||||||
core[0] = 'mn'
|
core[0] = 'mn'
|
||||||
end
|
end
|
||||||
|
|
||||||
local function noad_to_table(noad, sub, cur_style, mn)
|
local function noad_to_table(noad, sub, cur_style, joining, bin_replacements, text_families)
|
||||||
local class = noad_sub[sub]
|
local nucleus, core = kernel_to_table(noad.nucleus, sub == noad_over and cur_style//2*2+1 or cur_style, text_families)
|
||||||
local nucleus, core = kernel_to_table(noad.nucleus, class == 'over' and cur_style//2*2+1 or cur_style)
|
if not nucleus then return end
|
||||||
if class == 'ord' then
|
if core and core[0] == 'mo' and core.minsize and not core.maxsize then
|
||||||
|
core.maxsize = core.minsize -- This happens when a half-specified delimiter appears alone in a list.
|
||||||
|
-- If it has a minimal size, it should be fixed to that size (since there is nothing bigger in it's list)
|
||||||
|
end
|
||||||
|
if sub == noad_ord and not (bin_replacements[node.direct.todirect(noad)] or (nucleus == core and #core == 1 and always_mo[core[1]])) then
|
||||||
if core and core[0] == 'mo' then
|
if core and core[0] == 'mo' then
|
||||||
core[0] = 'mi'
|
|
||||||
core.stretchy, core.mathvariant = nil, #core == 1 and type(core[0]) == 'string' and utf8.len(core[0]) == 1 and utf8.codepoint(core[0]) < -0x10000 and 'normal' or nil
|
|
||||||
core['tex:class'] = nil
|
core['tex:class'] = nil
|
||||||
|
if not core.minsize and not core.movablelimits then
|
||||||
|
core[0] = 'mi'
|
||||||
|
core.movablelimits = nil
|
||||||
|
core.mathvariant = #core == 1 and type(core[1]) == 'string' and utf8.len(core[1]) == 1 and utf8.codepoint(core[1]) < 0x10000 and 'normal' or nil
|
||||||
|
core.stretchy, core.lspace, core.rspace = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if nucleus == core and #core == 1 then
|
if nucleus == core and #core == 1 then
|
||||||
if mn and core[0] == 'mi' and (core[1] == '.' or core[1] == ',') and maybe_to_mn(noad, core) or core[0] == 'mn' then
|
if joining and joining[0] == 'mn' and core[0] == 'mi' and (core[1] == '.' or core[1] == ',') and maybe_to_mn(noad, core)
|
||||||
if mn then
|
or core[0] == 'mn' or text_families[core['tex:family'] or 0] then
|
||||||
mn[#mn+1] = core[1]
|
if joining and core[0] == joining[0] and core['tex:family'] == joining['tex:family'] then
|
||||||
nucleus = do_sub_sup(mn, mn, noad, cur_style)
|
joining[#joining+1] = core[1]
|
||||||
if nucleus == mn then
|
local cnodes = core[':nodes']
|
||||||
return nil, mn, mn
|
if cnodes then -- very likely
|
||||||
|
local jnodes = joining[':nodes']
|
||||||
|
if jnodes then -- very likely
|
||||||
|
table.move(cnodes, 1, #cnodes, #jnodes+1, jnodes)
|
||||||
|
else
|
||||||
|
joining[':nodes'] = cnodes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nucleus = do_sub_sup(joining, joining, noad, cur_style, text_families)
|
||||||
|
if nucleus == joining then
|
||||||
|
return nil, joining, joining
|
||||||
else
|
else
|
||||||
return nucleus, mn, false
|
return nucleus, joining, false
|
||||||
end
|
end
|
||||||
elseif not noad.sub and not noad.sup then
|
elseif not noad.sub and not noad.sup then
|
||||||
return core, core, core
|
return core, core, core
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif class == 'opdisplaylimits' or class == 'oplimits' or class == 'opnolimits' or class == 'bin' or class == 'rel' or class == 'open'
|
elseif sub == noad_op or sub == noad_oplimits or sub == noad_opnolimits or sub == noad_bin or sub == noad_rel or sub == noad_open
|
||||||
or class == 'close' or class == 'punct' or class == 'inner' then
|
or sub == noad_close or sub == noad_punct or sub == noad_inner or sub == noad_ord then
|
||||||
if not core or not core[0] then
|
if not core or not core[0] then
|
||||||
-- TODO
|
-- TODO
|
||||||
else
|
else
|
||||||
core[0] = 'mo'
|
core[0] = 'mo'
|
||||||
if stretchy[core[1]] then core.stretchy = false end
|
if not core.minsize then
|
||||||
|
if stretchy[core[1]] then core.stretchy = false end
|
||||||
|
end
|
||||||
if core.mathvariant == 'normal' then core.mathvariant = nil end
|
if core.mathvariant == 'normal' then core.mathvariant = nil end
|
||||||
|
core.lspace, core.rspace = 0, 0
|
||||||
end
|
end
|
||||||
nucleus['tex:class'] = class
|
nucleus['tex:class'] = noad_names[sub]
|
||||||
|
|
||||||
if (noad.sup or noad.sub) and (class == 'opdisplaylimits' or class == 'oplimits') then
|
if (noad.sup or noad.sub) and (sub == noad_op or sub == noad_oplimits) then
|
||||||
nucleus.movablelimits = class == 'opdisplaylimits'
|
if core and core[0] == 'mo' then core.movablelimits = sub == noad_op end
|
||||||
local sub = kernel_to_table(noad.sub, sub_style(cur_style))
|
local sub = kernel_to_table(noad.sub, sub_style(cur_style), text_families)
|
||||||
local sup = kernel_to_table(noad.sup, sup_style(cur_style))
|
local sup = kernel_to_table(noad.sup, sup_style(cur_style), text_families)
|
||||||
return {[0] = sup and (sub and 'munderover' or 'mover') or 'munder',
|
return {[0] = sup and (sub and 'munderover' or 'mover') or 'munder',
|
||||||
nucleus,
|
nucleus,
|
||||||
sub or sup,
|
sub or sup,
|
||||||
sub and sup,
|
sub and sup,
|
||||||
}, core
|
}, core
|
||||||
end
|
end
|
||||||
elseif class == 'under' then
|
elseif sub == noad_under then
|
||||||
return {[0] = 'munder',
|
return {[0] = 'munder',
|
||||||
nucleus,
|
nucleus,
|
||||||
{[0] = 'mo', '_',},
|
{[0] = 'mo', '_',},
|
||||||
}, core
|
}, core
|
||||||
elseif class == 'over' then
|
elseif sub == noad_over then
|
||||||
return {[0] = 'mover',
|
return {[0] = 'mover',
|
||||||
nucleus,
|
nucleus,
|
||||||
{[0] = 'mo', '\u{203E}',},
|
{[0] = 'mo', '\u{203E}',},
|
||||||
}, core
|
}, core
|
||||||
elseif class == 'vcenter' then -- Ignored. Nucleus will need special handling anyway
|
elseif sub == noad_vcenter then -- Ignored. Nucleus will need special handling anyway
|
||||||
else
|
else
|
||||||
error[[confusion]]
|
error[[confusion]]
|
||||||
end
|
end
|
||||||
return do_sub_sup(nucleus, core, noad, cur_style)
|
return do_sub_sup(nucleus, core, noad, cur_style, text_families)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function accent_to_table(accent, sub, cur_style)
|
local function accent_to_table(accent, sub, cur_style, text_families)
|
||||||
local nucleus, core = kernel_to_table(accent.nucleus, cur_style//2*2+1)
|
local nucleus, core = kernel_to_table(accent.nucleus, cur_style//2*2+1, text_families)
|
||||||
local top_acc = acc_to_table(accent.accent, cur_style, sub & 1 == 1)
|
local top_acc = acc_to_table(accent.accent, cur_style, sub & 1 == 1)
|
||||||
local bot_acc = acc_to_table(accent.bot_accent, cur_style, sub & 2 == 2)
|
local bot_acc = acc_to_table(accent.bot_accent, cur_style, sub & 2 == 2)
|
||||||
return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder',
|
return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder',
|
||||||
@ -218,17 +360,18 @@ style_table.crampedscript, style_table.crampedscriptscript =
|
|||||||
style_table.display, style_table.text,
|
style_table.display, style_table.text,
|
||||||
style_table.script, style_table.scriptscript
|
style_table.script, style_table.scriptscript
|
||||||
|
|
||||||
local function radical_to_table(radical, sub, cur_style)
|
local function radical_to_table(radical, sub, cur_style, text_families)
|
||||||
local kind = radical_sub[sub]
|
local kind = radical_sub[sub]
|
||||||
local nucleus, core = kernel_to_table(radical.nucleus, cur_style//2*2+1)
|
local nucleus, core = kernel_to_table(radical.nucleus, cur_style//2*2+1, text_families)
|
||||||
local left = delim_to_table(radical.left)
|
local left = delim_to_table(radical.left)
|
||||||
local elem
|
local elem
|
||||||
if kind == 'radical' or kind == 'uradical' then
|
if kind == 'radical' or kind == 'uradical' then
|
||||||
-- FIXME: Check that this is really a square root
|
-- FIXME: Check that this is really a square root
|
||||||
elem, core = {[0] = 'msqrt', nucleus}, nil
|
elem, core = {[0] = 'msqrt', nucleus, }, nil
|
||||||
elseif kind == 'uroot' then
|
elseif kind == 'uroot' then
|
||||||
-- FIXME: Check that this is really a root
|
-- FIXME: Check that this is really a root
|
||||||
elem, core = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)}, nil
|
-- UF 2024-12-04: force use of only one return value
|
||||||
|
elem, core = {[0] = 'mroot', nucleus, (kernel_to_table(radical.degree, 7, text_families))}, nil
|
||||||
elseif kind == 'uunderdelimiter' then
|
elseif kind == 'uunderdelimiter' then
|
||||||
elem, core = {[0] = 'munder', left, nucleus}, left
|
elem, core = {[0] = 'munder', left, nucleus}, left
|
||||||
elseif kind == 'uoverdelimiter' then
|
elseif kind == 'uoverdelimiter' then
|
||||||
@ -240,12 +383,12 @@ local function radical_to_table(radical, sub, cur_style)
|
|||||||
else
|
else
|
||||||
error[[confusion]]
|
error[[confusion]]
|
||||||
end
|
end
|
||||||
return do_sub_sup(elem, core, radical, cur_style)
|
return do_sub_sup(elem, core, radical, cur_style, text_families)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fraction_to_table(fraction, sub, cur_style)
|
local function fraction_to_table(fraction, sub, cur_style, text_families)
|
||||||
local num, core = kernel_to_table(fraction.num, sup_style(cur_style))
|
local num, core = kernel_to_table(fraction.num, cur_style + 2 - cur_style//6*2, text_families)
|
||||||
local denom = kernel_to_table(fraction.denom, sub_style(cur_style))
|
local denom = kernel_to_table(fraction.denom, cur_style//2*2 + 3 - cur_style//6*2, text_families)
|
||||||
local left = delim_to_table(fraction.left)
|
local left = delim_to_table(fraction.left)
|
||||||
local right = delim_to_table(fraction.right)
|
local right = delim_to_table(fraction.right)
|
||||||
local mfrac = {[0] = 'mfrac',
|
local mfrac = {[0] = 'mfrac',
|
||||||
@ -272,8 +415,31 @@ end
|
|||||||
|
|
||||||
local function fence_to_table(fence, sub, cur_style)
|
local function fence_to_table(fence, sub, cur_style)
|
||||||
local delim, core = delim_to_table(fence.delim)
|
local delim, core = delim_to_table(fence.delim)
|
||||||
if delim[0] == 'mo' then
|
if core[0] ~= 'mo' then
|
||||||
delim.fence = 'true'
|
return delim, core
|
||||||
|
end
|
||||||
|
core.fence, core.symmetric = 'true', 'true'
|
||||||
|
local options = fence.options
|
||||||
|
local axis
|
||||||
|
if fence.height ~= 0 or fence.depth ~= 0 then
|
||||||
|
axis = 0xA == options & 0xA
|
||||||
|
local exact = 0x18 == options & 0x18
|
||||||
|
-- We treat them always as exact. mpadded would allow us to support
|
||||||
|
-- non-exact ones too and I will implement that if I ever encounter
|
||||||
|
-- someone who does that intentionally. Until then, we warn people
|
||||||
|
-- since such fences are absurd.
|
||||||
|
if not exact then
|
||||||
|
texio.write_nl'luamml: The document uses a fence with \z
|
||||||
|
explicit dimensions but without the "exact" option. \z
|
||||||
|
This is probably a mistake.'
|
||||||
|
end
|
||||||
|
core.minsize = string.format("%.3fpt", (fence.height + fence.depth)/65781.76)
|
||||||
|
core.maxsize = core.minsize
|
||||||
|
else
|
||||||
|
axis = 0xC ~= options & 0xC
|
||||||
|
end
|
||||||
|
if not axis then
|
||||||
|
texio.write_nl'luamml: Baseline centered fence will be centered around math axis instead'
|
||||||
end
|
end
|
||||||
return delim, core
|
return delim, core
|
||||||
end
|
end
|
||||||
@ -296,67 +462,87 @@ local function rule_to_table(rule, sub, cur_style)
|
|||||||
if height == running_length then
|
if height == running_length then
|
||||||
height = '0.8em'
|
height = '0.8em'
|
||||||
else
|
else
|
||||||
height = height
|
height = string.format("%.3fpt", height/65781.76)
|
||||||
end
|
end
|
||||||
local depth = rule.depth
|
local depth = rule.depth
|
||||||
if depth == running_length then
|
if depth == running_length then
|
||||||
depth = '0.2em'
|
depth = '0.2em'
|
||||||
else
|
else
|
||||||
depth = depth
|
depth = string.format("%.3fpt", depth/65781.76)
|
||||||
end
|
end
|
||||||
return {[0] = 'mspace', mathbackground = 'currentColor', width = width, height = height, depth = depth}, space_like
|
return {[0] = 'mspace', mathbackground = 'currentColor', width = width, height = height, depth = depth}, space_like
|
||||||
end
|
end
|
||||||
|
|
||||||
function nodes_to_table(head, cur_style)
|
-- The only part which changes the nodelist, we are converting bin into ord
|
||||||
|
-- nodes in the same way TeX would do it later anyway.
|
||||||
|
local function cleanup_mathbin(head)
|
||||||
|
local replacements = {}
|
||||||
|
local last = 'open' -- last sub if id was noad_t, left fence acts fakes being a open noad, bin are themselves. Every other noad is ord
|
||||||
|
for n, id, sub in node.traverse(head) do
|
||||||
|
if id == noad_t then
|
||||||
|
if sub == noad_bin then
|
||||||
|
if node.is_node(last) or last == noad_opdisplaylimits
|
||||||
|
or last == noad_oplimits or last == noad_opnolimits
|
||||||
|
or last == noad_rel or last == noad_open or last == noad_punct then
|
||||||
|
replacements[node.direct.todirect(n)] = true
|
||||||
|
n.subtype, last = noad_ord, noad_ord
|
||||||
|
else
|
||||||
|
last = n
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (sub == noad_rel or sub == noad_close or sub == noad_punct)
|
||||||
|
and node.is_node(last) then
|
||||||
|
replacements[node.direct.todirect(last)] = true
|
||||||
|
last.subtype = noad_ord
|
||||||
|
end
|
||||||
|
last = sub
|
||||||
|
end
|
||||||
|
elseif id == fence_t then
|
||||||
|
if sub == fence_sub.left then
|
||||||
|
last = noad_open
|
||||||
|
else
|
||||||
|
if node.is_node(last) then
|
||||||
|
replacements[node.direct.todirect(last)] = true
|
||||||
|
last.subtype = noad_ord, noad_ord
|
||||||
|
end
|
||||||
|
last = noad_ord
|
||||||
|
end
|
||||||
|
elseif id == fraction_t or id == radical_t or id == accent_t then
|
||||||
|
last = noad_ord
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if node.is_node(last) then
|
||||||
|
replacements[node.direct.todirect(last)] = true
|
||||||
|
last.subtype = noad_ord
|
||||||
|
end
|
||||||
|
return replacements
|
||||||
|
end
|
||||||
|
|
||||||
|
function nodes_to_table(head, cur_style, text_families)
|
||||||
|
local bin_replacements = cleanup_mathbin(head)
|
||||||
local t = {[0] = 'mrow'}
|
local t = {[0] = 'mrow'}
|
||||||
local result = t
|
local result = t
|
||||||
local nonscript
|
local nonscript
|
||||||
local core, mn = space_like
|
local core, last_noad, last_core, joining = space_like, nil, nil, nil
|
||||||
local no_binop_context, last_noad, last_noad_core = true
|
|
||||||
for n, id, sub in node.traverse(head) do
|
for n, id, sub in node.traverse(head) do
|
||||||
if last_noad and ((id == noad_t and noad_sub[sub] == 'punct') or (id == fence_t and fence_sub[sub] ~= 'left')) then
|
local new_core, new_joining, new_node, new_noad
|
||||||
last_noad['tex:class'], last_noad_core[0] = nil, 'mi'
|
|
||||||
last_noad_core.stretchy, last_noad_core.mathvariant = nil, #last_noad_core == 1
|
|
||||||
and type(last_noad_core[0]) == 'string'
|
|
||||||
and utf8.len(last_noad_core[0]) == 1
|
|
||||||
and utf8.codepoint(last_noad_core[0]) < -0x10000
|
|
||||||
and 'normal' or nil
|
|
||||||
end
|
|
||||||
local new_core, new_mn
|
|
||||||
local props = properties[n]
|
local props = properties[n]
|
||||||
props = props and props.mathml_table
|
local mathml_core = props and props.mathml_core
|
||||||
if props then
|
local mathml_table = props and (props.mathml_table or mathml_core)
|
||||||
t[#t+1], new_core = props, user_provided
|
if mathml_table ~= nil then
|
||||||
|
new_node, new_core = mathml_table, mathml_core
|
||||||
elseif id == noad_t then
|
elseif id == noad_t then
|
||||||
local substr = noad_sub[sub]
|
|
||||||
if substr == 'bin' then
|
|
||||||
if no_binop_context then
|
|
||||||
sub, substr = 0, 'ord'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
no_binop_context = false
|
|
||||||
or substr == 'bin'
|
|
||||||
or substr == 'opdisplaylimits'
|
|
||||||
or substr == 'oplimits'
|
|
||||||
or substr == 'opnolimits'
|
|
||||||
or substr == 'rel'
|
|
||||||
or substr == 'open'
|
|
||||||
or substr == 'punct'
|
|
||||||
local new_n
|
local new_n
|
||||||
new_n, new_core, new_mn = noad_to_table(n, sub, cur_style, mn)
|
new_n, new_core, new_joining = noad_to_table(n, sub, cur_style, joining, bin_replacements, text_families)
|
||||||
if new_mn == false then
|
if new_joining == false then
|
||||||
t[#t], new_mn = new_n, nil
|
t[#t], new_joining = new_n, nil
|
||||||
else
|
else
|
||||||
t[#t+1] = new_n -- might be nil
|
new_node = new_n -- might be nil
|
||||||
end
|
|
||||||
if substr == 'bin' then
|
|
||||||
last_noad, last_noad_core = new_n, new_core
|
|
||||||
else
|
|
||||||
last_noad, last_noad_core = nil, nil
|
|
||||||
end
|
end
|
||||||
|
new_noad = sub
|
||||||
elseif id == accent_t then
|
elseif id == accent_t then
|
||||||
t[#t+1], new_core = accent_to_table(n, sub, cur_style)
|
new_node, new_core = accent_to_table(n, sub, cur_style, text_families)
|
||||||
no_binop_context, last_noad, last_noad_core = false, nil, nil
|
new_noad = noad_ord
|
||||||
elseif id == style_t then
|
elseif id == style_t then
|
||||||
if sub ~= cur_style then
|
if sub ~= cur_style then
|
||||||
if #t == 0 then
|
if #t == 0 then
|
||||||
@ -376,52 +562,77 @@ function nodes_to_table(head, cur_style)
|
|||||||
new_core = space_like
|
new_core = space_like
|
||||||
elseif id == choice_t then
|
elseif id == choice_t then
|
||||||
local size = cur_style//2
|
local size = cur_style//2
|
||||||
t[#t+1], new_core = nodes_to_table(n[size == 0 and 'display'
|
new_node, new_core = nodes_to_table(n[size == 0 and 'display'
|
||||||
or size == 1 and 'text'
|
or size == 1 and 'text'
|
||||||
or size == 2 and 'script'
|
or size == 2 and 'script'
|
||||||
or size == 3 and 'scriptscript'
|
or size == 3 and 'scriptscript'
|
||||||
or assert(false)], 2*size), space_like
|
or assert(false)], 2*size, text_families), space_like
|
||||||
elseif id == radical_t then
|
elseif id == radical_t then
|
||||||
t[#t+1], new_core = radical_to_table(n, sub, cur_style)
|
new_node, new_core = radical_to_table(n, sub, cur_style, text_families)
|
||||||
no_binop_context, last_noad, last_noad_core = false, nil, nil
|
new_noad = noad_ord
|
||||||
elseif id == fraction_t then
|
elseif id == fraction_t then
|
||||||
t[#t+1], new_core = fraction_to_table(n, sub, cur_style)
|
new_node, new_core = fraction_to_table(n, sub, cur_style, text_families)
|
||||||
no_binop_context, last_noad, last_noad_core = false, nil, nil
|
new_noad = noad_inner
|
||||||
elseif id == fence_t then
|
elseif id == fence_t then
|
||||||
t[#t+1], new_core = fence_to_table(n, sub, cur_style)
|
new_node, new_core = fence_to_table(n, sub, cur_style)
|
||||||
no_binop_context, last_noad, last_noad_core = false, nil, nil
|
local class = n.class
|
||||||
|
new_noad = class >= 0 and class or sub == fence_sub.left and noad_open or noad_close
|
||||||
elseif id == kern_t then
|
elseif id == kern_t then
|
||||||
if not nonscript then
|
if not nonscript then
|
||||||
t[#t+1], new_core = space_to_table(n.kern, sub, cur_style)
|
new_node, new_core = space_to_table(n.kern, sub, cur_style)
|
||||||
end
|
end
|
||||||
elseif id == glue_t then
|
elseif id == glue_t then
|
||||||
if cur_style >= 4 or not nonscript then
|
if cur_style >= 4 or not nonscript then
|
||||||
if sub == 98 then -- TODO magic number
|
if sub == 98 then -- TODO magic number
|
||||||
nonscript = true
|
nonscript = true
|
||||||
else
|
else
|
||||||
t[#t+1], new_core = space_to_table(n.width, sub, cur_style)
|
new_node, new_core = space_to_table(n.width, sub, cur_style)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif id == rule_t then
|
elseif id == rule_t then
|
||||||
t[#t+1], new_core = rule_to_table(n, sub, cur_style)
|
new_node, new_core = rule_to_table(n, sub, cur_style)
|
||||||
-- elseif id == disc_t then -- Uncommon, does not play nicely with math mode and no sensible mapping anyway
|
-- elseif id == disc_t then -- Uncommon, does not play nicely with math mode and no sensible mapping anyway
|
||||||
end -- The other possible ids are whatsit, penalty, adjust, ins, mark. Ignore them.
|
end -- The other possible ids are whatsit, penalty, adjust, ins, mark. Ignore them.
|
||||||
nonscript = nil
|
nonscript = nil
|
||||||
if core and new_core ~= space_like then
|
if core and new_core ~= space_like then
|
||||||
core = core == space_like and new_core or nil
|
core = core == space_like and new_core or nil
|
||||||
end
|
end
|
||||||
mn = new_mn
|
if new_node then
|
||||||
|
if new_noad then
|
||||||
|
local space = last_noad and (cur_style >= 4 and spacing_table_script or spacing_table)[last_noad + 1][new_noad + 1] or 0
|
||||||
|
if assert(space) ~= 0 then
|
||||||
|
if new_core and new_core[0] == 'mo' then
|
||||||
|
new_core.lspace = space
|
||||||
|
elseif last_core and last_core[0] == 'mo' then
|
||||||
|
last_core.rspace = space
|
||||||
|
else
|
||||||
|
t[#t+1] = {[0] = 'mspace', width = space} -- TODO Move into operators whenever possible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
last_noad, last_core = new_noad, new_core
|
||||||
|
elseif new_node[0] ~= 'mspace' or new_node.mathbackground then
|
||||||
|
last_core = nil
|
||||||
|
end
|
||||||
|
t[#t+1] = new_node
|
||||||
|
end
|
||||||
|
joining = new_joining
|
||||||
end
|
end
|
||||||
-- In TeX, groups are never space like
|
-- In TeX, groups are never space like, so we insert an artificial node instead.
|
||||||
|
-- This node should be ignored for most purposes
|
||||||
if core == space_like then
|
if core == space_like then
|
||||||
core = {[0] = 'mi', intent = '@ignore'}
|
core = {[0] = 'mi', ['tex:ignore'] = 'true'}
|
||||||
result[#result+1] = core
|
result[#result+1] = core
|
||||||
end
|
end
|
||||||
if t[0] == 'mrow' and #t == 1 then
|
if t[0] == 'mrow' and #t == 1 then
|
||||||
assert(t == result)
|
assert(t == result)
|
||||||
result = t[1]
|
result = t[1]
|
||||||
end
|
end
|
||||||
return result, core
|
local mathml_filter = props and props.mathml_filter
|
||||||
|
if mathml_filter then
|
||||||
|
return mathml_filter(result, core)
|
||||||
|
else
|
||||||
|
return result, core
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function register_remap(family, mapping)
|
local function register_remap(family, mapping)
|
||||||
@ -447,6 +658,6 @@ end
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
register_family = register_remap,
|
register_family = register_remap,
|
||||||
process = function(head, style) return nodes_to_table(head, style or 2) end,
|
process = function(head, style, families) return nodes_to_table(head, style or 2, families) end,
|
||||||
make_root = to_math,
|
make_root = to_math,
|
||||||
}
|
}
|
||||||
|
82
luamml-demo.sty
Normal file
82
luamml-demo.sty
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesExplPackage{luamml-demo}{2025-03-06}{0.5.0}{Reasonable default definitions for luamml}
|
||||||
|
|
||||||
|
\sys_if_engine_luatex:F {
|
||||||
|
\msg_new:nnn {luamml-demo} {pdftex-option-ignored} {Option~`#1'~is~being~ignored~in~pdfTeX~mode.}
|
||||||
|
\DeclareOption*{\msg_warning:nnx {luamml-demo} {pdftex-option-ignored} {\CurrentOption}}
|
||||||
|
\ProcessOptions\relax
|
||||||
|
\RequirePackage{luamml-pdf-demo}
|
||||||
|
\endinput
|
||||||
|
}
|
||||||
|
|
||||||
|
\RequirePackage{luamml}% Loading luamml is pretty much the point
|
||||||
|
\RequirePackage{amsmath,array}% These are more or less expected in luamml especially for advanced constructs
|
||||||
|
|
||||||
|
\AtBeginDocument{%
|
||||||
|
\@ifpackageloaded{unicode-math}{}{%
|
||||||
|
\RegisterFamilyMapping\symsymbols{oms}%
|
||||||
|
\RegisterFamilyMapping\symletters{oml}%
|
||||||
|
\RegisterFamilyMapping\symlargesymbols{omx}%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\bool_new:N \l__luamml_demo_structelem_bool
|
||||||
|
|
||||||
|
\DeclareOption{tracing}{
|
||||||
|
\tracingmathml=2
|
||||||
|
}
|
||||||
|
\DeclareOption{structelem}{
|
||||||
|
\bool_set_true:N \l__luamml_demo_structelem_bool
|
||||||
|
\luamml_structelem:
|
||||||
|
}
|
||||||
|
\DeclareOption{files}{
|
||||||
|
\int_new:N \g__luamml_demo_mathml_int
|
||||||
|
\luamml_set_filename:n {
|
||||||
|
\immediateassignment \int_gincr:N \g__luamml_demo_mathml_int
|
||||||
|
\jobname -formula- \int_use:N \g__luamml_demo_mathml_int .xml
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\DeclareOption{l3build}{
|
||||||
|
\luamml_set_filename:n {
|
||||||
|
\jobname .mml
|
||||||
|
}
|
||||||
|
\luamml_begin_single_file:
|
||||||
|
}
|
||||||
|
\ProcessOptions\relax
|
||||||
|
|
||||||
|
\cs_new_eq:NN \LuaMMLSetFilename \luamml_set_filename:n
|
||||||
|
|
||||||
|
\cs_generate_variant:Nn \pdffile_filespec:nnn {ene}
|
||||||
|
\int_new:N \g__luamml_demo_af_int
|
||||||
|
\cs_new_protected:Npn \LuaMMLTagAF #1#2 {
|
||||||
|
\tag_mc_end_push:
|
||||||
|
\int_gincr:N \g__luamml_demo_af_int
|
||||||
|
\exp_args:Ne \pdf_object_new:nn{__luamml_demo_\int_use:N \g__luamml_demo_af_int}{dict}
|
||||||
|
\exp_args:Ne \tag_struct_begin:n{tag=Formula,AF=__luamml_demo_\int_use:N \g__luamml_demo_af_int,#1}
|
||||||
|
\bool_if:NF \l__luamml_demo_structelem_bool {
|
||||||
|
\tag_mc_begin:n{tag=Formula}
|
||||||
|
}
|
||||||
|
#2
|
||||||
|
\group_begin:
|
||||||
|
\pdfdict_put:nnn {l_pdffile/Filespec} {AFRelationship}{/Supplement}
|
||||||
|
\pdffile_filespec:ene
|
||||||
|
{ __luamml_demo_ \int_use:N \g__luamml_demo_af_int }
|
||||||
|
{ test.xml }
|
||||||
|
{ \luamml_get_last_mathml_stream:e{}\c_space_tl 0~R}
|
||||||
|
\group_end:
|
||||||
|
\bool_if:NF \l__luamml_demo_structelem_bool {
|
||||||
|
\tag_mc_end:
|
||||||
|
}
|
||||||
|
\tag_struct_end:
|
||||||
|
\tag_mc_begin_pop:n{}
|
||||||
|
}
|
||||||
|
|
||||||
|
\NewDocumentCommand\AnnotateFormula{ o m m }{%
|
||||||
|
\IfValueTF{#1}{%
|
||||||
|
\luamml_annotate:nen{#1}%
|
||||||
|
}{
|
||||||
|
\luamml_annotate:en
|
||||||
|
}{#2}{#3}
|
||||||
|
}
|
||||||
|
|
||||||
|
\cs_set_eq:NN \WriteoutFormula \luamml_pdf_write:
|
@ -26,6 +26,7 @@ local remap_oml = { [0] =
|
|||||||
0x1D465, 0x1D466, 0x1D467, 0x1D6A4, 0x1D6A5, 0x2118, 0x2192, nil,
|
0x1D465, 0x1D466, 0x1D467, 0x1D6A4, 0x1D6A5, 0x2118, 0x2192, nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Something fishy here. Starting with "3D the entries seem wrong
|
||||||
local remap_oms = { [0] =
|
local remap_oms = { [0] =
|
||||||
0x2212, 0x22C5, 0xD7, 0x2A, 0xF7, 0x22C4, 0xB1, 0x2213,
|
0x2212, 0x22C5, 0xD7, 0x2A, 0xF7, 0x22C4, 0xB1, 0x2213,
|
||||||
0x2295, 0x2296, 0x2297, 0x2298, 0x2299, 0x25CB, 0x2218, 0x2219,
|
0x2295, 0x2296, 0x2297, 0x2298, 0x2299, 0x25CB, 0x2218, 0x2219,
|
||||||
@ -34,7 +35,7 @@ local remap_oms = { [0] =
|
|||||||
0x2190, 0x2192, 0x2191, 0x2193, 0x2194, 0x2197, 0x2198, 0x2243,
|
0x2190, 0x2192, 0x2191, 0x2193, 0x2194, 0x2197, 0x2198, 0x2243,
|
||||||
0x21D0, 0x21D2, 0x21D1, 0x21D3, 0x21D4, 0x2196, 0x2199, 0x221D,
|
0x21D0, 0x21D2, 0x21D1, 0x21D3, 0x21D4, 0x2196, 0x2199, 0x221D,
|
||||||
0x2032, 0x221E, 0x2208, 0x220B, 0x25B3, 0x25BD, 0x0338, 0x21A6,
|
0x2032, 0x221E, 0x2208, 0x220B, 0x25B3, 0x25BD, 0x0338, 0x21A6,
|
||||||
0x2200, 0x2203, 0xAC, 0x2205, 0x211C, 0x22A9, 0x22A4, 0x22A5,
|
0x2200, 0x2203, 0xAC, 0x2205, 0x211C, 0x2111, 0x22A4, 0x22A5,
|
||||||
0x2135, 0x1D49C, 0x212C, 0x1D49E, 0x1D49F, 0x2130, 0x2131, 0x1D4A2,
|
0x2135, 0x1D49C, 0x212C, 0x1D49E, 0x1D49F, 0x2130, 0x2131, 0x1D4A2,
|
||||||
0x210B, 0x2110, 0x1D4A5, 0x1D4A6, 0x2112, 0x2133, 0x1D4A9, 0x1D4AA,
|
0x210B, 0x2110, 0x1D4A5, 0x1D4A6, 0x2112, 0x2133, 0x1D4A9, 0x1D4AA,
|
||||||
0x1D4AB, 0x1D4AC, 0x211B, 0x1D4AE, 0x1D4AF, 0x1D4B0, 0x1D4B1, 0x1D4B2,
|
0x1D4AB, 0x1D4AC, 0x211B, 0x1D4AE, 0x1D4AF, 0x1D4B0, 0x1D4B1, 0x1D4B2,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
local properties = node.get_properties_table()
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
local function to_unicode(head, tail)
|
local function to_unicode(head, tail)
|
||||||
local result, subresult, i = {[0] = 'mrow'}, {}, 0
|
local result, subresult, i = {[0] = 'mtext'}, {}, 0
|
||||||
local characters, last_fid
|
local characters, last_fid
|
||||||
local iter, state, n = node.traverse(head)
|
local iter, state, n = node.traverse(head)
|
||||||
while true do
|
while true do
|
||||||
@ -10,7 +10,7 @@ local function to_unicode(head, tail)
|
|||||||
local props = properties[n]
|
local props = properties[n]
|
||||||
if props and props.glyph_info then
|
if props and props.glyph_info then
|
||||||
i = i+1
|
i = i+1
|
||||||
subresult[i] = glyph_info
|
result[i] = glyph_info
|
||||||
else
|
else
|
||||||
local char, fid = node.is_glyph(n)
|
local char, fid = node.is_glyph(n)
|
||||||
if char then
|
if char then
|
||||||
@ -23,27 +23,23 @@ local function to_unicode(head, tail)
|
|||||||
i = i+1
|
i = i+1
|
||||||
if uni then
|
if uni then
|
||||||
if type(uni) == 'number' then
|
if type(uni) == 'number' then
|
||||||
subresult[i] = utf.char(uni)
|
result[i] = utf.char(uni)
|
||||||
else
|
else
|
||||||
subresult[i] = utf.char(table.unpack(uni))
|
result[i] = utf.char(table.unpack(uni))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if char < 0x110000 then
|
if char < 0x110000 then
|
||||||
subresult[i] = utf.char(char)
|
result[i] = utf.char(char)
|
||||||
else
|
else
|
||||||
subresult[i] = '\u{FFFD}'
|
result[i] = '\u{FFFD}'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif node.id'math' == id then
|
elseif node.id'math' == id then
|
||||||
if props then
|
if props then
|
||||||
local mml = props.saved_mathml_table
|
local mml = props.saved_mathml_table or props.saved_mathml_core
|
||||||
if mml then
|
if mml then
|
||||||
if i ~= 0 then
|
i = i+1
|
||||||
result[#result+1] = {[0] = 'mtext', table.concat(subresult)}
|
result[i] = mml
|
||||||
for j = i, 1, -1 do subresult[j] = nil end
|
|
||||||
i = 0
|
|
||||||
end
|
|
||||||
result[#result+1] = mml
|
|
||||||
n = node.end_of_math(n)
|
n = node.end_of_math(n)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -52,46 +48,23 @@ local function to_unicode(head, tail)
|
|||||||
elseif node.id'glue' == id then
|
elseif node.id'glue' == id then
|
||||||
if n.width > 1000 then -- FIXME: Coordinate constant with tagpdf
|
if n.width > 1000 then -- FIXME: Coordinate constant with tagpdf
|
||||||
i = i+1
|
i = i+1
|
||||||
subresult[i] = '\u{00A0}' -- non breaking space... There is no real reason why it has to be non breaking, except that MathML often ignore other spaces
|
result[i] = '\u{00A0}' -- non breaking space... There is no real reason why it has to be non breaking, except that MathML often ignore other spaces
|
||||||
end
|
end
|
||||||
elseif node.id'hlist' == id then
|
elseif node.id'hlist' == id then
|
||||||
local nested = to_unicode(n.head)
|
local nested = to_unicode(n.head)
|
||||||
if nested[0] == 'mtext' and #nested == 1 and type(nested[1]) == 'string' then
|
table.move(nested, 1, #nested, i+1, result)
|
||||||
i=i+1
|
i = i+#nested
|
||||||
subresult[i] = nested[1]
|
|
||||||
else
|
|
||||||
if i ~= 0 then
|
|
||||||
result[#result+1] = {[0] = 'mtext', table.concat(subresult)}
|
|
||||||
for j = i, 1, -1 do subresult[j] = nil end
|
|
||||||
i = 0
|
|
||||||
end
|
|
||||||
if nested[0] == 'mrow' then
|
|
||||||
table.move(nested, 1, #nested, #result+1, result)
|
|
||||||
else -- should be unreachable (propbably actually is reachable if the inner list only contains math
|
|
||||||
result[#result+1] = nested
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif node.id'vlist' == id then
|
elseif node.id'vlist' == id then
|
||||||
i = i+1
|
i = i+1
|
||||||
subresult[i] = '\u{FFFD}'
|
result[i] = '\u{FFFD}'
|
||||||
elseif node.id'rule' == id then
|
elseif node.id'rule' == id then
|
||||||
if n.width ~= 0 then
|
if n.width ~= 0 then
|
||||||
i = i+1
|
i = i+1
|
||||||
subresult[i] = '\u{FFFD}'
|
result[i] = '\u{FFFD}'
|
||||||
end
|
end
|
||||||
end -- CHECK: Everything else can probably be ignored, otherwise shout at me
|
end -- CHECK: Everything else can probably be ignored, otherwise shout at me
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if i ~= 0 then
|
|
||||||
result[#result+1] = {[0] = 'mtext', table.concat(subresult)}
|
|
||||||
end
|
|
||||||
if #result == 0 then
|
|
||||||
local r = {[0] = 'mtext', ''}
|
|
||||||
return r, r
|
|
||||||
elseif #result == 1 then
|
|
||||||
result = result[1]
|
|
||||||
if result[1] == 'mtext' then return result, result end
|
|
||||||
end
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,109 +1,440 @@
|
|||||||
\ProvidesExplPackage {luamml-patches-amsmath} {2021-04-23} {0.0.1-alpha}
|
\ProvidesExplPackage {luamml-patches-amsmath} {2025-03-06} {0.5.0}
|
||||||
{Feel free to add a description here}
|
{Feel free to add a description here}
|
||||||
|
|
||||||
\lua_now:n { require'luamml-amsmath' }
|
\lua_now:n { require'luamml-amsmath' }
|
||||||
|
|
||||||
\cs_set:Npn \align@preamble {
|
% For all of these changes, the redefinitions appear huge.
|
||||||
&
|
% But they are almost identical to the original and only
|
||||||
\hfil
|
% add luamml commands in appropriate places, so they would
|
||||||
\strut@
|
% mostly disappear if there were enough hooks in amsmath.
|
||||||
\setboxz@h {
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-02-24}
|
||||||
\@lign
|
{}
|
||||||
$
|
{
|
||||||
\m@th
|
\def\common@align@ending {
|
||||||
\displaystyle {
|
\math@cr \black@\totwidth@
|
||||||
##
|
\UseExpandableTaggingSocket {math/luamml/mtable/finalize} {\@currenvir}
|
||||||
}
|
|
||||||
\ifmeasuring@
|
|
||||||
\luamml_flag_ignore:
|
|
||||||
\else
|
|
||||||
\luamml_flag_save:
|
|
||||||
\fi
|
|
||||||
$
|
|
||||||
}
|
|
||||||
\ifmeasuring@
|
|
||||||
\savefieldlength@
|
|
||||||
\else
|
|
||||||
\__luamml_amsmath_add_box_to_row:
|
|
||||||
\fi
|
|
||||||
\set@field
|
|
||||||
\tabskip\z@skip
|
|
||||||
&
|
|
||||||
\setboxz@h {
|
|
||||||
\@lign
|
|
||||||
$
|
|
||||||
\m@th
|
|
||||||
\displaystyle
|
|
||||||
{
|
|
||||||
{}
|
|
||||||
##
|
|
||||||
}
|
|
||||||
\ifmeasuring@
|
|
||||||
\luamml_flag_ignore:
|
|
||||||
\else
|
|
||||||
\luamml_flag_save:
|
|
||||||
\fi
|
|
||||||
$
|
|
||||||
}
|
|
||||||
\ifmeasuring@
|
|
||||||
\savefieldlength@
|
|
||||||
\else
|
|
||||||
\__luamml_amsmath_add_box_to_row:
|
|
||||||
\fi
|
|
||||||
\set@field
|
|
||||||
\hfil
|
|
||||||
\tabskip\alignsep@
|
|
||||||
}
|
|
||||||
|
|
||||||
\cs_set:Npn \math@cr@@@align {
|
|
||||||
\ifst@rred
|
|
||||||
\nonumber
|
|
||||||
\fi
|
|
||||||
\if@eqnsw
|
|
||||||
\global \tag@true
|
|
||||||
\fi
|
|
||||||
\global \advance \row@ \@ne
|
|
||||||
\add@amps \maxfields@
|
|
||||||
\omit
|
|
||||||
\kern -\alignsep@
|
|
||||||
\iftag@
|
|
||||||
\setboxz@h {
|
|
||||||
\@lign
|
|
||||||
\strut@
|
|
||||||
{ \make@display@tag }
|
|
||||||
}
|
|
||||||
\place@tag
|
|
||||||
\__luamml_amsmath_set_tag:
|
|
||||||
\fi
|
|
||||||
\ifst@rred
|
|
||||||
\else
|
|
||||||
\global \@eqnswtrue
|
|
||||||
\fi
|
|
||||||
\global \lineht@ \z@
|
|
||||||
\cr
|
|
||||||
}
|
|
||||||
|
|
||||||
\cs_set:Npn \maketag@@@ #1 {
|
|
||||||
\hbox {
|
|
||||||
\m@th
|
|
||||||
\normalfont
|
|
||||||
#1
|
|
||||||
\__luamml_amsmath_save_tag:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
\cs_set:Npn \endalign {
|
|
||||||
\math@cr
|
|
||||||
\black@ \totwidth@
|
|
||||||
\__luamml_amsmath_finalize_table:
|
|
||||||
\egroup
|
\egroup
|
||||||
\ifingather@
|
\ifingather@
|
||||||
\restorealignstate@
|
\restorealignstate@
|
||||||
\egroup
|
\egroup
|
||||||
\nonumber
|
\nonumber
|
||||||
\ifnum0=‘{\fi\iffalse}\fi
|
\ifnum0=`{\fi\iffalse}\fi
|
||||||
\else
|
\else
|
||||||
$$
|
$$%
|
||||||
\fi
|
\fi
|
||||||
\ignorespacesafterend
|
\ignorespacesafterend
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
\PackageInfo{luamml}{patching~\string\start@aligned}
|
||||||
|
% aligned and friends
|
||||||
|
\cs_set:Npn \start@aligned #1#2 {
|
||||||
|
\RIfM@
|
||||||
|
\else
|
||||||
|
\nonmatherr@ { \begin { \@currenvir } }
|
||||||
|
\fi
|
||||||
|
\savecolumn@ % Assumption: called inside a group
|
||||||
|
\UseTaggingSocket{ math/luamml/annotate/false } {}{ \alignedspace@left }
|
||||||
|
\ams@start@box {#1} \bgroup
|
||||||
|
\maxfields@ #2 \relax
|
||||||
|
\ifnum \maxfields@ > \m@ne
|
||||||
|
\multiply \maxfields@ \tw@
|
||||||
|
\let \math@cr@@@ \math@cr@@@alignedat
|
||||||
|
\alignsep@ \z@skip
|
||||||
|
\else
|
||||||
|
\let \math@cr@@@ \math@cr@@@aligned
|
||||||
|
\alignsep@ \minalignsep
|
||||||
|
\fi
|
||||||
|
\Let@ \chardef \dspbrk@context \@ne
|
||||||
|
\default@tag
|
||||||
|
\spread@equation % no-op if already called
|
||||||
|
\global \column@ \z@
|
||||||
|
\ialign \bgroup
|
||||||
|
& \column@plus
|
||||||
|
\hfil
|
||||||
|
\strut@
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
{##}
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\tabskip \z@skip
|
||||||
|
& \column@plus
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
{
|
||||||
|
{}
|
||||||
|
##
|
||||||
|
}
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\hfil
|
||||||
|
\tabskip\alignsep@
|
||||||
|
\crcr
|
||||||
|
\ams@return@opt@arg
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~gathered}
|
||||||
|
\renewcommand \gathered [1] [c] {
|
||||||
|
\RIfM@
|
||||||
|
\else
|
||||||
|
\nonmatherr@ { \begin {gathered} }
|
||||||
|
\fi
|
||||||
|
\UseTaggingSocket{ math/luamml/annotate/false } {}{ \alignedspace@left }
|
||||||
|
\ams@start@box {#1} \bgroup
|
||||||
|
\Let@
|
||||||
|
\chardef \dspbrk@context \@ne
|
||||||
|
\restore@math@cr
|
||||||
|
\spread@equation
|
||||||
|
\ialign \bgroup
|
||||||
|
\hfil
|
||||||
|
\strut@
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
##
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\hfil
|
||||||
|
\crcr
|
||||||
|
\ams@return@opt@arg
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\endaligned}
|
||||||
|
\cs_set:Npn \endaligned {
|
||||||
|
\crcr
|
||||||
|
\UseExpandableTaggingSocket{math/luamml/mtable/innertable/save}
|
||||||
|
\egroup
|
||||||
|
\restorecolumn@
|
||||||
|
\egroup
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/innertable/finalize}
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\gather@}
|
||||||
|
\cs_set:Npn \gather@ #1 {
|
||||||
|
\ingather@true
|
||||||
|
\let \split \insplit@
|
||||||
|
\let \tag \tag@in@align
|
||||||
|
\let \label \label@in@display
|
||||||
|
\chardef \dspbrk@context \z@
|
||||||
|
\intertext@ \displ@y@ \Let@
|
||||||
|
\let \math@cr@@@ \math@cr@@@gather
|
||||||
|
\gmeasure@ {#1}
|
||||||
|
\global \shifttag@false
|
||||||
|
\tabskip \z@skip
|
||||||
|
\global \row@ \@ne
|
||||||
|
\halign to \displaywidth \bgroup
|
||||||
|
\strut@
|
||||||
|
\setboxz@h {
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
{##}
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
}
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{box}
|
||||||
|
\calc@shift@gather
|
||||||
|
\set@gather@field
|
||||||
|
\tabskip\@centering
|
||||||
|
&
|
||||||
|
\setboxz@h {
|
||||||
|
\strut@
|
||||||
|
{##}
|
||||||
|
}
|
||||||
|
\dim_compare:nNnTF {0pt} = {
|
||||||
|
\box_wd:N \c_zero_int
|
||||||
|
}
|
||||||
|
{ \place@tag@gather }
|
||||||
|
{
|
||||||
|
\place@tag@gather
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/tag/set}
|
||||||
|
}
|
||||||
|
\tabskip \iftagsleft@
|
||||||
|
\gdisplaywidth@
|
||||||
|
\else
|
||||||
|
\z@skip
|
||||||
|
\span \fi
|
||||||
|
\crcr
|
||||||
|
#1
|
||||||
|
}
|
||||||
|
% in latex lab, add the luamml_ignore to \measuring@true instead.
|
||||||
|
\PackageInfo{luamml}{patching~\string\gmeasure@}
|
||||||
|
\cs_new_eq:NN \__luamml_amsmath_original_gmeasure:n \gmeasure@
|
||||||
|
\cs_set:Npn \gmeasure@ #1 {
|
||||||
|
\exp_last_unbraced:Nno
|
||||||
|
\use_ii_i:nn
|
||||||
|
{ \luamml_ignore: }
|
||||||
|
{ \__luamml_amsmath_original_gmeasure:n {#1} }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
\PackageInfo{luamml}{patching~\string\endgather}
|
||||||
|
\cs_set:Npn \endgather {
|
||||||
|
\math@cr
|
||||||
|
\black@ \totwidth@
|
||||||
|
\UseExpandableTaggingSocket{math/luamml/mtable/finalize} {gather}
|
||||||
|
\egroup
|
||||||
|
$$
|
||||||
|
\ignorespacesafterend
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
% align and friends
|
||||||
|
\PackageInfo{luamml}{patching~\string\align@preamble}
|
||||||
|
\cs_set:Npn \align@preamble {
|
||||||
|
&
|
||||||
|
\hfil
|
||||||
|
\strut@
|
||||||
|
\setboxz@h {
|
||||||
|
\@lign
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
{##}
|
||||||
|
\ifmeasuring@
|
||||||
|
\luamml_ignore:
|
||||||
|
\else
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
\fi
|
||||||
|
$
|
||||||
|
}
|
||||||
|
\ifmeasuring@
|
||||||
|
\savefieldlength@
|
||||||
|
\else
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{box}
|
||||||
|
\fi
|
||||||
|
\set@field
|
||||||
|
\tabskip\z@skip
|
||||||
|
&
|
||||||
|
\setboxz@h {
|
||||||
|
\@lign
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\displaystyle
|
||||||
|
{
|
||||||
|
{}
|
||||||
|
##
|
||||||
|
}
|
||||||
|
\ifmeasuring@
|
||||||
|
\luamml_ignore:
|
||||||
|
\else
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
\fi
|
||||||
|
$
|
||||||
|
}
|
||||||
|
\ifmeasuring@
|
||||||
|
\savefieldlength@
|
||||||
|
\else
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{box}
|
||||||
|
\fi
|
||||||
|
\set@field
|
||||||
|
\hfil
|
||||||
|
\tabskip\alignsep@
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\math@cr@@@align}
|
||||||
|
\cs_set:Npn \math@cr@@@align {
|
||||||
|
\ifst@rred
|
||||||
|
\nonumber
|
||||||
|
\fi
|
||||||
|
\if@eqnsw
|
||||||
|
\global \tag@true
|
||||||
|
\fi
|
||||||
|
\global \advance \row@ \@ne
|
||||||
|
\add@amps \maxfields@
|
||||||
|
\omit
|
||||||
|
\kern -\alignsep@
|
||||||
|
\iftag@
|
||||||
|
\setboxz@h {
|
||||||
|
\@lign
|
||||||
|
\strut@
|
||||||
|
{ \make@display@tag }
|
||||||
|
}
|
||||||
|
\place@tag
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/tag/set}
|
||||||
|
\fi
|
||||||
|
\ifst@rred
|
||||||
|
\else
|
||||||
|
\global \@eqnswtrue
|
||||||
|
\fi
|
||||||
|
\global \lineht@ \z@
|
||||||
|
\cr
|
||||||
|
}
|
||||||
|
|
||||||
|
% This was lost anyway, as the latex-lab code overwrites
|
||||||
|
% the definition again.
|
||||||
|
\PackageInfo{luamml}{patching~\string\maketag@@@}
|
||||||
|
\cs_set:Npn \maketag@@@ #1
|
||||||
|
{
|
||||||
|
\hbox {
|
||||||
|
\m@th
|
||||||
|
\normalfont
|
||||||
|
#1
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/tag/save}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\endalign}
|
||||||
|
% this handled in latex-lab through \common@align@ending
|
||||||
|
\cs_set:Npn \endalign {
|
||||||
|
\math@cr
|
||||||
|
\black@ \totwidth@
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalize} {align}
|
||||||
|
\egroup
|
||||||
|
\ifingather@
|
||||||
|
\restorealignstate@
|
||||||
|
\egroup
|
||||||
|
\nonumber
|
||||||
|
\ifnum0=`{\fi\iffalse}\fi
|
||||||
|
\else
|
||||||
|
$$
|
||||||
|
\fi
|
||||||
|
\ignorespacesafterend
|
||||||
|
}
|
||||||
|
|
||||||
|
\PackageInfo{luamml}{patching~\string\multline@}
|
||||||
|
% For a more interesting one, let's consider multline:
|
||||||
|
\cs_new_eq:NN \__luamml_amsmath_original_multline:n \multline@
|
||||||
|
\cs_set:Npn \multline@ #1 {
|
||||||
|
\__luamml_amsmath_original_multline:n {
|
||||||
|
\ifmeasuring@ \else
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/aligncol} {left}
|
||||||
|
\fi
|
||||||
|
#1
|
||||||
|
\ifmeasuring@ \else
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/aligncol} {right}
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%this is not move to latex-lab as the luamml_ignore is inserting with
|
||||||
|
% \measuringtrue
|
||||||
|
\PackageInfo{luamml}{patching~\string\mmeasure@}
|
||||||
|
\cs_new_eq:NN \__luamml_amsmath_original_mmeasure:n \mmeasure@
|
||||||
|
\cs_set:Npn \mmeasure@ #1 {
|
||||||
|
\exp_last_unbraced:Nno
|
||||||
|
\use_ii_i:nn
|
||||||
|
{ \luamml_ignore: }
|
||||||
|
{ \__luamml_amsmath_original_mmeasure:n {#1} }
|
||||||
|
}
|
||||||
|
% Luckily, {multline} uses \endmultline@math in exactly
|
||||||
|
% the spot where we have to set the flag.
|
||||||
|
% Less luckily, \endmultline@math sometimes get overwritten for the last line.
|
||||||
|
% But that isn't a problem since we want special behavior there anyway.
|
||||||
|
\PackageInfo{luamml}{patching~\string\endmultline@math}
|
||||||
|
\cs_set:Npn \endmultline@math {
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{{} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\rendmultline@}
|
||||||
|
\cs_set:Npn \rendmultline@ {
|
||||||
|
\iftag@
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{{} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\let \endmultline@math \relax
|
||||||
|
\ifshifttag@
|
||||||
|
\hskip \multlinegap
|
||||||
|
\llap {
|
||||||
|
\vtop {
|
||||||
|
\raise@tag
|
||||||
|
\normalbaselines
|
||||||
|
\setbox \@ne \null
|
||||||
|
\dp \@ne \lineht@
|
||||||
|
\box \@ne
|
||||||
|
\hbox {
|
||||||
|
\strut@
|
||||||
|
\make@display@tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\else
|
||||||
|
\hskip \multlinetaggap
|
||||||
|
\make@display@tag
|
||||||
|
\fi
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/tag/set}
|
||||||
|
\else
|
||||||
|
\hskip \multlinegap
|
||||||
|
\fi
|
||||||
|
\hfilneg
|
||||||
|
\math@cr
|
||||||
|
\UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline}
|
||||||
|
\egroup
|
||||||
|
$$
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\lendmultline@}
|
||||||
|
\cs_set:Npn \lendmultline@ {
|
||||||
|
\hfilneg
|
||||||
|
\hskip\multlinegap
|
||||||
|
\math@cr
|
||||||
|
\UseExpandableTaggingSocket {math/luamml/mtable/finalize} {multline}
|
||||||
|
%\__luamml_amsmath_finalize_table:n {multline}
|
||||||
|
\egroup
|
||||||
|
$$
|
||||||
|
}
|
||||||
|
|
||||||
|
\PackageInfo{luamml}{patching~smallmatrix}
|
||||||
|
\renewenvironment {smallmatrix} {
|
||||||
|
\UseTaggingSocket{ math/luamml/annotate/false } {} { \null\, }
|
||||||
|
\vcenter \bgroup
|
||||||
|
\Let@
|
||||||
|
\restore@math@cr
|
||||||
|
\default@tag
|
||||||
|
\baselineskip 6 \ex@
|
||||||
|
\lineskip 1.5 \ex@
|
||||||
|
\lineskiplimit \lineskip
|
||||||
|
\ialign \bgroup
|
||||||
|
\hfil
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\scriptstyle
|
||||||
|
##
|
||||||
|
% No \scriptsize here since we want to add the mstyle nodes
|
||||||
|
\UseTaggingSocket{math/luamml/save/nn}{ {} {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\hfil
|
||||||
|
&&
|
||||||
|
\thickspace
|
||||||
|
\hfil
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
\scriptstyle
|
||||||
|
##
|
||||||
|
% No \scriptsize here since we want to add the mstyle nodes
|
||||||
|
\UseTaggingSocket{math/luamml/save/nn}{ {} {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\hfil
|
||||||
|
\crcr
|
||||||
|
}{%
|
||||||
|
\crcr
|
||||||
|
\UseExpandableTaggingSocket{math/luamml/mtable/smallmatrix/save}
|
||||||
|
\egroup
|
||||||
|
\egroup
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/innertable/finalize}
|
||||||
|
\UseTaggingSocket{math/luamml/annotate/false} {}{ \, }
|
||||||
|
}
|
||||||
|
|
||||||
|
% {cases} is defined by the kernel, but we patch the overwritten version by amsmath.
|
||||||
|
\PackageInfo{luamml}{patching~\string\env@cases}
|
||||||
|
\cs_set:Npn \env@cases {
|
||||||
|
\let \@ifnextchar \new@ifnextchar
|
||||||
|
\left \lbrace
|
||||||
|
\def \arraystretch {1.2}
|
||||||
|
\array {@{}l@{\quad \luamml_ignore:}l@{}}
|
||||||
|
}
|
||||||
|
\PackageInfo{luamml}{patching~\string\bBigg@}
|
||||||
|
\cs_set:Npn \bBigg@ #1 #2 {
|
||||||
|
{
|
||||||
|
\ensuremath {
|
||||||
|
\Uvextensible height~#1 \big@size axis~exact~#2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} %end package test
|
||||||
|
29
luamml-patches-amstext.sty
Normal file
29
luamml-patches-amstext.sty
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
\ProvidesExplPackage {luamml-patches-amstext} {2025-03-06} {0.5.0}
|
||||||
|
{patches of amstext commands}
|
||||||
|
|
||||||
|
% This is the same definition as in latex-lab-amsmath. It can go with the
|
||||||
|
% 2025-06-01 release.
|
||||||
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
\PackageInfo{luamml}{patching~\string\text@}
|
||||||
|
\sys_if_engine_luatex:T
|
||||||
|
{
|
||||||
|
\def\text@#1{
|
||||||
|
\tag_socket_use:nnn {math/luamml/hbox}{}
|
||||||
|
{{%
|
||||||
|
\ifcase\mathstyle
|
||||||
|
\hbox{{#1}}\or
|
||||||
|
\hbox{{#1}}\or
|
||||||
|
\hbox{{#1}}\or
|
||||||
|
\hbox{{#1}}\or
|
||||||
|
\hbox{{\let\f@size\sf@size\selectfont#1}}\or
|
||||||
|
\hbox{{\let\f@size\sf@size\selectfont#1}}\or
|
||||||
|
\hbox{{\let\f@size\ssf@size\selectfont#1}}\or
|
||||||
|
\hbox{{\let\f@size\ssf@size\selectfont#1}}\or
|
||||||
|
\ERROR
|
||||||
|
\fi
|
||||||
|
\check@mathfonts
|
||||||
|
}}}
|
||||||
|
}
|
||||||
|
}
|
@ -1,71 +0,0 @@
|
|||||||
\ProvidesExplPackage {luamml-patches-array} {2021-04-23} {0.0.1-alpha}
|
|
||||||
{Feel free to add a description here}
|
|
||||||
|
|
||||||
\lua_now:n { require'luamml-array' }
|
|
||||||
|
|
||||||
\cs_set:Npn \@classz {
|
|
||||||
\@classx
|
|
||||||
\@tempcnta \count@
|
|
||||||
\prepnext@tok
|
|
||||||
\@addtopreamble {
|
|
||||||
\ifcase \@chnum
|
|
||||||
\hfil
|
|
||||||
\hskip 1sp
|
|
||||||
\d@llarbegin
|
|
||||||
\__luamml_array_init_col:
|
|
||||||
\insert@column
|
|
||||||
\luamml_flag_save:
|
|
||||||
\d@llarend
|
|
||||||
\__luamml_array_finalize_col:w 0~
|
|
||||||
\do@row@strut
|
|
||||||
\hfil
|
|
||||||
\or
|
|
||||||
\hskip 1sp
|
|
||||||
\d@llarbegin
|
|
||||||
\__luamml_array_init_col:
|
|
||||||
\insert@column
|
|
||||||
\luamml_flag_save:
|
|
||||||
\d@llarend
|
|
||||||
\__luamml_array_finalize_col:w 1~
|
|
||||||
\do@row@strut
|
|
||||||
\hfil
|
|
||||||
\or
|
|
||||||
\hfil
|
|
||||||
\hskip 1sp
|
|
||||||
\d@llarbegin
|
|
||||||
\__luamml_array_init_col:
|
|
||||||
\insert@column
|
|
||||||
\luamml_flag_save:
|
|
||||||
\d@llarend
|
|
||||||
\__luamml_array_finalize_col:w 2~
|
|
||||||
\do@row@strut
|
|
||||||
\or
|
|
||||||
\setbox \ar@mcellbox \vbox \@startpbox { \@nextchar }
|
|
||||||
\insert@column
|
|
||||||
\@endpbox
|
|
||||||
\ar@align@mcell
|
|
||||||
\do@row@strut
|
|
||||||
\or
|
|
||||||
\vtop \@startpbox { \@nextchar }
|
|
||||||
\insert@column
|
|
||||||
\@endpbox
|
|
||||||
\do@row@strut
|
|
||||||
\or
|
|
||||||
\vbox \@startpbox { \@nextchar }
|
|
||||||
\insert@column
|
|
||||||
\@endpbox
|
|
||||||
\do@row@strut
|
|
||||||
\fi
|
|
||||||
}
|
|
||||||
\prepnext@tok
|
|
||||||
}
|
|
||||||
|
|
||||||
\cs_set:Npn \endarray {
|
|
||||||
\crcr
|
|
||||||
\__luamml_array_save_array:
|
|
||||||
\egroup
|
|
||||||
\egroup
|
|
||||||
\__luamml_array_finalize_array:
|
|
||||||
\@arrayright
|
|
||||||
\gdef \@preamble {}
|
|
||||||
}
|
|
84
luamml-patches-kernel.sty
Normal file
84
luamml-patches-kernel.sty
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
\ProvidesExplPackage {luamml-patches-kernel} {2025-03-06} {0.5.0}
|
||||||
|
{Feel free to add a description here}
|
||||||
|
|
||||||
|
|
||||||
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
\PackageInfo{luamml}{patching~\string\mathsm@sh}
|
||||||
|
\cs_set:Npn \mathsm@sh #1 #2 {
|
||||||
|
\setbox \z@ \hbox {
|
||||||
|
$
|
||||||
|
\m@th #1 {
|
||||||
|
#2
|
||||||
|
}
|
||||||
|
\luamml_save:nNn {mathsmash} #1 {mpadded}
|
||||||
|
\luamml_pdf_write:
|
||||||
|
$
|
||||||
|
}
|
||||||
|
\luamml_annotate:nen {2} {
|
||||||
|
nucleus = true,
|
||||||
|
core = consume_label('mathsmash', function(padded)
|
||||||
|
padded.height, padded.depth = 0, 0~
|
||||||
|
end),
|
||||||
|
} {
|
||||||
|
{}
|
||||||
|
\finsm@sh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\PackageInfo{luamml}{patching~\string\mathph@nt}
|
||||||
|
\cs_set:Npn \mathph@nt #1 #2 {
|
||||||
|
\setbox \z@ = \hbox {
|
||||||
|
$
|
||||||
|
\m@th
|
||||||
|
#1
|
||||||
|
{#2}
|
||||||
|
\luamml_save:nNn {mathphant} #1 {mphantom}
|
||||||
|
$
|
||||||
|
}
|
||||||
|
\luamml_annotate:nen {1} {
|
||||||
|
nucleus = true,
|
||||||
|
core = {[0] = 'mpadded',
|
||||||
|
\ifh@\else
|
||||||
|
width = 0,
|
||||||
|
\fi
|
||||||
|
\ifv@\else
|
||||||
|
height = 0, depth = 0,
|
||||||
|
\fi
|
||||||
|
consume_label'mathphant',
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
\finph@nt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\IfFileLoadedT {latex-lab-math.ltx} {
|
||||||
|
\RequirePackage{luamml-patches-lab-math}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
% This is not moved to latex-lab for now. It doesn't work properly with structure elements
|
||||||
|
% active: the content is outside of the math.
|
||||||
|
\@ifpackageloaded {unicode-math} {} {
|
||||||
|
\cs_new:Npn \__luamml_kernel_define_character:Nnn #1#2#3 {
|
||||||
|
\cs_set:cpx { \cs_to_str:N #1 ~ } {
|
||||||
|
\luamml_annotate:nen {#2} {
|
||||||
|
nucleus = true, core = {[0] = 'mi', '\string\u{#3}'},
|
||||||
|
} {
|
||||||
|
\exp_not:v { \cs_to_str:N #1 ~ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\__luamml_kernel_define_character:Nnn \models {3} {22a7}
|
||||||
|
\__luamml_kernel_define_character:Nnn \hookrightarrow {3} {21aa}
|
||||||
|
\__luamml_kernel_define_character:Nnn \hookleftarrow {3} {21a9}
|
||||||
|
\__luamml_kernel_define_character:Nnn \bowtie {3} {22c8}
|
||||||
|
\__luamml_kernel_define_character:Nnn \Longrightarrow {3} {27f9}
|
||||||
|
\__luamml_kernel_define_character:Nnn \longrightarrow {3} {27f6}
|
||||||
|
\__luamml_kernel_define_character:Nnn \Longleftarrow {3} {27f8}
|
||||||
|
\__luamml_kernel_define_character:Nnn \longleftarrow {3} {27f5}
|
||||||
|
\__luamml_kernel_define_character:Nnn \Longleftrightarrow {3} {27fa}
|
||||||
|
\__luamml_kernel_define_character:Nnn \longleftrightarrow {3} {27f7}
|
||||||
|
\__luamml_kernel_define_character:Nnn \longmapsto {4} {27fc}
|
||||||
|
}
|
27
luamml-patches-lab-math.sty
Normal file
27
luamml-patches-lab-math.sty
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
\ProvidesExplPackage {luamml-patches-lab-math} {2025-03-06} {0.5.0}
|
||||||
|
{Feel free to add a description here}
|
||||||
|
|
||||||
|
% This definition is identical to the one in latex-lab-math.
|
||||||
|
% The redefinition and the whole patch file can be removed in 2025-06-01
|
||||||
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
\AddToHook{begindocument} {
|
||||||
|
\PackageInfo{luamml}{patching~\string\common@align@ending}
|
||||||
|
\cs_set:Npn \common@align@ending {
|
||||||
|
\math@cr
|
||||||
|
\black@ \totwidth@
|
||||||
|
\UseExpandableTaggingSocket{math/luamml/mtable/finalize}{align}
|
||||||
|
\egroup
|
||||||
|
\ifingather@
|
||||||
|
\restorealignstate@
|
||||||
|
\egroup
|
||||||
|
\nonumber
|
||||||
|
\ifnum0=`{\fi\iffalse}\fi
|
||||||
|
\else
|
||||||
|
$$
|
||||||
|
\fi
|
||||||
|
\ignorespacesafterend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
luamml-patches-mathtools.sty
Normal file
38
luamml-patches-mathtools.sty
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
\ProvidesExplPackage {luamml-patches-mathtools} {2025-03-06} {0.5.0}
|
||||||
|
{Feel free to add a description here}
|
||||||
|
\IfPackageAtLeastTF{latex-lab-testphase-math}{2025-01-24}
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
\RequirePackage{luamml-patches-amsmath}
|
||||||
|
% see https://github.com/latex3/tagging-project/issues/734
|
||||||
|
\renewcommand*\MT_mult_internal:n [1]{
|
||||||
|
\MH_if_boolean:nF {outer_mult}{\alignedspace@left} %<-- requires amsmath 2016/11/05
|
||||||
|
\MT_next:
|
||||||
|
\bgroup
|
||||||
|
\Let@
|
||||||
|
\def\l_MT_multline_lastline_fint{0 }
|
||||||
|
\chardef\dspbrk@context\@ne \restore@math@cr
|
||||||
|
\MH_let:NwN \math@cr@@\MT_mult_mathcr_atat:w
|
||||||
|
\MH_let:NwN \shoveleft\MT_shoveleft:wn
|
||||||
|
\MH_let:NwN \shoveright\MT_shoveright:wn
|
||||||
|
\spread@equation
|
||||||
|
\MH_set_boolean_F:n {mult_firstline}
|
||||||
|
\MT_measure_mult:n {#1}
|
||||||
|
\MH_if_dim:w \l_MT_multwidth_dim<\l_MT_multline_measure_fdim
|
||||||
|
\MH_setlength:dn \l_MT_multwidth_dim{\l_MT_multline_measure_fdim}
|
||||||
|
\fi
|
||||||
|
\MH_set_boolean_T:n {mult_firstline}
|
||||||
|
\MH_if_num:w \l_MT_multline_lastline_fint=\@ne
|
||||||
|
\MH_let:NwN \math@cr@@ \MT_mult_firstandlast_mathcr:w
|
||||||
|
\MH_fi:
|
||||||
|
\ialign\bgroup
|
||||||
|
\hfil\strut@$\m@th\displaystyle{}##
|
||||||
|
\UseTaggingSocket{math/luamml/save/nNn}{ {} \displaystyle {mtd}}
|
||||||
|
$
|
||||||
|
\UseTaggingSocket{math/luamml/mtable/finalizecol}{last}
|
||||||
|
\hfil
|
||||||
|
\crcr
|
||||||
|
\hfilneg
|
||||||
|
#1
|
||||||
|
}
|
||||||
|
}
|
50
luamml-pdf-demo.sty
Normal file
50
luamml-pdf-demo.sty
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesExplPackage{luamml-pdf-demo}{2025-03-06}{0.5.0}{Reasonable default definitions for luamml-pdf}
|
||||||
|
|
||||||
|
\RequirePackage{luamml-pdf}% Loading luamml-pdf is pretty much the point
|
||||||
|
% \RequirePackage{amsmath,array}% May come back if the patches get ported
|
||||||
|
|
||||||
|
% Delay family mappings to allow for replacements
|
||||||
|
\AddToHook{begindocument/before}{%
|
||||||
|
\@ifpackageloaded{unicode-math}{}{%
|
||||||
|
\RegisterFamilyMapping\symsymbols{oms}%
|
||||||
|
\RegisterFamilyMapping\symletters{oml}%
|
||||||
|
\RegisterFamilyMapping\symlargesymbols{omx}%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\cs_new_protected:Npn \LuaMMLSetFilename #1 {}
|
||||||
|
|
||||||
|
% TODO.
|
||||||
|
% \cs_generate_variant:Nn \pdffile_filespec:nnn {ene}
|
||||||
|
% \int_new:N \g__luamml_demo_af_int
|
||||||
|
% \cs_new_protected:Npn \LuaMMLTagAF #1#2 {
|
||||||
|
% \int_gincr:N \g__luamml_demo_af_int
|
||||||
|
% \exp_args:Ne \pdf_object_new:nn{__luamml_demo_\int_use:N \g__luamml_demo_af_int}{dict}
|
||||||
|
% \exp_args:Ne \tagstructbegin{tag=Formula,AF=__luamml_demo_\int_use:N \g__luamml_demo_af_int,#1}
|
||||||
|
% \bool_if:NF \l__luamml_demo_structelem_bool {
|
||||||
|
% \tagmcbegin{tag=Formula}
|
||||||
|
% }
|
||||||
|
% #2
|
||||||
|
% \group_begin:
|
||||||
|
% \pdfdict_put:nnn {l_pdffile/Filespec} {AFRelationship}{/Supplement}
|
||||||
|
% \pdffile_filespec:ene
|
||||||
|
% { __luamml_demo_ \int_use:N \g__luamml_demo_af_int }
|
||||||
|
% { test.xml }
|
||||||
|
% { \luamml_get_last_mathml_stream:e{}\c_space_tl 0~R}
|
||||||
|
% \group_end:
|
||||||
|
% \bool_if:NF \l__luamml_demo_structelem_bool {
|
||||||
|
% \tagmcend
|
||||||
|
% }
|
||||||
|
% \tagstructend
|
||||||
|
% }
|
||||||
|
|
||||||
|
\NewDocumentCommand\AnnotateFormula{ o m m }{%
|
||||||
|
\IfValueTF{#1}{%
|
||||||
|
\luamml_annotate:nen{#1}%
|
||||||
|
}{
|
||||||
|
\luamml_annotate:en
|
||||||
|
}{#2}{#3}
|
||||||
|
}
|
||||||
|
|
||||||
|
\cs_set_eq:NN \WriteoutFormula \luamml_pdf_write:
|
143
luamml-structelemwriter.lua
Normal file
143
luamml-structelemwriter.lua
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
local struct_begin = token.create'tag_struct_begin:n'
|
||||||
|
local struct_use = token.create'tag_struct_use:n'
|
||||||
|
local struct_use_num = token.create'tag_struct_use_num:n'
|
||||||
|
local struct_end = token.create'tag_struct_end:'
|
||||||
|
|
||||||
|
local mc_begin = token.create'tag_mc_begin:n'
|
||||||
|
local mc_end = token.create'tag_mc_end:'
|
||||||
|
|
||||||
|
local catlatex = luatexbase.registernumber("catcodetable@latex")
|
||||||
|
|
||||||
|
ltx = ltx or {}
|
||||||
|
ltx.__tag = ltx.__tag or {}
|
||||||
|
ltx.__tag.struct = ltx.__tag.struct or {}
|
||||||
|
ltx.__tag.struct.luamml = ltx.__tag.struct.luamml or {}
|
||||||
|
ltx.__tag.struct.luamml.labels = ltx.__tag.struct.luamml.labels or {}
|
||||||
|
|
||||||
|
local function escape_name(name)
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
local function escape_string(str)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local ltx
|
||||||
|
local function get_ltx()
|
||||||
|
if not ltx then
|
||||||
|
ltx = _ENV.ltx
|
||||||
|
if not ltx then
|
||||||
|
tex.error("LaTeX PDF support not loaded", {"Maybe try adding \\DocumentMetadata."})
|
||||||
|
ltx = {pdf = {object_id = function() return 0 end}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ltx
|
||||||
|
end
|
||||||
|
|
||||||
|
local mathml_ns_obj
|
||||||
|
local function get_mathml_ns_obj()
|
||||||
|
if not mathml_ns_obj then
|
||||||
|
mathml_ns_obj = get_ltx().pdf.object_id'tag/NS/mathml'
|
||||||
|
if not mathml_ns_obj then
|
||||||
|
tex.error("Failed to find MathML namespace", {"The PDF support does not know the mathml namespace"})
|
||||||
|
mathml_ns_obj = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return mathml_ns_obj
|
||||||
|
end
|
||||||
|
|
||||||
|
local attribute_counter = 0
|
||||||
|
local attributes = setmetatable({}, {__index = function(t, k)
|
||||||
|
attribute_counter = attribute_counter + 1
|
||||||
|
local attr_name = string.format('luamml_attr_%i', attribute_counter)
|
||||||
|
t[k] = attr_name
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(catlatex,string.format('\\tagpdfsetup{newattribute={%s}{/O/NSO/NS %i 0 R',
|
||||||
|
attr_name, mathml_ns_obj or get_mathml_ns_obj()))
|
||||||
|
-- tex.sprint(string.format('\\tagpdfsetup{newattribute={%s}{/O/MathML-3',
|
||||||
|
-- attr_name))
|
||||||
|
tex.cprint(12, k)
|
||||||
|
tex.sprint'}}'
|
||||||
|
end)
|
||||||
|
return attr_name
|
||||||
|
end})
|
||||||
|
|
||||||
|
local mc_type = luatexbase.attributes.g__tag_mc_type_attr
|
||||||
|
local mc_cnt = luatexbase.attributes.g__tag_mc_cnt_attr
|
||||||
|
-- print('!!!', mc_type, mc_cnt)
|
||||||
|
|
||||||
|
local stash_cnt = 0
|
||||||
|
local attrs = {}
|
||||||
|
local function write_elem(tree, stash)
|
||||||
|
if tree[':struct'] then
|
||||||
|
return tex.runtoks(function()
|
||||||
|
return tex.sprint(struct_use, '{', tree[':struct'], '}')
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if tree[':structnum'] then
|
||||||
|
return tex.runtoks(function()
|
||||||
|
return tex.sprint(struct_use_num, '{', tree[':structnum'], '}')
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if not tree[0] then print('ERR', require'inspect'(tree)) end
|
||||||
|
local i = 0
|
||||||
|
for attr, val in next, tree do if type(attr) == 'string' and not string.find(attr, ':') and attr ~= 'xmlns' then
|
||||||
|
-- for attr, val in next, tree do if type(attr) == 'string' and string.byte(attr) ~= 0x3A then
|
||||||
|
i = i + 1
|
||||||
|
attrs[i] = string.format('/%s(%s)', escape_name(attr), escape_string(val))
|
||||||
|
end end
|
||||||
|
table.sort(attrs)
|
||||||
|
|
||||||
|
if stash then
|
||||||
|
tree[':structnum'] = get_ltx().tag.get_struct_num_next()
|
||||||
|
stash = ', stash, '
|
||||||
|
end
|
||||||
|
|
||||||
|
local attr_flag = i ~= 0 and ', attribute=' .. attributes[table.concat(attrs)]
|
||||||
|
tex.sprint(struct_begin, '{tag=' .. tree[0] .. '/mathml')
|
||||||
|
if stash then tex.sprint(stash) end
|
||||||
|
if attr_flag then tex.sprint(attr_flag) end
|
||||||
|
tex.sprint'}'
|
||||||
|
for j = 1, i do attrs[j] = nil end
|
||||||
|
|
||||||
|
if tree[':nodes'] then
|
||||||
|
local n = tree[':nodes']
|
||||||
|
tex.runtoks(function()
|
||||||
|
if tree[':actual'] then
|
||||||
|
tex.sprint(mc_begin,'{tag=Span,actualtext=')
|
||||||
|
tex.cprint(12,tree[':actual'])
|
||||||
|
tex.sprint('}')
|
||||||
|
else
|
||||||
|
tex.sprint{mc_begin, string.format('{tag=%s}', tree[0])}
|
||||||
|
end
|
||||||
|
-- NOTE: This will also flush all previous sprint's... That's often annoying, but in this case actually intentional.
|
||||||
|
end)
|
||||||
|
local mct, mcc = tex.attribute[mc_type], tex.attribute[mc_cnt]
|
||||||
|
for i = 1, #n do
|
||||||
|
node.set_attribute(n[i], mc_type, mct)
|
||||||
|
node.set_attribute(n[i], mc_cnt, mcc)
|
||||||
|
end
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(mc_end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
for _, elem in ipairs(tree) do
|
||||||
|
if type(elem) ~= 'string' and not elem['tex:ignore'] then
|
||||||
|
if elem['intent']==':equation-label' and ltx.__tag.struct.luamml.labels then
|
||||||
|
if #ltx.__tag.struct.luamml.labels > 0 then
|
||||||
|
-- print("CHECK LABEL STRUCTURE: ",table.serialize(elem), table.serialize(ltx.__tag.struct.luamml.labels))
|
||||||
|
local num= table.remove(ltx.__tag.struct.luamml.labels,1)
|
||||||
|
elem[1][#elem+1]={[':structnum']= num}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
write_elem(elem)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(struct_end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(element, stash)
|
||||||
|
return write_elem(element, stash)
|
||||||
|
end
|
@ -4,8 +4,23 @@ local save_result = require'luamml-tex'.save_result
|
|||||||
|
|
||||||
local properties = node.get_properties_table()
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
|
local glue_id = node.id'glue'
|
||||||
|
local tabskip_sub = 12
|
||||||
|
assert(node.subtypes'glue'[tabskip_sub] == 'tabskip')
|
||||||
|
|
||||||
local function store_get_row()
|
local function store_get_row()
|
||||||
local row_temp = tex.nest[tex.nest.ptr-1].head
|
local row_temp
|
||||||
|
for i=tex.nest.ptr-1, 0, -1 do
|
||||||
|
local head = tex.nest[i].head
|
||||||
|
local glue = head.next
|
||||||
|
if glue and glue.id == glue_id and glue.subtype == tabskip_sub then
|
||||||
|
row_temp = head
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not row_temp then
|
||||||
|
error[[luamml_table's store function called outside of table]]
|
||||||
|
end
|
||||||
local props = properties[row_temp]
|
local props = properties[row_temp]
|
||||||
if not props then
|
if not props then
|
||||||
props = {}
|
props = {}
|
||||||
@ -20,32 +35,45 @@ local function store_get_row()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function store_column_xml(mml, display)
|
local function store_column_xml(mml, display)
|
||||||
if display and mml[0] == 'mstyle' and mml.displaystyle == true then
|
if mml[0] ~= 'mtd' then
|
||||||
mml[0], mml.displaystyle, mml.scriptlevel = 'mtd', nil, nil
|
if display and mml[0] == 'mstyle' and mml.displaystyle == true then
|
||||||
else
|
mml[0], mml.displaystyle, mml.scriptlevel = 'mtd', nil, nil
|
||||||
if display and mml[0] ~= 'mstyle' then
|
else
|
||||||
mml = {[0] = 'mstyle', displaystyle = false, mml}
|
if display and mml[0] ~= 'mstyle' then
|
||||||
|
mml = {[0] = 'mstyle', displaystyle = false, mml}
|
||||||
|
end
|
||||||
|
mml = {[0] = 'mtd', mml}
|
||||||
end
|
end
|
||||||
mml = {[0] = 'mtd', mml}
|
|
||||||
end
|
end
|
||||||
table.insert(store_get_row(), mml)
|
table.insert(store_get_row(), mml)
|
||||||
return mml
|
return mml
|
||||||
end
|
end
|
||||||
|
|
||||||
local function store_column(startmath, display)
|
local function store_column(startmath)
|
||||||
local props = properties[startmath]
|
local props = properties[startmath]
|
||||||
if not props then return end
|
if not props then return end
|
||||||
local mml = props.saved_mathml_table
|
local mml = props.saved_mathml_table or props.saved_mathml_core
|
||||||
if mml then return store_column_xml(mml, display) end
|
if mml then return store_column_xml(mml) end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function store_tag(xml)
|
local function store_tag(xml)
|
||||||
local mml_row = store_get_row()
|
local mml_row = store_get_row()
|
||||||
mml_row[0] = 'mlabeledtr'
|
xml.intent = ':equation-label'
|
||||||
table.insert(mml_row, 1, xml)
|
table.insert(mml_row, 1, xml)
|
||||||
last_tag = nil
|
last_tag = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function store_notag(xml)
|
||||||
|
local mml_row = store_get_row()
|
||||||
|
xml.intent = ':no-equation-label'
|
||||||
|
table.insert(mml_row, 1, xml)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_row_attribute(name, value)
|
||||||
|
local mml_row = store_get_row()
|
||||||
|
mml_row[name] = value
|
||||||
|
end
|
||||||
|
|
||||||
luatexbase.add_to_callback('hpack_filter', function(_, group)
|
luatexbase.add_to_callback('hpack_filter', function(_, group)
|
||||||
if group ~= 'fin_row' then return true end
|
if group ~= 'fin_row' then return true end
|
||||||
|
|
||||||
@ -83,5 +111,7 @@ return {
|
|||||||
store_column = store_column,
|
store_column = store_column,
|
||||||
store_column_xml = store_column_xml,
|
store_column_xml = store_column_xml,
|
||||||
store_tag = store_tag,
|
store_tag = store_tag,
|
||||||
|
store_notag = store_notag,
|
||||||
|
set_row_attribute = set_row_attribute,
|
||||||
get_table = get_table,
|
get_table = get_table,
|
||||||
}
|
}
|
||||||
|
140
luamml-tex-annotate.lua
Normal file
140
luamml-tex-annotate.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
local nest = tex.nest
|
||||||
|
|
||||||
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
|
local mark_environment = {
|
||||||
|
data = {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
do
|
||||||
|
local _ENV = mark_environment
|
||||||
|
function consume_label(label, fn)
|
||||||
|
local mathml = data.mathml[label]
|
||||||
|
data.mathml[label] = nil
|
||||||
|
if fn then fn(mathml) end
|
||||||
|
return mathml
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function annotate()
|
||||||
|
local annotation, err = load( 'return {'
|
||||||
|
.. token.scan_argument()
|
||||||
|
.. '}', nil, 't', mark_environment)
|
||||||
|
if not annotation then
|
||||||
|
tex.error('Error while parsing LuaMML annotation', {err})
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
annotation = annotation()
|
||||||
|
local nesting = nest.top
|
||||||
|
local props = properties[nesting.head]
|
||||||
|
local current = props and props.luamml__annotate_context
|
||||||
|
if current then
|
||||||
|
current, props.luamml__annotate_context = current.head, current.prev
|
||||||
|
else
|
||||||
|
tex.error('Mismatched LuaMML annotation',
|
||||||
|
{'Something odd happened. Maybe you forgot braces around an annotated symbol in a subscript or superscript?'})
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
local after = nesting.tail
|
||||||
|
local count, offset = 0, annotation.offset
|
||||||
|
local marked
|
||||||
|
if current == after then
|
||||||
|
tex.error'Empty LuaMML annotation'
|
||||||
|
else
|
||||||
|
repeat
|
||||||
|
current = current.next
|
||||||
|
count = count + 1
|
||||||
|
if count == offset then
|
||||||
|
marked = current
|
||||||
|
elseif offset or current ~= after then
|
||||||
|
local props = properties[current]
|
||||||
|
if not props then
|
||||||
|
props = {}
|
||||||
|
properties[current] = props
|
||||||
|
end
|
||||||
|
props.mathml_table, props.mathml_core = nil, false
|
||||||
|
end
|
||||||
|
until current == after
|
||||||
|
if offset and not marked then
|
||||||
|
tex.error'Invalid offset in LuaMML annotation'
|
||||||
|
end
|
||||||
|
marked = marked or current
|
||||||
|
if annotation.nucleus then
|
||||||
|
marked = marked.nucleus
|
||||||
|
end
|
||||||
|
if marked then
|
||||||
|
local props = properties[marked]
|
||||||
|
if not props then
|
||||||
|
props = {}
|
||||||
|
properties[marked] = props
|
||||||
|
end
|
||||||
|
if annotation.core ~= nil then
|
||||||
|
props.mathml_core = annotation.core
|
||||||
|
end
|
||||||
|
if annotation.struct ~= nil then
|
||||||
|
local saved = props.mathml_filter
|
||||||
|
local struct = annotation.struct
|
||||||
|
function props.mathml_filter(mml, core)
|
||||||
|
mml[':struct'] = struct
|
||||||
|
if saved then
|
||||||
|
return saved(mml, core)
|
||||||
|
else
|
||||||
|
return mml, core
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if annotation.structnum ~= nil then
|
||||||
|
local saved = props.mathml_filter
|
||||||
|
local structnum = annotation.structnum
|
||||||
|
function props.mathml_filter(mml, core)
|
||||||
|
mml[':structnum'] = structnum
|
||||||
|
if saved then
|
||||||
|
return saved(mml, core)
|
||||||
|
else
|
||||||
|
return mml, core
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tex.error'Unable to annotate nucleus of node without nucleus'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
local funcid = luatexbase.new_luafunction'__luamml_annotate_begin:'
|
||||||
|
token.set_lua('__luamml_annotate_begin:', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
local top = nest.top
|
||||||
|
local temp = top.head
|
||||||
|
local props = properties[temp]
|
||||||
|
if not props then
|
||||||
|
props = {}
|
||||||
|
properties[temp] = props
|
||||||
|
end
|
||||||
|
props.luamml__annotate_context = {
|
||||||
|
prev = props.luamml__annotate_context,
|
||||||
|
head = top.tail,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_annotate_end:we'
|
||||||
|
token.set_lua('__luamml_annotate_end:we', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
local count = token.scan_int()
|
||||||
|
local real_count = annotate()
|
||||||
|
if count ~= real_count then
|
||||||
|
tex.error('Incorrect count in LuaMML annotation', {
|
||||||
|
'A LuaMML annotation was discovered with an explicit count \z
|
||||||
|
which was not the same as the number of top-level nodes annotated.',
|
||||||
|
string.format('This can be fixed by changing the supplied count from %i to %i \z
|
||||||
|
or by omitting the count value entirely.', count, real_count)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'__luamml_annotate_end:e'
|
||||||
|
token.set_lua('__luamml_annotate_end:e', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = annotate
|
||||||
|
|
||||||
|
return mark_environment
|
220
luamml-tex.lua
220
luamml-tex.lua
@ -5,8 +5,43 @@ local register_family = mlist_to_mml.register_family
|
|||||||
|
|
||||||
local mappings = require'luamml-legacy-mappings'
|
local mappings = require'luamml-legacy-mappings'
|
||||||
local write_xml = require'luamml-xmlwriter'
|
local write_xml = require'luamml-xmlwriter'
|
||||||
|
local write_struct = require'luamml-structelemwriter'
|
||||||
|
|
||||||
|
local filename_token = token.create'l__luamml_filename_tl'
|
||||||
|
local label_token = token.create'l__luamml_label_tl'
|
||||||
|
local left_brace = token.new(string.byte'{', 1)
|
||||||
|
local right_brace = token.new(string.byte'}', 2)
|
||||||
|
|
||||||
|
local output_hook_token
|
||||||
|
local global_text_families = {}
|
||||||
|
local text_families_meta = {__index = function(t, fam)
|
||||||
|
if fam == nil then return nil end
|
||||||
|
local assignment = global_text_families[fam]
|
||||||
|
if assignment == nil then
|
||||||
|
local fid = node.family_font(fam)
|
||||||
|
local fontdir = font.getfont(fid)
|
||||||
|
if not fontdir then
|
||||||
|
-- FIXME(?): If there is no font...
|
||||||
|
error'Please load your fonts?!?'
|
||||||
|
end
|
||||||
|
assignment = not (fontdir.MathConstants and next(fontdir.MathConstants))
|
||||||
|
end
|
||||||
|
t[fam] = assignment
|
||||||
|
return assignment
|
||||||
|
end}
|
||||||
|
|
||||||
local properties = node.get_properties_table()
|
local properties = node.get_properties_table()
|
||||||
|
local mmode, hmode, vmode do
|
||||||
|
local result, input = {}, tex.getmodevalues()
|
||||||
|
for k,v in next, tex.getmodevalues() do
|
||||||
|
if v == 'math' then mmode = k
|
||||||
|
elseif v == 'horizontal' then hmode = k
|
||||||
|
elseif v == 'vertical' then vmode = k
|
||||||
|
else assert(v == 'unset')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(mmode and hmode and vmode)
|
||||||
|
end
|
||||||
|
|
||||||
local funcid = luatexbase.new_luafunction'RegisterFamilyMapping'
|
local funcid = luatexbase.new_luafunction'RegisterFamilyMapping'
|
||||||
token.set_lua('RegisterFamilyMapping', funcid, 'protected')
|
token.set_lua('RegisterFamilyMapping', funcid, 'protected')
|
||||||
@ -15,70 +50,128 @@ lua.get_functions_table()[funcid] = function()
|
|||||||
local mapping = token.scan_string()
|
local mapping = token.scan_string()
|
||||||
if mappings[mapping] then
|
if mappings[mapping] then
|
||||||
register_family(fam, mappings[mapping])
|
register_family(fam, mappings[mapping])
|
||||||
|
if global_text_families[fam] == nil then
|
||||||
|
global_text_families[fam] = false
|
||||||
|
end
|
||||||
else
|
else
|
||||||
tex.error(string.format('Unknown font mapping %q', mapping))
|
tex.error(string.format('Unknown font mapping %q', mapping))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Possible flag values:
|
local funcid = luatexbase.new_luafunction'RegisterFamilyMapping'
|
||||||
-- 0: Normal (This is the only supported one in display mode)
|
token.set_lua('RegisterTextFamily', funcid, 'protected')
|
||||||
-- 1: Like 0, result is display math
|
lua.get_functions_table()[funcid] = function()
|
||||||
-- 2: Generate MathML, but only save it for later usage in startmath node
|
local fam = token.scan_int()
|
||||||
-- 3: Skip
|
local _kind = token.scan_string()
|
||||||
-- 4: Prepend node list from buffer before generating
|
global_text_families[fam] = true
|
||||||
-- 5: Like 5, result is display math
|
end
|
||||||
-- 6: 2+4
|
|
||||||
-- 7: Skip but save copy of node list in buffer
|
|
||||||
--
|
|
||||||
-- In other words:
|
|
||||||
-- Bit 1: Suppress output
|
|
||||||
-- Bit 0: Force display if 1 isn't set, if it is then skip MathML generation
|
|
||||||
-- Bit 2: Integrate with table mechanism
|
|
||||||
|
|
||||||
local mlist_buffer
|
local function shallow_copy(t)
|
||||||
local mlist_result, mlist_display
|
local tt = {}
|
||||||
|
for k,v in next, t do
|
||||||
local function save_result(xml, display)
|
tt[k] = v
|
||||||
mlist_result, mlist_display = xml, display
|
|
||||||
if tex.count.tracingmathml > 1 then
|
|
||||||
-- Here xml gets wrapped in an mrow to avoid modifying it.
|
|
||||||
texio.write_nl(write_xml(make_root({[0] = 'mrow', xml}, display and 0 or 2)) .. '\n')
|
|
||||||
end
|
end
|
||||||
|
return tt
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Possible flag values:
|
||||||
|
-- 0: Skip
|
||||||
|
-- 1: Generate MathML, but only save it for later usage in startmath node
|
||||||
|
-- 3: Normal (This is the only supported one in display mode)
|
||||||
|
-- 11: Generate MathML structure elements
|
||||||
|
--
|
||||||
|
-- More generally, flags is a bitfield with the defined bits:
|
||||||
|
-- Bit 5-7: See Bit 4
|
||||||
|
-- Bit 4: Overwrite mathstyle with bit 9-11
|
||||||
|
-- Bit 3: Generate MathML structure elements
|
||||||
|
-- Bit 2: Change root element name for saved element
|
||||||
|
-- Bit 1: Save MathML as a fully converted formula
|
||||||
|
-- Bit 0: Save MathML for later usage in startmath node. Ignored for display math.
|
||||||
|
|
||||||
|
local out_file
|
||||||
|
|
||||||
|
local mlist_result
|
||||||
|
|
||||||
|
local undefined_cmd = token.command_id'undefined_cs'
|
||||||
|
local call_cmd = token.command_id'call'
|
||||||
|
|
||||||
|
local labelled_mathml = {}
|
||||||
|
|
||||||
|
local function save_result(xml, display, structelem)
|
||||||
|
mlist_result = make_root(xml, display and 0 or 2)
|
||||||
|
if out_file then
|
||||||
|
out_file:write(write_xml(mlist_result, tex.count.l__luamml_pretty_int & 1 == 1):sub(2) .. '\n')
|
||||||
|
else
|
||||||
|
token.put_next(filename_token)
|
||||||
|
local filename = token.scan_argument()
|
||||||
|
if filename ~= '' then
|
||||||
|
assert(io.open(filename, 'w'))
|
||||||
|
:write(write_xml(mlist_result, tex.count.l__luamml_pretty_int & 1 == 1):sub(2) .. '\n')
|
||||||
|
:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local tracing = tex.count.tracingmathml > 1
|
||||||
|
if tracing then
|
||||||
|
texio.write_nl(write_xml(mlist_result, tex.count.l__luamml_pretty_int & 2 == 2) .. '\n')
|
||||||
|
end
|
||||||
|
if output_hook_token then
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(-2, output_hook_token, left_brace, write_xml(mlist_result, tex.count.l__luamml_pretty_int & 4 == 4), right_brace)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if tex.count.l__luamml_flag_int & 8 == 8 then
|
||||||
|
write_struct(mlist_result)
|
||||||
|
end
|
||||||
|
return mlist_result
|
||||||
end
|
end
|
||||||
|
|
||||||
luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style)
|
luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style)
|
||||||
local flag = tex.count.l__luamml_flag_int
|
if tex.nest.top.mode == mmode then -- This is a equation label generated with \eqno
|
||||||
if flag & 3 == 3 then
|
|
||||||
if flag & 4 == 4 then
|
|
||||||
assert(mlist_buffer == nil)
|
|
||||||
mlist_buffer = node.copy_list(mlist)
|
|
||||||
end
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local new_mlist, buffer_tail
|
local flag = tex.count.l__luamml_flag_int
|
||||||
|
if flag & 3 == 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local display = style == 'display'
|
||||||
|
local startmath = tex.nest.top.tail -- Must come before any write_struct calls which adds nodes
|
||||||
|
style = flag & 16 == 16 and flag>>5 & 0x7 or display and 0 or 2
|
||||||
|
local xml, core = process_mlist(mlist, style, setmetatable({}, text_families_meta))
|
||||||
|
if flag & 2 == 2 then
|
||||||
|
xml = save_result(shallow_copy(xml), display)
|
||||||
|
end
|
||||||
if flag & 4 == 4 then
|
if flag & 4 == 4 then
|
||||||
new_mlist, buffer_tail = assert(mlist_buffer), node.tail(mlist_buffer)
|
local element_type = token.get_macro'l__luamml_root_tl'
|
||||||
mlist.prev, buffer_tail.next = buffer_tail, mlist
|
if element_type ~= 'mrow' then
|
||||||
mlist_buffer = nil
|
if xml[0] == 'mrow' then
|
||||||
else
|
xml[0] = element_type
|
||||||
new_mlist = mlist
|
else
|
||||||
|
xml = {[0] = element_type, xml}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local xml = process_mlist(new_mlist, style == 'display' and 0 or 2)
|
if not display and flag & 1 == 1 then
|
||||||
if flag & 2 == 0 then
|
|
||||||
save_result(xml, style == 'display' or flag & 1 == 1)
|
|
||||||
end
|
|
||||||
if style == 'text' then
|
|
||||||
local startmath = tex.nest.top.tail
|
|
||||||
local props = properties[startmath]
|
local props = properties[startmath]
|
||||||
if not props then
|
if not props then
|
||||||
props = {}
|
props = {}
|
||||||
properties[startmath] = props
|
properties[startmath] = props
|
||||||
end
|
end
|
||||||
props.saved_mathml_table = xml
|
props.saved_mathml_table, props.saved_mathml_core = xml, core
|
||||||
end
|
token.put_next(label_token)
|
||||||
if buffer_tail then
|
local label = token.scan_argument()
|
||||||
mlist.prev, buffer_tail.next = nil, nil
|
if label ~= '' then
|
||||||
node.flush_list(new_mlist)
|
if labelled_mathml[label] then
|
||||||
|
tex.error('MathML Label already in use', {
|
||||||
|
'A MathML expression has a label which is already used by another \z
|
||||||
|
formula. If you do not want to label this formula with a unique \z
|
||||||
|
label, set a empty label instead.'})
|
||||||
|
else
|
||||||
|
labelled_mathml[label] = xml
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if flag & 10 == 8 then
|
||||||
|
write_struct(xml, true) -- This modifies xml in-place to reference the struture element
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end, 'dump_list')
|
end, 'dump_list')
|
||||||
@ -91,7 +184,7 @@ lua.get_functions_table()[funcid] = function()
|
|||||||
"I was asked to provide MathML code for the last formula, but there weren't any new formulas since you last asked."
|
"I was asked to provide MathML code for the last formula, but there weren't any new formulas since you last asked."
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
local mml = write_xml(make_root(mlist_result, mlist_display and 0 or 2))
|
local mml = write_xml(mlist_result, tex.count.l__luamml_pretty_int & 8 == 8)
|
||||||
if tex.count.tracingmathml == 1 then
|
if tex.count.tracingmathml == 1 then
|
||||||
texio.write_nl(mml .. '\n')
|
texio.write_nl(mml .. '\n')
|
||||||
end
|
end
|
||||||
@ -99,6 +192,41 @@ lua.get_functions_table()[funcid] = function()
|
|||||||
mlist_result = nil
|
mlist_result = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'luamml_begin_single_file:'
|
||||||
|
token.set_lua('luamml_begin_single_file:', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
token.put_next(filename_token)
|
||||||
|
local filename = token.scan_argument()
|
||||||
|
if filename ~= '' then
|
||||||
|
out_file = assert(io.open(filename, 'w'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'luamml_end_single_file:'
|
||||||
|
token.set_lua('luamml_end_single_file:', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
if out_file then
|
||||||
|
out_file:close()
|
||||||
|
out_file = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'luamml_register_output_hook:N'
|
||||||
|
token.set_lua('__luamml_register_output_hook:N', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
output_hook_token = token.get_next()
|
||||||
|
end
|
||||||
|
|
||||||
|
funcid = luatexbase.new_luafunction'luamml_disable_output_hook:'
|
||||||
|
token.set_lua('__luamml_disable_output_hook:', funcid, 'protected')
|
||||||
|
lua.get_functions_table()[funcid] = function()
|
||||||
|
output_hook_token = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local annotate_context = require'luamml-tex-annotate'
|
||||||
|
annotate_context.data.mathml = labelled_mathml
|
||||||
|
|
||||||
return {
|
return {
|
||||||
save_result = save_result,
|
save_result = save_result,
|
||||||
|
labelled = labelled_mathml,
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,9 @@ local escapes = {
|
|||||||
['&'] = "&",
|
['&'] = "&",
|
||||||
}
|
}
|
||||||
local function escape_text(text)
|
local function escape_text(text)
|
||||||
return string.gsub(tostring(text), '("<>&)', escapes)
|
return string.gsub(string.gsub(tostring(text), '["<>&]', escapes), '[\x00-\x08\x0B\x0C\x0E-\x1F]', function(x)
|
||||||
|
return string.format('^^%02x', string.byte(x))
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local attrs = {}
|
local attrs = {}
|
||||||
@ -19,8 +21,11 @@ local function write_elem(tree, indent)
|
|||||||
local escaped_name = escape_name(assert(tree[0]))
|
local escaped_name = escape_name(assert(tree[0]))
|
||||||
local i = 0
|
local i = 0
|
||||||
for attr, val in next, tree do if type(attr) == 'string' then
|
for attr, val in next, tree do if type(attr) == 'string' then
|
||||||
i = i + 1
|
if not string.find(attr, ':', 1, true) then
|
||||||
attrs[i] = string.format(' %s="%s"', escape_name(attr), escape_text(val))
|
-- if string.byte(attr) ~= 0x3A then
|
||||||
|
i = i + 1
|
||||||
|
attrs[i] = string.format(' %s="%s"', escape_name(attr), escape_text(val))
|
||||||
|
end
|
||||||
end end
|
end end
|
||||||
table.sort(attrs)
|
table.sort(attrs)
|
||||||
local out = string.format('%s<%s%s', indent or '', escaped_name, table.concat(attrs))
|
local out = string.format('%s<%s%s', indent or '', escaped_name, table.concat(attrs))
|
||||||
@ -29,15 +34,24 @@ local function write_elem(tree, indent)
|
|||||||
return out .. '/>'
|
return out .. '/>'
|
||||||
end
|
end
|
||||||
out = out .. '>'
|
out = out .. '>'
|
||||||
|
-- Never indent the content if it's purely text.
|
||||||
|
if #tree == 1 and type(tree[1]) == 'string' then
|
||||||
|
indent = nil
|
||||||
|
end
|
||||||
local inner_indent = indent and indent .. ' '
|
local inner_indent = indent and indent .. ' '
|
||||||
|
local is_string
|
||||||
for _, elem in ipairs(tree) do
|
for _, elem in ipairs(tree) do
|
||||||
if type(elem) == 'string' then
|
if type(elem) == 'string' then
|
||||||
if inner_indent then
|
if inner_indent and not is_string then
|
||||||
out = out .. inner_indent
|
out = out .. inner_indent
|
||||||
end
|
end
|
||||||
out = out .. escape_text(elem)
|
out = out .. escape_text(elem)
|
||||||
|
is_string = true
|
||||||
else
|
else
|
||||||
out = out .. write_elem(elem, inner_indent)
|
if not elem['tex:ignore'] then
|
||||||
|
out = out .. write_elem(elem, inner_indent)
|
||||||
|
end
|
||||||
|
is_string = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if indent then out = out .. indent end
|
if indent then out = out .. indent end
|
||||||
@ -46,5 +60,5 @@ end
|
|||||||
|
|
||||||
return function(element, indent, version)
|
return function(element, indent, version)
|
||||||
return (version == '11' and '<?xml version="1.1"?>' or '') ..
|
return (version == '11' and '<?xml version="1.1"?>' or '') ..
|
||||||
write_elem(element, indent and '' or nil)
|
write_elem(element, indent and '\n' or nil)
|
||||||
end
|
end
|
||||||
|
1006
luamml.dtx
Normal file
1006
luamml.dtx
Normal file
File diff suppressed because it is too large
Load Diff
32
luamml.sty
32
luamml.sty
@ -1,32 +0,0 @@
|
|||||||
\ProvidesExplPackage {luamml} {2021-04-23} {0.0.1-alpha}
|
|
||||||
{Feel free to add a description here}
|
|
||||||
|
|
||||||
\int_new:N \l__luamml_flag_int
|
|
||||||
\int_new:N \tracingmathml
|
|
||||||
\lua_now:n { require'luamml-tex' }
|
|
||||||
|
|
||||||
\cs_new:Nn \luamml_flag_save: {
|
|
||||||
\int_set:Nn \l__luamml_flag_int { 2 }
|
|
||||||
}
|
|
||||||
\cs_new:Nn \luamml_flag_ignore: {
|
|
||||||
\int_set:Nn \l__luamml_flag_int { 3 }
|
|
||||||
}
|
|
||||||
\cs_new:Nn \luamml_flag_alignment_left: {
|
|
||||||
\int_set:Nn \l__luamml_flag_int { 7 }
|
|
||||||
}
|
|
||||||
\cs_new:Nn \luamml_flag_alignment_right: {
|
|
||||||
\int_set:Nn \l__luamml_flag_int { 6 }
|
|
||||||
}
|
|
||||||
|
|
||||||
\cs_new:Npn \__luamml_patch_package:nn #1 #2 {
|
|
||||||
\@ifpackageloaded {#1} {#2} {
|
|
||||||
\hook_gput_code:nnn {package/after/#1} {luamml} {#2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
\cs_new:Npn \__luamml_patch_package:n #1 {
|
|
||||||
\__luamml_patch_package:nn {#1} {
|
|
||||||
\RequirePackage { luamml-patches-#1 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
\__luamml_patch_package:n {amsmath}
|
|
||||||
\__luamml_patch_package:n {array}
|
|
39
pdfmml-emulate-node.lua
Normal file
39
pdfmml-emulate-node.lua
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
local properties = {}
|
||||||
|
local subtypes = {
|
||||||
|
noad = {[0] = 'ord', 'opdisplaylimits', 'oplimits', 'opnolimits', 'bin', 'rel', 'open', 'close', 'punct', 'inner', 'under', 'over', 'vcenter'},
|
||||||
|
fence = {[0] = 'unset', 'left', 'middle', 'right', 'no'},
|
||||||
|
radical = {[0] = 'radical', 'uradical', 'uroot', 'uunderdelimiter', 'uoverdelimiter', 'udelimiterunder', 'udelimiterover'},
|
||||||
|
}
|
||||||
|
local function traverse_iter(context, head)
|
||||||
|
if head == nil then
|
||||||
|
head = context
|
||||||
|
else
|
||||||
|
head = head.next
|
||||||
|
end
|
||||||
|
if head then
|
||||||
|
return head, head.id, head.subtype
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
node = {
|
||||||
|
get_properties_table = function()
|
||||||
|
return properties
|
||||||
|
end,
|
||||||
|
id = function(name)
|
||||||
|
return name
|
||||||
|
end,
|
||||||
|
is_node = function(node)
|
||||||
|
return type(node) == 'table' and node.id and true or false
|
||||||
|
end,
|
||||||
|
subtypes = function(id)
|
||||||
|
return subtypes[id]
|
||||||
|
end,
|
||||||
|
traverse = function(head)
|
||||||
|
return traverse_iter, head, nil
|
||||||
|
end,
|
||||||
|
direct = {
|
||||||
|
todirect = function(n) return n end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
tex.nulldelimiterspace = tex.nulldelimiterspace or 78643 -- 1.2pt
|
61
pdfmml-logreader.lua
Normal file
61
pdfmml-logreader.lua
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
local l = lpeg or require'lpeg'
|
||||||
|
|
||||||
|
local line = (1-l.P'\n')^0 * '\n'
|
||||||
|
|
||||||
|
local id = l.R'09'^1/tonumber
|
||||||
|
local non_final_list_block = (l.C((1-l.P'\n')^1) * '\n' - '### ' + '\n')^0
|
||||||
|
local math_lists_block = l.Ct('### ' * l.Cg(l.C'display' * ' ', 'display')^-1 * 'math mode entered at line ' * l.Cg(l.R'09'^1 / tonumber, 'line') * '\n'
|
||||||
|
* non_final_list_block)^1
|
||||||
|
local generic_list_block = '### ' * (line - 'current page:') * non_final_list_block
|
||||||
|
local luamml_block = l.Cg('LUAMML_FORMULA_BEGIN:' * id * ':' * l.Ct(
|
||||||
|
l.Cg(id, 'flag') * ':' * l.Cg((1-l.S':\n')^0, 'tag') * ':' * l.Cg((1-l.P'\n')^1, 'label')^-1 * l.P'\n'^1
|
||||||
|
|
||||||
|
* (math_lists_block + generic_list_block/0)^0
|
||||||
|
* (line - 'LUAMML_FORMULA_END\n')^0
|
||||||
|
* 'LUAMML_FORMULA_END\n') * l.Cc'groups')
|
||||||
|
|
||||||
|
local luamml_mark = l.Cg('LUAMML_MARK:' * id * ':' * l.Cs((1 - l.P'\n' + l.Cg('\n' * l.Cc'' - '\nLUAMML_MARK_END\n'))^0) * '\nLUAMML_MARK_END\n' * l.Cc'marks')
|
||||||
|
|
||||||
|
local function add(a, b) return a + b end
|
||||||
|
local count_block = '### ' * line * l.Cf(l.Cc(0) * (('\\' * l.Cc(1))^-1 * line - '### ')^0, add)
|
||||||
|
local luamml_precount = l.Cg('LUAMML_COUNT:' * id * l.P'\n'^1
|
||||||
|
* count_block * l.Cc'precount')
|
||||||
|
|
||||||
|
local luamml_postcount = l.Cg('LUAMML_COUNT_END:' * id * l.P'\n'^1
|
||||||
|
* count_block * l.Cc'postcount')
|
||||||
|
|
||||||
|
local luamml_instruction = l.Cg('LUAMML_INSTRUCTION:' * l.Cc(nil) * l.C((1 - l.P'\n')^0) * '\n' * l.Cc'instructions')
|
||||||
|
|
||||||
|
local function multi_table_set(t, key, value, table)
|
||||||
|
table = t[table]
|
||||||
|
table[key or #table + 1] = value
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
local log_file = l.Cf(l.Ct(l.Cg(l.Ct'', 'groups')
|
||||||
|
* l.Cg(l.Ct'', 'precount')
|
||||||
|
* l.Cg(l.Ct'', 'postcount')
|
||||||
|
* l.Cg(l.Ct'', 'marks')
|
||||||
|
* l.Cg(l.Ct'', 'instructions'))
|
||||||
|
* (luamml_block + luamml_mark + luamml_instruction + luamml_precount + luamml_postcount + line)^0,
|
||||||
|
multi_table_set)
|
||||||
|
|
||||||
|
return function(filename)
|
||||||
|
local f
|
||||||
|
if filename and filename ~= '-' then
|
||||||
|
local msg f, msg = assert(io.open(filename, 'r'))
|
||||||
|
if not f then return f, msg end
|
||||||
|
end
|
||||||
|
local content = (f or io.stdin):read'a'
|
||||||
|
if f then f:close() end
|
||||||
|
-- The following does *not* end with * -1 since we want to allow the last line to not end with \n.
|
||||||
|
-- In that case we ignore the last line, but that's safe since the last line never contains our markers.
|
||||||
|
local parsed = assert(log_file:match(content))
|
||||||
|
local precount, postcount, count = parsed.precount, parsed.postcount, {}
|
||||||
|
for id, pre in next, precount do
|
||||||
|
local post = assert(postcount[id], 'Unbalanced count')
|
||||||
|
count[id], postcount[id] = post-pre, nil
|
||||||
|
end
|
||||||
|
assert(not next(postcount), 'Unbalanced count')
|
||||||
|
parsed.precount, parsed.postcount, parsed.count = nil, nil, count
|
||||||
|
return parsed
|
||||||
|
end
|
234
pdfmml-showlists.lua
Normal file
234
pdfmml-showlists.lua
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
require'pdfmml-emulate-node'
|
||||||
|
|
||||||
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
|
local l = lpeg or require'lpeg'
|
||||||
|
local hex_digit = l.R('09', 'af')
|
||||||
|
local function hex_to_int(s) return tonumber(s, 16) end
|
||||||
|
local tex_char = l.Cg('^^' * (hex_digit * hex_digit / hex_to_int
|
||||||
|
+ l.R'\0\x3F' / function(s) return s:byte() + 0x40 end
|
||||||
|
+ l.R'\x40\x7F' / function(s) return s:byte() - 0x40 end)
|
||||||
|
+ l.P(1) / string.byte)
|
||||||
|
|
||||||
|
local scaled = l.P'-'^-1 * l.R'09'^1 * '.' * l.R'09'^1 / function(s) return (tonumber(s * 0x10000) + .5) // 1 end
|
||||||
|
local int = l.P'-'^-1 * l.R'09'^1 / tonumber
|
||||||
|
local glue_order_mu = 'filll' * l.Cc(3)
|
||||||
|
+ 'fill' * l.Cc(2)
|
||||||
|
+ 'fil' * l.Cc(1)
|
||||||
|
+ 'mu' * l.Cc(0)
|
||||||
|
local glue_order_pt = 'filll' * l.Cc(3)
|
||||||
|
+ 'fill' * l.Cc(2)
|
||||||
|
+ 'fil' * l.Cc(1)
|
||||||
|
+ 'pt' * l.Cc(0)
|
||||||
|
local glue_order = 'filll' * l.Cc(3)
|
||||||
|
+ 'fill' * l.Cc(2)
|
||||||
|
+ 'fil' * l.Cc(1)
|
||||||
|
+ l.Cc(0)
|
||||||
|
local delimiter_code = '"' * (l.R('09', 'AF')^1 / function(s)
|
||||||
|
local code = tonumber(s, 16)
|
||||||
|
return {id = 'delim',
|
||||||
|
small_fam = (code >> 20) & 0xF,
|
||||||
|
small_char = (code >> 12) & 0xFF,
|
||||||
|
large_fam = (code >> 8) & 0xF,
|
||||||
|
large_char = code & 0xFF,
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
local balanced_braces = l.Ct{'{' * (1-l.S'{}'+l.V(1))^0 * '}'}
|
||||||
|
|
||||||
|
local math_char = l.Ct('\\fam' * l.Cg(l.R'09'^1 / tonumber, 'fam') * ' ' * l.Cg(tex_char, 'char') * l.Cg(l.Cc'math_char', 'id'))
|
||||||
|
|
||||||
|
local hdw = '(' * l.Cg(scaled + '*' * l.Cc(-0x40000000), 'height') * '+' * l.Cg(scaled + '*' * l.Cc(-0x40000000), 'depth') * ')x' * l.Cg(scaled + '*' * l.Cc(-0x40000000), 'width')
|
||||||
|
|
||||||
|
local generic_simple_node = l.Ct('\\' * (
|
||||||
|
l.Cg('rule', 'id') * hdw
|
||||||
|
+ l.Cg('kern', 'id') * l.Cg(' ' * l.Cc(1) + l.Cc(0), 'subtype') * l.Cg(scaled, 'kern') * (' (for ' * (l.R'az' + l.S'/\\') * ')')^-1
|
||||||
|
+ l.Cg('glue', 'id') * l.Cg('(\\' * (
|
||||||
|
'line' * l.Cc(1)
|
||||||
|
+ 'baseline' * l.Cc(2)
|
||||||
|
+ 'par' * l.Cc(3)
|
||||||
|
+ 'abovedisplay' * l.Cc(4)
|
||||||
|
+ 'belowdisplay' * l.Cc(5)
|
||||||
|
+ 'abovedisplayshort' * l.Cc(6)
|
||||||
|
+ 'belowdisplayshort' * l.Cc(7)
|
||||||
|
+ 'left' * l.Cc(8)
|
||||||
|
+ 'right' * l.Cc(9)
|
||||||
|
+ 'top' * l.Cc(10)
|
||||||
|
+ 'splittop' * l.Cc(11)
|
||||||
|
+ 'tab' * l.Cc(12)
|
||||||
|
+ 'space' * l.Cc(13)
|
||||||
|
+ 'xspace' * l.Cc(14)
|
||||||
|
+ 'parfill' * l.Cc(15)
|
||||||
|
+ 'math' * l.Cc(16)
|
||||||
|
+ 'thinmu' * l.Cc(17)
|
||||||
|
+ 'medmu' * l.Cc(18)
|
||||||
|
+ 'thickmu' * l.Cc(19)) * 'skip)' + l.Cc(0), 'subtype')
|
||||||
|
* ' ' * l.Cg(scaled, 'width')
|
||||||
|
* (' plus ' * l.Cg(scaled, 'stretch') * l.Cg(glue_order, 'stretch_order') + l.Cg(l.Cc(0), 'stretch') * l.Cg(l.Cc(0), 'stretch_order'))
|
||||||
|
* (' minus ' * l.Cg(scaled, 'shrink') * l.Cg(glue_order, 'shrink_order') + l.Cg(l.Cc(0), 'shrink') * l.Cg(l.Cc(0), 'shrink_order'))
|
||||||
|
+ l.Cg('penalty', 'id') * ' ' * l.Cg(int, 'penalty')
|
||||||
|
+ l.Cg('mark', 'id') * l.Cg('s' * int + l.Cc(0), 'class') * l.Cg(balanced_braces, 'mark')
|
||||||
|
)) * -1
|
||||||
|
|
||||||
|
local simple_noad = l.Ct('\\' * (
|
||||||
|
'math' * l.Cg(
|
||||||
|
'ord' * l.Cc(0)
|
||||||
|
+ 'open' * l.Cc(6)
|
||||||
|
+ 'op\\limits' * l.Cc(2)
|
||||||
|
+ 'op\\nolimits' * l.Cc(3)
|
||||||
|
+ 'op' * l.Cc(1)
|
||||||
|
+ 'bin' * l.Cc(4)
|
||||||
|
+ 'rel' * l.Cc(5)
|
||||||
|
+ 'close' * l.Cc(7)
|
||||||
|
+ 'punct' * l.Cc(8)
|
||||||
|
+ 'inner' * l.Cc(9)
|
||||||
|
+ 'under' * l.Cc(10)
|
||||||
|
+ 'over' * l.Cc(11)
|
||||||
|
+ 'vcenter' * l.Cc(12)
|
||||||
|
, 'subtype') * l.Cg(l.Cc'noad', 'id')
|
||||||
|
+ l.Cg('radical', 'id') * l.Cg(delimiter_code, 'left') * l.Cg(l.Cc(0), 'subtype')
|
||||||
|
+ l.Cg('accent', 'id') * l.Cg(math_char, 'accent') * l.Cg(l.Cc(0), 'subtype')
|
||||||
|
+ l.Cg('left' * l.Cc(1)
|
||||||
|
+ 'middle' * l.Cc(2)
|
||||||
|
+ 'right' * l.Cc(3), 'subtype') * l.Cg(delimiter_code, 'delim')
|
||||||
|
* l.Cg(l.Cc(0), 'options') * l.Cg(l.Cc(0), 'height')
|
||||||
|
* l.Cg(l.Cc(0), 'depth') * l.Cg(l.Cc(0), 'height')
|
||||||
|
* l.Cg(l.Cc(-1), 'class') * l.Cg(l.Cc'fence', 'id')
|
||||||
|
+ l.Cg(
|
||||||
|
'display' * l.Cc(0)
|
||||||
|
+ 'text' * l.Cc(2)
|
||||||
|
+ 'scriptscript' * l.Cc(6)
|
||||||
|
+ 'script' * l.Cc(4), 'subtype') * l.Cg('style', 'id')
|
||||||
|
+ 'm' * l.Cg('kern', 'id') * l.Cg(scaled, 'kern') * 'mu' * l.Cg(l.Cc(99), 'subtype')
|
||||||
|
+ l.Cg('glue', 'id') * (
|
||||||
|
'(\\nonscript)' * l.Cg(l.Cc(98), 'subtype')
|
||||||
|
+ '(\\mskip)' * l.Cg(l.Cc(99), 'subtype')
|
||||||
|
* ' ' * l.Cg(scaled, 'width') * 'mu'
|
||||||
|
* (' plus ' * l.Cg(scaled, 'stretch') * l.Cg(glue_order_mu, 'stretch_order') + l.Cg(l.Cc(0), 'stretch') * l.Cg(l.Cc(0), 'stretch_order'))
|
||||||
|
* (' minus ' * l.Cg(scaled, 'shrink') * l.Cg(glue_order_mu, 'shrink_order') + l.Cg(l.Cc(0), 'shrink') * l.Cg(l.Cc(0), 'shrink_order'))
|
||||||
|
)
|
||||||
|
)) * -1
|
||||||
|
+ generic_simple_node
|
||||||
|
|
||||||
|
local simple_text = l.Ct('\\' * (
|
||||||
|
l.Cg('math', 'id') * l.Cg(
|
||||||
|
'on' * l.Cc(0)
|
||||||
|
+ 'off' * l.Cc(1)
|
||||||
|
, 'subtype') * l.Cg(', surrounded ' * scaled + l.Cc(0), 'surround')
|
||||||
|
)) * -1
|
||||||
|
+ generic_simple_node
|
||||||
|
|
||||||
|
local box_node = l.Ct('\\' * l.Cg('h' * l.Cc'hlist'
|
||||||
|
+ 'v' * l.Cc'vlist') * 'box'
|
||||||
|
* hdw
|
||||||
|
* (', glue set ' * l.Cg('- ' * l.Cc(2) + l.Cc(1), 'glue_sign')
|
||||||
|
* l.Cg(scaled/function (s) return s/65536 end, 'glue_set')
|
||||||
|
* l.Cg(glue_order, 'glue_order')
|
||||||
|
+ l.Cg(l.Cc(0), 'glue_sign') * l.Cg(l.Cc(0), 'glue_set') * l.Cg(l.Cc(0), 'glue_order'))
|
||||||
|
* l.Cg(', shifted ' * scaled + l.Cc(0), 'shift')) * -1
|
||||||
|
|
||||||
|
local fraction_noad = l.Ct('\\fraction, thickness '
|
||||||
|
* l.Cg('= default' * l.Cc(0x40000000) + scaled, 'width')
|
||||||
|
* l.Cg(', left-delimiter ' * delimiter_code, 'left')^-1 * l.Cg(', right-delimiter ' * delimiter_code, 'right')^-1
|
||||||
|
* l.Cg(l.Cc'fraction', 'id'))
|
||||||
|
* -1
|
||||||
|
|
||||||
|
local mathchoice_noad = l.Ct('\\mathchoice' * l.Cg(l.Cc'choice', 'id') * -1)
|
||||||
|
|
||||||
|
local mark_whatsit = '\\write' * ('-' + l.R'09'^1) * '{LUAMML_MARK_REF:' * (l.R'09'^1/tonumber) * ':'
|
||||||
|
|
||||||
|
local parse_list
|
||||||
|
local function parse_kernel(lines, i, prefix, parsed)
|
||||||
|
local line = lines[i]
|
||||||
|
if not line or line:sub(1, #prefix) ~= prefix then return nil, i end
|
||||||
|
local result = math_char:match(lines[i], #prefix + 1)
|
||||||
|
if result then return result, i+1 end
|
||||||
|
if box_node:match(lines[i], #prefix + 1) then return skip_list(lines, i+1, prefix .. '.') end
|
||||||
|
result, i = parse_list(lines, i, prefix, parsed)
|
||||||
|
return {list = result, id = 'sub_mlist'}, i
|
||||||
|
end
|
||||||
|
function skip_list(lines, i, prefix)
|
||||||
|
i = i or 1
|
||||||
|
local count = #lines
|
||||||
|
while i <= count and lines[i]:sub(1, #prefix) == prefix do
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
return {id = 'sub_box', list = {}}, i
|
||||||
|
end
|
||||||
|
function parse_list(lines, i, prefix, parsed)
|
||||||
|
i = i or 1
|
||||||
|
prefix = prefix or ''
|
||||||
|
local head, last
|
||||||
|
local mark_environment = {data = parsed,}
|
||||||
|
local current_mark, current_count, current_offset
|
||||||
|
while true do
|
||||||
|
local skip
|
||||||
|
local line = lines[i]
|
||||||
|
if not line or line:sub(1, #prefix) ~= prefix then break end
|
||||||
|
local simple = simple_noad:match(line, #prefix+1)
|
||||||
|
if simple then
|
||||||
|
simple.nucleus, i = parse_kernel(lines, i + 1, prefix .. '.', parsed)
|
||||||
|
simple.sup, i = parse_kernel(lines, i, prefix .. '^', parsed)
|
||||||
|
simple.sub, i = parse_kernel(lines, i, prefix .. '_', parsed)
|
||||||
|
if last then
|
||||||
|
simple.prev, last.next = last, simple
|
||||||
|
end
|
||||||
|
last = simple
|
||||||
|
else
|
||||||
|
local fraction = fraction_noad:match(line, #prefix+1)
|
||||||
|
if fraction then
|
||||||
|
fraction.num, i = parse_kernel(lines, i + 1, prefix .. '\\', parsed)
|
||||||
|
fraction.denom, i = parse_kernel(lines, i, prefix .. '/', parsed)
|
||||||
|
if last then
|
||||||
|
fraction.prev, last.next = last, fraction
|
||||||
|
end
|
||||||
|
last = fraction
|
||||||
|
else
|
||||||
|
local mathchoice = mathchoice_noad:match(line, #prefix+1)
|
||||||
|
if mathchoice then
|
||||||
|
mathchoice.display, i = parse_list(lines, i + 1, prefix .. 'D', parsed)
|
||||||
|
mathchoice.text, i = parse_list(lines, i, prefix .. 'T', parsed)
|
||||||
|
mathchoice.script, i = parse_list(lines, i, prefix .. 'S', parsed)
|
||||||
|
mathchoice.scriptscript, i = parse_list(lines, i, prefix .. 's', parsed)
|
||||||
|
if last then
|
||||||
|
mathchoice.prev, last.next = last, mathchoice
|
||||||
|
end
|
||||||
|
last = mathchoice
|
||||||
|
else
|
||||||
|
skip = true
|
||||||
|
local mark = mark_whatsit:match(line, #prefix+1)
|
||||||
|
if mark then
|
||||||
|
local mark_table = assert(load('return {' .. assert(parsed.marks[mark], 'Undefined mark encountered') .. '}', nil, 't', mark_environment))()
|
||||||
|
if current_mark then
|
||||||
|
if (mark_table.count or 1) > current_count then
|
||||||
|
error'Invalid mark nesting'
|
||||||
|
end
|
||||||
|
-- Ignore new mark if existing mark is evaluated. This should be replaced with proper nesting
|
||||||
|
else
|
||||||
|
current_mark, current_count = mark_table, mark_table.count or 1
|
||||||
|
current_offset = mark_table.offset or current_count
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
else
|
||||||
|
print(line, prefix, i)
|
||||||
|
print('unknown noad ' .. line:sub(#prefix+1))
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not head then head = last end
|
||||||
|
if not skip and current_mark then
|
||||||
|
current_count = current_count - 1
|
||||||
|
current_offset = current_offset - 1
|
||||||
|
if current_offset == 0 then
|
||||||
|
properties[current_mark.nucleus and last.nucleus or last] = {mathml_core = current_mark.core}
|
||||||
|
else
|
||||||
|
properties[last] = {mathml_core = false}
|
||||||
|
end
|
||||||
|
if current_count == 0 then current_mark = nil end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return head, i
|
||||||
|
end
|
||||||
|
return parse_list
|
96
pdfmml.lua
Executable file
96
pdfmml.lua
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env texlua
|
||||||
|
require'pdfmml-emulate-node'
|
||||||
|
local convert = require'luamml-convert'
|
||||||
|
local mappings = require'luamml-legacy-mappings'
|
||||||
|
local to_xml = require'luamml-xmlwriter'
|
||||||
|
|
||||||
|
local parse_showlists = require'pdfmml-showlists'
|
||||||
|
local parse_log = require'pdfmml-logreader'
|
||||||
|
|
||||||
|
local text_families = {}
|
||||||
|
|
||||||
|
local attributes = lfs.attributes
|
||||||
|
local function try_extensions_(base, extension, ...)
|
||||||
|
if extension == nil then return end
|
||||||
|
local fullname = base .. extension
|
||||||
|
if attributes(fullname, 'mode') == 'file' then
|
||||||
|
return fullname
|
||||||
|
end
|
||||||
|
return try_extensions_(base, ...)
|
||||||
|
end
|
||||||
|
local function try_extensions(base, ...)
|
||||||
|
if attributes(base, 'mode') == 'file' then return base end
|
||||||
|
return try_extensions_(base, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #arg < 1 then
|
||||||
|
io.stderr:write(string.format('Usage: %s {logname} [{outname}]\n\z
|
||||||
|
If {outname} includes {}, then a separate file is written for every formula with {} replaced by the formula id.\n', arg[0]))
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
local parsed = assert(parse_log(assert(try_extensions(arg[1], '.tml', '.log'),
|
||||||
|
"Couldn't find input file.")))
|
||||||
|
|
||||||
|
for i, inst in ipairs(parsed.instructions) do
|
||||||
|
local _, _, family, mapping_name = inst:find'^REGISTER_MAPPING:([0-9]+):(.*)$'
|
||||||
|
if family then
|
||||||
|
local mapping = mappings[mapping_name]
|
||||||
|
if mapping then
|
||||||
|
convert.register_family(tonumber(family), mapping)
|
||||||
|
else
|
||||||
|
io.stderr:write(string.format('Unknown mapping %s ignored\n', mapping_name))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
io.stderr:write'Unknown instruction ignored\n'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local out_prefix, out_suffix, out_stream
|
||||||
|
if not arg[2] or arg[2] == '-' then
|
||||||
|
out_stream = io.stdout
|
||||||
|
else
|
||||||
|
local _ _, _, out_prefix, out_suffix = arg[2]:find'^(.*){}(.*)$'
|
||||||
|
if not out_prefix then
|
||||||
|
out_stream = assert(io.open(arg[2], 'w'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
parsed.mathml = {}
|
||||||
|
|
||||||
|
local function shallow_copy(t)
|
||||||
|
local new = {}
|
||||||
|
for k, v in next, t do
|
||||||
|
new[k] = v
|
||||||
|
end
|
||||||
|
return new
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Currently only 3 flag values are supported:
|
||||||
|
-- 0: Ignore (Doesn't make a lot of sense here)
|
||||||
|
-- 1: Only save
|
||||||
|
-- 3: Generate normally
|
||||||
|
for i, block in ipairs(parsed.groups) do
|
||||||
|
local flag, tag, label = block.flag, block.tag, block.label
|
||||||
|
block = block[1]
|
||||||
|
if flag & 3 ~= 0 then
|
||||||
|
local style = flag & 16 == 16 and flag>>5 & 0x7 or block.display and 0 or 2
|
||||||
|
local xml = convert.process(parse_showlists(block, nil, nil, parsed), style, text_families)
|
||||||
|
if flag & 2 == 2 then
|
||||||
|
local stream = out_stream or assert(io.open(out_prefix .. tostring(i) .. out_suffix, 'w'))
|
||||||
|
stream:write(to_xml(convert.make_root(shallow_copy(xml), style)), '\n')
|
||||||
|
if not out_stream then stream:close() end
|
||||||
|
end
|
||||||
|
if tag ~= 'mrow' then
|
||||||
|
if xml[0] == 'mrow' then
|
||||||
|
xml[0] = tag
|
||||||
|
else
|
||||||
|
xml = {[0] = tag, xml}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (not block.display) and flag & 1 == 1 and label then
|
||||||
|
if parsed.mathml[label] then
|
||||||
|
error'Invalid label reuse'
|
||||||
|
end
|
||||||
|
parsed.mathml[label] = xml
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
98
support/luamml-algorithm.tex
Normal file
98
support/luamml-algorithm.tex
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
% \newcommand\Luamml{\pkg{Luamml}}
|
||||||
|
% \newcommand\luamml{\pkg{luamml}}
|
||||||
|
% \newcommand\xmltag[1]{\texttt{<#1>}}
|
||||||
|
% \section{\Luamml's representation of XML and MathML}
|
||||||
|
% In the following I assume basic familiarity with both Lua\TeX's representation of math noads and MathML.
|
||||||
|
%
|
||||||
|
% \subsection{Representation of XML elements}
|
||||||
|
% In many places, \luamml\ passes around XML elements. Every element is represented by a Lua table.
|
||||||
|
% Element \texttt 0 must always be present and is a string representing the tag name.
|
||||||
|
% The positive integer elements of the table represent child elements (either strings for direct text content or nested tables for nested elements).
|
||||||
|
% All string members which do not start with a colon are attributes, whose value is the result of applying \texttt{tostring} to the field value.
|
||||||
|
% This implies that these values should almost always be strings, except that the value \texttt 0 (since it never needs a unit) can often be set as a number.
|
||||||
|
% For example the XML document
|
||||||
|
% \begin{verbatim}
|
||||||
|
% <math block="display">
|
||||||
|
% <mn>0</mn>
|
||||||
|
% <mo> < </mo>
|
||||||
|
% <mi mathvariant="normal">x</mi>
|
||||||
|
% </math>
|
||||||
|
% \end{verbatim}
|
||||||
|
% would be represented by the Lua table
|
||||||
|
% \begin{verbatim}
|
||||||
|
% {[0] = "math", block="display",
|
||||||
|
% {[0] = "mn", "0"},
|
||||||
|
% {[0] = "mo", "<"},
|
||||||
|
% {[0] = "mi", mathvariant="normal", "x"}
|
||||||
|
% }
|
||||||
|
% \end{verbatim}
|
||||||
|
%
|
||||||
|
% \subsection{Expression cores}
|
||||||
|
% MathML knows the concept of \enquote{embellished operators}:
|
||||||
|
% \begin{blockquote}
|
||||||
|
% The precise definition of an \enquote{embellished operator} is:
|
||||||
|
% \begin{itemize}
|
||||||
|
% \item an \xmltag{mo} element;
|
||||||
|
% \item or one of the elements \xmltag{msub}, \xmltag{msup}, \xmltag{msubsup}, \xmltag{munder}, \xmltag{mover}, \xmltag{munderover}, \xmltag{mmultiscripts}, \xmltag{mfrac}, or \xmltag{semantics} (§ 5.1 Annotation Framework), whose first argument exists and is an embellished operator;
|
||||||
|
% \item or one of the elements \xmltag{mstyle}, \xmltag{mphantom}, or \xmltag{mpadded}, such that an mrow containing the same arguments would be an embellished operator;
|
||||||
|
% \item or an \xmltag{maction} element whose selected sub-expression exists and is an embellished operator;
|
||||||
|
% \item or an \xmltag{mrow} whose arguments consist (in any order) of one embellished operator and zero or more space-like elements.
|
||||||
|
% \end{itemize}
|
||||||
|
% \end{blockquote}
|
||||||
|
% For every embellished operator, MathML calls the \xmltag{mo} element defining the embellished operator the \enquote{core} of the embellished operator.
|
||||||
|
%
|
||||||
|
% \Luamml\ makes this slightly more general: Every expression is represented by a pair of two elements: The expression and it's core.
|
||||||
|
% The core is always a \xmltag{mo}, \xmltag{mi}, or \xmltag{mn}, \texttt{nil} or s special marker for space like elements.
|
||||||
|
%
|
||||||
|
% If and only if the element is a embellished operator the core is a \xmltag{mo} element representing the core of the embellished operator.
|
||||||
|
% The core is a \xmltag{mi} or a \xmltag{mn} element if and only if the element would be an embellished operator with this core if this element where a \xmltag{mo} element.
|
||||||
|
% The core is the special space like marker for space like elements. Otherwise the core is \texttt{nil}.
|
||||||
|
%
|
||||||
|
% \subsection{Translation of math noads}
|
||||||
|
% A math lists can contain the following node types: noad, fence, fraction, radical, accent, style, choice, ins, mark, adjust, boundary, whatsit, penalty, disc, glue, and kern. The \enquote{noads}
|
||||||
|
%
|
||||||
|
% \subsubsection{Translation of kernel noads}
|
||||||
|
% The math noads of this list contain nested kernel noads. So in the first step, we look into how kernel nodes are translated to math nodes.
|
||||||
|
%
|
||||||
|
% \paragraph{\texttt{math_char} kernel noads}
|
||||||
|
% First the family and character value in the \texttt{math_char} are used to lookup the Unicode character value of this \texttt{math_char}.
|
||||||
|
% (For \texttt{unicode-math}, this is usually just the character value. Legacy maths has to be remapped based on the family.)
|
||||||
|
% Then there are two cases: The digits \texttt{0} to \texttt{9} are mapped to \xmltag{mn} elements, everything else becomes a \xmltag{mi} element with \texttt{mathvariant} set to \texttt{normal}.
|
||||||
|
% (The \texttt{mathvariant} value might get suppressed if the character defaults to mathvariant \texttt{normal}.)
|
||||||
|
% In either case, the \texttt{tex:family} attribute is set to the family number if it's not \texttt{0}.
|
||||||
|
%
|
||||||
|
% The core is always set to the expression itself. E.g.\ the \texttt{math_char} kernel noad \verb+\fam3 a+ would become (assuming no remapping for this family)
|
||||||
|
% \begin{verbatim}
|
||||||
|
% {[0] = 'mi',
|
||||||
|
% mathvariant = 'normal',
|
||||||
|
% ["tex:family"] = 3,
|
||||||
|
% "a"
|
||||||
|
% }
|
||||||
|
% \end{verbatim}
|
||||||
|
%
|
||||||
|
% \subsubsection{\texttt{sub_box} kernel noads}
|
||||||
|
% I am open to suggestions how to convert them properly.
|
||||||
|
%
|
||||||
|
% \subsubsection{\texttt{sub_mlist} kernel noads}
|
||||||
|
% The inner list is converted as a \xmltag{mrow} element, with the core being the core of the \xmltag{mrow} element. See the rules for this later.
|
||||||
|
%
|
||||||
|
% \subsubsection{\texttt{delim} kernel noads}
|
||||||
|
% If the \texttt{small_char} is zero, these get converted as space like elements of the form
|
||||||
|
% \begin{verbatim}
|
||||||
|
% {[0] = 'mspace',
|
||||||
|
% width = '1.196pt',
|
||||||
|
% }
|
||||||
|
% \end{verbatim}
|
||||||
|
% where 1.196 is replaced by the current value of \verb+\nulldelimiterspace+ converted to \texttt{bp}.
|
||||||
|
%
|
||||||
|
% Otherwise the same rules as for \texttt{math_char} apply,
|
||||||
|
% except that instead of \texttt{mi} or \xmltag{mn} elements,
|
||||||
|
% \texttt{mo} elements are generated,
|
||||||
|
% \texttt{mathvariant} is never set,
|
||||||
|
% \texttt{stretchy} is set to \texttt{true} if the operator is not on the list of default stretchy operators in the MathML specification
|
||||||
|
% nd \texttt{lspace} and \texttt{rspace} attributes are set to zero.
|
||||||
|
%
|
||||||
|
% \subsubsection{\texttt{acc} kernel noads}
|
||||||
|
% Depending on the surrounding element containing the \texttt{acc} kernel noad, it is either stretchy or not.
|
||||||
|
% If it's stretchy, the same rules as for \texttt{delim} apply, except that \texttt{lspace} and \texttt{rspace} are not set.
|
||||||
|
% Otherwise the \texttt{stretchy} attribute is set to false if the operator is on the list of default stretchy operators.
|
46
test_tex.tex
46
test_tex.tex
@ -1,46 +0,0 @@
|
|||||||
\documentclass{article}
|
|
||||||
\usepackage{luamml}
|
|
||||||
\usepackage{amsmath,array}
|
|
||||||
|
|
||||||
\usepackage{unicode-math}
|
|
||||||
%% Uncomment the following lines when used without unicode-math
|
|
||||||
% \RegisterFamilyMapping\symsymbols{oms}
|
|
||||||
% \RegisterFamilyMapping\symletters{oml}
|
|
||||||
% \RegisterFamilyMapping\symlargesymbols{omx}
|
|
||||||
|
|
||||||
\ExplSyntaxOn
|
|
||||||
\tracingmathml=2
|
|
||||||
\pdfvariable compresslevel=0
|
|
||||||
\cs_new_protected:Npn \ShowMathMLObj {
|
|
||||||
\message { \luamml_get_last_mathml_stream:e{}~0~R }
|
|
||||||
}
|
|
||||||
\ExplSyntaxOff
|
|
||||||
|
|
||||||
\begin{document}
|
|
||||||
\[
|
|
||||||
\begin{pmatrix}
|
|
||||||
1 & 0 & 0 \\
|
|
||||||
0 & 1 & 0 \\
|
|
||||||
0 & 0 & 1
|
|
||||||
\end{pmatrix}
|
|
||||||
=
|
|
||||||
\begin{cases}
|
|
||||||
1 & $if $a=b\\
|
|
||||||
2 & $else$
|
|
||||||
\end{cases}
|
|
||||||
\]
|
|
||||||
\[
|
|
||||||
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
|
||||||
\]
|
|
||||||
\[
|
|
||||||
\sum_a\underline c\dot bc'
|
|
||||||
\]
|
|
||||||
|
|
||||||
\begin{align}
|
|
||||||
abc&=def & e^{\mathrm{i}\pi}&=-1\\
|
|
||||||
1+2&=3\\
|
|
||||||
5
|
|
||||||
\end{align}
|
|
||||||
|
|
||||||
Es gilt $\sin(x)-\sin(x+2\pi)=0$.
|
|
||||||
\end{document}
|
|
142
testfiles-lua/cases.mlr
Normal file
142
testfiles-lua/cases.mlr
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">(</mo>
|
||||||
|
<mspace width="-4.981pt" />
|
||||||
|
<mpadded lspace="+4.981pt" width="+9.963pt">
|
||||||
|
<mtable>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
</mtable>
|
||||||
|
</mpadded>
|
||||||
|
<mspace width="-4.981pt" />
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">)</mo>
|
||||||
|
</mrow>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mrow>
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">{</mo>
|
||||||
|
<mpadded lspace="+4.981pt" width="+9.963pt">
|
||||||
|
<mtable>
|
||||||
|
<mtr>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mtext>if 
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
</math></mtext>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mn>2</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mtext>else</mtext>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
</mtable>
|
||||||
|
</mpadded>
|
||||||
|
<mspace width="1.196pt" />
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo lspace="0" rspace="0.222em">−</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">±</mo>
|
||||||
|
<msqrt>
|
||||||
|
<mrow>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mn>2</mn>
|
||||||
|
</msup>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">−</mo>
|
||||||
|
<mn>4</mn>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
</mrow>
|
||||||
|
</msqrt>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
<mo lspace="0" rspace="0">.</mo>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<munder>
|
||||||
|
<mo lspace="0" movablelimits="true" rspace="0.167em">∑</mo>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
</munder>
|
||||||
|
<munder>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
<mo>_</mo>
|
||||||
|
</munder>
|
||||||
|
<mover>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mo stretchy="true">.</mo>
|
||||||
|
</mover>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
<mi mathvariant="normal">′</mi>
|
||||||
|
</msup>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi mathvariant="normal">sin</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">−</mo>
|
||||||
|
<mi mathvariant="normal">sin</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">+</mo>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mi>𝜋</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mn>0</mn>
|
||||||
|
</math>
|
44
testfiles-lua/cases.mlt
Normal file
44
testfiles-lua/cases.mlt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
\DocumentMetadata{
|
||||||
|
uncompress,
|
||||||
|
pdfversion = 2.0,
|
||||||
|
testphase = {phase-III,table,math},
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\ExplSyntaxOn
|
||||||
|
\luamml_set_filename:n {
|
||||||
|
\jobname .mml
|
||||||
|
}
|
||||||
|
\luamml_process:
|
||||||
|
\luamml_begin_single_file:
|
||||||
|
\ExplSyntaxOff
|
||||||
|
|
||||||
|
\[
|
||||||
|
\left(\begin{matrix}
|
||||||
|
1 & 0 & 0 \\
|
||||||
|
0 & 1 & 0 \\
|
||||||
|
0 & 0 & 1
|
||||||
|
\end{matrix}\right)
|
||||||
|
=
|
||||||
|
\begin{cases}
|
||||||
|
1 & \mbox{if $a=b$}\\
|
||||||
|
2 & \mbox{else}
|
||||||
|
\end{cases}
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
\sum_a\underline c\dot bc'
|
||||||
|
\]
|
||||||
|
|
||||||
|
Es gilt $\sin(x)-\sin(x+2\pi)=0$.
|
||||||
|
\ExplSyntaxOn
|
||||||
|
\luamml_end_single_file:
|
||||||
|
\ExplSyntaxOff
|
||||||
|
\end{document}
|
33
testfiles-lua/test_sqrt-xml.mlr
Normal file
33
testfiles-lua/test_sqrt-xml.mlr
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<msqrt>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
</msqrt>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<msqrt>
|
||||||
|
<msqrt>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
</msqrt>
|
||||||
|
</msqrt>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">+</mo>
|
||||||
|
<mn>2</mn>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<msqrt>
|
||||||
|
<mroot>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑦</mi>
|
||||||
|
<mn>2</mn>
|
||||||
|
</msup>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mroot>
|
||||||
|
</msqrt>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mroot>
|
||||||
|
<mi>𝑦</mi>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mroot>
|
||||||
|
</math>
|
28
testfiles-lua/test_sqrt-xml.mlt
Normal file
28
testfiles-lua/test_sqrt-xml.mlt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
\DocumentMetadata{
|
||||||
|
uncompress,
|
||||||
|
pdfversion = 2.0,
|
||||||
|
testphase = {phase-III,table,math},
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\ExplSyntaxOn
|
||||||
|
\luamml_set_filename:n {
|
||||||
|
\jobname .mml
|
||||||
|
}
|
||||||
|
\luamml_process:
|
||||||
|
\luamml_begin_single_file:
|
||||||
|
\ExplSyntaxOff
|
||||||
|
|
||||||
|
$ \sqrt{x} $
|
||||||
|
|
||||||
|
$ \sqrt{\sqrt{x}} + 2 $
|
||||||
|
|
||||||
|
$ x = \sqrt{\sqrt[3]{y^2}} $
|
||||||
|
|
||||||
|
$\sqrt[3]{y}$
|
||||||
|
\end{document}
|
||||||
|
|
||||||
|
|
22
testfiles-lua/test_sqrt.pvt
Normal file
22
testfiles-lua/test_sqrt.pvt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
\ExplSyntaxOn
|
||||||
|
\sys_gset_rand_seed:n{42}
|
||||||
|
\ExplSyntaxOff
|
||||||
|
\DocumentMetadata{
|
||||||
|
uncompress,
|
||||||
|
pdfversion = 2.0,
|
||||||
|
testphase = {phase-III,math,table},
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
\tagpdfsetup{math/mathml/structelem,attach-css=false}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
$ \sqrt{x} $
|
||||||
|
|
||||||
|
$ \sqrt{\sqrt{x}} + 2 $
|
||||||
|
|
||||||
|
$ x = \sqrt{\sqrt[3]{y^2}} $
|
||||||
|
|
||||||
|
$\sqrt[3]{y}$
|
||||||
|
\end{document}
|
990
testfiles-lua/test_sqrt.tpf
Normal file
990
testfiles-lua/test_sqrt.tpf
Normal file
@ -0,0 +1,990 @@
|
|||||||
|
%PDF-2.0
|
||||||
|
%ÌÕÁÔÅØÐÄÆ
|
||||||
|
22 0 obj
|
||||||
|
<< /Type /EmbeddedFile /Subtype /application#2Fmathml+xml /Params<</ModDate (D:20160520) >> /Length 88 >>
|
||||||
|
stream
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML"> <msqrt> <mi>ð<>‘¥</mi> </msqrt> </math>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
23 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Supplement /Desc (mathml-1) /F (mathml-1.xml) /UF <FEFF006D006100740068006D006C002D0031002E0078006D006C> /EF<</F 22 0 R/UF 22 0 R>> >>
|
||||||
|
endobj
|
||||||
|
24 0 obj
|
||||||
|
<< /Type /EmbeddedFile /Subtype /application#2Fmathml+xml /Params<</ModDate (D:20160520) >> /Length 161 >>
|
||||||
|
stream
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML"> <msqrt> <msqrt> <mi>ð<>‘¥</mi> </msqrt> </msqrt> <mo lspace="0.222em" rspace="0.222em">+</mo> <mn>2</mn> </math>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
25 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Supplement /Desc (mathml-2) /F (mathml-2.xml) /UF <FEFF006D006100740068006D006C002D0032002E0078006D006C> /EF<</F 24 0 R/UF 24 0 R>> >>
|
||||||
|
endobj
|
||||||
|
26 0 obj
|
||||||
|
<< /Type /EmbeddedFile /Subtype /application#2Fmathml+xml /Params<</ModDate (D:20160520) >> /Length 201 >>
|
||||||
|
stream
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>ð<>‘¥</mi> <mo lspace="0.278em" rspace="0.278em">=</mo> <msqrt> <mroot> <msup> <mi>ð<>‘¦</mi> <mn>2</mn> </msup> <mn>3</mn> </mroot> </msqrt> </math>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
27 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Supplement /Desc (mathml-3) /F (mathml-3.xml) /UF <FEFF006D006100740068006D006C002D0033002E0078006D006C> /EF<</F 26 0 R/UF 26 0 R>> >>
|
||||||
|
endobj
|
||||||
|
28 0 obj
|
||||||
|
<< /Type /EmbeddedFile /Subtype /application#2Fmathml+xml /Params<</ModDate (D:20160520) >> /Length 99 >>
|
||||||
|
stream
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML"> <mroot> <mi>ð<>‘¦</mi> <mn>3</mn> </mroot> </math>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
29 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Supplement /Desc (mathml-4) /F (mathml-4.xml) /UF <FEFF006D006100740068006D006C002D0034002E0078006D006C> /EF<</F 28 0 R/UF 28 0 R>> >>
|
||||||
|
endobj
|
||||||
|
35 0 obj
|
||||||
|
<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 11 >>
|
||||||
|
stream
|
||||||
|
$\sqrt {x}$
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
36 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Source /Desc (TeX source) /F (tag-AFfile1.tex) /UF <FEFF007400610067002D0041004600660069006C00650031002E007400650078> /EF<</F 35 0 R/UF 35 0 R>> >>
|
||||||
|
endobj
|
||||||
|
43 0 obj
|
||||||
|
<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 23 >>
|
||||||
|
stream
|
||||||
|
$\sqrt {\sqrt {x}} + 2$
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
44 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Source /Desc (TeX source) /F (tag-AFfile2.tex) /UF <FEFF007400610067002D0041004600660069006C00650032002E007400650078> /EF<</F 43 0 R/UF 43 0 R>> >>
|
||||||
|
endobj
|
||||||
|
50 0 obj
|
||||||
|
<< /O/NSO/NS 13 0 R/lspace(0.222em)/rspace(0.222em) >>
|
||||||
|
endobj
|
||||||
|
55 0 obj
|
||||||
|
<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 28 >>
|
||||||
|
stream
|
||||||
|
$x = \sqrt {\sqrt [3]{y^2}}$
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
56 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Source /Desc (TeX source) /F (tag-AFfile3.tex) /UF <FEFF007400610067002D0041004600660069006C00650033002E007400650078> /EF<</F 55 0 R/UF 55 0 R>> >>
|
||||||
|
endobj
|
||||||
|
60 0 obj
|
||||||
|
<< /O/NSO/NS 13 0 R/lspace(0.278em)/rspace(0.278em) >>
|
||||||
|
endobj
|
||||||
|
70 0 obj
|
||||||
|
<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 14 >>
|
||||||
|
stream
|
||||||
|
$\sqrt [3]{y}$
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
71 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Source /Desc (TeX source) /F (tag-AFfile4.tex) /UF <FEFF007400610067002D0041004600660069006C00650034002E007400650078> /EF<</F 70 0 R/UF 70 0 R>> >>
|
||||||
|
endobj
|
||||||
|
76 0 obj
|
||||||
|
<< /Type /Metadata /Subtype /XML /Length 11691 >>
|
||||||
|
stream
|
||||||
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
|
||||||
|
xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
|
||||||
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
||||||
|
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||||
|
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
|
||||||
|
xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/"
|
||||||
|
xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/"
|
||||||
|
xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"
|
||||||
|
xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/"
|
||||||
|
xmlns:prism="http://prismstandard.org/namespaces/basic/3.0/"
|
||||||
|
xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
|
||||||
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||||
|
xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
|
||||||
|
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
|
||||||
|
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
|
||||||
|
xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#"
|
||||||
|
xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#">
|
||||||
|
<pdfaExtension:schemas>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>OriginalDocumentID</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>URI</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>The common identifier for all versions and renditions of a document.</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/A Identification Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfaid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>year</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Year of standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>rev</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Revision year of standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/UA Universal Accessibility Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.aiim.org/pdfua/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>part</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Part of ISO 14289 standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>rev</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Revision of ISO 14289 standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfxid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.npes.org/pdfx/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PRISM Basic Metadata</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>prism</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://prismstandard.org/namespaces/basic/3.0/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>complianceProfile</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>PRISM specification compliance profile to which this document adheres</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>publicationName</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication name</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>aggregationType</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication type</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>bookEdition</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Edition of the book in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>volume</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication volume number</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>number</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication issue number within a volume</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>pageRange</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Page range for the document within the print version of its publication</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>issn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISSN for the printed publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>eIssn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISSN for the electronic publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>isbn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISBN for the publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>doi</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Digital Object Identifier for the document</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>url</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>URL</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>URL at which the document can be found</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>byteCount</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Approximate file size in octets</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>pageCount</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Number of pages in the print version of the document</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>subtitle</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Document's subtitle</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</pdfaExtension:schemas>
|
||||||
|
<pdf:Producer>luahbtex-NN.NN.NN</pdf:Producer>
|
||||||
|
<pdf:PDFVersion>2.0</pdf:PDFVersion>
|
||||||
|
<dc:type>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>Text</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:type>
|
||||||
|
<dc:language>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>en</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:language>
|
||||||
|
<dc:date>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>2016-05-20T09:00:00Z</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</dc:date>
|
||||||
|
<dc:format>application/pdf</dc:format>
|
||||||
|
<dc:source>test_sqrt.tex</dc:source>
|
||||||
|
<xmp:CreatorTool>LaTeX</xmp:CreatorTool>
|
||||||
|
<xmp:CreateDate>2016-05-20T09:00:00Z</xmp:CreateDate>
|
||||||
|
<xmp:ModifyDate>2016-05-20T09:00:00Z</xmp:ModifyDate>
|
||||||
|
<xmp:MetadataDate>2016-05-20T09:00:00Z</xmp:MetadataDate>
|
||||||
|
<xmpMM:DocumentID>uuid:d1433a12-c113-44c0-8c00-afe828e37deb</xmpMM:DocumentID>
|
||||||
|
<xmpMM:InstanceID>uuid:0a57c455-157a-4141-8c19-6237d832fc80</xmpMM:InstanceID>
|
||||||
|
<prism:complianceProfile>three</prism:complianceProfile>
|
||||||
|
<prism:pageCount>1</prism:pageCount>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
<?xpacket end="w"?>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
79 0 obj
|
||||||
|
<< /Length 2081 >>
|
||||||
|
stream
|
||||||
|
/opacity1 gs
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 0>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 148.712 664.413 Tm [<0C05>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 157.011 664.613 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 5.699 0 l S
|
||||||
|
Q
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 1>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 157.011 657.235 Tm [<0527>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 2>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 148.712 644.986 Tm [<0C09>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 158.675 653.255 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 13.998 0 l S
|
||||||
|
Q
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 158.675 651.412 Tm [<0C05>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 166.974 651.611 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 5.699 0 l S
|
||||||
|
Q
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 3>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 166.974 644.234 Tm [<0527>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mo<</MCID 4>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 174.886 644.234 Tm [<000C>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mn<</MCID 5>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 184.851 644.234 Tm [<0013>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 6>> BDC
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 7>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 148.712 627.309 Tm [<0527>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mo<</MCID 8>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 157.178 627.309 Tm [<001E>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 9>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 167.697 628.648 Tm [<0C0A>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 177.659 639.905 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 20.272 0 l S
|
||||||
|
Q
|
||||||
|
EMC
|
||||||
|
/mn<</MCID 10>> BDC
|
||||||
|
BT
|
||||||
|
/F22 4.98132 Tf
|
||||||
|
1 0 0 1 180.429 631.686 Tm [<0258>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 11>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 178.282 628 Tm [<0C09>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 188.244 636.269 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 9.687 0 l S
|
||||||
|
Q
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 12>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 188.244 627.309 Tm [<0528>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mn<</MCID 13>> BDC
|
||||||
|
BT
|
||||||
|
/F21 6.97385 Tf
|
||||||
|
1 0 0 1 193.405 630.188 Tm [<03F5>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 14>> BDC
|
||||||
|
EMC
|
||||||
|
/mn<</MCID 15>> BDC
|
||||||
|
BT
|
||||||
|
/F22 4.98132 Tf
|
||||||
|
1 0 0 1 151.482 616.792 Tm [<0258>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Formula<</MCID 16>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 149.335 620.379 Tm [<0C05>]TJ
|
||||||
|
ET
|
||||||
|
q
|
||||||
|
1 0 0 1 157.634 620.578 cm
|
||||||
|
[] 0 d 0 J 0.398 w 0 0 m 4.882 0 l S
|
||||||
|
Q
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 17>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 157.634 614.167 Tm [<0528>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
BT
|
||||||
|
/F15 9.96264 Tf
|
||||||
|
1 0 0 1 303.133 89.365 Tm [<0052>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
78 0 obj
|
||||||
|
<< /Type /Page /Contents 79 0 R /Resources 77 0 R /MediaBox [ 0 0 612 792 ] /StructParents 0/Tabs /S /Parent 84 0 R >>
|
||||||
|
endobj
|
||||||
|
77 0 obj
|
||||||
|
<< /ExtGState 1 0 R /Font << /F20 80 0 R /F22 81 0 R /F21 82 0 R /F15 83 0 R >> >>
|
||||||
|
endobj
|
||||||
|
1 0 obj
|
||||||
|
<< /opacity1 <</ca 1/CA 1>> >>
|
||||||
|
endobj
|
||||||
|
85 0 obj
|
||||||
|
<< /Marked true >>
|
||||||
|
endobj
|
||||||
|
86 0 obj
|
||||||
|
<< /Names[(l3ef0001) 23 0 R (l3ef0002) 25 0 R (l3ef0003) 27 0 R (l3ef0004) 29 0 R] >>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<< /Nums [0 [ 34 0 R 39 0 R 42 0 R 48 0 R 49 0 R 51 0 R 54 0 R 58 0 R 59 0 R 54 0 R 66 0 R 54 0 R 64 0 R 65 0 R 69 0 R 75 0 R 69 0 R 74 0 R]
|
||||||
|
] >>
|
||||||
|
endobj
|
||||||
|
87 0 obj
|
||||||
|
<< /Limits [(ID.002) (ID.038)]/Names [(ID.002) 21 0 R (ID.003) 30 0 R (ID.004) 31 0 R (ID.005) 32 0 R (ID.006) 33 0 R (ID.007) 34 0 R (ID.008) 37 0 R (ID.009) 38 0 R (ID.010) 39 0 R (ID.011) 40 0 R (ID.012) 41 0 R (ID.013) 42 0 R (ID.014) 45 0 R (ID.015) 46 0 R (ID.016) 47 0 R (ID.017) 48 0 R (ID.018) 49 0 R (ID.019) 51 0 R (ID.020) 52 0 R (ID.021) 53 0 R (ID.022) 54 0 R (ID.023) 57 0 R (ID.024) 58 0 R (ID.025) 59 0 R (ID.026) 61 0 R (ID.027) 62 0 R (ID.028) 63 0 R (ID.029) 64 0 R (ID.030) 65 0 R (ID.031) 66 0 R (ID.032) 67 0 R (ID.033) 68 0 R (ID.034) 69 0 R (ID.035) 72 0 R (ID.036) 73 0 R (ID.037) 74 0 R (ID.038) 75 0 R ] >>
|
||||||
|
endobj
|
||||||
|
88 0 obj
|
||||||
|
<< /Kids [87 0 R] >>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<< /Artifact /NonStruct /DocumentFragment /Art /Aside /Note /H7 /H6 /H8 /H6 /H9 /H6 /H10 /H6 /Title /P /FENote /Note /Sub /Span /Em /Span /Strong /Span /title /P /part /P /section /H1 /subsection /H2 /subsubsection /H3 /paragraph /H4 /subparagraph /H5 /list /L /itemize /L /enumerate /L /description /L /quote /BlockQuote /quotation /BlockQuote /verbatim /P /item /LI /itemlabel /Lbl /itembody /LBody /footnote /Note /footnotemark /Lbl /footnotelabel /Lbl /text-unit /Part /text /P /theorem-like /Sect /codeline /Span /float /Note /figures /Sect /tables /Sect >>
|
||||||
|
endobj
|
||||||
|
89 0 obj
|
||||||
|
<< /justify <</O/Layout/TextAlign/Justify>>
|
||||||
|
/inline <</O/Layout/Placement/Inline>>
|
||||||
|
/TH-both <</O/Table/Scope/Both>>
|
||||||
|
/TH-row <</O/Table/Scope/Row>>
|
||||||
|
/TH-col <</O/Table/Scope/Column>>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://iso.org/pdf/ssn) >>
|
||||||
|
endobj
|
||||||
|
11 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://iso.org/pdf2/ssn) >>
|
||||||
|
endobj
|
||||||
|
13 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://www.w3.org/1998/Math/MathML) >>
|
||||||
|
endobj
|
||||||
|
16 0 obj
|
||||||
|
<< /title [/Title 11 0 R] /part [/Title 11 0 R] /section [/H1 11 0 R] /subsection [/H2 11 0 R] /subsubsection [/H3 11 0 R] /paragraph [/H4 11 0 R] /subparagraph [/H5 11 0 R] /list [/L 11 0 R] /itemize [/L 11 0 R] /enumerate [/L 11 0 R] /description [/L 11 0 R] /quote [/BlockQuote 9 0 R] /quotation [/BlockQuote 9 0 R] /verbatim [/P 11 0 R] /item [/LI 11 0 R] /itemlabel [/Lbl 11 0 R] /itembody [/LBody 11 0 R] /footnote [/FENote 11 0 R] /footnotemark [/Lbl 11 0 R] /footnotelabel [/Lbl 11 0 R] /text-unit [/Part 11 0 R] /text [/P 11 0 R] /theorem-like [/Sect 11 0 R] /codeline [/Sub 11 0 R] /float [/Aside 11 0 R] /figures [/Sect 11 0 R] /tables [/Sect 11 0 R] >>
|
||||||
|
endobj
|
||||||
|
15 0 obj
|
||||||
|
<< /Type /Namespace /NS (https://www.latex-project.org/ns/dflt) /RoleMapNS 16 0 R >>
|
||||||
|
endobj
|
||||||
|
18 0 obj
|
||||||
|
<< /chapter [/H1 11 0 R] /section [/H2 11 0 R] /subsection [/H3 11 0 R] /subsubsection [/H4 11 0 R] /paragraph [/H5 11 0 R] /subparagraph [/H6 11 0 R] >>
|
||||||
|
endobj
|
||||||
|
17 0 obj
|
||||||
|
<< /Type /Namespace /NS (https://www.latex-project.org/ns/book) /RoleMapNS 18 0 R >>
|
||||||
|
endobj
|
||||||
|
19 0 obj
|
||||||
|
<< /Type /Namespace /NS (data:,C9B55C18-275C-494E-C10F-E4B83CD03F23) >>
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
[ 9 0 R 11 0 R 13 0 R 15 0 R 17 0 R 19 0 R ]
|
||||||
|
endobj
|
||||||
|
21 0 obj
|
||||||
|
<< /Type /StructElem /S /Document /NS 11 0 R /P 5 0 R /K [32 0 R 40 0 R 52 0 R 67 0 R] /ID (ID.002) >>
|
||||||
|
endobj
|
||||||
|
30 0 obj
|
||||||
|
<< /Type /StructElem /S /Artifact /NS 15 0 R /P 5 0 R /ID (ID.003) >>
|
||||||
|
endobj
|
||||||
|
31 0 obj
|
||||||
|
<< /Type /StructElem /S /Artifact /NS 15 0 R /P 5 0 R /ID (ID.004) >>
|
||||||
|
endobj
|
||||||
|
32 0 obj
|
||||||
|
<< /Type /StructElem /S /text-unit /NS 15 0 R /P 21 0 R /K 33 0 R /ID (ID.005) >>
|
||||||
|
endobj
|
||||||
|
33 0 obj
|
||||||
|
<< /Type /StructElem /C /justify /S /text /NS 15 0 R /P 32 0 R /K [ 34 0 R ] /ID (ID.006) >>
|
||||||
|
endobj
|
||||||
|
34 0 obj
|
||||||
|
<< /Type /StructElem /C /inline /AF [23 0 R 36 0 R] /T <FEFF006D006100740068> /S /Formula /NS 11 0 R /P 33 0 R /K [<</Type /MCR /Pg 78 0 R /MCID 0>> 37 0 R] /ID (ID.007) >>
|
||||||
|
endobj
|
||||||
|
37 0 obj
|
||||||
|
<< /Type /StructElem /S /math /NS 13 0 R /P 34 0 R /K 38 0 R /ID (ID.008) >>
|
||||||
|
endobj
|
||||||
|
38 0 obj
|
||||||
|
<< /Type /StructElem /S /msqrt /NS 13 0 R /P 37 0 R /K 39 0 R /ID (ID.009) >>
|
||||||
|
endobj
|
||||||
|
39 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 38 0 R /K <</Type /MCR /Pg 78 0 R /MCID 1>> /ID (ID.010) >>
|
||||||
|
endobj
|
||||||
|
40 0 obj
|
||||||
|
<< /Type /StructElem /S /text-unit /NS 15 0 R /P 21 0 R /K 41 0 R /ID (ID.011) >>
|
||||||
|
endobj
|
||||||
|
41 0 obj
|
||||||
|
<< /Type /StructElem /C /justify /S /text /NS 15 0 R /P 40 0 R /K [ 42 0 R ] /ID (ID.012) >>
|
||||||
|
endobj
|
||||||
|
42 0 obj
|
||||||
|
<< /Type /StructElem /C /inline /AF [25 0 R 44 0 R] /T <FEFF006D006100740068> /S /Formula /NS 11 0 R /P 41 0 R /K [<</Type /MCR /Pg 78 0 R /MCID 2>> 45 0 R] /ID (ID.013) >>
|
||||||
|
endobj
|
||||||
|
45 0 obj
|
||||||
|
<< /Type /StructElem /S /math /NS 13 0 R /P 42 0 R /K [46 0 R 49 0 R 51 0 R] /ID (ID.014) >>
|
||||||
|
endobj
|
||||||
|
46 0 obj
|
||||||
|
<< /Type /StructElem /S /msqrt /NS 13 0 R /P 45 0 R /K 47 0 R /ID (ID.015) >>
|
||||||
|
endobj
|
||||||
|
47 0 obj
|
||||||
|
<< /Type /StructElem /S /msqrt /NS 13 0 R /P 46 0 R /K 48 0 R /ID (ID.016) >>
|
||||||
|
endobj
|
||||||
|
48 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 47 0 R /K <</Type /MCR /Pg 78 0 R /MCID 3>> /ID (ID.017) >>
|
||||||
|
endobj
|
||||||
|
49 0 obj
|
||||||
|
<< /Type /StructElem /A 50 0 R /S /mo /NS 13 0 R /P 45 0 R /K <</Type /MCR /Pg 78 0 R /MCID 4>> /ID (ID.018) >>
|
||||||
|
endobj
|
||||||
|
51 0 obj
|
||||||
|
<< /Type /StructElem /S /mn /NS 13 0 R /P 45 0 R /K <</Type /MCR /Pg 78 0 R /MCID 5>> /ID (ID.019) >>
|
||||||
|
endobj
|
||||||
|
52 0 obj
|
||||||
|
<< /Type /StructElem /S /text-unit /NS 15 0 R /P 21 0 R /K 53 0 R /ID (ID.020) >>
|
||||||
|
endobj
|
||||||
|
53 0 obj
|
||||||
|
<< /Type /StructElem /C /justify /S /text /NS 15 0 R /P 52 0 R /K [ 54 0 R ] /ID (ID.021) >>
|
||||||
|
endobj
|
||||||
|
54 0 obj
|
||||||
|
<< /Type /StructElem /C /inline /AF [27 0 R 56 0 R] /T <FEFF006D006100740068> /S /Formula /NS 11 0 R /P 53 0 R /K [<</Type /MCR /Pg 78 0 R /MCID 6>> <</Type /MCR /Pg 78 0 R /MCID 9>> <</Type /MCR /Pg 78 0 R /MCID 11>> 57 0 R] /ID (ID.022) >>
|
||||||
|
endobj
|
||||||
|
57 0 obj
|
||||||
|
<< /Type /StructElem /S /math /NS 13 0 R /P 54 0 R /K [58 0 R 59 0 R 61 0 R] /ID (ID.023) >>
|
||||||
|
endobj
|
||||||
|
58 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 57 0 R /K <</Type /MCR /Pg 78 0 R /MCID 7>> /ID (ID.024) >>
|
||||||
|
endobj
|
||||||
|
59 0 obj
|
||||||
|
<< /Type /StructElem /A 60 0 R /S /mo /NS 13 0 R /P 57 0 R /K <</Type /MCR /Pg 78 0 R /MCID 8>> /ID (ID.025) >>
|
||||||
|
endobj
|
||||||
|
61 0 obj
|
||||||
|
<< /Type /StructElem /S /msqrt /NS 13 0 R /P 57 0 R /K 62 0 R /ID (ID.026) >>
|
||||||
|
endobj
|
||||||
|
62 0 obj
|
||||||
|
<< /Type /StructElem /S /mroot /NS 13 0 R /P 61 0 R /K [63 0 R 66 0 R] /ID (ID.027) >>
|
||||||
|
endobj
|
||||||
|
63 0 obj
|
||||||
|
<< /Type /StructElem /S /msup /NS 13 0 R /P 62 0 R /K [64 0 R 65 0 R] /ID (ID.028) >>
|
||||||
|
endobj
|
||||||
|
64 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 63 0 R /K <</Type /MCR /Pg 78 0 R /MCID 12>> /ID (ID.029) >>
|
||||||
|
endobj
|
||||||
|
65 0 obj
|
||||||
|
<< /Type /StructElem /S /mn /NS 13 0 R /P 63 0 R /K <</Type /MCR /Pg 78 0 R /MCID 13>> /ID (ID.030) >>
|
||||||
|
endobj
|
||||||
|
66 0 obj
|
||||||
|
<< /Type /StructElem /S /mn /NS 13 0 R /P 62 0 R /K <</Type /MCR /Pg 78 0 R /MCID 10>> /ID (ID.031) >>
|
||||||
|
endobj
|
||||||
|
67 0 obj
|
||||||
|
<< /Type /StructElem /S /text-unit /NS 15 0 R /P 21 0 R /K 68 0 R /ID (ID.032) >>
|
||||||
|
endobj
|
||||||
|
68 0 obj
|
||||||
|
<< /Type /StructElem /C /justify /S /text /NS 15 0 R /P 67 0 R /K [ 69 0 R ] /ID (ID.033) >>
|
||||||
|
endobj
|
||||||
|
69 0 obj
|
||||||
|
<< /Type /StructElem /C /inline /AF [29 0 R 71 0 R] /T <FEFF006D006100740068> /S /Formula /NS 11 0 R /P 68 0 R /K [<</Type /MCR /Pg 78 0 R /MCID 14>> <</Type /MCR /Pg 78 0 R /MCID 16>> 72 0 R] /ID (ID.034) >>
|
||||||
|
endobj
|
||||||
|
72 0 obj
|
||||||
|
<< /Type /StructElem /S /math /NS 13 0 R /P 69 0 R /K 73 0 R /ID (ID.035) >>
|
||||||
|
endobj
|
||||||
|
73 0 obj
|
||||||
|
<< /Type /StructElem /S /mroot /NS 13 0 R /P 72 0 R /K [74 0 R 75 0 R] /ID (ID.036) >>
|
||||||
|
endobj
|
||||||
|
74 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 73 0 R /K <</Type /MCR /Pg 78 0 R /MCID 17>> /ID (ID.037) >>
|
||||||
|
endobj
|
||||||
|
75 0 obj
|
||||||
|
<< /Type /StructElem /S /mn /NS 13 0 R /P 73 0 R /K <</Type /MCR /Pg 78 0 R /MCID 15>> /ID (ID.038) >>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Type /StructTreeRoot /Namespaces 8 0 R /IDTree 88 0 R /ClassMap 89 0 R /ParentTree 6 0 R /RoleMap 7 0 R /K 21 0 R >>
|
||||||
|
endobj
|
||||||
|
90 0 obj
|
||||||
|
[ 82 [ 500 ] ]
|
||||||
|
endobj
|
||||||
|
92 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 574 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
91 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /JFRMQG+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 92 0 R >>
|
||||||
|
endobj
|
||||||
|
93 0 obj
|
||||||
|
<< /Length 692 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-JFRMQG-LMRoman10-Regular-0)
|
||||||
|
%%Title: (TeX-JFRMQG-LMRoman10-Regular-0 TeX JFRMQG-LMRoman10-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (JFRMQG-LMRoman10-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-JFRMQG-LMRoman10-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
1 beginbfchar
|
||||||
|
<0052> <0031>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
83 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /JFRMQG+LMRoman10-Regular /DescendantFonts [ 94 0 R ] /ToUnicode 93 0 R >>
|
||||||
|
endobj
|
||||||
|
94 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /JFRMQG+LMRoman10-Regular /FontDescriptor 91 0 R /W 90 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
95 0 obj
|
||||||
|
[ 1013 [ 569 ] ]
|
||||||
|
endobj
|
||||||
|
97 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 702 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
96 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /MGWLKY+LatinModernMath-Regular /Flags 4 /FontBBox [ -1042 -3060 4082 3560 ] /Ascent 806 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 113 /XHeight 431 /FontFile3 97 0 R >>
|
||||||
|
endobj
|
||||||
|
98 0 obj
|
||||||
|
<< /Length 722 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-MGWLKY-LatinModernMath-Regular-0)
|
||||||
|
%%Title: (TeX-MGWLKY-LatinModernMath-Regular-0 TeX MGWLKY-LatinModernMath-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (MGWLKY-LatinModernMath-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-MGWLKY-LatinModernMath-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
1 beginbfchar
|
||||||
|
<03F5> <0032>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
82 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /MGWLKY+LatinModernMath-Regular /DescendantFonts [ 99 0 R ] /ToUnicode 98 0 R >>
|
||||||
|
endobj
|
||||||
|
99 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /MGWLKY+LatinModernMath-Regular /FontDescriptor 96 0 R /W 95 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
100 0 obj
|
||||||
|
[ 600 [ 681 ] ]
|
||||||
|
endobj
|
||||||
|
102 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 743 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
101 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /DPSGTM+LatinModernMath-Regular /Flags 4 /FontBBox [ -1042 -3060 4082 3560 ] /Ascent 806 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 153 /XHeight 431 /FontFile3 102 0 R >>
|
||||||
|
endobj
|
||||||
|
103 0 obj
|
||||||
|
<< /Length 722 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-DPSGTM-LatinModernMath-Regular-0)
|
||||||
|
%%Title: (TeX-DPSGTM-LatinModernMath-Regular-0 TeX DPSGTM-LatinModernMath-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (DPSGTM-LatinModernMath-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-DPSGTM-LatinModernMath-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
1 beginbfchar
|
||||||
|
<0258> <0033>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
81 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /DPSGTM+LatinModernMath-Regular /DescendantFonts [ 104 0 R ] /ToUnicode 103 0 R >>
|
||||||
|
endobj
|
||||||
|
104 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /DPSGTM+LatinModernMath-Regular /FontDescriptor 101 0 R /W 100 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
105 0 obj
|
||||||
|
[ 12 [ 778 ] 19 [ 500 ] 30 [ 778 ] 1319 [ 572 490 ] 3077 [ 833 ] 3081 [ 1000 1000 ] ]
|
||||||
|
endobj
|
||||||
|
107 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 1511 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
106 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /NDJELI+LatinModernMath-Regular /Flags 4 /FontBBox [ -1042 -3060 4082 3560 ] /Ascent 806 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 107 0 R >>
|
||||||
|
endobj
|
||||||
|
108 0 obj
|
||||||
|
<< /Length 828 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-NDJELI-LatinModernMath-Regular-0)
|
||||||
|
%%Title: (TeX-NDJELI-LatinModernMath-Regular-0 TeX NDJELI-LatinModernMath-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (NDJELI-LatinModernMath-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-NDJELI-LatinModernMath-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
8 beginbfchar
|
||||||
|
<000C> <002B>
|
||||||
|
<0013> <0032>
|
||||||
|
<001E> <003D>
|
||||||
|
<0527> <D835DC65>
|
||||||
|
<0528> <D835DC66>
|
||||||
|
<0C05> <221A>
|
||||||
|
<0C09> <221A>
|
||||||
|
<0C0A> <221A>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
80 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /NDJELI+LatinModernMath-Regular /DescendantFonts [ 109 0 R ] /ToUnicode 108 0 R >>
|
||||||
|
endobj
|
||||||
|
109 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /NDJELI+LatinModernMath-Regular /FontDescriptor 106 0 R /W 105 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
84 0 obj
|
||||||
|
<< /Type /Pages /Count 1 /Kids [ 78 0 R ] >>
|
||||||
|
endobj
|
||||||
|
110 0 obj
|
||||||
|
<< /EmbeddedFiles 86 0 R >>
|
||||||
|
endobj
|
||||||
|
111 0 obj
|
||||||
|
<< /Type /Catalog /Pages 84 0 R /Names 110 0 R /MarkInfo 85 0 R/Lang (en)/Metadata 76 0 R/StructTreeRoot 5 0 R >>
|
||||||
|
endobj
|
||||||
|
112 0 obj
|
||||||
|
<< /Producer (LuaTeX)/Creator (TeX)/CreationDate (D:20160520090000Z)/ModDate (D:20160520090000Z) /Trapped /False >>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 113
|
||||||
|
0000000002 65535 f
|
||||||
|
0000017659 00000 n
|
||||||
|
0000000003 00000 f
|
||||||
|
0000000004 00000 f
|
||||||
|
0000000010 00000 f
|
||||||
|
0000025382 00000 n
|
||||||
|
0000017844 00000 n
|
||||||
|
0000018694 00000 n
|
||||||
|
0000020839 00000 n
|
||||||
|
0000019474 00000 n
|
||||||
|
0000000012 00000 f
|
||||||
|
0000019542 00000 n
|
||||||
|
0000000014 00000 f
|
||||||
|
0000019612 00000 n
|
||||||
|
0000000020 00000 f
|
||||||
|
0000020375 00000 n
|
||||||
|
0000019693 00000 n
|
||||||
|
0000020648 00000 n
|
||||||
|
0000020477 00000 n
|
||||||
|
0000020750 00000 n
|
||||||
|
0000000000 00000 f
|
||||||
|
0000020900 00000 n
|
||||||
|
0000000020 00000 n
|
||||||
|
0000000257 00000 n
|
||||||
|
0000000444 00000 n
|
||||||
|
0000000754 00000 n
|
||||||
|
0000000941 00000 n
|
||||||
|
0000001291 00000 n
|
||||||
|
0000001478 00000 n
|
||||||
|
0000001726 00000 n
|
||||||
|
0000021021 00000 n
|
||||||
|
0000021109 00000 n
|
||||||
|
0000021197 00000 n
|
||||||
|
0000021297 00000 n
|
||||||
|
0000021408 00000 n
|
||||||
|
0000001913 00000 n
|
||||||
|
0000002067 00000 n
|
||||||
|
0000021600 00000 n
|
||||||
|
0000021695 00000 n
|
||||||
|
0000021791 00000 n
|
||||||
|
0000021912 00000 n
|
||||||
|
0000022012 00000 n
|
||||||
|
0000022123 00000 n
|
||||||
|
0000002267 00000 n
|
||||||
|
0000002433 00000 n
|
||||||
|
0000022315 00000 n
|
||||||
|
0000022426 00000 n
|
||||||
|
0000022522 00000 n
|
||||||
|
0000022618 00000 n
|
||||||
|
0000022739 00000 n
|
||||||
|
0000002633 00000 n
|
||||||
|
0000022871 00000 n
|
||||||
|
0000022992 00000 n
|
||||||
|
0000023092 00000 n
|
||||||
|
0000023203 00000 n
|
||||||
|
0000002704 00000 n
|
||||||
|
0000002875 00000 n
|
||||||
|
0000023464 00000 n
|
||||||
|
0000023575 00000 n
|
||||||
|
0000023696 00000 n
|
||||||
|
0000003075 00000 n
|
||||||
|
0000023828 00000 n
|
||||||
|
0000023924 00000 n
|
||||||
|
0000024029 00000 n
|
||||||
|
0000024133 00000 n
|
||||||
|
0000024255 00000 n
|
||||||
|
0000024377 00000 n
|
||||||
|
0000024499 00000 n
|
||||||
|
0000024599 00000 n
|
||||||
|
0000024710 00000 n
|
||||||
|
0000003146 00000 n
|
||||||
|
0000003303 00000 n
|
||||||
|
0000024938 00000 n
|
||||||
|
0000025033 00000 n
|
||||||
|
0000025138 00000 n
|
||||||
|
0000025260 00000 n
|
||||||
|
0000003503 00000 n
|
||||||
|
0000017560 00000 n
|
||||||
|
0000017425 00000 n
|
||||||
|
0000015284 00000 n
|
||||||
|
0000034795 00000 n
|
||||||
|
0000031606 00000 n
|
||||||
|
0000029365 00000 n
|
||||||
|
0000027181 00000 n
|
||||||
|
0000035166 00000 n
|
||||||
|
0000017706 00000 n
|
||||||
|
0000017742 00000 n
|
||||||
|
0000018006 00000 n
|
||||||
|
0000018657 00000 n
|
||||||
|
0000019273 00000 n
|
||||||
|
0000025519 00000 n
|
||||||
|
0000026208 00000 n
|
||||||
|
0000025550 00000 n
|
||||||
|
0000026429 00000 n
|
||||||
|
0000027335 00000 n
|
||||||
|
0000027535 00000 n
|
||||||
|
0000028354 00000 n
|
||||||
|
0000027568 00000 n
|
||||||
|
0000028583 00000 n
|
||||||
|
0000029525 00000 n
|
||||||
|
0000029731 00000 n
|
||||||
|
0000030592 00000 n
|
||||||
|
0000029764 00000 n
|
||||||
|
0000030823 00000 n
|
||||||
|
0000031768 00000 n
|
||||||
|
0000031977 00000 n
|
||||||
|
0000033676 00000 n
|
||||||
|
0000032080 00000 n
|
||||||
|
0000033906 00000 n
|
||||||
|
0000034957 00000 n
|
||||||
|
0000035228 00000 n
|
||||||
|
0000035273 00000 n
|
||||||
|
0000035404 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 113 /Root 111 0 R /Info 112 0 R /ID [ <2350CAD05F8A7AF0AA4058486855344F> <2350CAD05F8A7AF0AA4058486855344F> ] >>
|
||||||
|
startxref
|
||||||
|
35537
|
||||||
|
%%EOF
|
47
testfiles-lua/test_struct.pvt
Normal file
47
testfiles-lua/test_struct.pvt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
\ExplSyntaxOn
|
||||||
|
\sys_gset_rand_seed:n{42}
|
||||||
|
\ExplSyntaxOff
|
||||||
|
\DocumentMetadata{
|
||||||
|
uncompress,
|
||||||
|
pdfversion = 2.0,
|
||||||
|
testphase = {phase-III,math,table},
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
\tagpdfsetup{math/mathml/structelem,attach-css=false}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
|
\[
|
||||||
|
\begin{pmatrix}
|
||||||
|
1 & 0 & 0 \\
|
||||||
|
0 & 1 & 0 \\
|
||||||
|
0 & 0 & 1
|
||||||
|
\end{pmatrix}
|
||||||
|
=
|
||||||
|
\begin{cases}
|
||||||
|
1 & \text{if $a=b$} \\
|
||||||
|
2 & \text{else}
|
||||||
|
\end{cases}
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
\sum_a\underline c\dot bc'
|
||||||
|
\]
|
||||||
|
|
||||||
|
\begin{align}
|
||||||
|
abc&=def & e^{\mathrm{i}\pi}&=-1\\
|
||||||
|
\Big(1+2&=3\Big)\\
|
||||||
|
5
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
|
||||||
|
Es gilt $\sin(x)-\sin(x+2\pi)=0$.
|
||||||
|
|
||||||
|
\end{document}
|
2058
testfiles-lua/test_struct.tpf
Normal file
2058
testfiles-lua/test_struct.tpf
Normal file
File diff suppressed because it is too large
Load Diff
35
testfiles-lua/test_structnum.pvt
Normal file
35
testfiles-lua/test_structnum.pvt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
\ExplSyntaxOn
|
||||||
|
\sys_gset_rand_seed:n{42}
|
||||||
|
\ExplSyntaxOff
|
||||||
|
\DocumentMetadata{
|
||||||
|
lang=en,
|
||||||
|
testphase={phase-III,math},
|
||||||
|
pdfversion=2.0,
|
||||||
|
pdfstandard=ua-2,
|
||||||
|
pdfstandard=a-4f,
|
||||||
|
uncompress
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
|
||||||
|
% suppress writing of luamml-mathml
|
||||||
|
\tagpdfsetup{math/mathml/luamml/write=false} %
|
||||||
|
|
||||||
|
% suppress mathml-AF reading
|
||||||
|
\tagpdfsetup{math/mathml/sources=} %
|
||||||
|
\tagpdfsetup{math/mathml/AF=false,attach-css=false}
|
||||||
|
\begin{document}
|
||||||
|
\ExplSyntaxOn
|
||||||
|
|
||||||
|
\luamml_structelem:
|
||||||
|
$a = b \quad
|
||||||
|
\tagstructbegin{tag=mtext,stash}\tagmcbegin{}
|
||||||
|
\luamml_annotate:en{nucleus=true,structnum=\tag_get:n{struct_num}}
|
||||||
|
{\mbox{some~text~with~\emph{structure}}}
|
||||||
|
\tagmcend\tagstructend
|
||||||
|
$
|
||||||
|
\ExplSyntaxOff
|
||||||
|
\end{document}
|
||||||
|
|
783
testfiles-lua/test_structnum.tpf
Normal file
783
testfiles-lua/test_structnum.tpf
Normal file
@ -0,0 +1,783 @@
|
|||||||
|
%PDF-2.0
|
||||||
|
%ÌÕÁÔÅØÐÄÆ
|
||||||
|
22 0 obj
|
||||||
|
<< /N 3 /Length 3268 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
23 0 obj
|
||||||
|
<< /Type /OutputIntent /S /GTS_PDFA1 /DestOutputProfile 22 0 R /OutputConditionIdentifier (IEC\040sRGB) /Info (IEC\04061966-2.1\040Default\040RGB\040colour\040space\040-\040sRGB) /RegistryName (http://www.iec.ch) >>
|
||||||
|
endobj
|
||||||
|
29 0 obj
|
||||||
|
<< /Subtype /application#2Fx-tex/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 192 >>
|
||||||
|
stream
|
||||||
|
$a=b\quad \tagstructbegin {tag=mtext,stash}\tagmcbegin {}\luamml_annotate:en {nucleus=true,structnum=\tag_get:n {struct_num}}{\mbox {some text with \emph {structure}}}\tagmcend \tagstructend $
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
30 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Source /Desc (TeX source) /F (tag-AFfile1.tex) /UF <FEFF007400610067002D0041004600660069006C00650031002E007400650078> /EF<</F 29 0 R/UF 29 0 R>> >>
|
||||||
|
endobj
|
||||||
|
36 0 obj
|
||||||
|
<< /O/NSO/NS 13 0 R/lspace(0.278em)/rspace(0.278em) >>
|
||||||
|
endobj
|
||||||
|
39 0 obj
|
||||||
|
<< /O/NSO/NS 13 0 R/width(9.963pt) >>
|
||||||
|
endobj
|
||||||
|
40 0 obj
|
||||||
|
<< /Type /Metadata /Subtype /XML /Length 16669 >>
|
||||||
|
stream
|
||||||
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
|
||||||
|
xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
|
||||||
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
||||||
|
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||||
|
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
|
||||||
|
xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/"
|
||||||
|
xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/"
|
||||||
|
xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"
|
||||||
|
xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/"
|
||||||
|
xmlns:prism="http://prismstandard.org/namespaces/basic/3.0/"
|
||||||
|
xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
|
||||||
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||||
|
xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
|
||||||
|
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
|
||||||
|
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
|
||||||
|
xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#"
|
||||||
|
xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#"
|
||||||
|
xmlns:pdfd="http://pdfa.org/declarations/">
|
||||||
|
<pdfaExtension:schemas>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>OriginalDocumentID</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>URI</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>The common identifier for all versions and renditions of a document.</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/A Identification Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfaid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>year</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Year of standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>rev</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Revision year of standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/UA Universal Accessibility Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.aiim.org/pdfua/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>part</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Part of ISO 14289 standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>rev</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Revision of ISO 14289 standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfxid</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://www.npes.org/pdfx/ns/id/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PRISM Basic Metadata</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>prism</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://prismstandard.org/namespaces/basic/3.0/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>complianceProfile</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>PRISM specification compliance profile to which this document adheres</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>publicationName</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication name</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>aggregationType</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication type</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>bookEdition</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Edition of the book in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>volume</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication volume number</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>number</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Publication issue number within a volume</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>pageRange</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Page range for the document within the print version of its publication</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>issn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISSN for the printed publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>eIssn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISSN for the electronic publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>isbn</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>ISBN for the publication in which the document was published</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>doi</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Digital Object Identifier for the document</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>url</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>URL</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>URL at which the document can be found</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>byteCount</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Approximate file size in octets</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>pageCount</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Integer</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>internal</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Number of pages in the print version of the document</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>subtitle</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>Document's subtitle</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaSchema:schema>PDF Declarations Schema</pdfaSchema:schema>
|
||||||
|
<pdfaSchema:prefix>pdfd</pdfaSchema:prefix>
|
||||||
|
<pdfaSchema:namespaceURI>http://pdfa.org/declarations/</pdfaSchema:namespaceURI>
|
||||||
|
<pdfaSchema:property>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaProperty:name>declarations</pdfaProperty:name>
|
||||||
|
<pdfaProperty:valueType>Bag declaration</pdfaProperty:valueType>
|
||||||
|
<pdfaProperty:category>external</pdfaProperty:category>
|
||||||
|
<pdfaProperty:description>An unordered array of PDF Declaration entries, where each PDF Declaration representing a statement of conformance with an identified external standard or profile, along with optional information identifying the nature of the claim.</pdfaProperty:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:property>
|
||||||
|
<pdfaSchema:valueType>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaType:type>claim</pdfaType:type>
|
||||||
|
<pdfaType:namespaceURI>http://pdfa.org/declarations/</pdfaType:namespaceURI>
|
||||||
|
<pdfaType:prefix>pdfd</pdfaType:prefix>
|
||||||
|
<pdfaType:description>A structure describing properties of an individualclaim.</pdfaType:description>
|
||||||
|
<pdfaType:field>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>claimReport</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Text</pdfaField:valueType>
|
||||||
|
<pdfaField:description>A URL to a report containing details of the specific conformance claim.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>claimCredentials</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Text</pdfaField:valueType>
|
||||||
|
<pdfaField:description>The claimant's credentials.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>claimDate</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Text</pdfaField:valueType>
|
||||||
|
<pdfaField:description>A date identifying when the claim was made.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>claimBy</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Text</pdfaField:valueType>
|
||||||
|
<pdfaField:description>The name of the organization and/or individual and/or software making the claim.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaType:field>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaType:type>declaration</pdfaType:type>
|
||||||
|
<pdfaType:namespaceURI>http://pdfa.org/declarations/</pdfaType:namespaceURI>
|
||||||
|
<pdfaType:prefix>pdfd</pdfaType:prefix>
|
||||||
|
<pdfaType:description>A structure describing a single PDF Declaration asserting conformance with an externally-identified standard or profile.</pdfaType:description>
|
||||||
|
<pdfaType:field>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>conformsTo</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Text</pdfaField:valueType>
|
||||||
|
<pdfaField:description>A property containing a URI specifying the standard or profile by the PDF Declaration. This property is intended to mirror the Dublin Core property dc:conformsTo.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfaField:name>claimData</pdfaField:name>
|
||||||
|
<pdfaField:valueType>Bag claim</pdfaField:valueType>
|
||||||
|
<pdfaField:description>An unordered array of claim data, where each claim identifies the nature of the claim.</pdfaField:description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaType:field>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</pdfaSchema:valueType>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</pdfaExtension:schemas>
|
||||||
|
<pdf:Producer>luahbtex-NN.NN.NN</pdf:Producer>
|
||||||
|
<pdf:PDFVersion>2.0</pdf:PDFVersion>
|
||||||
|
<pdfaid:part>4</pdfaid:part>
|
||||||
|
<pdfaid:conformance>F</pdfaid:conformance>
|
||||||
|
<pdfaid:rev>2020</pdfaid:rev>
|
||||||
|
<pdfuaid:part>2</pdfuaid:part>
|
||||||
|
<pdfuaid:rev>2024</pdfuaid:rev>
|
||||||
|
<pdfd:declarations>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfd:conformsTo>http://pdfa.org/declarations/wtpdf#accessibility1.0</pdfd:conformsTo>
|
||||||
|
<pdfd:claimData>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfd:claimBy>LaTeX Project</pdfd:claimBy>
|
||||||
|
<pdfd:claimDate>2016-05-20</pdfd:claimDate>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</pdfd:claimData>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfd:conformsTo>http://pdfa.org/declarations/wtpdf#reuse1.0</pdfd:conformsTo>
|
||||||
|
<pdfd:claimData>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<pdfd:claimBy>LaTeX Project</pdfd:claimBy>
|
||||||
|
<pdfd:claimDate>2016-05-20</pdfd:claimDate>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</pdfd:claimData>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</pdfd:declarations>
|
||||||
|
<dc:type>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>Text</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:type>
|
||||||
|
<dc:language>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>en</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:language>
|
||||||
|
<dc:date>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>2016-05-20T09:00:00Z</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</dc:date>
|
||||||
|
<dc:format>application/pdf</dc:format>
|
||||||
|
<dc:source>test_structnum.tex</dc:source>
|
||||||
|
<xmp:CreatorTool>LaTeX</xmp:CreatorTool>
|
||||||
|
<xmp:CreateDate>2016-05-20T09:00:00Z</xmp:CreateDate>
|
||||||
|
<xmp:ModifyDate>2016-05-20T09:00:00Z</xmp:ModifyDate>
|
||||||
|
<xmp:MetadataDate>2016-05-20T09:00:00Z</xmp:MetadataDate>
|
||||||
|
<xmpMM:DocumentID>uuid:2b6fecb9-b74a-4265-883d-138c87e7152f</xmpMM:DocumentID>
|
||||||
|
<xmpMM:InstanceID>uuid:0a57c455-157a-4141-8c19-6237d832fc80</xmpMM:InstanceID>
|
||||||
|
<prism:complianceProfile>three</prism:complianceProfile>
|
||||||
|
<prism:pageCount>1</prism:pageCount>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
<?xpacket end="w"?>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
43 0 obj
|
||||||
|
<< /Length 653 >>
|
||||||
|
stream
|
||||||
|
/opacity1 gs
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 0>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 148.712 657.235 Tm [<0510>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mo<</MCID 1>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 156.75 657.235 Tm [<001E>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mi<</MCID 2>> BDC
|
||||||
|
BT
|
||||||
|
/F20 9.96264 Tf
|
||||||
|
1 0 0 1 167.268 657.235 Tm [<0511>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/mtext<</MCID 3>> BDC
|
||||||
|
BT
|
||||||
|
/F15 9.96264 Tf
|
||||||
|
1 0 0 1 181.505 657.235 Tm [<00620051004B0032006700690032007400690067007200420069003F0067>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Em<</MCID 4>> BDC
|
||||||
|
BT
|
||||||
|
/F32 9.96264 Tf
|
||||||
|
1 0 0 1 249.898 657.235 Tm [<006200690060006D002B0069006D0060>51<0032>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
BT
|
||||||
|
/F15 9.96264 Tf
|
||||||
|
1 0 0 1 303.133 89.365 Tm [<0052>]TJ
|
||||||
|
ET
|
||||||
|
EMC
|
||||||
|
/Artifact BMC
|
||||||
|
EMC
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
42 0 obj
|
||||||
|
<< /Type /Page /Contents 43 0 R /Resources 41 0 R /MediaBox [ 0 0 612 792 ] /StructParents 0/Tabs /S /Parent 47 0 R >>
|
||||||
|
endobj
|
||||||
|
41 0 obj
|
||||||
|
<< /ExtGState 1 0 R /Font << /F20 44 0 R /F15 45 0 R /F32 46 0 R >> >>
|
||||||
|
endobj
|
||||||
|
1 0 obj
|
||||||
|
<< /opacity1 <</ca 1/CA 1>> >>
|
||||||
|
endobj
|
||||||
|
48 0 obj
|
||||||
|
<< /Marked true >>
|
||||||
|
endobj
|
||||||
|
49 0 obj
|
||||||
|
[ 23 0 R ]
|
||||||
|
endobj
|
||||||
|
50 0 obj
|
||||||
|
<< /Subtype /text#2Fplain/Type /EmbeddedFile /Params<</ModDate (D:20160520) >> /Length 115 >>
|
||||||
|
stream
|
||||||
|
The document was declared to be of type PDF/A-4f but hasn't any attachments. LaTeX therefore added this dummy file.
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
51 0 obj
|
||||||
|
<< /Type /Filespec /AFRelationship /Unspecified /Desc (note about PDF/A-4F) /F (pdf-A4f.txt) /UF <FEFF007000640066002D004100340066002E007400780074> /EF<</F 50 0 R/UF 50 0 R>> >>
|
||||||
|
endobj
|
||||||
|
52 0 obj
|
||||||
|
<< /Names[(pdf-A4f) 51 0 R] >>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<< /Nums [0 [ 34 0 R 35 0 R 37 0 R 31 0 R 32 0 R]
|
||||||
|
] >>
|
||||||
|
endobj
|
||||||
|
53 0 obj
|
||||||
|
<< /Limits [(ID.002) (ID.014)]/Names [(ID.002) 21 0 R (ID.003) 24 0 R (ID.004) 25 0 R (ID.005) 26 0 R (ID.006) 27 0 R (ID.007) 28 0 R (ID.008) 31 0 R (ID.009) 32 0 R (ID.010) 33 0 R (ID.011) 34 0 R (ID.012) 35 0 R (ID.013) 37 0 R (ID.014) 38 0 R ] >>
|
||||||
|
endobj
|
||||||
|
54 0 obj
|
||||||
|
<< /Kids [53 0 R] >>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<< /Artifact /NonStruct /DocumentFragment /Art /Aside /Note /H7 /H6 /H8 /H6 /H9 /H6 /H10 /H6 /Title /P /FENote /Note /Sub /Span /Em /Span /Strong /Span /title /P /part /P /section /H1 /subsection /H2 /subsubsection /H3 /paragraph /H4 /subparagraph /H5 /list /L /itemize /L /enumerate /L /description /L /quote /BlockQuote /quotation /BlockQuote /verbatim /P /item /LI /itemlabel /Lbl /itembody /LBody /footnote /Note /footnotemark /Lbl /footnotelabel /Lbl /text-unit /Part /text /P /theorem-like /Sect /codeline /Span /float /Note /figures /Sect /tables /Sect >>
|
||||||
|
endobj
|
||||||
|
55 0 obj
|
||||||
|
<< /justify <</O/Layout/TextAlign/Justify>>
|
||||||
|
/inline <</O/Layout/Placement/Inline>>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://iso.org/pdf/ssn) >>
|
||||||
|
endobj
|
||||||
|
11 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://iso.org/pdf2/ssn) >>
|
||||||
|
endobj
|
||||||
|
13 0 obj
|
||||||
|
<< /Type /Namespace /NS (http://www.w3.org/1998/Math/MathML) >>
|
||||||
|
endobj
|
||||||
|
16 0 obj
|
||||||
|
<< /title [/Title 11 0 R] /part [/Title 11 0 R] /section [/H1 11 0 R] /subsection [/H2 11 0 R] /subsubsection [/H3 11 0 R] /paragraph [/H4 11 0 R] /subparagraph [/H5 11 0 R] /list [/L 11 0 R] /itemize [/L 11 0 R] /enumerate [/L 11 0 R] /description [/L 11 0 R] /quote [/BlockQuote 9 0 R] /quotation [/BlockQuote 9 0 R] /verbatim [/P 11 0 R] /item [/LI 11 0 R] /itemlabel [/Lbl 11 0 R] /itembody [/LBody 11 0 R] /footnote [/FENote 11 0 R] /footnotemark [/Lbl 11 0 R] /footnotelabel [/Lbl 11 0 R] /text-unit [/Part 11 0 R] /text [/P 11 0 R] /theorem-like [/Sect 11 0 R] /codeline [/Sub 11 0 R] /float [/Aside 11 0 R] /figures [/Sect 11 0 R] /tables [/Sect 11 0 R] >>
|
||||||
|
endobj
|
||||||
|
15 0 obj
|
||||||
|
<< /Type /Namespace /NS (https://www.latex-project.org/ns/dflt) /RoleMapNS 16 0 R >>
|
||||||
|
endobj
|
||||||
|
18 0 obj
|
||||||
|
<< /chapter [/H1 11 0 R] /section [/H2 11 0 R] /subsection [/H3 11 0 R] /subsubsection [/H4 11 0 R] /paragraph [/H5 11 0 R] /subparagraph [/H6 11 0 R] >>
|
||||||
|
endobj
|
||||||
|
17 0 obj
|
||||||
|
<< /Type /Namespace /NS (https://www.latex-project.org/ns/book) /RoleMapNS 18 0 R >>
|
||||||
|
endobj
|
||||||
|
19 0 obj
|
||||||
|
<< /Type /Namespace /NS (data:,C9B55C18-275C-494E-C10F-E4B83CD03F23) >>
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
[ 9 0 R 11 0 R 13 0 R 15 0 R 17 0 R 19 0 R ]
|
||||||
|
endobj
|
||||||
|
21 0 obj
|
||||||
|
<< /Type /StructElem /S /Document /NS 11 0 R /P 5 0 R /K 26 0 R /ID (ID.002) >>
|
||||||
|
endobj
|
||||||
|
24 0 obj
|
||||||
|
<< /Type /StructElem /S /Artifact /NS 15 0 R /P 5 0 R /ID (ID.003) >>
|
||||||
|
endobj
|
||||||
|
25 0 obj
|
||||||
|
<< /Type /StructElem /S /Artifact /NS 15 0 R /P 5 0 R /ID (ID.004) >>
|
||||||
|
endobj
|
||||||
|
26 0 obj
|
||||||
|
<< /Type /StructElem /S /text-unit /NS 15 0 R /P 21 0 R /K 27 0 R /ID (ID.005) >>
|
||||||
|
endobj
|
||||||
|
27 0 obj
|
||||||
|
<< /Type /StructElem /C /justify /S /text /NS 15 0 R /P 26 0 R /K [ 28 0 R ] /ID (ID.006) >>
|
||||||
|
endobj
|
||||||
|
28 0 obj
|
||||||
|
<< /Type /StructElem /C /inline /AF [30 0 R] /T <FEFF006D006100740068> /S /Formula /NS 11 0 R /P 27 0 R /K [ 33 0 R] /ID (ID.007) >>
|
||||||
|
endobj
|
||||||
|
31 0 obj
|
||||||
|
<< /Type /StructElem /S /mtext /NS 13 0 R /P 33 0 R /K [<</Type /MCR /Pg 42 0 R /MCID 3>> 32 0 R ] /ID (ID.008) >>
|
||||||
|
endobj
|
||||||
|
32 0 obj
|
||||||
|
<< /Type /StructElem /S /Em /NS 11 0 R /P 31 0 R /K <</Type /MCR /Pg 42 0 R /MCID 4>> /ID (ID.009) >>
|
||||||
|
endobj
|
||||||
|
33 0 obj
|
||||||
|
<< /Type /StructElem /S /math /NS 13 0 R /P 28 0 R /K [34 0 R 35 0 R 37 0 R 38 0 R 31 0 R] /ID (ID.010) >>
|
||||||
|
endobj
|
||||||
|
34 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 33 0 R /K <</Type /MCR /Pg 42 0 R /MCID 0>> /ID (ID.011) >>
|
||||||
|
endobj
|
||||||
|
35 0 obj
|
||||||
|
<< /Type /StructElem /A 36 0 R /S /mo /NS 13 0 R /P 33 0 R /K <</Type /MCR /Pg 42 0 R /MCID 1>> /ID (ID.012) >>
|
||||||
|
endobj
|
||||||
|
37 0 obj
|
||||||
|
<< /Type /StructElem /S /mi /NS 13 0 R /P 33 0 R /K <</Type /MCR /Pg 42 0 R /MCID 2>> /ID (ID.013) >>
|
||||||
|
endobj
|
||||||
|
38 0 obj
|
||||||
|
<< /Type /StructElem /A 39 0 R /S /mspace /NS 13 0 R /P 33 0 R /ID (ID.014) >>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Type /StructTreeRoot /Namespaces 8 0 R /IDTree 54 0 R /ClassMap 55 0 R /ParentTree 6 0 R /RoleMap 7 0 R /K 21 0 R >>
|
||||||
|
endobj
|
||||||
|
56 0 obj
|
||||||
|
[ 43 [ 460 ] 50 [ 460 ] 96 [ 422 ] 98 [ 409 ] 105 [ 332 ] 109 [ 537 ] ]
|
||||||
|
endobj
|
||||||
|
58 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 1274 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
57 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /ADNFRA+LMRoman10-Italic /Flags 4 /FontBBox [ -458 -290 1386 1125 ] /Ascent 1125 /CapHeight 683 /Descent -290 /ItalicAngle -15 /StemV 102 /XHeight 431 /FontFile3 58 0 R >>
|
||||||
|
endobj
|
||||||
|
59 0 obj
|
||||||
|
<< /Length 757 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-ADNFRA-LMRoman10-Italic-0)
|
||||||
|
%%Title: (TeX-ADNFRA-LMRoman10-Italic-0 TeX ADNFRA-LMRoman10-Italic 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (ADNFRA-LMRoman10-Italic)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-ADNFRA-LMRoman10-Italic def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
6 beginbfchar
|
||||||
|
<002B> <0063>
|
||||||
|
<0032> <0065>
|
||||||
|
<0060> <0072>
|
||||||
|
<0062> <0073>
|
||||||
|
<0069> <0074>
|
||||||
|
<006D> <0075>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
46 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /ADNFRA+LMRoman10-Italic /DescendantFonts [ 60 0 R ] /ToUnicode 59 0 R >>
|
||||||
|
endobj
|
||||||
|
60 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /ADNFRA+LMRoman10-Italic /FontDescriptor 57 0 R /W 56 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
61 0 obj
|
||||||
|
[ 50 [ 444 ] 63 [ 556 ] 66 [ 278 ] 75 [ 833 ] 81 [ 500 500 ] 98 [ 394 ] 103 [ 333 ] 105 [ 389 ] 114 [ 722 ] 116 [ 528 ] ]
|
||||||
|
endobj
|
||||||
|
63 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 1812 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
62 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /GZYIXU+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 63 0 R >>
|
||||||
|
endobj
|
||||||
|
64 0 obj
|
||||||
|
<< /Length 833 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-GZYIXU-LMRoman10-Regular-0)
|
||||||
|
%%Title: (TeX-GZYIXU-LMRoman10-Regular-0 TeX GZYIXU-LMRoman10-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (GZYIXU-LMRoman10-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-GZYIXU-LMRoman10-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
11 beginbfchar
|
||||||
|
<0032> <0065>
|
||||||
|
<003F> <0068>
|
||||||
|
<0042> <0069>
|
||||||
|
<004B> <006D>
|
||||||
|
<0051> <006F>
|
||||||
|
<0052> <0031>
|
||||||
|
<0062> <0073>
|
||||||
|
<0067> <0020>
|
||||||
|
<0069> <0074>
|
||||||
|
<0072> <0077>
|
||||||
|
<0074> <0078>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
45 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /GZYIXU+LMRoman10-Regular /DescendantFonts [ 65 0 R ] /ToUnicode 64 0 R >>
|
||||||
|
endobj
|
||||||
|
65 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /GZYIXU+LMRoman10-Regular /FontDescriptor 62 0 R /W 61 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
66 0 obj
|
||||||
|
[ 30 [ 778 ] 1296 [ 529 429 ] ]
|
||||||
|
endobj
|
||||||
|
68 0 obj
|
||||||
|
<< /Subtype /CIDFontType0C /Length 984 >>
|
||||||
|
[BINARY STREAM]
|
||||||
|
endobj
|
||||||
|
67 0 obj
|
||||||
|
<< /Type /FontDescriptor /FontName /NFEDYW+LatinModernMath-Regular /Flags 4 /FontBBox [ -1042 -3060 4082 3560 ] /Ascent 806 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 68 0 R >>
|
||||||
|
endobj
|
||||||
|
69 0 obj
|
||||||
|
<< /Length 758 >>
|
||||||
|
stream
|
||||||
|
%!PS-Adobe-3.0 Resource-CMap
|
||||||
|
%%DocumentNeededResources: ProcSet (CIDInit)
|
||||||
|
%%IncludeResource: ProcSet (CIDInit)
|
||||||
|
%%BeginResource: CMap (TeX-NFEDYW-LatinModernMath-Regular-0)
|
||||||
|
%%Title: (TeX-NFEDYW-LatinModernMath-Regular-0 TeX NFEDYW-LatinModernMath-Regular 0)
|
||||||
|
%%Version: 1.000
|
||||||
|
%%EndComments
|
||||||
|
/CIDInit /ProcSet findresource begin
|
||||||
|
12 dict begin
|
||||||
|
begincmap
|
||||||
|
/CIDSystemInfo
|
||||||
|
<< /Registry (TeX)
|
||||||
|
/Ordering (NFEDYW-LatinModernMath-Regular)
|
||||||
|
/Supplement 0
|
||||||
|
>> def
|
||||||
|
/CMapName /TeX-Identity-NFEDYW-LatinModernMath-Regular def
|
||||||
|
/CMapType 2 def
|
||||||
|
1 begincodespacerange
|
||||||
|
<0000> <FFFF>
|
||||||
|
endcodespacerange
|
||||||
|
0 beginbfrange
|
||||||
|
endbfrange
|
||||||
|
3 beginbfchar
|
||||||
|
<001E> <003D>
|
||||||
|
<0510> <D835DC4E>
|
||||||
|
<0511> <D835DC4F>
|
||||||
|
endbfchar
|
||||||
|
endcmap
|
||||||
|
CMapName currentdict /CMap defineresource pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%EndResource
|
||||||
|
%%EOF
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
44 0 obj
|
||||||
|
<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /NFEDYW+LatinModernMath-Regular /DescendantFonts [ 70 0 R ] /ToUnicode 69 0 R >>
|
||||||
|
endobj
|
||||||
|
70 0 obj
|
||||||
|
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /NFEDYW+LatinModernMath-Regular /FontDescriptor 67 0 R /W 66 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
|
||||||
|
endobj
|
||||||
|
47 0 obj
|
||||||
|
<< /Type /Pages /Count 1 /Kids [ 42 0 R ] >>
|
||||||
|
endobj
|
||||||
|
71 0 obj
|
||||||
|
<< /EmbeddedFiles 52 0 R >>
|
||||||
|
endobj
|
||||||
|
72 0 obj
|
||||||
|
<< /Type /Catalog /Pages 47 0 R /Names 71 0 R /MarkInfo 48 0 R/OutputIntents 49 0 R/Lang (en)/Metadata 40 0 R/StructTreeRoot 5 0 R >>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 73
|
||||||
|
0000000002 65535 f
|
||||||
|
0000021940 00000 n
|
||||||
|
0000000003 00000 f
|
||||||
|
0000000004 00000 f
|
||||||
|
0000000010 00000 f
|
||||||
|
0000026513 00000 n
|
||||||
|
0000022542 00000 n
|
||||||
|
0000022917 00000 n
|
||||||
|
0000024964 00000 n
|
||||||
|
0000023599 00000 n
|
||||||
|
0000000012 00000 f
|
||||||
|
0000023667 00000 n
|
||||||
|
0000000014 00000 f
|
||||||
|
0000023737 00000 n
|
||||||
|
0000000020 00000 f
|
||||||
|
0000024500 00000 n
|
||||||
|
0000023818 00000 n
|
||||||
|
0000024773 00000 n
|
||||||
|
0000024602 00000 n
|
||||||
|
0000024875 00000 n
|
||||||
|
0000000000 00000 f
|
||||||
|
0000025025 00000 n
|
||||||
|
0000000020 00000 n
|
||||||
|
0000003353 00000 n
|
||||||
|
0000025123 00000 n
|
||||||
|
0000025211 00000 n
|
||||||
|
0000025299 00000 n
|
||||||
|
0000025399 00000 n
|
||||||
|
0000025510 00000 n
|
||||||
|
0000003586 00000 n
|
||||||
|
0000003921 00000 n
|
||||||
|
0000025661 00000 n
|
||||||
|
0000025795 00000 n
|
||||||
|
0000025916 00000 n
|
||||||
|
0000026041 00000 n
|
||||||
|
0000026162 00000 n
|
||||||
|
0000004121 00000 n
|
||||||
|
0000026294 00000 n
|
||||||
|
0000026415 00000 n
|
||||||
|
0000004192 00000 n
|
||||||
|
0000004246 00000 n
|
||||||
|
0000021853 00000 n
|
||||||
|
0000021718 00000 n
|
||||||
|
0000021005 00000 n
|
||||||
|
0000035152 00000 n
|
||||||
|
0000032636 00000 n
|
||||||
|
0000029136 00000 n
|
||||||
|
0000035518 00000 n
|
||||||
|
0000021987 00000 n
|
||||||
|
0000022023 00000 n
|
||||||
|
0000022050 00000 n
|
||||||
|
0000022301 00000 n
|
||||||
|
0000022495 00000 n
|
||||||
|
0000022613 00000 n
|
||||||
|
0000022880 00000 n
|
||||||
|
0000023496 00000 n
|
||||||
|
0000026650 00000 n
|
||||||
|
0000028096 00000 n
|
||||||
|
0000026738 00000 n
|
||||||
|
0000028319 00000 n
|
||||||
|
0000029289 00000 n
|
||||||
|
0000029488 00000 n
|
||||||
|
0000031522 00000 n
|
||||||
|
0000029626 00000 n
|
||||||
|
0000031743 00000 n
|
||||||
|
0000032790 00000 n
|
||||||
|
0000032990 00000 n
|
||||||
|
0000034106 00000 n
|
||||||
|
0000033038 00000 n
|
||||||
|
0000034334 00000 n
|
||||||
|
0000035312 00000 n
|
||||||
|
0000035580 00000 n
|
||||||
|
0000035624 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 73 /Root 72 0 R /ID [ <2350CAD05F8A7AF0AA4058486855344F> <2350CAD05F8A7AF0AA4058486855344F> ] >>
|
||||||
|
startxref
|
||||||
|
35774
|
||||||
|
%%EOF
|
196
testfiles-lua/test_xml.mlr
Normal file
196
testfiles-lua/test_xml.mlr
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">(</mo>
|
||||||
|
<mspace width="-4.981pt" />
|
||||||
|
<mpadded lspace="+4.981pt" width="+9.963pt">
|
||||||
|
<mtable>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>0</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
</mtable>
|
||||||
|
</mpadded>
|
||||||
|
<mspace width="-4.981pt" />
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">)</mo>
|
||||||
|
</mrow>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mrow>
|
||||||
|
<mo fence="true" lspace="0" rspace="0" symmetric="true">{</mo>
|
||||||
|
<mpadded lspace="+4.981pt" width="+9.963pt">
|
||||||
|
<mtable>
|
||||||
|
<mtr>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mtext>if 
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
</math></mtext>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mn>2</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd columnalign="left">
|
||||||
|
<mtext>else</mtext>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
</mtable>
|
||||||
|
</mpadded>
|
||||||
|
<mspace width="1.196pt" />
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo lspace="0" rspace="0.222em">−</mo>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">±</mo>
|
||||||
|
<msqrt>
|
||||||
|
<mrow>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mn>2</mn>
|
||||||
|
</msup>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">−</mo>
|
||||||
|
<mn>4</mn>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
</mrow>
|
||||||
|
</msqrt>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
<mo lspace="0" rspace="0">.</mo>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<munder>
|
||||||
|
<mo lspace="0" movablelimits="true" rspace="0.167em">∑</mo>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
</munder>
|
||||||
|
<munder>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
<mo>_</mo>
|
||||||
|
</munder>
|
||||||
|
<mover>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mo stretchy="true">.</mo>
|
||||||
|
</mover>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
<mi mathvariant="normal">′</mi>
|
||||||
|
</msup>
|
||||||
|
</math>
|
||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mtable class="align" columnalign="left right left right left" columnspacing="0 0 .8em 0" displaystyle="true" intent=":system-of-equations">
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mi>𝑎</mi>
|
||||||
|
<mi>𝑏</mi>
|
||||||
|
<mi>𝑐</mi>
|
||||||
|
</mtd>
|
||||||
|
<mtd intent=":pause-medium">
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mi>𝑑</mi>
|
||||||
|
<mi>𝑒</mi>
|
||||||
|
<mi>𝑓</mi>
|
||||||
|
</mtd>
|
||||||
|
<mtd>
|
||||||
|
<msup>
|
||||||
|
<mi>𝑒</mi>
|
||||||
|
<mrow>
|
||||||
|
<mi mathvariant="normal">i</mi>
|
||||||
|
<mi>𝜋</mi>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mtd>
|
||||||
|
<mtd intent=":pause-medium">
|
||||||
|
<mo lspace="0.278em" rspace="0">=</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0">−</mo>
|
||||||
|
<mn>1</mn>
|
||||||
|
</mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mo fence="true" lspace="0" maxsize="17.861pt" minsize="17.861pt" rspace="0" symmetric="true">(</mo>
|
||||||
|
<mn>1</mn>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">+</mo>
|
||||||
|
<mn>2</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd intent=":pause-medium">
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mn>3</mn>
|
||||||
|
<mo fence="true" lspace="0" maxsize="17.861pt" minsize="17.861pt" rspace="0" symmetric="true">)</mo>
|
||||||
|
</mtd>
|
||||||
|
<mtd></mtd>
|
||||||
|
<mtd intent=":pause-medium"></mtd>
|
||||||
|
</mtr>
|
||||||
|
<mtr>
|
||||||
|
<mtd>
|
||||||
|
<mn>5</mn>
|
||||||
|
</mtd>
|
||||||
|
<mtd intent=":pause-medium"></mtd>
|
||||||
|
<mtd></mtd>
|
||||||
|
<mtd intent=":pause-medium"></mtd>
|
||||||
|
</mtr>
|
||||||
|
</mtable>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi mathvariant="normal">sin</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">−</mo>
|
||||||
|
<mi mathvariant="normal">sin</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">+</mo>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mi>𝜋</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mn>0</mn>
|
||||||
|
</math>
|
48
testfiles-lua/test_xml.mlt
Normal file
48
testfiles-lua/test_xml.mlt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
\DocumentMetadata{
|
||||||
|
uncompress,
|
||||||
|
pdfversion = 2.0,
|
||||||
|
testphase = {phase-III,table,math},
|
||||||
|
}
|
||||||
|
\input{regression-test}
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{unicode-math}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\ExplSyntaxOn
|
||||||
|
\luamml_set_filename:n {
|
||||||
|
\jobname .mml
|
||||||
|
}
|
||||||
|
\luamml_process:
|
||||||
|
\luamml_begin_single_file:
|
||||||
|
\ExplSyntaxOff
|
||||||
|
|
||||||
|
\[
|
||||||
|
\begin{pmatrix}
|
||||||
|
1 & 0 & 0 \\
|
||||||
|
0 & 1 & 0 \\
|
||||||
|
0 & 0 & 1
|
||||||
|
\end{pmatrix}
|
||||||
|
=
|
||||||
|
\begin{cases}
|
||||||
|
1 & \text{if $a=b$}\\
|
||||||
|
2 & \text{else}
|
||||||
|
\end{cases}
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
||||||
|
\]
|
||||||
|
|
||||||
|
\[
|
||||||
|
\sum_a\underline c\dot bc'
|
||||||
|
\]
|
||||||
|
|
||||||
|
\begin{align}
|
||||||
|
abc&=def & e^{\mathrm{i}\pi}&=-1\\
|
||||||
|
\Big(1+2&=3\Big)\\
|
||||||
|
5
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
Es gilt $\sin(x)-\sin(x+2\pi)=0$.
|
||||||
|
|
||||||
|
\end{document}
|
51
testfiles-pdf/test.mlr
Normal file
51
testfiles-pdf/test.mlr
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mi mathvariant="normal">∅</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0">⊧</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑝</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em" stretchy="false">⇒</mo>
|
||||||
|
<mi>𝑞</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">⇒</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑞</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em" stretchy="false">⇒</mo>
|
||||||
|
<mi>𝑟</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">⇒</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑝</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">⇒</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑞</mi>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em" stretchy="false">⇒</mo>
|
||||||
|
<mi>𝑟</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
</math>
|
||||||
|
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mi mathvariant="normal">s</mi>
|
||||||
|
<mi mathvariant="normal">i</mi>
|
||||||
|
<mi mathvariant="normal">n</mi>
|
||||||
|
</mrow>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">−</mo>
|
||||||
|
<mrow>
|
||||||
|
<mi mathvariant="normal">s</mi>
|
||||||
|
<mi mathvariant="normal">i</mi>
|
||||||
|
<mi mathvariant="normal">n</mi>
|
||||||
|
</mrow>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">(</mo>
|
||||||
|
<mi>𝑥</mi>
|
||||||
|
<mo lspace="0.222em" rspace="0.222em">+</mo>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mi>𝜋</mi>
|
||||||
|
<mo lspace="0" rspace="0" stretchy="false">)</mo>
|
||||||
|
<mo lspace="0.278em" rspace="0.278em">=</mo>
|
||||||
|
<mn>0</mn>
|
||||||
|
</math>
|
20
testfiles-pdf/test.mlt
Normal file
20
testfiles-pdf/test.mlt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
\documentclass{article}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{luamml-demo}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\[
|
||||||
|
\emptyset\models((p\Rightarrow q)\Rightarrow(q\Rightarrow r))\Rightarrow (p\Rightarrow (q\Rightarrow r))
|
||||||
|
\WriteoutFormula
|
||||||
|
\]
|
||||||
|
|
||||||
|
%\begin{align}
|
||||||
|
% abc&=def & e^{\mathrm{i}\pi}&=-1\\
|
||||||
|
% \Big(1+2&=3\Big)\\
|
||||||
|
% &4\\
|
||||||
|
% 5
|
||||||
|
%\end{align}
|
||||||
|
|
||||||
|
Es gilt $\sin(x)-\sin(x+2\pi)=0\WriteoutFormula$.
|
||||||
|
\end{document}
|
||||||
|
|
218
testfiles-pdf/test_pdf.txr
Normal file
218
testfiles-pdf/test_pdf.txr
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
LUAMML_INSTRUCTION:REGISTER_MAPPING:2:oms
|
||||||
|
LUAMML_INSTRUCTION:REGISTER_MAPPING:1:oml
|
||||||
|
LUAMML_INSTRUCTION:REGISTER_MAPPING:3:omx
|
||||||
|
LUAMML_MARK:1:count=3,nucleus=true,core={[0]='mi','\u{22a7}'},
|
||||||
|
LUAMML_MARK_END
|
||||||
|
LUAMML_FORMULA_BEGIN:1:3:mrow:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### display math mode entered at line 6
|
||||||
|
\mathord
|
||||||
|
.\fam2 ;
|
||||||
|
\write3{LUAMML_MARK_REF:1:}
|
||||||
|
\mathrel
|
||||||
|
.\fam2 j
|
||||||
|
\mathrel
|
||||||
|
.\mkern-3.0mu
|
||||||
|
\mathrel
|
||||||
|
.\fam0 =
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 p
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathord
|
||||||
|
.\fam1 q
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 q
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathord
|
||||||
|
.\fam1 r
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 p
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 q
|
||||||
|
\mathrel
|
||||||
|
.\fam2 )
|
||||||
|
\mathord
|
||||||
|
.\fam1 r
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
|
||||||
|
### vertical mode entered at line 0
|
||||||
|
### current page:
|
||||||
|
\write-{}
|
||||||
|
\glue(\topskip) 10.0
|
||||||
|
\hbox(0.0+0.0)x345.0, glue set 330.0fil
|
||||||
|
.\hbox(0.0+0.0)x15.0
|
||||||
|
.\penalty 10000
|
||||||
|
.\glue(\parfillskip) 0.0 plus 1.0fil
|
||||||
|
.\glue(\rightskip) 0.0
|
||||||
|
|
||||||
|
total height 10.0
|
||||||
|
goal height 550.0
|
||||||
|
|
||||||
|
prevdepth 0.0, prevgraf 1 line
|
||||||
|
|
||||||
|
|
||||||
|
! OK
|
||||||
|
LUAMML_FORMULA_END
|
||||||
|
LUAMML_FORMULA_BEGIN:2:3:mrow:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### math mode entered at line 18
|
||||||
|
\mathop\nolimits
|
||||||
|
.\kern 0.0
|
||||||
|
.\mathord
|
||||||
|
..\fam0 s
|
||||||
|
.\mathord
|
||||||
|
..\fam0 i
|
||||||
|
.\mathord
|
||||||
|
..\fam0 n
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 x
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathbin
|
||||||
|
.\fam2 ^^@
|
||||||
|
\mathop\nolimits
|
||||||
|
.\kern 0.0
|
||||||
|
.\mathord
|
||||||
|
..\fam0 s
|
||||||
|
.\mathord
|
||||||
|
..\fam0 i
|
||||||
|
.\mathord
|
||||||
|
..\fam0 n
|
||||||
|
\mathopen
|
||||||
|
.\fam0 (
|
||||||
|
\mathord
|
||||||
|
.\fam1 x
|
||||||
|
\mathbin
|
||||||
|
.\fam0 +
|
||||||
|
\mathord
|
||||||
|
.\fam0 2
|
||||||
|
\mathord
|
||||||
|
.\fam1 ^^Y
|
||||||
|
\mathclose
|
||||||
|
.\fam0 )
|
||||||
|
\mathrel
|
||||||
|
.\fam0 =
|
||||||
|
\mathord
|
||||||
|
.\fam0 0
|
||||||
|
|
||||||
|
### horizontal mode entered at line 18
|
||||||
|
\hbox(0.0+0.0)x15.0
|
||||||
|
\OT1/cmr/m/n/10 E
|
||||||
|
\OT1/cmr/m/n/10 s
|
||||||
|
\glue 3.33333 plus 1.66666 minus 1.11111
|
||||||
|
\OT1/cmr/m/n/10 g
|
||||||
|
\OT1/cmr/m/n/10 i
|
||||||
|
\OT1/cmr/m/n/10 l
|
||||||
|
\OT1/cmr/m/n/10 t
|
||||||
|
\glue 3.33333 plus 1.66666 minus 1.11111
|
||||||
|
|
||||||
|
spacefactor 1000
|
||||||
|
### vertical mode entered at line 0
|
||||||
|
### current page:
|
||||||
|
\write-{}
|
||||||
|
\glue(\topskip) 10.0
|
||||||
|
\hbox(0.0+0.0)x345.0, glue set 330.0fil
|
||||||
|
.\hbox(0.0+0.0)x15.0
|
||||||
|
.\penalty 10000
|
||||||
|
.\glue(\parfillskip) 0.0 plus 1.0fil
|
||||||
|
.\glue(\rightskip) 0.0
|
||||||
|
\penalty 10000
|
||||||
|
\glue(\abovedisplayshortskip) 0.0 plus 3.0
|
||||||
|
\glue(\baselineskip) 4.5
|
||||||
|
\hbox(7.5+2.5)x185.77597, shifted 79.61201, display
|
||||||
|
.\OMS/cmsy/m/n/10 ;
|
||||||
|
.\write3{LUAMML_MARK_REF:1:}
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 j
|
||||||
|
.\hbox(0.0+0.0)x-1.66663
|
||||||
|
..\kern -1.66663
|
||||||
|
.\OT1/cmr/m/n/10 =
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OT1/cmr/m/n/10 (
|
||||||
|
.\OT1/cmr/m/n/10 (
|
||||||
|
.\OML/cmm/m/it/10 p
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OML/cmm/m/it/10 q
|
||||||
|
.\kern0.35878
|
||||||
|
.\OT1/cmr/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OT1/cmr/m/n/10 (
|
||||||
|
.\OML/cmm/m/it/10 q
|
||||||
|
.\kern0.35878
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OML/cmm/m/it/10 r
|
||||||
|
.\kern0.27779
|
||||||
|
.\OT1/cmr/m/n/10 )
|
||||||
|
.\OT1/cmr/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OT1/cmr/m/n/10 (
|
||||||
|
.\OML/cmm/m/it/10 p
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OT1/cmr/m/n/10 (
|
||||||
|
.\OML/cmm/m/it/10 q
|
||||||
|
.\kern0.35878
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OMS/cmsy/m/n/10 )
|
||||||
|
.\glue(\thickmuskip) 2.77771 plus 2.77771
|
||||||
|
.\OML/cmm/m/it/10 r
|
||||||
|
.\kern0.27779
|
||||||
|
.\OT1/cmr/m/n/10 )
|
||||||
|
.\OT1/cmr/m/n/10 )
|
||||||
|
\penalty 0
|
||||||
|
\glue(\belowdisplayshortskip) 6.0 plus 3.0 minus 3.0
|
||||||
|
\glue(\parskip) 0.0 plus 1.0
|
||||||
|
\glue(\parskip) 0.0
|
||||||
|
|
||||||
|
total height 30.5 plus 7.0 minus 3.0
|
||||||
|
goal height 550.0
|
||||||
|
|
||||||
|
prevdepth 2.5
|
||||||
|
|
||||||
|
|
||||||
|
! OK
|
||||||
|
LUAMML_FORMULA_END
|
||||||
|
LUAMML_MARK_REF:1:
|
||||||
|
|
20
testfiles-pdf/test_pdf.xrt
Normal file
20
testfiles-pdf/test_pdf.xrt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
\documentclass{article}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{luamml-demo}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\[
|
||||||
|
\emptyset\models((p\Rightarrow q)\Rightarrow(q\Rightarrow r))\Rightarrow (p\Rightarrow (q\Rightarrow r))
|
||||||
|
\WriteoutFormula
|
||||||
|
\]
|
||||||
|
|
||||||
|
%\begin{align}
|
||||||
|
% abc&=def & e^{\mathrm{i}\pi}&=-1\\
|
||||||
|
% \Big(1+2&=3\Big)\\
|
||||||
|
% &4\\
|
||||||
|
% 5
|
||||||
|
%\end{align}
|
||||||
|
|
||||||
|
Es gilt $\sin(x)-\sin(x+2\pi)=0\WriteoutFormula$.
|
||||||
|
\end{document}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user