Core Nearley displayMode off
+ What’s this?
A JavaScript implementation of simple mathematical formula markup language. It is more readable and easy to learn compared with LaTeX \LaTeX L A T E X .
How to Use
API
You can use either asciimath-parser
or asciimath-parser-nearley
. This documentation is for the former, while the latter has some differences. Please refer to its README .
Basic Usage
Install the package with npm/yarn/pnpm.
pnpm i -D asciimath-parser
Import it and create an instance of Asciimath, then use the toTex
method to generate LaTeX code.
import { AsciiMath } from ' asciimath-parser '
const am = new AsciiMath ()
console . log ( am . toTex ( ' sum_(n=1)^(+oo)1/n^2=pi^2/6 ' ))
// \displaystyle{ \sum _{ n = 1 } ^{ + \infty } \frac{ 1 }{ n ^{ 2 } } = \frac{ \pi ^{ 2 } }{ 6 } }
Configuration and Custom Tokens
The following is the type declaration of AsciiMath config.
type ReplaceLaw = [ RegExp | string , string | ( ( substring : string , ... args : any [] ) => string )]
interface AsciiMathConfig {
display ?: boolean
replaceBeforeTokenizing ?: ReplaceLaw []
symbols ?: Array < [ string , SymbolValueType ] > | Record < string , SymbolValueType >
}
display
Specify whether the generated formula is wrapped in \displaystyle
environment. The default value is true
.
replaceBeforeTokenizing
Replace the matched strings with the target strings respectively before the formula is parsed by AsciiMath.
Click to show details.
For example, if you specify it like below:
const cfg : AsciiMathConfig = {
replaceBeforeTokenizing : [
[ / d0 / g , ' {:"d"theta:} ' ] ,
[ / x ( \d + )/ g , ( _ , $1 ) => ` x^( ${ $1 } ) ` ] ,
]
}
const am = new AsciiMath ( cfg )
console . log ( am . toTex ( ' ... ' ))
All of the d0
will be replaced with {:"d"theta:}
, and then be parsed into { \text{d} \theta }
by AsciiMath.
Strings like x2
and x10
will be replaced with x^(2)
and x^(10)
, and then be parsed into x^{ 2 }
and x^{ 10 }
, respectively. (I think no one should write them like this, though ¯\_(ツ)_/¯)
symbols
Specify the extended tokens. If you want to view all of the token types, please refer to symbols.ts
. However, it is not recommended to extend all of them. The following lists the recommended token types for extension
enum TokenTypes {
Const , // transform matched string into tex
OperatorOA , // with unary operand, like `abs(a)`
OperatorOAB , // with binary operands, like `frac(a)(b)`
OperatorAOB , // infix operator, like `a / b`
OperatorAO , // suffix operator, like factorial `n!`
}
Click to show details.
You can specify it below
const cfg : AsciiMathConfig = {
symbols : {
dx : { type : TokenTypes . Const , tex : ' { \\ mathrm{d}x} ' },
rm : { type : TokenTypes . OperatorOA , tex : ' \\ mathrm{$1} ' , eatNext : true },
frac : { type : TokenTypes . OperatorOAB , tex : ' \\ frac{ $1 }{ $2 } ' },
over : { type : TokenTypes . OperatorAOB , tex : ' { $1 \\ over $2 } ' },
}
}
const am = new AsciiMath ( cfg )
console . log ( am . toTex ( ' ... ' ))
Then dx
, rm
, frac
and over
will be recognized as tokens of AsciiMath, and the results will be
dx
into {\mathrm{d}x}
rm(absc)
into \mathrm{absc}
, where $1
will be replaced with absc
If eatNext
is set to true
, then the next word will be “eaten” by tokenizer and recognized as a literal string
even if there is any token in it. In the example above, absc
contains the token abs
, but the
program just simply read the word and put absc
at the $1
.
Without eatNext
, you will get \mathrm{ \left|c\right| }
.
If you want to read a longer sentense, just wrap it with doublequotes "
or
parens (
)
like rm "here is a mathrm block"
eatNext
is only recommended to be used with OperatorOA
and OperatorOAB
.
frac(m)(n)
into \frac{ m }{ n }
, where $1
and $2
will be replaced with m
and n
, respectively
a over b
into { a \over b }
, where $1
and $2
will be replaced with a
and b
, respectively
Cli
Install the cli locally or globally.
pnpm add -g asciimath-parser-cli
Transform input files with inline asciimath formulas (wrapped with backticks) to LaTeX formulas.
am-parse input.txt
# It will yield input_parsed_xxx.tex
User Story
Caution
This library is refactored by me, which means that some of the syntax may be inconsistent with asciimath.org , especially the matrix .
Asciimath parser itself does not depend on DOM or mathml, it simply parses your input code into LaTeX code. If you want to display formulas, please work it out with KaTeX or mathjax (for websites) or LaTeX (for articles).
Special Thanks
zmx0142857’s note and his great help.
Report an Issue
Go to GitHub issue and provide a template that can reproduce the problem you ran into.
Examples Theme output source Super and subscript a 1 2 + b 1 2 = c 1 2 \displaystyle{ a _{ 1 } ^{ 2 } + b _{ 1 } ^{ 2 } = c _{ 1 } ^{ 2 } } a 1 2 + b 1 2 = c 1 2 a_1^2 + b_1^2 = c_1^2 Text hello world \displaystyle{ \text{hello world} } hello world "hello world" Fraction a b , a / b \displaystyle{ \frac{ a }{ b } , a {/} b } b a , a / b a/b, a//b Square root n , x n , a 2 b \displaystyle{ \sqrt{ n } , \sqrt[ n ]{ x } , \frac{ a ^{ 2 } }{ \sqrt{ b } } } n , n x , b a 2 sqrt n, root n x, a^2/sqrt b Limit lim n → ∞ ( 1 + 1 n ) n \displaystyle{ \lim _{ n \to \infty } \left( 1 + \frac{ 1 }{ n } \right) ^{ n } } n → ∞ lim ( 1 + n 1 ) n lim_(n->oo) (1+1/n)^n Integral ∫ a b f ( x ) d x \displaystyle{ \int _{ a } ^{ b } f \left( x \right) {\text{d}x} } ∫ a b f ( x ) d x int_a^b f(x) dx Hidden parens sin x 2 \displaystyle{ \sin { \frac{ x }{ 2 } } } sin 2 x sin {: x/2 :} Differential d y d x , d r d θ , f ′ ′ ( x ) \displaystyle{ \frac{ {\text{d}y} }{ {\text{d}x} } , \frac{ \text{d} r }{ \text{d} \theta } , f ^{\prime\prime} \left( x \right) } d x d y , d θ d r , f ′′ ( x ) dy/dx, ("d"r)/("d"theta), f''(x) Differential (exprimental) d f d x , d 2 f d x 2 , x ¨ \displaystyle{ \frac{ \mathrm{d} f }{ \mathrm{d} x } , \frac{ \mathrm{d} ^{ 2 } f }{ \mathrm{d} x ^{ 2 } } , \ddot{ x } } d x d f , d x 2 d 2 f , x ¨ ddfx , dd^2 f x , ddot x Partial ∂ f ∂ x , ∂ 3 f ∂ x ∂ y 2 \displaystyle{ \frac{ \partial f }{ \partial x } , \frac{ \partial ^{ 3 } f }{ \partial x \partial y ^{ 2 } } } ∂ x ∂ f , ∂ x ∂ y 2 ∂ 3 f (del f)/(del x), (del^3 f)/(del x del y^2) Partial (experiment) ∂ f ∂ x , ∂ 3 f ∂ x ∂ y 2 , ∂ ∂ x \displaystyle{ \frac{ \partial f }{ \partial x } , \frac{ \partial ^{ 3 } f }{ \partial x \partial y ^{ 2 } } , \frac{ \partial { } }{ \partial x } } ∂ x ∂ f , ∂ x ∂ y 2 ∂ 3 f , ∂ x ∂ ppfx, pp^3 f (x y^2), pp {::} x Matrix [ a b c d ] , [ a b c d e f ] \displaystyle{ \left[ \begin{array}{cc} a & b \\ c & d \end{array} \right] , \left[ \begin{array}{cc|c} a & b & c \\ d & e & f \end{array} \right] } [ a c b d ] , [ a d b e c f ] [a, b; c, d], [a, b | c; d, e | f] Piecewise function ∣ x ∣ = { x if x > 0 − x otherwise \displaystyle{ \left| x \right| = \left\lbrace \begin{array}{ll} x & \text{if}\quad x > 0 \\ - x & \text{otherwise}\quad \end{array} \right. } ∣ x ∣ = { x − x if x > 0 otherwise |x| = { x, if x > 0; -x, otherwise :}
Manual Greek Alphabet output source output source output source output source α \displaystyle{ \alpha } α alpha β \displaystyle{ \beta } β beta χ \displaystyle{ \chi } χ chi δ \displaystyle{ \delta } δ delta Δ \displaystyle{ \Delta } Δ Delta ε \displaystyle{ \varepsilon } ε epsi ϵ \displaystyle{ \epsilon } ϵ epsilon η \displaystyle{ \eta } η eta γ \displaystyle{ \gamma } γ gamma Γ \displaystyle{ \Gamma } Γ Gamma ι \displaystyle{ \iota } ι iota κ \displaystyle{ \kappa } κ kappa λ \displaystyle{ \lambda } λ lambda Λ \displaystyle{ \Lambda } Λ Lambda μ \displaystyle{ \mu } μ mu ν \displaystyle{ \nu } ν nu ω \displaystyle{ \omega } ω omega Ω \displaystyle{ \Omega } Ω Omega ϕ \displaystyle{ \phi } ϕ phi φ \displaystyle{ \varphi } φ varphi Φ \displaystyle{ \Phi } Φ Phi Φ \displaystyle{ \varPhi } Φ varPhi π \displaystyle{ \pi } π pi Π \displaystyle{ \Pi } Π Pi ψ \displaystyle{ \psi } ψ psi Ψ \displaystyle{ \Psi } Ψ Psi ρ \displaystyle{ \rho } ρ rho σ \displaystyle{ \sigma } σ sigma Σ \displaystyle{ \Sigma } Σ Sigma τ \displaystyle{ \tau } τ tau θ \displaystyle{ \theta } θ theta ϑ \displaystyle{ \vartheta } ϑ vartheta Θ \displaystyle{ \Theta } Θ Theta υ \displaystyle{ \upsilon } υ upsilon ξ \displaystyle{ \xi } ξ xi Ξ \displaystyle{ \Xi } Ξ Xi ζ \displaystyle{ \zeta } ζ zeta
Paren output source output source output source output source ( \displaystyle{ \left( \right. } ( ( ) \displaystyle{ ) } ) ) \displaystyle{ \left. \right. } {: . \displaystyle{ . } . :} [ \displaystyle{ \left[ \right. } [ [ ] \displaystyle{ ] } ] ] { \displaystyle{ \left\lbrace \right. } { { } \displaystyle{ \rbrace } } } ⟨ \displaystyle{ \left\langle \right. } ⟨ (: ⟩ \displaystyle{ \rangle } ⟩ :) ⌊ \displaystyle{ \left\lfloor \right. } ⌊ |__ ⌋ \displaystyle{ \rfloor } ⌋ __| ⌈ \displaystyle{ \left\lceil \right. } ⌈ |~ ⌉ \displaystyle{ \rceil } ⌉ ~| ∣ \displaystyle{ \mid } ∣ | ∣ x ∣ \displaystyle{ \left| x \right| } ∣ x ∣ abs(x) ∥ v ∥ \displaystyle{ \left\| \mathbf{ v } \right\| } ∥ v ∥ norm(bb(v)) ⌊ x 2 ⌋ \displaystyle{ \left\lfloor \frac{ x }{ 2 } \right\rfloor } ⌊ 2 x ⌋ floor(x/2) ⌈ x 3 ⌉ \displaystyle{ \left\lceil \frac{ x }{ 3 } \right\rceil } ⌈ 3 x ⌉ ceil(x/3)
Operator output source output source output source output source + \displaystyle{ + } + + − \displaystyle{ - } − - ⋅ \displaystyle{ \cdot } ⋅ * ∗ \displaystyle{ \ast } ∗ ** / \displaystyle{ {/} } / // \ \displaystyle{ \backslash } \ \\ × \displaystyle{ \times } × xx ÷ \displaystyle{ \div } ÷ -: ∘ \displaystyle{ \circ } ∘ @ ⊕ \displaystyle{ \oplus } ⊕ o+ ⊗ \displaystyle{ \otimes } ⊗ ox ⊙ \displaystyle{ \odot } ⊙ o. ∑ \displaystyle{ \sum } ∑ sum ∏ \displaystyle{ \prod } ∏ prod ∧ \displaystyle{ \wedge } ∧ ^^ ⋀ \displaystyle{ \bigwedge } ⋀ ^^^ ∨ \displaystyle{ \vee } ∨ vv ⋁ \displaystyle{ \bigvee } ⋁ vvv ∩ \displaystyle{ \cap } ∩ nn ⋂ \displaystyle{ \bigcap } ⋂ nnn ∪ \displaystyle{ \cup } ∪ uu ⋃ \displaystyle{ \bigcup } ⋃ uuu % \displaystyle{ \% } % %
Relation Symbol output source output source output source output source = \displaystyle{ = } = = ≠ \displaystyle{ \ne } = != ≡ \displaystyle{ \equiv } ≡ -= ≢ \displaystyle{ \not\equiv } ≡ !-= ≅ \displaystyle{ \cong } ≅ ~= ≈ \displaystyle{ \approx } ≈ ~~ < \displaystyle{ < } < lt > \displaystyle{ > } > gt ≥ \displaystyle{ \ge } ≥ ge ≤ \displaystyle{ \le } ≤ le ⩽ \displaystyle{ \leqslant } ⩽ <= ⩾ \displaystyle{ \geqslant } ⩾ >= ≺ \displaystyle{ \prec } ≺ -< ≻ \displaystyle{ \succ } ≻ >- ∈ \displaystyle{ \in } ∈ in ∉ \displaystyle{ \notin } ∈ / !in ⊂ \displaystyle{ \subset } ⊂ sub ⊃ \displaystyle{ \supset } ⊃ sup ⊆ \displaystyle{ \subseteq } ⊆ sube ⊇ \displaystyle{ \supseteq } ⊇ supe ⊈ \displaystyle{ \not\subseteq } ⊆ !sube ⫋ \displaystyle{ \subsetneqq } ⫋ subne ⊴ \displaystyle{ \unlhd } ⊴ normal ⊵ \displaystyle{ \unrhd } ⊵ rnormal ⊲ \displaystyle{ \lhd } ⊲ lhd ⊳ \displaystyle{ \rhd } ⊳ rhd ∽ \displaystyle{ ∽ } ∽ S~ ∝ \displaystyle{ \propto } ∝ prop ∁ \displaystyle{ \complement } ∁ complement
Logical Operator output source output source output source output source and \displaystyle{ \text{ and } } and and or \displaystyle{ \text{ or } } or or ¬ \displaystyle{ \neg } ¬ not ⇒ \displaystyle{ \Rightarrow } ⇒ rArr if \displaystyle{ \text{if}\quad } if if ⟺ \displaystyle{ \iff } ⟺ iff ∀ \displaystyle{ \forall } ∀ AA ∃ \displaystyle{ \exists } ∃ EE ⊥ \displaystyle{ \bot } ⊥ _|_ ⊤ \displaystyle{ \top } ⊤ TT ⊢ \displaystyle{ \vdash } ⊢ |-- ⊨ \displaystyle{ \models } ⊨ |==
Others output source output source output source output source ∫ \displaystyle{ \int } ∫ int ∬ \displaystyle{ \iint } ∬ iint ∭ \displaystyle{ \iiint } ∭ iiint ∮ \displaystyle{ \oint } ∮ oint ∂ \displaystyle{ \partial } ∂ del ∇ \displaystyle{ \nabla } ∇ grad ± \displaystyle{ \pm } ± +- ∅ \displaystyle{ \varnothing } ∅ O/ ∞ \displaystyle{ \infty } ∞ oo ℵ \displaystyle{ \aleph } ℵ aleph ∠ \displaystyle{ \angle } ∠ /_ ∴ \displaystyle{ \therefore } ∴ :. ∵ \displaystyle{ \because } ∵ :' … \displaystyle{ \ldots } … ... ⋯ \displaystyle{ \cdots } ⋯ cdots ⋮ \displaystyle{ \vdots } ⋮ vdots ⋱ \displaystyle{ \ddots } ⋱ ddots □ \displaystyle{ \square } □ square N \displaystyle{ \mathbb{N} } N NN Q \displaystyle{ \mathbb{Q} } Q QQ R \displaystyle{ \mathbb{R} } R RR C \displaystyle{ \mathbb{C} } C CC Z \displaystyle{ \mathbb{Z} } Z ZZ ( N k ) \displaystyle{ { N \choose k } } ( k N ) N choose k
Math Function output source output source output source output source sin \displaystyle{ \sin } sin sin cos \displaystyle{ \cos } cos cos tan \displaystyle{ \tan } tan tan cot \displaystyle{ \cot } cot cot sec \displaystyle{ \sec } sec sec csc \displaystyle{ \csc } csc csc sinh \displaystyle{ \sinh } sinh sinh cosh \displaystyle{ \cosh } cosh cosh tanh \displaystyle{ \tanh } tanh tanh coth \displaystyle{ \coth } coth coth csch \displaystyle{ \operatorname{csch} } csch csch sech \displaystyle{ \operatorname{sech} } sech sech arcsin \displaystyle{ \arcsin } arcsin arcsin arccos \displaystyle{ \arccos } arccos arccos arctan \displaystyle{ \arctan } arctan arctan log \displaystyle{ \log } log log ln \displaystyle{ \ln } ln ln det \displaystyle{ \det } det det dim \displaystyle{ \dim } dim dim lim \displaystyle{ \lim } lim lim mod \displaystyle{ \operatorname{mod} } mod mod gcd \displaystyle{ \gcd } g cdgcd lcm \displaystyle{ \operatorname{lcm} } lcm lcm min \displaystyle{ \min } min min max \displaystyle{ \max } max max sgn \displaystyle{ \operatorname{sgn} } sgn sgn sup \displaystyle{ \sup } sup Sup inf \displaystyle{ \inf } inf inf exp \displaystyle{ \exp } exp exp
Arrow output source output source output source output source ↑ \displaystyle{ \uparrow } ↑ uarr ↓ \displaystyle{ \downarrow } ↓ darr → \displaystyle{ \rightarrow } → rarr ← \displaystyle{ \leftarrow } ← larr → \displaystyle{ \to } → -> ↦ \displaystyle{ \mapsto } ↦ |-> ↔ \displaystyle{ \leftrightarrow } ↔ harr ⇒ \displaystyle{ \Rightarrow } ⇒ rArr ⇐ \displaystyle{ \Leftarrow } ⇐ lArr ⇔ \displaystyle{ \Leftrightarrow } ⇔ hArr ↠ \displaystyle{ \twoheadrightarrow } ↠ ->> ↣ \displaystyle{ \rightarrowtail } ↣ >-> ↶ \displaystyle{ \curvearrowleft } ↶ curvArrLt ↷ \displaystyle{ \curvearrowright } ↷ curvArrRt ↺ \displaystyle{ \circlearrowleft } ↺ circArrLt ↻ \displaystyle{ \circlearrowright } ↻ circArrRt ⇝ \displaystyle{ \rightsquigarrow } ⇝ ~> ↛ \displaystyle{ \nrightarrow } ↛ -/-> ↚ \displaystyle{ \nleftarrow } ↚ <-/- ↮ \displaystyle{ \nleftrightarrow } ↮ <-/->
Font output source output source output source output source A \displaystyle{ \mathbf{ A } } A bb A A \displaystyle{ \boldsymbol{ A } } A bm A A \displaystyle{ \mathbb{ A } } A bbb A A \displaystyle{ \mathcal{ A } } A cc A A \displaystyle{ \mathtt{ A } } A tt A A \displaystyle{ \mathfrak{ A } } A fr A A \displaystyle{ \mathsf{ A } } A sf A A \displaystyle{ \mathscr{ A } } A scr A
Notation output source output source output source output source x ^ \displaystyle{ \hat{ x } } x ^ hat x x ˉ \displaystyle{ \bar{ x } } x ˉ bar x x ‾ \displaystyle{ \underline{ x } } x ul x x ⃗ \displaystyle{ \vec{ x } } x vec x x ˙ \displaystyle{ \dot{ x } } x ˙ dot x x ¨ \displaystyle{ \ddot{ x } } x ¨ ddot x x ⌢ \displaystyle{ \stackrel{\frown}{ x } } x ⌢ arc x x ~ \displaystyle{ \tilde{ x } } x ~ tilde x A B → \displaystyle{ \overrightarrow{ A B } } A B Vec(AB) A B ^ \displaystyle{ \widehat{ A B } } A B Hat(AB) A B ~ \displaystyle{ \widetilde{ A B } } A B Tilde(AB)
Superposition output source output source x bala \displaystyle{ \overset{ \text{bala} }{ x } } x bala overset("bala")(x) 12345 ⏞ n \displaystyle{ \overbrace{ 12345 } ^{ n } } 12345 n overbrace(12345)^n 12345 ⏟ n \displaystyle{ \underbrace{ 12345 } _{ n } } n 12345 underbrace(12345)_n = 123 456 \displaystyle{ \xlongequal[ 123 ]{ 456 } } 456 123 ==_(123)^(456) → a b \displaystyle{ \xrightarrow[ a ]{ b } } b a -->_(a)^(b) a b \displaystyle{ { a \atop b } } b a a atop b
Special output source output source I’m here \displaystyle{ \text{I'm here} } I’m here text(I'm here) ℏ \displaystyle{ \hbar } ℏ tex"\hbar" a b c \displaystyle{ { \color{red} ab c } } ab c color(red)(abc) hello world \displaystyle{ \text{hello world} } hello world "hello world"
Escape output source output source output source output source # \displaystyle{ \# } # \# $ \displaystyle{ \$ } $ \$ @ \displaystyle{ @ } @ \@ _ \displaystyle{ \_ } _ \_
Font Size output source output source text \displaystyle{ {\tiny \text{text} } } text tiny "text" text \displaystyle{ {\small \text{text} } } text small "text" text \displaystyle{ {\large \text{text} } } text large "text" text \displaystyle{ {\huge \text{text} } } text huge "text"
Syntax Sugar output source output source output source output source d x \displaystyle{ {\text{d}x} } d x dx d y \displaystyle{ {\text{d}y} } d y dy d z \displaystyle{ {\text{d}z} } d z dz d t \displaystyle{ {\text{d}t} } d t dt
Use #
to insert displaystyle
output source [ ∂ 2 f ∂ x 2 ∂ 2 f ∂ x ∂ y ∂ 2 f ∂ y ∂ x ∂ 2 f ∂ y 2 ] \displaystyle{ \left[ \begin{array}{cc} \displaystyle \frac{ \partial ^{ 2 } f }{ \partial x ^{ 2 } } & \frac{ \partial ^{ 2 } f }{ \partial x \partial y } \\ \frac{ \partial ^{ 2 } f }{ \partial y \partial x } & \displaystyle \frac{ \partial ^{ 2 } f }{ \partial y ^{ 2 } } \end{array} \right] } ∂ x 2 ∂ 2 f ∂ y ∂ x ∂ 2 f ∂ x ∂ y ∂ 2 f ∂ y 2 ∂ 2 f [#part^2 f x, part^2 f (x y); part^2 f (y x), #part^2 f y]
With aligned
environment f(x) & = x "e"^x
<-- a blank line here
f'(x) & = (x + 1) "e"^x
<-- a blank line here
f''(x) & = (x + 2) "e"^x
f ( x ) = x e x f ′ ( x ) = ( x + 1 ) e x f ′ ′ ( x ) = ( x + 2 ) e x \displaystyle{ \begin{aligned}f \left( x \right) & = x \text{e} ^{ x } \\ f ^{\prime} \left( x \right) & = \left( x + 1 \right) \text{e} ^{ x } \\ f ^{\prime\prime} \left( x \right) & = \left( x + 2 \right) \text{e} ^{ x }\end{aligned} } f ( x ) f ′ ( x ) f ′′ ( x ) = x e x = ( x + 1 ) e x = ( x + 2 ) e x Caution The &
acts as &
in aligned
env, and the blank lines act as \\
in LaTeX.
Spaces output source width a b \displaystyle{ a \quad b } a b a quad b 1 em a b \displaystyle{ a \qquad b } a b a qquad b 2 em a b \displaystyle{ a \enspace b } a b a enspace b 0.5 em a b \displaystyle{ a \; b } a b a \; b 5/18 em a b \displaystyle{ a \: b } a b a \: b 4/18 em a b \displaystyle{ a \, b } a b a \, b 3/18 em a b \displaystyle{ a \! b } a b a \! b -3/18 em a b \displaystyle{ a \hspace{12pt} b } a b a hspace(12pt) b 12 pt