Comparing version 0.8.0 to 0.9.1
{ | ||
"name": "mf-parser", | ||
"version": "0.8.0", | ||
"version": "0.9.1", | ||
"description": "", | ||
@@ -21,7 +21,10 @@ "main": "src/index.js", | ||
"dependencies": { | ||
"atom-sorter": "^0.8.0", | ||
"chemical-elements": "^0.7.0", | ||
"chemical-groups": "^0.8.0", | ||
"mf-utilities": "^0.8.0" | ||
"atom-sorter": "^0.9.1", | ||
"chemical-elements": "^0.9.1", | ||
"chemical-groups": "^0.9.1", | ||
"mf-utilities": "^0.9.1" | ||
}, | ||
"devDependencies": { | ||
"jest-matcher-deep-close-to": "^1.3.0" | ||
} | ||
} |
'use strict'; | ||
const toMatchCloseTo = require('jest-matcher-deep-close-to').toMatchCloseTo; | ||
expect.extend({ toMatchCloseTo }); | ||
@@ -18,5 +19,5 @@ | ||
let result4 = new MF('C2 . 2C').getEA(); | ||
expect(result1).toEqual(result2); | ||
expect(result1).toEqual(result3); | ||
expect(result1).toEqual(result4); | ||
expect(result1).toStrictEqual(result2); | ||
expect(result1).toStrictEqual(result3); | ||
expect(result1).toStrictEqual(result4); | ||
@@ -23,0 +24,0 @@ expect(new MF('[13C]').getEA()).toMatchCloseTo( |
@@ -6,23 +6,23 @@ 'use strict'; | ||
test('getIsotopesInfo from C{50,50}[13C]H2', () => { | ||
var mf = new MF('[13C]3CC{50,50}((2+))2'); | ||
var info = mf.getIsotopesInfo(); | ||
var mf = new MF('[13C]3CC{50,50}((2+))2'); | ||
var info = mf.getIsotopesInfo(); | ||
expect(info.charge).toBe(4); | ||
expect(info.isotopes[0].distribution).toEqual([{ x: 12, y: 0.9893 }, { x: 13.00335483507, y: 0.0107 }]); | ||
expect(info.isotopes[1].distribution).toEqual([{ x: 13.00335483507, y: 1 }]); | ||
expect(info.isotopes[2].distribution).toEqual([{ x: 12, y: 0.5 }, { x: 13.00335483507, y: 0.5 }]); | ||
expect(info.charge).toBe(4); | ||
expect(info.isotopes[0].distribution).toStrictEqual([{ x: 12, y: 0.9893 }, { x: 13.00335483507, y: 0.0107 }]); | ||
expect(info.isotopes[1].distribution).toStrictEqual([{ x: 13.00335483507, y: 1 }]); | ||
expect(info.isotopes[2].distribution).toStrictEqual([{ x: 12, y: 0.5 }, { x: 13.00335483507, y: 0.5 }]); | ||
}); | ||
test('getIsotopesInfo from C.H', () => { | ||
expect(() => { | ||
var mf = new MF('C.H'); | ||
mf.getIsotopesInfo(); | ||
}).toThrow('getIsotopesInfo can not be applied on multipart MF'); | ||
expect(() => { | ||
var mf = new MF('C.H'); | ||
mf.getIsotopesInfo(); | ||
}).toThrow('getIsotopesInfo can not be applied on multipart MF'); | ||
}); | ||
test('getIsotopesInfo from (CH3(+))2', () => { | ||
var mf = new MF('(CH3(+))2'); | ||
var info = mf.getIsotopesInfo(); | ||
expect(info.charge).toBe(2); | ||
var mf = new MF('(CH3(+))2'); | ||
var info = mf.getIsotopesInfo(); | ||
expect(info.charge).toBe(2); | ||
}); | ||
@@ -6,4 +6,4 @@ 'use strict'; | ||
test('parseToHtml', () => { | ||
var result = MFParser.parseToHtml('SO4(--)'); | ||
expect(result).toBe('SO<span style="flex-direction: column;display: inline-flex;justify-content: center;text-align: left;vertical-align: middle;"><sup style="line-height: 1; font-size: 70%">-2</sup><sub style="line-height: 1; font-size: 70%">4</sub></span>'); | ||
var result = MFParser.parseToHtml('SO4(--)'); | ||
expect(result).toBe('SO<span style="flex-direction: column;display: inline-flex;justify-content: center;text-align: left;vertical-align: middle;"><sup style="line-height: 1; font-size: 70%">-2</sup><sub style="line-height: 1; font-size: 70%">4</sub></span>'); | ||
}); |
@@ -9,3 +9,3 @@ 'use strict'; | ||
expect(parts).toEqual([[{kind: 'atom', value: 'C', multiplier: 1}]]); | ||
expect(parts).toStrictEqual([[{ kind: 'atom', value: 'C', multiplier: 1 }]]); | ||
@@ -22,3 +22,3 @@ var newMF = mf.toMF(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
monoisotopicMass: 12, | ||
@@ -29,3 +29,3 @@ mass: 12.010735896735248, | ||
mf: 'C', | ||
atoms: {C: 1} | ||
atoms: { C: 1 } | ||
}); | ||
@@ -39,5 +39,5 @@ }); | ||
var info2H = mf2H.getInfo(); | ||
expect(infoD).toEqual(info2H); | ||
expect(infoD).toEqual({ | ||
atoms: {H: 1}, | ||
expect(infoD).toStrictEqual(info2H); | ||
expect(infoD).toStrictEqual({ | ||
atoms: { H: 1 }, | ||
charge: 0, | ||
@@ -55,11 +55,11 @@ mass: 2.01410177812, | ||
expect(parts).toEqual([ | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{kind: 'atom', value: 'C', multiplier: 6}, | ||
{kind: 'atom', value: 'H', multiplier: 15}, | ||
{kind: 'atom', value: 'N', multiplier: 1} | ||
{ kind: 'atom', value: 'C', multiplier: 6 }, | ||
{ kind: 'atom', value: 'H', multiplier: 15 }, | ||
{ kind: 'atom', value: 'N', multiplier: 1 } | ||
], | ||
[ | ||
{kind: 'atom', value: 'H', multiplier: 1}, | ||
{kind: 'atom', value: 'Cl', multiplier: 1} | ||
{ kind: 'atom', value: 'H', multiplier: 1 }, | ||
{ kind: 'atom', value: 'Cl', multiplier: 1 } | ||
] | ||
@@ -77,3 +77,3 @@ ]); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
parts: [ | ||
@@ -86,3 +86,3 @@ { | ||
unsaturation: 0, | ||
atoms: {C: 6, H: 15, N: 1} | ||
atoms: { C: 6, H: 15, N: 1 } | ||
}, | ||
@@ -95,3 +95,3 @@ { | ||
unsaturation: 0, | ||
atoms: {H: 1, Cl: 1} | ||
atoms: { H: 1, Cl: 1 } | ||
} | ||
@@ -108,10 +108,12 @@ ], | ||
var mf = new MF('(Me2CH)3N'); | ||
var parts = mf.toParts({expand: false}); | ||
var parts = mf.toParts({ expand: false }); | ||
expect(parts).toEqual([[ | ||
{kind: 'atom', value: 'C', multiplier: 3}, | ||
{kind: 'atom', value: 'H', multiplier: 3}, | ||
{kind: 'atom', value: 'Me', multiplier: 6}, | ||
{kind: 'atom', value: 'N', multiplier: 1} | ||
]]); | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{ kind: 'atom', value: 'C', multiplier: 3 }, | ||
{ kind: 'atom', value: 'H', multiplier: 3 }, | ||
{ kind: 'atom', value: 'Me', multiplier: 6 }, | ||
{ kind: 'atom', value: 'N', multiplier: 1 } | ||
] | ||
]); | ||
@@ -122,3 +124,3 @@ var newMF = mf.toMF(); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
mass: 143.27008211723435, | ||
@@ -129,3 +131,3 @@ monoisotopicMass: 143.16739968126, | ||
unsaturation: 0, | ||
atoms: {C: 3, H: 3, Me: 6, N: 1} | ||
atoms: { C: 3, H: 3, Me: 6, N: 1 } | ||
}); | ||
@@ -136,9 +138,11 @@ }); | ||
var mf = new MF('(Me2CH)3N'); | ||
var parts = mf.toParts({expand: true}); | ||
var parts = mf.toParts({ expand: true }); | ||
expect(parts).toEqual([[ | ||
{kind: 'atom', value: 'C', multiplier: 9}, | ||
{kind: 'atom', value: 'H', multiplier: 21}, | ||
{kind: 'atom', value: 'N', multiplier: 1} | ||
]]); | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{ kind: 'atom', value: 'C', multiplier: 9 }, | ||
{ kind: 'atom', value: 'H', multiplier: 21 }, | ||
{ kind: 'atom', value: 'N', multiplier: 1 } | ||
] | ||
]); | ||
@@ -149,3 +153,3 @@ var newMF = mf.toMF(); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
mass: 143.27008211723435, | ||
@@ -156,3 +160,3 @@ monoisotopicMass: 143.16739968126, | ||
unsaturation: 0, | ||
atoms: {C: 9, H: 21, N: 1} | ||
atoms: { C: 9, H: 21, N: 1 } | ||
}); | ||
@@ -165,6 +169,9 @@ }); | ||
expect(parts).toEqual([[ | ||
{kind: 'atom', value: 'O', multiplier: 4}, | ||
{kind: 'atom', value: 'S', multiplier: 1}, {kind: 'charge', value: -2} | ||
]]); | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{ kind: 'atom', value: 'O', multiplier: 4 }, | ||
{ kind: 'atom', value: 'S', multiplier: 1 }, | ||
{ kind: 'charge', value: -2 } | ||
] | ||
]); | ||
@@ -174,4 +181,4 @@ var newMF = mf.toMF(); | ||
let info = mf.getInfo({customUnsaturations: {S: 4}}); | ||
expect(info).toEqual({ | ||
let info = mf.getInfo({ customUnsaturations: { S: 4 } }); | ||
expect(info).toStrictEqual({ | ||
monoisotopicMass: 95.95172965268, | ||
@@ -183,3 +190,3 @@ mass: 96.06240710340018, | ||
unsaturation: 4, | ||
atoms: {O: 4, S: 1} | ||
atoms: { O: 4, S: 1 } | ||
}); | ||
@@ -197,2 +204,4 @@ }); | ||
expect(new MF('NH4+').getInfo().unsaturation).toBe(-1); | ||
expect(new MF('H(+)').toHtml()).toBe('H<sup>+</sup>'); | ||
}); | ||
@@ -203,11 +212,13 @@ | ||
var parts = mf.toParts(); | ||
expect(parts).toEqual([[ | ||
{kind: 'atom', value: 'C', multiplier: 1}, | ||
{kind: 'isotope', value: {atom: 'C', isotope: 13}, multiplier: 1}, | ||
{kind: 'atom', value: 'N', multiplier: 4}, | ||
{kind: 'isotope', value: {atom: 'N', isotope: 15}, multiplier: 2} | ||
]]); | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{ kind: 'atom', value: 'C', multiplier: 1 }, | ||
{ kind: 'isotope', value: { atom: 'C', isotope: 13 }, multiplier: 1 }, | ||
{ kind: 'atom', value: 'N', multiplier: 4 }, | ||
{ kind: 'isotope', value: { atom: 'N', isotope: 15 }, multiplier: 2 } | ||
] | ||
]); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
monoisotopicMass: 111.01586865055, | ||
@@ -218,3 +229,3 @@ mass: 111.04112137534844, | ||
unsaturation: 6, | ||
atoms: {C: 2, N: 6} | ||
atoms: { C: 2, N: 6 } | ||
}); | ||
@@ -229,3 +240,3 @@ | ||
var info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
mass: 1253.8043977028433, | ||
@@ -235,3 +246,3 @@ monoisotopicMass: 1253.21310019311, | ||
mf: 'C39H51N15O25P4', | ||
atoms: {C: 39, H: 51, N: 15, O: 25, P: 4}, | ||
atoms: { C: 39, H: 51, N: 15, O: 25, P: 4 }, | ||
unsaturation: 24 | ||
@@ -244,3 +255,3 @@ }); | ||
var info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
mass: 653.388021231099, | ||
@@ -250,3 +261,3 @@ monoisotopicMass: 653.08838712715, | ||
mf: 'C19H25N7O15P2', | ||
atoms: {C: 19, H: 25, N: 7, O: 15, P: 2}, | ||
atoms: { C: 19, H: 25, N: 7, O: 15, P: 2 }, | ||
unsaturation: 12 | ||
@@ -259,7 +270,13 @@ }); | ||
var parts = mf.toParts(); | ||
expect(parts).toEqual([[ | ||
{kind: 'atom', value: 'C', multiplier: 1}, | ||
{kind: 'isotopeRatio', value: {atom: 'C', ratio: [50, 50]}, multiplier: 1}, | ||
{kind: 'atom', value: 'H', multiplier: 1} | ||
]]); | ||
expect(parts).toStrictEqual([ | ||
[ | ||
{ kind: 'atom', value: 'C', multiplier: 1 }, | ||
{ | ||
kind: 'isotopeRatio', | ||
value: { atom: 'C', ratio: [50, 50] }, | ||
multiplier: 1 | ||
}, | ||
{ kind: 'atom', value: 'H', multiplier: 1 } | ||
] | ||
]); | ||
@@ -270,3 +287,3 @@ var newMF = mf.toMF(); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
expect(info).toStrictEqual({ | ||
monoisotopicMass: 25.00782503223, | ||
@@ -277,3 +294,3 @@ mass: 25.520354068326025, | ||
unsaturation: 2.5, | ||
atoms: {C: 2, H: 1} | ||
atoms: { C: 2, H: 1 } | ||
}); | ||
@@ -289,4 +306,4 @@ }); | ||
let info = mf.getInfo(); | ||
expect(info).toEqual({ | ||
atoms: {H: 1}, | ||
expect(info).toStrictEqual({ | ||
atoms: { H: 1 }, | ||
charge: 0, | ||
@@ -293,0 +310,0 @@ mass: 1.0079407540557772, |
@@ -6,120 +6,156 @@ 'use strict'; | ||
var tests = { | ||
C10: [{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 10}], | ||
'C-1': [{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: -1}], | ||
C10: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: 10 }], | ||
'C-1': [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: -1 }], | ||
'C1-10': [ | ||
{kind: 'atom', value: 'C'}, | ||
{kind: 'multiplierRange', value: {from: 1, to: 10}} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplierRange', value: { from: 1, to: 10 } } | ||
], | ||
'2H': [{kind: 'preMultiplier', value: 2}, {kind: 'atom', value: 'H'}], | ||
'[13C]': [{kind: 'isotope', value: {atom: 'C', isotope: 13}}], | ||
'[2H]': [{kind: 'isotope', value: {atom: 'H', isotope: 2}}], | ||
'C+': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: 1}], | ||
'C-': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: -1}], | ||
'2H': [{ kind: 'preMultiplier', value: 2 }, { kind: 'atom', value: 'H' }], | ||
'[13C]': [{ kind: 'isotope', value: { atom: 'C', isotope: 13 } }], | ||
'[2H]': [{ kind: 'isotope', value: { atom: 'H', isotope: 2 } }], | ||
'C+': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 1 }], | ||
'C-': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: -1 }], | ||
'C-H': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'charge', value: -1}, | ||
{kind: 'atom', value: 'H'} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'charge', value: -1 }, | ||
{ kind: 'atom', value: 'H' } | ||
], | ||
'C++': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: 2}], | ||
'C--': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: -2}], | ||
'C++': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
'C--': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: -2 }], | ||
'C2+': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 2}, | ||
{kind: 'charge', value: 1} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'charge', value: 1 } | ||
], | ||
'C(2+)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: 2}], | ||
'C(++)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: 2}], | ||
'C(+2)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: 2}], | ||
'C(2-)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: -2}], | ||
'C(-2)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: -2}], | ||
'C(--)': [{kind: 'atom', value: 'C'}, {kind: 'charge', value: -2}], | ||
'C(2+)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
'C(++)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
'C(+2)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
'C(2-)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: -2 }], | ||
'C(-2)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: -2 }], | ||
'C(--)': [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: -2 }], | ||
'(H+)': [ | ||
{kind: 'openingParenthesis', value: '('}, {kind: 'atom', value: 'H'}, | ||
{kind: 'charge', value: 1}, {kind: 'closingParenthesis', value: ')'} | ||
{ kind: 'openingParenthesis', value: '(' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'charge', value: 1 }, | ||
{ kind: 'closingParenthesis', value: ')' } | ||
], | ||
C$ABC: [{kind: 'atom', value: 'C'}, {kind: 'comment', value: 'ABC'}], | ||
C$ABC: [{ kind: 'atom', value: 'C' }, { kind: 'comment', value: 'ABC' }], | ||
'C(-1)(-3)': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'charge', value: -1}, | ||
{kind: 'charge', value: -3} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'charge', value: -1 }, | ||
{ kind: 'charge', value: -3 } | ||
], | ||
'C(-1)2(-3)3': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'charge', value: -1}, | ||
{kind: 'multiplier', value: 2}, {kind: 'charge', value: -3}, | ||
{kind: 'multiplier', value: 3} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'charge', value: -1 }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'charge', value: -3 }, | ||
{ kind: 'multiplier', value: 3 } | ||
], | ||
'C(H-2)': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'openingParenthesis', value: '('}, | ||
{kind: 'atom', value: 'H'}, {kind: 'multiplier', value: -2}, | ||
{kind: 'closingParenthesis', value: ')'} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'openingParenthesis', value: '(' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: -2 }, | ||
{ kind: 'closingParenthesis', value: ')' } | ||
], | ||
'H.Cl': [ | ||
{kind: 'atom', value: 'H'}, {kind: 'salt', value: '.'}, | ||
{kind: 'atom', value: 'Cl'} | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
'H{1,1}': [{kind: 'isotopeRatio', value: {atom: 'H', ratio: [1, 1]}}], | ||
'H{1,1}': [{ kind: 'isotopeRatio', value: { atom: 'H', ratio: [1, 1] } }], | ||
'C10 . H20': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 10}, | ||
{kind: 'text', value: ' '}, {kind: 'salt', value: '.'}, | ||
{kind: 'text', value: ' '}, {kind: 'atom', value: 'H'}, | ||
{kind: 'multiplier', value: 20} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 10 }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: 20 } | ||
], | ||
'(CH(CH3)2)3N.2HCl': [ | ||
{kind: 'openingParenthesis', value: '('}, {kind: 'atom', value: 'C'}, | ||
{kind: 'atom', value: 'H'}, {kind: 'openingParenthesis', value: '('}, | ||
{kind: 'atom', value: 'C'}, {kind: 'atom', value: 'H'}, | ||
{kind: 'multiplier', value: 3}, {kind: 'closingParenthesis', value: ')'}, | ||
{kind: 'multiplier', value: 2}, {kind: 'closingParenthesis', value: ')'}, | ||
{kind: 'multiplier', value: 3}, {kind: 'atom', value: 'N'}, | ||
{kind: 'salt', value: '.'}, {kind: 'preMultiplier', value: 2}, | ||
{kind: 'atom', value: 'H'}, {kind: 'atom', value: 'Cl'} | ||
{ kind: 'openingParenthesis', value: '(' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'openingParenthesis', value: '(' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: 3 }, | ||
{ kind: 'closingParenthesis', value: ')' }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'closingParenthesis', value: ')' }, | ||
{ kind: 'multiplier', value: 3 }, | ||
{ kind: 'atom', value: 'N' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'preMultiplier', value: 2 }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
'C.C2.C3': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'salt', value: '.'}, | ||
{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 2}, | ||
{kind: 'salt', value: '.'}, {kind: 'atom', value: 'C'}, | ||
{kind: 'multiplier', value: 3} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 3 } | ||
], | ||
'C10.C20.C30': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 10}, | ||
{kind: 'salt', value: '.'}, {kind: 'atom', value: 'C'}, | ||
{kind: 'multiplier', value: 20}, {kind: 'salt', value: '.'}, | ||
{kind: 'atom', value: 'C'}, {kind: 'multiplier', value: 30} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 10 }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 20 }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 30 } | ||
], | ||
'C.0.5H2O.0.6HCl': [ | ||
{kind: 'atom', value: 'C'}, {kind: 'salt', value: '.'}, | ||
{kind: 'preMultiplier', value: 0.5}, {kind: 'atom', value: 'H'}, | ||
{kind: 'multiplier', value: 2}, {kind: 'atom', value: 'O'}, | ||
{kind: 'salt', value: '.'}, {kind: 'preMultiplier', value: 0.6}, | ||
{kind: 'atom', value: 'H'}, {kind: 'atom', value: 'Cl'} | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'preMultiplier', value: 0.5 }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'atom', value: 'O' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'preMultiplier', value: 0.6 }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
'NH3 . 2HCl': [ | ||
{kind: 'atom', value: 'N'}, {kind: 'atom', value: 'H'}, | ||
{kind: 'multiplier', value: 3}, {kind: 'text', value: ' '}, | ||
{kind: 'salt', value: '.'}, {kind: 'text', value: ' '}, | ||
{kind: 'preMultiplier', value: 2}, {kind: 'atom', value: 'H'}, | ||
{kind: 'atom', value: 'Cl'} | ||
{ kind: 'atom', value: 'N' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: 3 }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'preMultiplier', value: 2 }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
'2NH3 . 2HCl': [ | ||
{kind: 'preMultiplier', value: 2}, {kind: 'atom', value: 'N'}, | ||
{kind: 'atom', value: 'H'}, {kind: 'multiplier', value: 3}, | ||
{kind: 'text', value: ' '}, {kind: 'salt', value: '.'}, | ||
{kind: 'text', value: ' '}, {kind: 'preMultiplier', value: 2}, | ||
{kind: 'atom', value: 'H'}, {kind: 'atom', value: 'Cl'} | ||
{ kind: 'preMultiplier', value: 2 }, | ||
{ kind: 'atom', value: 'N' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: 3 }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'text', value: ' ' }, | ||
{ kind: 'preMultiplier', value: 2 }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
D: [{'kind': 'atom', 'value': 'D'}] | ||
D: [{ kind: 'atom', value: 'D' }] | ||
}; | ||
test('parse molecular formula', function() { | ||
for (var key of Object.keys(tests)) { | ||
checkMF(key, tests[key]); | ||
} | ||
test.each(Object.keys(tests))('parse molecular formula %s', function (key) { | ||
let parsed = parse(key); | ||
expect(parsed).toMatchObject(tests[key]); | ||
}); | ||
test('not same opening and closing parenthesis', function() { | ||
test('not same opening and closing parenthesis', function () { | ||
expect(() => { | ||
parse('C('); | ||
}).toThrowError(/.*opening and closing.*/); | ||
}).toThrow(/.*opening and closing.*/); | ||
}); | ||
function checkMF(mf, result) { | ||
let parsed = parse(mf); | ||
expect(parsed).toMatchObject(result); | ||
} |
@@ -8,6 +8,6 @@ 'use strict'; | ||
module.exports = { | ||
SUBSCRIPT: 'subscript', | ||
SUPERSCRIPT: 'superscript', | ||
SUPERIMPOSE: 'superimpose', | ||
TEXT: 'text' | ||
SUBSCRIPT: 'subscript', | ||
SUPERSCRIPT: 'superscript', | ||
SUPERIMPOSE: 'superimpose', | ||
TEXT: 'text' | ||
}; |
@@ -12,16 +12,16 @@ 'use strict'; | ||
function parseToHtml(mf) { | ||
var parsed = parse(mf); | ||
var display = toDisplay(parsed); | ||
return toHtml(display); | ||
var parsed = parse(mf); | ||
var display = toDisplay(parsed); | ||
return toHtml(display); | ||
} | ||
module.exports = { | ||
Kind: require('./Kind'), | ||
Format: require('./Format'), | ||
Style: require('./Style'), | ||
parse: require('./parse'), | ||
toDisplay, | ||
toHtml, | ||
parseToHtml, | ||
MF: require('./MF'), | ||
Kind: require('./Kind'), | ||
Format: require('./Format'), | ||
Style: require('./Style'), | ||
parse: require('./parse'), | ||
toDisplay, | ||
toHtml, | ||
parseToHtml, | ||
MF: require('./MF'), | ||
}; |
@@ -7,15 +7,15 @@ 'use strict'; | ||
module.exports = { | ||
BEGIN: 'begin', | ||
ATOM: 'atom', | ||
MULTIPLIER_RANGE: 'multiplierRange', | ||
ISOTOPE: 'isotope', | ||
ISOTOPE_RATIO: 'isotopeRatio', | ||
CHARGE: 'charge', | ||
SALT: 'salt', | ||
OPENING_PARENTHESIS: 'openingParenthesis', | ||
CLOSING_PARENTHESIS: 'closingParenthesis', | ||
PRE_MULTIPLIER: 'preMultiplier', | ||
MULTIPLIER: 'multiplier', | ||
TEXT: 'text', | ||
COMMENT: 'comment' | ||
BEGIN: 'begin', | ||
ATOM: 'atom', | ||
MULTIPLIER_RANGE: 'multiplierRange', | ||
ISOTOPE: 'isotope', | ||
ISOTOPE_RATIO: 'isotopeRatio', | ||
CHARGE: 'charge', | ||
SALT: 'salt', | ||
OPENING_PARENTHESIS: 'openingParenthesis', | ||
CLOSING_PARENTHESIS: 'closingParenthesis', | ||
PRE_MULTIPLIER: 'preMultiplier', | ||
MULTIPLIER: 'multiplier', | ||
TEXT: 'text', | ||
COMMENT: 'comment' | ||
}; |
338
src/parse.js
@@ -13,196 +13,196 @@ 'use strict'; | ||
module.exports = function parse(mf) { | ||
return new MFParser().parse(mf); | ||
return new MFParser().parse(mf); | ||
}; | ||
class MFParser { | ||
parse(mf = '') { | ||
this.mf = mf; | ||
this.i = 0; | ||
this.result = []; | ||
parse(mf = '') { | ||
this.mf = mf; | ||
this.i = 0; | ||
this.result = []; | ||
let lastKind = Kind.BEGIN; | ||
while (this.i < mf.length) { | ||
if (this.result.length > 0 && this.result[this.result.length - 1].kind !== Kind.TEXT) { | ||
lastKind = this.result[this.result.length - 1].kind; | ||
} | ||
let char = mf.charAt(this.i); | ||
let ascii = mf.charCodeAt(this.i); | ||
let nextAscii = 0; | ||
if (this.i + 1 < mf.length) nextAscii = mf.charCodeAt(this.i + 1); | ||
let lastKind = Kind.BEGIN; | ||
while (this.i < mf.length) { | ||
if (this.result.length > 0 && this.result[this.result.length - 1].kind !== Kind.TEXT) { | ||
lastKind = this.result[this.result.length - 1].kind; | ||
} | ||
let char = mf.charAt(this.i); | ||
let ascii = mf.charCodeAt(this.i); | ||
let nextAscii = 0; | ||
if (this.i + 1 < mf.length) nextAscii = mf.charCodeAt(this.i + 1); | ||
if ((ascii > 47 && ascii < 58) || (char === '-' && nextAscii > 47 && nextAscii < 58)) { // a number | ||
let value = this.getNumber(ascii); | ||
if (lastKind === Kind.SALT || lastKind === Kind.BEGIN || lastKind === Kind.OPENING_PARENTHESIS) { | ||
if (value.to) throw new MFError(this.mf, this.i, 'Premultiplier may not contain a -'); | ||
this.result.push({ kind: Kind.PRE_MULTIPLIER, value: value.from }); | ||
} else { | ||
if (value.to) { | ||
this.result.push({ kind: Kind.MULTIPLIER_RANGE, value }); | ||
} else { | ||
this.result.push({ kind: Kind.MULTIPLIER, value: value.from }); | ||
} | ||
} | ||
continue; | ||
} else if (char === '.') { // a point | ||
this.result.push({ kind: Kind.SALT, value: char }); | ||
// it is not in a number otherwise it would have been taken before | ||
// it must be in a salt | ||
} else if (ascii > 64 && ascii < 91) { // an uppercase = new atom | ||
let value = this.getAtom(ascii); | ||
this.result.push({ kind: Kind.ATOM, value }); | ||
continue; | ||
} else if (ascii > 96 && ascii < 123) { // a lowercase | ||
throw new MFError(this.mf, this.i, 'found a lowercase not following an uppercase'); | ||
} else if (char === '(') { | ||
let charge = this.getParenthesisCharge(ascii); | ||
if (charge) { | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else { | ||
this.result.push({ kind: Kind.OPENING_PARENTHESIS, value: '(' }); | ||
} | ||
} else if (char === ')') { | ||
this.result.push({ kind: Kind.CLOSING_PARENTHESIS, value: ')' }); | ||
} else if (char === '[') { // defines an isotope | ||
let isotope = this.getIsotope(ascii); | ||
this.result.push({ kind: Kind.ISOTOPE, value: isotope }); | ||
} else if (char === ']') { | ||
throw new MFError(this.mf, this.i, 'should never meet an closing bracket not in isotopes'); | ||
} else if (char === '{') { // can define an exotic isotopic ratio or mixtures of groups | ||
let isotopeRatio = this.getCurlyBracketIsotopeRatio(ascii); | ||
if (lastKind === Kind.ATOM) { | ||
let lastResult = this.result[this.result.length - 1]; | ||
lastResult.kind = Kind.ISOTOPE_RATIO; | ||
lastResult.value = { | ||
atom: lastResult.value, | ||
ratio: isotopeRatio | ||
}; | ||
} else { | ||
throw new MFError(this.mf, this.i, 'isotopic composition has to follow an atom'); | ||
} | ||
} else if (char === '}') { | ||
throw new MFError(this.mf, this.i, 'found a unexpected closing curly bracket'); | ||
} else if (char === '+') { // charge not in parenthesis | ||
let charge = this.getNonParenthesisCharge(ascii); | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else if (char === '-') { // charge not in parenthesis | ||
let charge = this.getNonParenthesisCharge(ascii); | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else if (char === '$') { // it is a comment after | ||
this.result.push({ kind: Kind.COMMENT, value: this.mf.substring(this.i + 1) }); | ||
break; | ||
} else { | ||
this.result.push({ kind: Kind.TEXT, value: char }); | ||
} | ||
this.i++; | ||
if ((ascii > 47 && ascii < 58) || (char === '-' && nextAscii > 47 && nextAscii < 58)) { // a number | ||
let value = this.getNumber(ascii); | ||
if (lastKind === Kind.SALT || lastKind === Kind.BEGIN || lastKind === Kind.OPENING_PARENTHESIS) { | ||
if (value.to) throw new MFError(this.mf, this.i, 'Premultiplier may not contain a -'); | ||
this.result.push({ kind: Kind.PRE_MULTIPLIER, value: value.from }); | ||
} else { | ||
if (value.to) { | ||
this.result.push({ kind: Kind.MULTIPLIER_RANGE, value }); | ||
} else { | ||
this.result.push({ kind: Kind.MULTIPLIER, value: value.from }); | ||
} | ||
} | ||
this.checkParenthesis(); | ||
return this.result; | ||
} | ||
checkParenthesis() { | ||
let counter = 0; | ||
for (let line of this.result) { | ||
if (line.kind === Kind.OPENING_PARENTHESIS) counter++; | ||
if (line.kind === Kind.CLOSING_PARENTHESIS) counter--; | ||
continue; | ||
} else if (char === '.') { // a point | ||
this.result.push({ kind: Kind.SALT, value: char }); | ||
// it is not in a number otherwise it would have been taken before | ||
// it must be in a salt | ||
} else if (ascii > 64 && ascii < 91) { // an uppercase = new atom | ||
let value = this.getAtom(ascii); | ||
this.result.push({ kind: Kind.ATOM, value }); | ||
continue; | ||
} else if (ascii > 96 && ascii < 123) { // a lowercase | ||
throw new MFError(this.mf, this.i, 'found a lowercase not following an uppercase'); | ||
} else if (char === '(') { | ||
let charge = this.getParenthesisCharge(ascii); | ||
if (charge) { | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else { | ||
this.result.push({ kind: Kind.OPENING_PARENTHESIS, value: '(' }); | ||
} | ||
if (counter !== 0) { | ||
throw new MFError(this.mf, this.i, 'number of opening and closing parenthesis not equal'); | ||
} else if (char === ')') { | ||
this.result.push({ kind: Kind.CLOSING_PARENTHESIS, value: ')' }); | ||
} else if (char === '[') { // defines an isotope | ||
let isotope = this.getIsotope(ascii); | ||
this.result.push({ kind: Kind.ISOTOPE, value: isotope }); | ||
} else if (char === ']') { | ||
throw new MFError(this.mf, this.i, 'should never meet an closing bracket not in isotopes'); | ||
} else if (char === '{') { // can define an exotic isotopic ratio or mixtures of groups | ||
let isotopeRatio = this.getCurlyBracketIsotopeRatio(ascii); | ||
if (lastKind === Kind.ATOM) { | ||
let lastResult = this.result[this.result.length - 1]; | ||
lastResult.kind = Kind.ISOTOPE_RATIO; | ||
lastResult.value = { | ||
atom: lastResult.value, | ||
ratio: isotopeRatio | ||
}; | ||
} else { | ||
throw new MFError(this.mf, this.i, 'isotopic composition has to follow an atom'); | ||
} | ||
} else if (char === '}') { | ||
throw new MFError(this.mf, this.i, 'found a unexpected closing curly bracket'); | ||
} else if (char === '+') { // charge not in parenthesis | ||
let charge = this.getNonParenthesisCharge(ascii); | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else if (char === '-') { // charge not in parenthesis | ||
let charge = this.getNonParenthesisCharge(ascii); | ||
this.result.push({ kind: Kind.CHARGE, value: charge }); | ||
} else if (char === '$') { // it is a comment after | ||
this.result.push({ kind: Kind.COMMENT, value: this.mf.substring(this.i + 1) }); | ||
break; | ||
} else { | ||
this.result.push({ kind: Kind.TEXT, value: char }); | ||
} | ||
this.i++; | ||
} | ||
getNumber(ascii) { | ||
let number = ''; | ||
let previous; | ||
do { | ||
previous = ascii; | ||
number += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii > 47 && ascii < 58 || ascii === 46 || ascii === 45); // number, . or - | ||
// we need to deal with the case there is a from / to | ||
if (previous === 46) this.i--; | ||
let indexOfDash = number.indexOf('-', 1); | ||
this.checkParenthesis(); | ||
return this.result; | ||
} | ||
if (indexOfDash > -1) { | ||
return { from: Number(number.substr(0, indexOfDash)), to: Number(number.substr(indexOfDash + 1)) }; | ||
} | ||
return { from: Number(number) }; | ||
checkParenthesis() { | ||
let counter = 0; | ||
for (let line of this.result) { | ||
if (line.kind === Kind.OPENING_PARENTHESIS) counter++; | ||
if (line.kind === Kind.CLOSING_PARENTHESIS) counter--; | ||
} | ||
getAtom(ascii) { | ||
let atom = ''; | ||
do { | ||
atom += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii > 96 && ascii < 123); | ||
return atom; | ||
if (counter !== 0) { | ||
throw new MFError(this.mf, this.i, 'number of opening and closing parenthesis not equal'); | ||
} | ||
} | ||
getIsotope(ascii) { // [13C] | ||
let substring = ''; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 93 && this.i <= this.mf.length); | ||
getNumber(ascii) { | ||
let number = ''; | ||
let previous; | ||
do { | ||
previous = ascii; | ||
number += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii > 47 && ascii < 58 || ascii === 46 || ascii === 45); // number, . or - | ||
// we need to deal with the case there is a from / to | ||
if (previous === 46) this.i--; | ||
let indexOfDash = number.indexOf('-', 1); | ||
let atom = substring.replace(/[^a-zA-Z]/g, ''); | ||
let isotope = Number(substring.replace(/[^0-9]/g, '')); | ||
return { atom, isotope }; | ||
if (indexOfDash > -1) { | ||
return { from: Number(number.substr(0, indexOfDash)), to: Number(number.substr(indexOfDash + 1)) }; | ||
} | ||
return { from: Number(number) }; | ||
} | ||
getAtom(ascii) { | ||
let atom = ''; | ||
do { | ||
atom += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii > 96 && ascii < 123); | ||
return atom; | ||
} | ||
getCurlyBracketIsotopeRatio(ascii) { | ||
let substring = ''; | ||
let first = true; | ||
do { | ||
if (!first) { | ||
substring += String.fromCharCode(ascii); | ||
} else { | ||
first = false; | ||
} | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 125 && this.i <= this.mf.length); // closing curly bracket | ||
if (substring.match(/^[0-9,]+$/)) { | ||
return substring.split(',').map((a) => Number(a)); | ||
} | ||
throw new MFError(this.mf, this.i, 'Curly brackets should contain only number and comma'); | ||
getIsotope(ascii) { // [13C] | ||
let substring = ''; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 93 && this.i <= this.mf.length); | ||
let atom = substring.replace(/[^a-zA-Z]/g, ''); | ||
let isotope = Number(substring.replace(/[^0-9]/g, '')); | ||
return { atom, isotope }; | ||
} | ||
getCurlyBracketIsotopeRatio(ascii) { | ||
let substring = ''; | ||
let first = true; | ||
do { | ||
if (!first) { | ||
substring += String.fromCharCode(ascii); | ||
} else { | ||
first = false; | ||
} | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 125 && this.i <= this.mf.length); // closing curly bracket | ||
if (substring.match(/^[0-9,]+$/)) { | ||
return substring.split(',').map((a) => Number(a)); | ||
} | ||
throw new MFError(this.mf, this.i, 'Curly brackets should contain only number and comma'); | ||
} | ||
getParenthesisCharge(ascii) { | ||
let substring = ''; | ||
let begin = this.i; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 41 && this.i <= this.mf.length); // closing parenthesis | ||
if (substring.match(/^\([0-9+-]+$/)) { | ||
return parseCharge(substring.substring(1)); | ||
} else { | ||
this.i = begin; | ||
return undefined; | ||
} | ||
getParenthesisCharge(ascii) { | ||
let substring = ''; | ||
let begin = this.i; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii !== 41 && this.i <= this.mf.length); // closing parenthesis | ||
if (substring.match(/^\([0-9+-]+$/)) { | ||
return parseCharge(substring.substring(1)); | ||
} else { | ||
this.i = begin; | ||
return undefined; | ||
} | ||
} | ||
getNonParenthesisCharge(ascii) { | ||
let substring = ''; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii === 43 || ascii === 45 || (ascii > 47 && ascii < 58)); | ||
this.i--; | ||
return parseCharge(substring); | ||
} | ||
getNonParenthesisCharge(ascii) { | ||
let substring = ''; | ||
do { | ||
substring += String.fromCharCode(ascii); | ||
this.i++; | ||
ascii = this.mf.charCodeAt(this.i); | ||
} while (ascii === 43 || ascii === 45 || (ascii > 47 && ascii < 58)); | ||
this.i--; | ||
return parseCharge(substring); | ||
} | ||
} | ||
class MFError extends SyntaxError { | ||
constructor(mf, i, message) { | ||
let text = `${message}\n\n${mf}\n${' '.repeat(i)}^`; | ||
super(text); | ||
} | ||
constructor(mf, i, message) { | ||
let text = `${message}\n\n${mf}\n${' '.repeat(i)}^`; | ||
super(text); | ||
} | ||
} |
'use strict'; | ||
module.exports = { | ||
SUPERIMPOSE: 'flex-direction: column;display: inline-flex;justify-content: center;text-align: left;vertical-align: middle;', | ||
SUPERIMPOSE_SUP_SUB: 'line-height: 1; font-size: 70%' | ||
SUPERIMPOSE: 'flex-direction: column;display: inline-flex;justify-content: center;text-align: left;vertical-align: middle;', | ||
SUPERIMPOSE_SUP_SUB: 'line-height: 1; font-size: 70%' | ||
}; | ||
@@ -6,7 +6,7 @@ 'use strict'; | ||
test('formatCharge', function () { | ||
expect(formatCharge(-2)).toBe('-2'); | ||
expect(formatCharge(-1)).toBe('-1'); | ||
expect(formatCharge(0)).toBe(''); | ||
expect(formatCharge(1)).toBe('+'); | ||
expect(formatCharge(2)).toBe('+2'); | ||
expect(formatCharge(-2)).toBe('-2'); | ||
expect(formatCharge(-1)).toBe('-1'); | ||
expect(formatCharge(0)).toBe(''); | ||
expect(formatCharge(1)).toBe('+'); | ||
expect(formatCharge(2)).toBe('+2'); | ||
}); |
@@ -6,9 +6,9 @@ 'use strict'; | ||
test('getCharge', function () { | ||
expect(getCharge('---')).toBe(-3); | ||
expect(getCharge('+++')).toBe(3); | ||
expect(getCharge('---++')).toBe(-1); | ||
expect(getCharge('(-3)')).toBe(-3); | ||
expect(getCharge('(+1)')).toBe(1); | ||
expect(getCharge('(---)')).toBe(-3); | ||
expect(getCharge('(++)')).toBe(2); | ||
expect(getCharge('---')).toBe(-3); | ||
expect(getCharge('+++')).toBe(3); | ||
expect(getCharge('---++')).toBe(-1); | ||
expect(getCharge('(-3)')).toBe(-3); | ||
expect(getCharge('(+1)')).toBe(1); | ||
expect(getCharge('(---)')).toBe(-3); | ||
expect(getCharge('(++)')).toBe(2); | ||
}); |
'use strict'; | ||
var tests = [ | ||
{ | ||
mf: 'C10', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: 10 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '10' }] | ||
}, | ||
{ | ||
mf: 'C-1', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: -1 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '-1' }] | ||
}, | ||
{ | ||
mf: 'C1-10', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplierRange', value: { from: 1, to: 10 } }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '1-10' }] | ||
}, | ||
{ | ||
mf: '2H', | ||
parsed: [{ kind: 'preMultiplier', value: 2 }, { kind: 'atom', value: 'H' }], | ||
result: [{ kind: 'text', value: '2H' }] | ||
}, | ||
{ | ||
mf: '[13C]', | ||
parsed: [{ kind: 'isotope', value: { atom: 'C', isotope: 13 } }], | ||
result: [{ kind: 'superscript', value: 13 }, { kind: 'text', value: 'C' }] | ||
}, | ||
{ | ||
mf: 'C++', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'superscript', value: '+2' }] | ||
}, | ||
{ | ||
mf: 'C2+', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: 2 }, { kind: 'charge', value: 1 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'superimpose', over: '+', under: '2' }] | ||
}, | ||
{ | ||
mf: 'C(H-2)', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'openingParenthesis', value: '(' }, { kind: 'atom', value: 'H' }, { kind: 'multiplier', value: -2 }, { kind: 'closingParenthesis', value: ')' }], | ||
result: [{ kind: 'text', value: 'C(H' }, { kind: 'subscript', value: '-2' }, { kind: 'text', value: ')' }] | ||
}, | ||
{ | ||
mf: 'H.Cl', | ||
parsed: [{ kind: 'atom', value: 'H' }, { kind: 'salt', value: '.' }, { kind: 'atom', value: 'Cl' }], | ||
result: [{ kind: 'text', value: 'H•Cl' }] | ||
}, | ||
{ | ||
mf: 'H{1,1}', | ||
parsed: [{ kind: 'isotopeRatio', value: { atom: 'H', ratio: [1, 1] } }], | ||
result: [{ kind: 'text', value: 'H' }, { kind: 'superscript', value: '{1,1}' }] | ||
}, | ||
{ | ||
mf: 'C10', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: 10 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '10' }] | ||
}, | ||
{ | ||
mf: 'C-1', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'multiplier', value: -1 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '-1' }] | ||
}, | ||
{ | ||
mf: 'C1-10', | ||
parsed: [ | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplierRange', value: { from: 1, to: 10 } } | ||
], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'subscript', value: '1-10' }] | ||
}, | ||
{ | ||
mf: '2H', | ||
parsed: [{ kind: 'preMultiplier', value: 2 }, { kind: 'atom', value: 'H' }], | ||
result: [{ kind: 'text', value: '2H' }] | ||
}, | ||
{ | ||
mf: '[13C]', | ||
parsed: [{ kind: 'isotope', value: { atom: 'C', isotope: 13 } }], | ||
result: [{ kind: 'superscript', value: 13 }, { kind: 'text', value: 'C' }] | ||
}, | ||
{ | ||
mf: 'C++', | ||
parsed: [{ kind: 'atom', value: 'C' }, { kind: 'charge', value: 2 }], | ||
result: [{ kind: 'text', value: 'C' }, { kind: 'superscript', value: '+2' }] | ||
}, | ||
{ | ||
mf: 'C2+', | ||
parsed: [ | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'multiplier', value: 2 }, | ||
{ kind: 'charge', value: 1 } | ||
], | ||
result: [ | ||
{ kind: 'text', value: 'C' }, | ||
{ kind: 'superimpose', over: '+', under: '2' } | ||
] | ||
}, | ||
{ | ||
mf: 'C(H-2)', | ||
parsed: [ | ||
{ kind: 'atom', value: 'C' }, | ||
{ kind: 'openingParenthesis', value: '(' }, | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'multiplier', value: -2 }, | ||
{ kind: 'closingParenthesis', value: ')' } | ||
], | ||
result: [ | ||
{ kind: 'text', value: 'C(H' }, | ||
{ kind: 'subscript', value: '-2' }, | ||
{ kind: 'text', value: ')' } | ||
] | ||
}, | ||
{ | ||
mf: 'H.Cl', | ||
parsed: [ | ||
{ kind: 'atom', value: 'H' }, | ||
{ kind: 'salt', value: '.' }, | ||
{ kind: 'atom', value: 'Cl' } | ||
], | ||
result: [{ kind: 'text', value: 'H•Cl' }] | ||
}, | ||
{ | ||
mf: 'H{1,1}', | ||
parsed: [{ kind: 'isotopeRatio', value: { atom: 'H', ratio: [1, 1] } }], | ||
result: [ | ||
{ kind: 'text', value: 'H' }, | ||
{ kind: 'superscript', value: '{1,1}' } | ||
] | ||
} | ||
]; | ||
const toDisplay = require('../toDisplay'); | ||
test('toDisplay', function () { | ||
for (let aTest of tests) { | ||
checkMF(aTest.parsed, aTest.result); | ||
} | ||
test.each(tests)('toDisplay', function (aTest) { | ||
var display = toDisplay(aTest.parsed); | ||
expect(display).toMatchObject(aTest.result); | ||
}); | ||
function checkMF(parsed, result) { | ||
var display = toDisplay(parsed); | ||
expect(display).toMatchObject(result); | ||
} | ||
@@ -6,12 +6,16 @@ 'use strict'; | ||
var tests = [ | ||
{mf: 'C', result: [[{kind: 'atom', value: 'C', multiplier: 1}]]}, | ||
{mf: 'C2', result: [[{kind: 'atom', value: 'C', multiplier: 2}]]}, | ||
{mf: 'CCC', result: [[{kind: 'atom', value: 'C', multiplier: 3}]]}, | ||
{mf: '2CCC', result: [[{kind: 'atom', value: 'C', multiplier: 6}]]}, | ||
{mf: '2C(C(C2)2)3', result: [[{kind: 'atom', value: 'C', multiplier: 32}]]}, { | ||
{ mf: 'C', result: [[{ kind: 'atom', value: 'C', multiplier: 1 }]] }, | ||
{ mf: 'C2', result: [[{ kind: 'atom', value: 'C', multiplier: 2 }]] }, | ||
{ mf: 'CCC', result: [[{ kind: 'atom', value: 'C', multiplier: 3 }]] }, | ||
{ mf: '2CCC', result: [[{ kind: 'atom', value: 'C', multiplier: 6 }]] }, | ||
{ | ||
mf: '2C(C(C2)2)3', | ||
result: [[{ kind: 'atom', value: 'C', multiplier: 32 }]] | ||
}, | ||
{ | ||
mf: '3C.2C.C4', | ||
result: [ | ||
[{kind: 'atom', value: 'C', multiplier: 3}], | ||
[{kind: 'atom', value: 'C', multiplier: 2}], | ||
[{kind: 'atom', value: 'C', multiplier: 4}] | ||
[{ kind: 'atom', value: 'C', multiplier: 3 }], | ||
[{ kind: 'atom', value: 'C', multiplier: 2 }], | ||
[{ kind: 'atom', value: 'C', multiplier: 4 }] | ||
] | ||
@@ -23,9 +27,9 @@ }, | ||
[ | ||
{kind: 'atom', value: 'C', multiplier: 6}, | ||
{kind: 'atom', value: 'H', multiplier: 15}, | ||
{kind: 'atom', value: 'N', multiplier: 1} | ||
{ kind: 'atom', value: 'C', multiplier: 6 }, | ||
{ kind: 'atom', value: 'H', multiplier: 15 }, | ||
{ kind: 'atom', value: 'N', multiplier: 1 } | ||
], | ||
[ | ||
{kind: 'atom', value: 'H', multiplier: 1}, | ||
{kind: 'atom', value: 'Cl', multiplier: 1} | ||
{ kind: 'atom', value: 'H', multiplier: 1 }, | ||
{ kind: 'atom', value: 'Cl', multiplier: 1 } | ||
] | ||
@@ -36,11 +40,12 @@ ] | ||
mf: '3[13C]2C', | ||
result: [[ | ||
{kind: 'atom', value: 'C', multiplier: 3}, | ||
{kind: 'isotope', value: {atom: 'C', isotope: 13}, multiplier: 6} | ||
]] | ||
result: [ | ||
[ | ||
{ kind: 'atom', value: 'C', multiplier: 3 }, | ||
{ kind: 'isotope', value: { atom: 'C', isotope: 13 }, multiplier: 6 } | ||
] | ||
] | ||
}, | ||
{ | ||
mf: 'D', | ||
result: | ||
[[{kind: 'isotope', value: {atom: 'H', isotope: 2}, multiplier: 1}]] | ||
result: [[{ kind: 'isotope', value: { atom: 'H', isotope: 2 }, multiplier: 1 }]] | ||
} | ||
@@ -51,12 +56,6 @@ ]; | ||
test('toParts', function() { | ||
for (let aTest of tests) { | ||
checkMF(aTest.mf, aTest.result); | ||
} | ||
test.each(tests)('toParts %p', function (aTest) { | ||
var parsed = parse(aTest.mf); | ||
var parts = toParts(parsed); | ||
expect(parts).toMatchObject(aTest.result); | ||
}); | ||
function checkMF(mf, result) { | ||
var parsed = parse(mf); | ||
var parts = toParts(parsed); | ||
expect(parts).toMatchObject(result); | ||
} |
'use strict'; | ||
module.exports = function formatCharge(charge) { | ||
if (charge === 1) return '+'; | ||
if (charge > 1) return `+${charge}`; | ||
if (charge < 0) return String(charge); | ||
return ''; | ||
if (charge === 1) return '+'; | ||
if (charge > 1) return `+${charge}`; | ||
if (charge < 0) return String(charge); | ||
return ''; | ||
}; |
'use strict'; | ||
'use strict'; | ||
const elements = require('chemical-elements/src/elementsAndStableIsotopesObject.js'); | ||
const groups = require('chemical-groups/src/groupsObject.js'); | ||
const Kind = require('../Kind'); | ||
@@ -17,3 +16,3 @@ | ||
*/ | ||
module.exports = function getInfo(parts, options = {}) { | ||
module.exports = function getInfo(parts) { | ||
var results = {}; | ||
@@ -44,3 +43,3 @@ for (let part of parts) { | ||
case Kind.ATOM: | ||
case Kind.ATOM: { | ||
let element = elements[line.value]; | ||
@@ -54,2 +53,4 @@ if (!element) { | ||
break; | ||
} | ||
case Kind.CHARGE: | ||
@@ -73,3 +74,3 @@ break; | ||
eas.forEach(ea => { | ||
eas.forEach((ea) => { | ||
ea.ratio = ea.mass / sum; | ||
@@ -76,0 +77,0 @@ }); |
'use strict'; | ||
const partToMF = require('./partToMF'); | ||
const elements = require('chemical-elements/src/elementsAndStableIsotopesObject.js'); | ||
const groups = require('chemical-groups/src/groupsObject.js'); | ||
const unsaturations = require('chemical-elements/src/unsaturationsObject.js'); | ||
const Kind = require('../Kind'); | ||
const { ELECTRON_MASS } = require('chemical-elements/src/constants'); | ||
const partToMF = require('./partToMF'); | ||
const partToAtoms = require('./partToAtoms'); | ||
const isotopes = require('./getIsotopesObject'); | ||
@@ -34,4 +36,4 @@ const getIsotopeRatioInfo = require('./getIsotopeRatioInfo'); | ||
result.charge = 0; | ||
result.mf = result.parts.map(a => a.mf).join('.'); | ||
result.parts.forEach(a => { | ||
result.mf = result.parts.map((a) => a.mf).join('.'); | ||
result.parts.forEach((a) => { | ||
result.mass += a.mass; | ||
@@ -130,2 +132,1 @@ result.monoisotopicMass += a.monoisotopicMass; | ||
@@ -30,5 +30,5 @@ 'use strict'; | ||
let sum = array.reduce((prev, current) => prev + current, 0); | ||
return array.map(a => a / sum); | ||
return array.map((a) => a / sum); | ||
} | ||
module.exports = getIsotopeRatioInfo; |
'use strict'; | ||
const elements = require('chemical-elements/src/elementsAndStableIsotopesObject.js'); | ||
const Kind = require('../Kind'); | ||
@@ -14,58 +15,55 @@ | ||
module.exports = function getIsotopesInfo(parts) { | ||
if (parts.length === 0) return []; | ||
if (parts.length > 1) throw new Error('getIsotopesInfo can not be applied on multipart MF'); | ||
if (parts.length === 0) return []; | ||
if (parts.length > 1) throw new Error('getIsotopesInfo can not be applied on multipart MF'); | ||
return getProcessedPart(parts[0]); | ||
return getProcessedPart(parts[0]); | ||
}; | ||
function getProcessedPart(part) { | ||
let result = { | ||
charge: 0, | ||
isotopes: [] | ||
}; | ||
for (let line of part) { | ||
switch (line.kind) { | ||
case Kind.ISOTOPE: { | ||
let isotope = isotopes[line.value.isotope + line.value.atom]; | ||
if (!isotope) throw Error('unknown isotope:', line.value.atom, line.value.isotope); | ||
result.isotopes.push({ | ||
atom: `[${line.value.isotope}${line.value.atom}]`, | ||
number: line.multiplier, | ||
distribution: [ | ||
{ x: isotope.mass, y: 1 } | ||
] | ||
}); | ||
break; | ||
} | ||
case Kind.ISOTOPE_RATIO: { | ||
let element = elements[line.value.atom]; | ||
if (!element) throw new Error('unknown element:', line.value); | ||
let result = { | ||
charge: 0, | ||
isotopes: [] | ||
}; | ||
for (let line of part) { | ||
switch (line.kind) { | ||
case Kind.ISOTOPE: { | ||
let isotope = isotopes[line.value.isotope + line.value.atom]; | ||
if (!isotope) throw Error('unknown isotope:', line.value.atom, line.value.isotope); | ||
result.isotopes.push({ | ||
atom: `[${line.value.isotope}${line.value.atom}]`, | ||
number: line.multiplier, | ||
distribution: [{ x: isotope.mass, y: 1 }] | ||
}); | ||
break; | ||
} | ||
case Kind.ISOTOPE_RATIO: { | ||
let element = elements[line.value.atom]; | ||
if (!element) throw new Error('unknown element:', line.value); | ||
let distribution = getDistribution(element.isotopes, line.value.ratio); | ||
result.isotopes.push({ | ||
atom: `${line.value.atom}{${line.value.ratio.join(',')}}`, | ||
number: line.multiplier, | ||
distribution | ||
}); | ||
} | ||
break; | ||
case Kind.ATOM: { | ||
let element = elements[line.value]; | ||
if (!element) throw new Error('unknown element:', line.value); | ||
result.isotopes.push({ | ||
atom: line.value, | ||
number: line.multiplier, | ||
distribution: element.isotopes.map((e) => ({ x: e.mass, y: e.abundance })) | ||
}); | ||
break; | ||
} | ||
case Kind.CHARGE: | ||
result.charge += line.value; | ||
break; | ||
default: | ||
throw new Error('partToMF unhandled Kind: ', line.kind); | ||
} | ||
let distribution = getDistribution(element.isotopes, line.value.ratio); | ||
result.isotopes.push({ | ||
atom: `${line.value.atom}{${line.value.ratio.join(',')}}`, | ||
number: line.multiplier, | ||
distribution | ||
}); | ||
} | ||
break; | ||
case Kind.ATOM: { | ||
let element = elements[line.value]; | ||
if (!element) throw new Error('unknown element:', line.value); | ||
result.isotopes.push({ | ||
atom: line.value, | ||
number: line.multiplier, | ||
distribution: element.isotopes.map((e) => ({ x: e.mass, y: e.abundance })) | ||
}); | ||
break; | ||
} | ||
case Kind.CHARGE: | ||
result.charge += line.value; | ||
break; | ||
default: | ||
throw new Error('partToMF unhandled Kind: ', line.kind); | ||
} | ||
return result; | ||
} | ||
return result; | ||
} | ||
@@ -75,19 +73,19 @@ | ||
function getDistribution(isotopesArray, ratio) { | ||
let ratios = normalize(ratio); | ||
let result = []; | ||
if (ratios.length > isotopesArray.length) { | ||
throw new Error(`the number of specified ratios is bigger that the number of stable isotopes: ${isotopes}`); | ||
} | ||
for (let i = 0; i < ratios.length; i++) { | ||
result.push({ | ||
x: isotopesArray[i].mass, | ||
y: ratios[i] | ||
}); | ||
} | ||
return result; | ||
let ratios = normalize(ratio); | ||
let result = []; | ||
if (ratios.length > isotopesArray.length) { | ||
throw new Error(`the number of specified ratios is bigger that the number of stable isotopes: ${isotopes}`); | ||
} | ||
for (let i = 0; i < ratios.length; i++) { | ||
result.push({ | ||
x: isotopesArray[i].mass, | ||
y: ratios[i] | ||
}); | ||
} | ||
return result; | ||
} | ||
function normalize(array) { | ||
let sum = array.reduce((prev, current) => prev + current, 0); | ||
return array.map((a) => a / sum); | ||
let sum = array.reduce((prev, current) => prev + current, 0); | ||
return array.map((a) => a / sum); | ||
} |
@@ -7,9 +7,9 @@ 'use strict'; | ||
Object.keys(elements).forEach((key) => { | ||
let e = elements[key]; | ||
e.isotopes.forEach((i) => { | ||
isotopes[i.nominal + key] = { | ||
abundance: i.abundance, | ||
mass: i.mass | ||
}; | ||
}); | ||
let e = elements[key]; | ||
e.isotopes.forEach((i) => { | ||
isotopes[i.nominal + key] = { | ||
abundance: i.abundance, | ||
mass: i.mass | ||
}; | ||
}); | ||
}); | ||
@@ -16,0 +16,0 @@ |
@@ -11,15 +11,15 @@ 'use strict'; | ||
module.exports = function parseCharge(charge) { | ||
charge = charge.replace(/[()]/g, ''); | ||
var chargeNumber = 0; | ||
if (charge.match(/^[+-]+$/)) { | ||
for (var i = 0; i < charge.length; i++) { | ||
if (charge.charAt(i) === '+') chargeNumber++; | ||
else chargeNumber--; | ||
} | ||
} else if (charge.match(/^[0-9]+[+-]$/)) { | ||
chargeNumber = Number(charge.charAt(charge.length - 1) + charge.substring(0, charge.length - 1)); | ||
} else { | ||
chargeNumber = Number(charge); | ||
charge = charge.replace(/[()]/g, ''); | ||
var chargeNumber = 0; | ||
if (charge.match(/^[+-]+$/)) { | ||
for (var i = 0; i < charge.length; i++) { | ||
if (charge.charAt(i) === '+') chargeNumber++; | ||
else chargeNumber--; | ||
} | ||
return chargeNumber; | ||
} else if (charge.match(/^[0-9]+[+-]$/)) { | ||
chargeNumber = Number(charge.charAt(charge.length - 1) + charge.substring(0, charge.length - 1)); | ||
} else { | ||
chargeNumber = Number(charge); | ||
} | ||
return chargeNumber; | ||
}; |
'use strict'; | ||
const Kind = require('../Kind'); | ||
const toDisplay = require('./toDisplay'); | ||
@@ -11,18 +12,17 @@ /** | ||
module.exports = function partsToDisplay(parts) { | ||
var lines = []; | ||
for (let part of parts) { | ||
if (lines.length > 0) lines.push({ kind: Kind.SALT, value: '•' }); | ||
for (let partLine of part) { | ||
lines.push(partLine); | ||
if (partLine.multiplier) { | ||
lines.push({ | ||
kind: Kind.MULTIPLIER, | ||
value: partLine.multiplier | ||
}); | ||
} | ||
} | ||
var lines = []; | ||
for (let part of parts) { | ||
if (lines.length > 0) lines.push({ kind: Kind.SALT, value: '•' }); | ||
for (let partLine of part) { | ||
lines.push(partLine); | ||
if (partLine.multiplier) { | ||
lines.push({ | ||
kind: Kind.MULTIPLIER, | ||
value: partLine.multiplier | ||
}); | ||
} | ||
} | ||
} | ||
return toDisplay(lines); | ||
return toDisplay(lines); | ||
}; |
@@ -10,3 +10,3 @@ 'use strict'; | ||
case Kind.ISOTOPE: | ||
if (line.multiplier !== 0) | ||
if (line.multiplier !== 0) { | ||
mf.push( | ||
@@ -17,5 +17,6 @@ `[${line.value.isotope}${line.value.atom}]${ | ||
); | ||
} | ||
break; | ||
case Kind.ISOTOPE_RATIO: | ||
if (line.multiplier !== 0) | ||
if (line.multiplier !== 0) { | ||
mf.push( | ||
@@ -26,6 +27,8 @@ `${line.value.atom}{${line.value.ratio.join(',')}}${ | ||
); | ||
} | ||
break; | ||
case Kind.ATOM: | ||
if (line.multiplier !== 0) | ||
if (line.multiplier !== 0) { | ||
mf.push(line.value + (line.multiplier !== 1 ? line.multiplier : '')); | ||
} | ||
break; | ||
@@ -32,0 +35,0 @@ case Kind.CHARGE: |
@@ -5,2 +5,3 @@ 'use strict'; | ||
const Format = require('../Format'); | ||
const formatCharge = require('./formatCharge'); | ||
@@ -14,91 +15,91 @@ | ||
module.exports = function convertForDisplay(lines) { | ||
let results = []; | ||
let result = {}; | ||
for (let line of lines) { | ||
switch (line.kind) { | ||
case Kind.MULTIPLIER: | ||
if (line.value !== 1) { | ||
result = { | ||
kind: Format.SUBSCRIPT, | ||
value: String(line.value) | ||
}; | ||
results.push(result); | ||
} | ||
break; | ||
case Kind.MULTIPLIER_RANGE: | ||
result = { | ||
kind: Format.SUBSCRIPT, | ||
value: `${String(line.value.from)}-${line.value.to}` | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.CHARGE: | ||
if (result.kind === Format.SUBSCRIPT) { | ||
result.kind = Format.SUPERIMPOSE; | ||
result.over = formatCharge(line.value); | ||
result.under = result.value; | ||
result.value = undefined; | ||
} else { | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: formatCharge(line.value) | ||
}; | ||
results.push(result); | ||
} | ||
let results = []; | ||
let result = {}; | ||
for (let line of lines) { | ||
switch (line.kind) { | ||
case Kind.MULTIPLIER: | ||
if (line.value !== 1) { | ||
result = { | ||
kind: Format.SUBSCRIPT, | ||
value: String(line.value) | ||
}; | ||
results.push(result); | ||
} | ||
break; | ||
case Kind.MULTIPLIER_RANGE: | ||
result = { | ||
kind: Format.SUBSCRIPT, | ||
value: `${String(line.value.from)}-${line.value.to}` | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.CHARGE: | ||
if (result.kind === Format.SUBSCRIPT) { | ||
result.kind = Format.SUPERIMPOSE; | ||
result.over = formatCharge(line.value); | ||
result.under = result.value; | ||
result.value = undefined; | ||
} else { | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: formatCharge(line.value) | ||
}; | ||
results.push(result); | ||
} | ||
break; | ||
break; | ||
case Kind.ISOTOPE: | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: line.value.isotope | ||
}; | ||
results.push(result); | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value.atom | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.ISOTOPE: | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: line.value.isotope | ||
}; | ||
results.push(result); | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value.atom | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.ISOTOPE_RATIO: | ||
if (result.kind === Format.TEXT) { | ||
result.value += line.value.atom; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value.atom | ||
}; | ||
results.push(result); | ||
} | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: `{${line.value.ratio.join(',')}}` | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.SALT: | ||
if (result.kind === Format.TEXT) { | ||
result.value += '•'; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: ' • ' | ||
}; | ||
results.push(result); | ||
} | ||
break; | ||
default: | ||
if (result.kind === Format.TEXT) { | ||
result.value += line.value; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value | ||
}; | ||
results.push(result); | ||
} | ||
case Kind.ISOTOPE_RATIO: | ||
if (result.kind === Format.TEXT) { | ||
result.value += line.value.atom; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value.atom | ||
}; | ||
results.push(result); | ||
} | ||
result = { | ||
kind: Format.SUPERSCRIPT, | ||
value: `{${line.value.ratio.join(',')}}` | ||
}; | ||
results.push(result); | ||
break; | ||
case Kind.SALT: | ||
if (result.kind === Format.TEXT) { | ||
result.value += '•'; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: ' • ' | ||
}; | ||
results.push(result); | ||
} | ||
break; | ||
default: | ||
if (result.kind === Format.TEXT) { | ||
result.value += line.value; | ||
} else { | ||
result = { | ||
kind: Format.TEXT, | ||
value: line.value | ||
}; | ||
results.push(result); | ||
} | ||
} | ||
return results; | ||
} | ||
return results; | ||
}; |
'use strict'; | ||
const Format = require('../Format'); | ||
const Style = require('../Style'); | ||
module.exports = function getHtml(lines) { | ||
var html = []; | ||
for (let line of lines) { | ||
switch (line.kind) { | ||
case Format.SUBSCRIPT: | ||
html.push(`<sub>${line.value}</sub>`); | ||
break; | ||
case Format.SUPERSCRIPT: | ||
html.push(`<sup>${line.value}</sup>`); | ||
break; | ||
case Format.SUPERIMPOSE: | ||
html.push(`<span style="${Style.SUPERIMPOSE}">`); | ||
html.push(`<sup style="${Style.SUPERIMPOSE_SUP_SUB}">${line.over}</sup>`); | ||
html.push(`<sub style="${Style.SUPERIMPOSE_SUP_SUB}">${line.under}</sub>`); | ||
html.push('</span>'); | ||
break; | ||
default: | ||
html.push(line.value); | ||
} | ||
var html = []; | ||
for (let line of lines) { | ||
switch (line.kind) { | ||
case Format.SUBSCRIPT: | ||
html.push(`<sub>${line.value}</sub>`); | ||
break; | ||
case Format.SUPERSCRIPT: | ||
html.push(`<sup>${line.value}</sup>`); | ||
break; | ||
case Format.SUPERIMPOSE: | ||
html.push(`<span style="${Style.SUPERIMPOSE}">`); | ||
html.push(`<sup style="${Style.SUPERIMPOSE_SUP_SUB}">${line.over}</sup>`); | ||
html.push(`<sub style="${Style.SUPERIMPOSE_SUP_SUB}">${line.under}</sub>`); | ||
html.push('</span>'); | ||
break; | ||
default: | ||
html.push(line.value); | ||
} | ||
return html.join(''); | ||
} | ||
return html.join(''); | ||
}; |
'use strict'; | ||
const Kind = require('../Kind'); | ||
const groups = require('chemical-groups/src/groupsObject.js'); | ||
const atomSorter = require('atom-sorter'); | ||
const Kind = require('../Kind'); | ||
/** | ||
@@ -22,2 +23,8 @@ * | ||
switch (line.kind) { | ||
case Kind.ATOM: | ||
case Kind.ISOTOPE_RATIO: | ||
case Kind.ISOTOPE: | ||
case Kind.CHARGE: | ||
currentPart.lines.push(Object.assign({}, line, { multiplier: 1 })); | ||
break; | ||
case Kind.OPENING_PARENTHESIS: | ||
@@ -40,8 +47,2 @@ openingParenthesis(currentPart); | ||
break; | ||
case Kind.ATOM: | ||
case Kind.ISOTOPE_RATIO: | ||
case Kind.ISOTOPE: | ||
case Kind.CHARGE: | ||
currentPart.lines.push(Object.assign({}, line, { multiplier: 1 })); | ||
break; | ||
case Kind.COMMENT: // we ignore comments to create the parts and canonized MF | ||
@@ -146,3 +147,3 @@ break; | ||
} | ||
if (expanded) part.lines = part.lines.filter(a => a); | ||
if (expanded) part.lines = part.lines.filter((a) => a); | ||
} | ||
@@ -149,0 +150,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1716
55822
1
+ Addedatom-sorter@0.9.1(transitive)
+ Addedchemical-elements@0.9.1(transitive)
+ Addedchemical-groups@0.9.1(transitive)
+ Addedmf-utilities@0.9.1(transitive)
- Removedatom-sorter@0.8.0(transitive)
- Removedchemical-elements@0.7.0(transitive)
- Removedchemical-groups@0.8.0(transitive)
- Removedmf-utilities@0.8.0(transitive)
Updatedatom-sorter@^0.9.1
Updatedchemical-elements@^0.9.1
Updatedchemical-groups@^0.9.1
Updatedmf-utilities@^0.9.1