retex / rex Goto Github PK
View Code? Open in Web Editor NEWReX - typesetting mathematics
ReX - typesetting mathematics
We would be better of using a binary search for these two tables instead of a hashmap, since they are so small.
Notice the compile size of each module
rw-r--r-- 0/0 8476 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-dimensions.o
rw-r--r-- 0/0 39136 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font.o
rw-r--r-- 0/0 5328 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-constants.o
rw-r--r-- 0/0 8420 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-fontselection.o
rw-r--r-- 0/0 137592 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-glyphs.o
rw-r--r-- 0/0 13312 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-kerning.o
rw-r--r-- 0/0 126672 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-kerning_table.o
rw-r--r-- 0/0 1468 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-offsets.o
rw-r--r-- 0/0 83956 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-symbols.o
rw-r--r-- 0/0 308764 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-variant_tables.o
rw-r--r-- 0/0 26452 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-font-variants.o
rw-r--r-- 0/0 65312 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-functions.o
rw-r--r-- 0/0 34940 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-layout.o
rw-r--r-- 0/0 11352 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-layout-builders.o
rw-r--r-- 0/0 96844 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-layout-engine.o
rw-r--r-- 0/0 3260 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-layout-spacing.o
rw-r--r-- 0/0 65672 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-lexer.o
rw-r--r-- 0/0 1100 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-lexer-lexer.o
rw-r--r-- 0/0 3452 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-parser.o
rw-r--r-- 0/0 4428 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-parser-atoms.o
rw-r--r-- 0/0 9056 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-parser-builders.o
rw-r--r-- 0/0 86720 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-parser-engine.o
rw-r--r-- 0/0 41780 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-parser-nodes.o
rw-r--r-- 0/0 47668 Jan 1 01:00 1970 rex-43e78ccd3d61ee32.rex-render.o
In particular, migrate symbols.rs
and glyphs.rs
to codegen from a build.rs script. See this example: https://github.com/nagisa/target_build_utils.rs/blob/master/build.rs#L26. We can place the data required to generate these in a json file.
Make it possible to compile without std
.
use_std
Motivation:
There is some prior work done here for related projects:
Selenium might be best for getting an accurate representation for our rendered SVG. I proposed that we places Rules
in the document to be used to assist in measuring distances. Another option would be to do something similar to what KaTeX does and compare the output with LaTeX.
I'm having trouble compiling this library.
The issue seems to be with the static_map
dependency. Notably,
Compiling font_types v0.1.0 (/Users/colbyn/Scratch/ReX/fonts/types)
Compiling stix2 v0.1.0 (/Users/colbyn/Scratch/ReX/fonts/stix2)
error: proc-macro derive panicked
--> fonts/stix2/src/variants.rs:1660:65
|
1660 | pub static HORZ_VARIANTS: static_map::Map<u32, GlyphVariants> = static_map! {
| _________________________________________________________________^
1661 | | Default: GlyphVariants { constructable: None, replacements: &[] },
1662 | | 0x302 => GlyphVariants { // uni0302
1663 | | constructable: None,
... |
2864 | |
2865 | | };
| |_^
|
= help: message: assertion failed: input.starts_with(LEADING)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: proc-macro derive panicked
--> fonts/stix2/src/variants.rs:5:65
|
5 | pub static VERT_VARIANTS: static_map::Map<u32, GlyphVariants> = static_map! {
| _________________________________________________________________^
6 | | Default: GlyphVariants { constructable: None, replacements: &[] },
7 | | 0x2F => GlyphVariants { // slash
8 | | constructable: None,
... |
1656 | |
1657 | | };
| |_^
|
= help: message: assertion failed: input.starts_with(LEADING)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: proc-macro derive panicked
--> fonts/stix2/src/symbols.rs:12:61
|
12 | pub static SYMBOLS: static_map::Map<&'static str, Symbol> = static_map! {
| _____________________________________________________________^
13 | | Default: Symbol { unicode: 0x00, atom_type: AtomType::Accent },
14 | | // unicode-math.dtx command table
15 | | "mathexclam" => Symbol { unicode: 0x21, atom_type: AtomType::Close }, // 33
... |
2537 | | "|" => Symbol { unicode: 0x2016, atom_type: AtomType::Fence }, // 8214
2538 | | };
| |_^
|
= help: message: assertion failed: input.starts_with(LEADING)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: proc-macro derive panicked
--> fonts/stix2/src/glyphs.rs:15:50
|
15 | pub static GLYPHS: static_map::Map<u32, Glyph> = static_map! {
| __________________________________________________^
16 | | Default: Glyph { unicode: 0x0000_u32, bbox: BBox(fontunit!(0), fontunit!(0), fontunit!(0), fontunit!(0)), attachment: fontunit!(0), a...
17 | |
18 | | 0x0020_u32 => Glyph { unicode: 0x0020_u32, bbox: BBox(fontunit!(0), fontunit!(0), fontunit!(0), fontunit!(0)), attachment: fontunit!(...
... |
5290 | | 0x1d455_u32 => Glyph { unicode: 0x210e_u32, bbox: BBox(fontunit!(47), fontunit!(-10), fontunit!(549), fontunit!(706)), attachment: fo...
5291 | | };
| |_^
|
= help: message: assertion failed: input.starts_with(LEADING)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find macro `__static_map__construct_map` in this scope
--> fonts/stix2/src/variants.rs:1660:65
|
1660 | pub static HORZ_VARIANTS: static_map::Map<u32, GlyphVariants> = static_map! {
| _________________________________________________________________^
1661 | | Default: GlyphVariants { constructable: None, replacements: &[] },
1662 | | 0x302 => GlyphVariants { // uni0302
1663 | | constructable: None,
... |
2864 | |
2865 | | };
| |_^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find macro `__static_map__construct_map` in this scope
--> fonts/stix2/src/variants.rs:5:65
|
5 | pub static VERT_VARIANTS: static_map::Map<u32, GlyphVariants> = static_map! {
| _________________________________________________________________^
6 | | Default: GlyphVariants { constructable: None, replacements: &[] },
7 | | 0x2F => GlyphVariants { // slash
8 | | constructable: None,
... |
1656 | |
1657 | | };
| |_^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
The library seems to be unmaintained.
Any interest in replacing the library with something simple?
Perhaps something akin to:
macro_rules! indexfor {
($keys:expr, $target:expr) => {{
// let mut index: Option<usize> = None;
let mut index: usize = 0;
let mut result: Option<usize> = None;
for k in $keys {
if $target == *k {
result = Some(index);
break;
}
index = index + 1;
}
result.unwrap()
}};
}
macro_rules! hardcoded {
($name:ident ($kty:ty, $vty:ty) {$($key:expr => $value:expr),* $(,)?}) => {
#[allow(non_upper_case_globals)]
pub static Entries: &'static [($kty, $vty)] = &[
$(
($key, $value),
)*
];
macro_rules! $name {
($id:expr) => {{
let index = indexfor!(&[$($key),*], $id);
Entries[index].1
}};
}
};
}
hardcoded!{
get_symbol(&str, &str) {
"a" => "lorem",
"b" => "ipsum",
"c" => "red",
}
}
fn main() {
let x = get_symbol!("a");
println!("Output: {:#?}", x);
}
Instead of a Map like data structure, we just replace it with a static array, using the getter generated by hardcoded!
, i.e. get_symbol!(key)
.
PS: Awesome library! I can see this replacing libraries like iosMath, that offer math rendering without embedding a browser.
I wish I had known about this library when I started working on Subscript for my school math notes.
On IRC we discussed the possibility of using a scale of internal font units (in xits it's 1/1000 em) for internal dimension in ReX. We concluded that it would probably be best if we use a 24.8 fixedpoint representation of the internal font unit. A cursory glance of the code showed that *2, /2, and +/- is by far the most common operation. However, *0.68 is used for scripts scaling, and it is unclear what the distribution of *0.68 use is to make a fully informed decision.
Pertinent numbers from the intel optimization manual:
Latency | Throughput | |
---|---|---|
ADD | 1 | 0.5 |
MUL | 7,8 | 6,7 |
SHL | 1 | 1 |
FADD | 5 | 4,1 |
FMUL | 5 | 1 |
Considering the number of *2, /2 uses, it seems unlikely that f64 will afford the same bitshift optimizations that a u32 would. FDIV is not listed, but expensive.
sebk also pointed out that it could be possible to put a scaling call in both the layout and renderer, but depending on a feature flag, one would be a no op and the other wouldn't.
Using a scaled font unit would also rid of all the Pixels -> FontUnit conversions in the Layout (there seem to be quite a few).
Hi cbreeden,
This is a continuation of the reddit thread; it'd be great to get support for OpenType working, or at least a primitive version. I tried to get Latin Modern Math working today and this is how much I've accomplished so far. It would be great to get your mentorship and progress further.
python3 rexify.py latinmodern-math.otf out/lmmodern
in the rex-fonts
directory to generate the files (e.g., glyphs.rs
).Issue. Due to changes changes in Rust 2018 and my recent PR, you need to change the glyphs.mako.rs
file. I will submit a PR soon.
Create a new crate in ReX/fonts
, and copy over the files generated in the previous step. However, the styles.rs
, kernings.rs
and macros.rs
(and lib.rs
) are missing, so I just copied them over from the ReX/fonts/stix2
directory. Note that kernings.rs
is supposed to be generated during the previous script, but the rexify.py
reports that no kerning tables are found.
In the root Cargo.toml
file, point stix2 are the new crate (never mind the fact that it's still called "stix2").
cargo build --release
[Bug.] In the generated styles.rs
, we need to add the following lines. It's interesting that the python script doesn't generate these lines automatically, but they are somehow found in the stix2
package.
pub const NULL_DELIMITER_SPACE: FontUnit = fontunit!(100);
pub const DELIMITER_SHORT_FALL: FontUnit = fontunit!(100);
pub const DELIMITER_FACTOR: FontUnit = fontunit_raw!(0xE6); // 90.1%
main.rs
so the generated SVG reads from the correct file.Here is the SVG produced for \sum_{n\geq1} \frac{1}{n^2} = \pi^2/6
, which looks like this. The problem is that operator symbols are somehow not working. I would need some assistance to figure out how to fix this -- where does the code look for these tables? (My guess is that the automatically generated symbols.rs
somehow is not working.)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="639.3165" height="260.053125" viewBox="0 0 6659 2708" xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css">@font-face{font-family:rex;src:url('rex-lmodern.otf');}</style>
</defs>
<g font-family="rex" font-size="1000">
<rect x="250" y="100" width="6159" height="1343" fill="none" stroke="blue" stroke-width="8"/>
<rect x="250" y="293" width="1444" height="2315" fill="none" stroke="red" stroke-width="8"/>
<rect x="972" y="293" width="1444" height="0" fill="none" stroke="blue" stroke-width="8"/>
<rect x="972" y="293" width="0" height="0" fill="none" stroke="blue" stroke-width="8"/>
<rect x="250" y="493" width="1444" height="950" fill="none" stroke="blue" stroke-width="8"/>
<rect x="250" y="493" width="1444" height="1400" fill="none" stroke="red" stroke-width="8"/>
<rect x="250" y="493" width="1444" height="1400" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(250, 1443)">ξ</text>
<rect x="315" y="2060" width="1444" height="465" fill="none" stroke="blue" stroke-width="8"/>
<rect x="315" y="2060" width="1313" height="465" fill="none" stroke="blue" stroke-width="8"/>
<rect x="315" y="2216" width="419" height="316" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(315, 2525) scale(0.70)">π</text>
<rect x="734" y="2084" width="543" height="524" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(734, 2525) scale(0.70)">β₯</text>
<rect x="1278" y="2060" width="349" height="465" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(1278, 2525) scale(0.70)">1</text>
<rect x="1960" y="100" width="949" height="2040" fill="none" stroke="red" stroke-width="8"/>
<rect x="2185" y="100" width="949" height="666" fill="none" stroke="blue" stroke-width="8"/>
<rect x="2185" y="100" width="500" height="666" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(2185, 766)">1</text>
<rect x="1960" y ="1173" width="949" height="40" fill="#000"/>
<rect x="1960" y="1374" width="949" height="754" fill="none" stroke="blue" stroke-width="8"/>
<rect x="1960" y="1687" width="600" height="442" fill="none" stroke="blue" stroke-width="8"/>
<rect x="1960" y="1687" width="600" height="453" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(1960, 2129)">π</text>
<rect x="2560" y="1374" width="349" height="754" fill="none" stroke="red" stroke-width="8"/>
<rect x="2560" y="1374" width="349" height="465" fill="none" stroke="blue" stroke-width="8"/>
<rect x="2560" y="1374" width="349" height="465" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(2560, 1840) scale(0.70)">2</text>
<rect x="3343" y="1076" width="778" height="234" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(3343, 1443)">=</text>
<rect x="4454" y="1012" width="570" height="431" fill="none" stroke="blue" stroke-width="8"/>
<rect x="4454" y="1012" width="570" height="442" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(4454, 1443)">π</text>
<rect x="5024" y="614" width="384" height="828" fill="none" stroke="red" stroke-width="8"/>
<rect x="5024" y="614" width="384" height="465" fill="none" stroke="blue" stroke-width="8"/>
<rect x="5059" y="614" width="349" height="465" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(5059, 1080) scale(0.70)">2</text>
<rect x="5409" y="693" width="500" height="1000" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(5409, 1443)">/</text>
<rect x="5909" y="777" width="500" height="688" fill="none" stroke="green" stroke-width="8"/>
<text transform="translate(5909, 1443)">6</text>
</g>
</svg>
I would like to see output on the JS side looking like:
layout β¦ Ok
[I] preparing XYZ
[W] problem ..
[I] finishing XYZ
rendering β¦ Error
[I] allocating resources
[I] collecting glyphs
drawing formula β¦ Ok
[I] rasterizing glyphs
[I] painting glyphs
[E] cannot save image
this might be created by the following calls
let layout_log = log.create_context("layout");
layout_log.info("preparing {}", z.name);
layout_log.warn("problem {:d}", β¦);
layout_log.info("finishing {}", z.name);
let render_log = log.create_context("rendering");
render_log.info("allocating resouces");
let drawing_log = render_log.create_context("drawing formula");
drawing_log.info("rasterizing glyphs");
drawing_log.info("painting glyphs");
render_log.error("cannot save image");
Radicals go too far down, shift them up
The README.md has a license section that states the following:
See LICENSE-APACHE, and LICENSE-MIT for details.
These two files, however, are not in the repository. Could you put the respective files into the repository root such that the project is unambigously usable under the MIT and Apache 2.0 licenses? Thanks!
This can be useful for
BottomAccent
: vertical placement is directly below nucleus,WideAccent
vs Accent
: Don't expand non-WideAccent
types by default.FlattenedAccentBaseHeight
.This is trick. Some math fonts don't include standard kerning for the glyphs, will most likely need to resort to a different font file if desired. I noticed that KaTeX and MathJax neither support kerning for \text
We should be taking the italics correction from the variant operator glyph instead. We need to layout the contents of the base before taking italics corrections for base.
I changed the types for the kerning table to take a static slice over an array, since some fonts have different size requirements here.
I also changed the variant tables to use static_map!
. Codegen needs to be updated accordingly.
A symbol for 'h' is equivalent to the planck constant 'h'. The unicode standard omits the mathematical 'h' to avoid the duplication.
ReX currently uses this non-existing glyph and fails to render 'h'.
A workaround is to check for this special case and use the alternative codepoint.
Find and replace
match codepoint {
LOWER_A..=LOWER_Z => style_lookup(&LATIN_LOWER_LUT, codepoint, style),
with
const LOWER_H: u32 = 'h' as u32;
match codepoint {
LOWER_H..=LOWER_H => 0x210E, // planck constant
LOWER_A..=LOWER_Z => style_lookup(&LATIN_LOWER_LUT, codepoint, style),
It appears that I don't layout Rules
the same way I layout Glyphs
while in Vertical mode. This has caused me to miscalculate a few different layout algorithms that use rules (ie: fraction). Check for consistency.
Test with (T)(F)(P)(V)(W)(Y)
Accents are too narrow in scaled variations. Accents are too high in scaled variations. Test \overbrace{1234456789}
While testing fractions, it appears that NULL_DELIMITER_SPACE doesn't accurate represent the correct spacing. Check that the scaling is correct.
Font property selection (italic, bold, monospace) should be recognized when using \alpha
, \beta
, etc.. But only is recognized when using directly unicode input for now. We should probably find a list of all such symbols that are commands as well.
This is a list of tests that I think should be added when we have a testing framework.
\displaystyle\int\limits_0^1\int
\textstyle\int\limits_0^1\int
\scriptstyle\int\limits_0^1\int
\scriptscriptstyle\int\limits_0^1\int
\limits
and display style)\displaystyle\int_0^1\sum_0^1
\textstyle\int_0^1\sum_0^1
\displaystyle\int\displaylimits_0^1
\textstyle\int\displaylimits_0^1
\displaystyle\mathop{\mathrm{lim}}\limits_{x \to \infity}
\displaystyle\sum_{a+b+c+d}^{a+b+c+d+e+f}
\displaystyle\sum_k^n
\displaystyle\mathop{\mathrm{lim}}\limits_{x \to \infty}\mathop{\mathrm{lim}}\limits_{M \to \infty}
\displaystyle\mathop{\mathrm{lim\,sup}}\limits_{x \to \infty}\mathop{\mathrm{lim\,sup}}\limits_{M \to \infty}
Hey I'm interested in contributing to this project. Any words on the status of this project?
Since it seems like there is an unofficial rewrite over here that hasn't been merged back into this repo.
Hello Developers,
ReX at 69593e240f10f3976ea4a86c1243678483c2de03
failed to build with
rustc 1.21.0-nightly (1d2a6df38 2017-08-03)
Compiling rex v0.1.0 (file:///scratch/github/ReX)
error: unexpected end of macro invocation
--> src/layout/engine.rs:578:17
|
578 | contents,
| ^
error: Could not compile `rex`.
Thanks
R_\mathfrak{e} should work.
Our minus sign symbol is much smaller
Currently, \hat{A}
will place A
in a ParseNode::Group
, and \hat A
will simply place a ParseNode::Symbol
in the nucleus of the ParseNode::Accent
.
As a macro argument, the opening and closing braces should be transparent to the processing of ParseNode::Accent
. In particular, this will give false positives to nucleus.is_symbol
when processing superscripts.
It may be worth considering changing the nucleus
field of an Accent
to a Vec<ParseNode>
instead.
Generating the SVG seems to be expensive, I'm curious if using a different library for displaying floats could reduce the load. See https://github.com/dtolnay/dtoa
Though, converting to a fixed-point representation (#22) is probably better.
Currently we pass a string. We also fail to expand during this phase (even though we don't support macros yet).
First, thank you for this fantastic work.
This is what I've been looking for for a long time.
(My dream is to have a WYSIWYM latex math input method. ReTeX can help a lot.)
I notice that a primed symbol like t'
only shows t
in the online demo, without the prime. Interestingly, t"
is fine.
This isn't a concern yet, as we don't have an OperatorName command, since we don't support macros. But for future reference.
In OperatorName
, special handling occurs for some symbols.
See http://tex.stackexchange.com/questions/84302/what-is-the-difference-of-mathop-operatorname-and-declaremathoperator for explanation of the definition. The special symbol handling is done by:
\gdef\newmcodes@{\mathcode`\'39\mathcode`\*42\mathcode`\."613A%
\mathcode`\-45\mathcode`\/47\mathcode`\:"603A\relax}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.