Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. var CommentParser = (function (exports) {
  2. 'use strict';
  3. function isSpace(source) {
  4. return /^\s+$/.test(source);
  5. }
  6. function splitCR(source) {
  7. const matches = source.match(/\r+$/);
  8. return matches == null
  9. ? ['', source]
  10. : [source.slice(-matches[0].length), source.slice(0, -matches[0].length)];
  11. }
  12. function splitSpace(source) {
  13. const matches = source.match(/^\s+/);
  14. return matches == null
  15. ? ['', source]
  16. : [source.slice(0, matches[0].length), source.slice(matches[0].length)];
  17. }
  18. function splitLines(source) {
  19. return source.split(/\n/);
  20. }
  21. function seedBlock(block = {}) {
  22. return Object.assign({ description: '', tags: [], source: [], problems: [] }, block);
  23. }
  24. function seedSpec(spec = {}) {
  25. return Object.assign({ tag: '', name: '', type: '', optional: false, description: '', problems: [], source: [] }, spec);
  26. }
  27. function seedTokens(tokens = {}) {
  28. return Object.assign({ start: '', delimiter: '', postDelimiter: '', tag: '', postTag: '', name: '', postName: '', type: '', postType: '', description: '', end: '', lineEnd: '' }, tokens);
  29. }
  30. /**
  31. * Assures Block.tags[].source contains references to the Block.source items,
  32. * using Block.source as a source of truth. This is a counterpart of rewireSpecs
  33. * @param block parsed coments block
  34. */
  35. function rewireSource(block) {
  36. const source = block.source.reduce((acc, line) => acc.set(line.number, line), new Map());
  37. for (const spec of block.tags) {
  38. spec.source = spec.source.map((line) => source.get(line.number));
  39. }
  40. return block;
  41. }
  42. /**
  43. * Assures Block.source contains references to the Block.tags[].source items,
  44. * using Block.tags[].source as a source of truth. This is a counterpart of rewireSource
  45. * @param block parsed coments block
  46. */
  47. function rewireSpecs(block) {
  48. const source = block.tags.reduce((acc, spec) => spec.source.reduce((acc, line) => acc.set(line.number, line), acc), new Map());
  49. block.source = block.source.map((line) => source.get(line.number) || line);
  50. return block;
  51. }
  52. const reTag = /^@\S+/;
  53. /**
  54. * Creates configured `Parser`
  55. * @param {Partial<Options>} options
  56. */
  57. function getParser$3({ fence = '```', } = {}) {
  58. const fencer = getFencer(fence);
  59. const toggleFence = (source, isFenced) => fencer(source) ? !isFenced : isFenced;
  60. return function parseBlock(source) {
  61. // start with description section
  62. const sections = [[]];
  63. let isFenced = false;
  64. for (const line of source) {
  65. if (reTag.test(line.tokens.description) && !isFenced) {
  66. sections.push([line]);
  67. }
  68. else {
  69. sections[sections.length - 1].push(line);
  70. }
  71. isFenced = toggleFence(line.tokens.description, isFenced);
  72. }
  73. return sections;
  74. };
  75. }
  76. function getFencer(fence) {
  77. if (typeof fence === 'string')
  78. return (source) => source.split(fence).length % 2 === 0;
  79. return fence;
  80. }
  81. exports.Markers = void 0;
  82. (function (Markers) {
  83. Markers["start"] = "/**";
  84. Markers["nostart"] = "/***";
  85. Markers["delim"] = "*";
  86. Markers["end"] = "*/";
  87. })(exports.Markers || (exports.Markers = {}));
  88. function getParser$2({ startLine = 0, } = {}) {
  89. let block = null;
  90. let num = startLine;
  91. return function parseSource(source) {
  92. let rest = source;
  93. const tokens = seedTokens();
  94. [tokens.lineEnd, rest] = splitCR(rest);
  95. [tokens.start, rest] = splitSpace(rest);
  96. if (block === null &&
  97. rest.startsWith(exports.Markers.start) &&
  98. !rest.startsWith(exports.Markers.nostart)) {
  99. block = [];
  100. tokens.delimiter = rest.slice(0, exports.Markers.start.length);
  101. rest = rest.slice(exports.Markers.start.length);
  102. [tokens.postDelimiter, rest] = splitSpace(rest);
  103. }
  104. if (block === null) {
  105. num++;
  106. return null;
  107. }
  108. const isClosed = rest.trimRight().endsWith(exports.Markers.end);
  109. if (tokens.delimiter === '' &&
  110. rest.startsWith(exports.Markers.delim) &&
  111. !rest.startsWith(exports.Markers.end)) {
  112. tokens.delimiter = exports.Markers.delim;
  113. rest = rest.slice(exports.Markers.delim.length);
  114. [tokens.postDelimiter, rest] = splitSpace(rest);
  115. }
  116. if (isClosed) {
  117. const trimmed = rest.trimRight();
  118. tokens.end = rest.slice(trimmed.length - exports.Markers.end.length);
  119. rest = trimmed.slice(0, -exports.Markers.end.length);
  120. }
  121. tokens.description = rest;
  122. block.push({ number: num, source, tokens });
  123. num++;
  124. if (isClosed) {
  125. const result = block.slice();
  126. block = null;
  127. return result;
  128. }
  129. return null;
  130. };
  131. }
  132. function getParser$1({ tokenizers }) {
  133. return function parseSpec(source) {
  134. var _a;
  135. let spec = seedSpec({ source });
  136. for (const tokenize of tokenizers) {
  137. spec = tokenize(spec);
  138. if ((_a = spec.problems[spec.problems.length - 1]) === null || _a === void 0 ? void 0 : _a.critical)
  139. break;
  140. }
  141. return spec;
  142. };
  143. }
  144. /**
  145. * Splits the `@prefix` from remaining `Spec.lines[].token.descrioption` into the `tag` token,
  146. * and populates `spec.tag`
  147. */
  148. function tagTokenizer() {
  149. return (spec) => {
  150. const { tokens } = spec.source[0];
  151. const match = tokens.description.match(/\s*(@(\S+))(\s*)/);
  152. if (match === null) {
  153. spec.problems.push({
  154. code: 'spec:tag:prefix',
  155. message: 'tag should start with "@" symbol',
  156. line: spec.source[0].number,
  157. critical: true,
  158. });
  159. return spec;
  160. }
  161. tokens.tag = match[1];
  162. tokens.postTag = match[3];
  163. tokens.description = tokens.description.slice(match[0].length);
  164. spec.tag = match[2];
  165. return spec;
  166. };
  167. }
  168. /**
  169. * Sets splits remaining `Spec.lines[].tokes.description` into `type` and `description`
  170. * tokens and populates Spec.type`
  171. *
  172. * @param {Spacing} spacing tells how to deal with a whitespace
  173. * for type values going over multiple lines
  174. */
  175. function typeTokenizer(spacing = 'compact') {
  176. const join = getJoiner$1(spacing);
  177. return (spec) => {
  178. let curlies = 0;
  179. let lines = [];
  180. for (const [i, { tokens }] of spec.source.entries()) {
  181. let type = '';
  182. if (i === 0 && tokens.description[0] !== '{')
  183. return spec;
  184. for (const ch of tokens.description) {
  185. if (ch === '{')
  186. curlies++;
  187. if (ch === '}')
  188. curlies--;
  189. type += ch;
  190. if (curlies === 0)
  191. break;
  192. }
  193. lines.push([tokens, type]);
  194. if (curlies === 0)
  195. break;
  196. }
  197. if (curlies !== 0) {
  198. spec.problems.push({
  199. code: 'spec:type:unpaired-curlies',
  200. message: 'unpaired curlies',
  201. line: spec.source[0].number,
  202. critical: true,
  203. });
  204. return spec;
  205. }
  206. const parts = [];
  207. const offset = lines[0][0].postDelimiter.length;
  208. for (const [i, [tokens, type]] of lines.entries()) {
  209. tokens.type = type;
  210. if (i > 0) {
  211. tokens.type = tokens.postDelimiter.slice(offset) + type;
  212. tokens.postDelimiter = tokens.postDelimiter.slice(0, offset);
  213. }
  214. [tokens.postType, tokens.description] = splitSpace(tokens.description.slice(type.length));
  215. parts.push(tokens.type);
  216. }
  217. parts[0] = parts[0].slice(1);
  218. parts[parts.length - 1] = parts[parts.length - 1].slice(0, -1);
  219. spec.type = join(parts);
  220. return spec;
  221. };
  222. }
  223. const trim = (x) => x.trim();
  224. function getJoiner$1(spacing) {
  225. if (spacing === 'compact')
  226. return (t) => t.map(trim).join('');
  227. else if (spacing === 'preserve')
  228. return (t) => t.join('\n');
  229. else
  230. return spacing;
  231. }
  232. const isQuoted = (s) => s && s.startsWith('"') && s.endsWith('"');
  233. /**
  234. * Splits remaining `spec.lines[].tokens.description` into `name` and `descriptions` tokens,
  235. * and populates the `spec.name`
  236. */
  237. function nameTokenizer() {
  238. const typeEnd = (num, { tokens }, i) => tokens.type === '' ? num : i;
  239. return (spec) => {
  240. // look for the name in the line where {type} ends
  241. const { tokens } = spec.source[spec.source.reduce(typeEnd, 0)];
  242. const source = tokens.description.trimLeft();
  243. const quotedGroups = source.split('"');
  244. // if it starts with quoted group, assume it is a literal
  245. if (quotedGroups.length > 1 &&
  246. quotedGroups[0] === '' &&
  247. quotedGroups.length % 2 === 1) {
  248. spec.name = quotedGroups[1];
  249. tokens.name = `"${quotedGroups[1]}"`;
  250. [tokens.postName, tokens.description] = splitSpace(source.slice(tokens.name.length));
  251. return spec;
  252. }
  253. let brackets = 0;
  254. let name = '';
  255. let optional = false;
  256. let defaultValue;
  257. // assume name is non-space string or anything wrapped into brackets
  258. for (const ch of source) {
  259. if (brackets === 0 && isSpace(ch))
  260. break;
  261. if (ch === '[')
  262. brackets++;
  263. if (ch === ']')
  264. brackets--;
  265. name += ch;
  266. }
  267. if (brackets !== 0) {
  268. spec.problems.push({
  269. code: 'spec:name:unpaired-brackets',
  270. message: 'unpaired brackets',
  271. line: spec.source[0].number,
  272. critical: true,
  273. });
  274. return spec;
  275. }
  276. const nameToken = name;
  277. if (name[0] === '[' && name[name.length - 1] === ']') {
  278. optional = true;
  279. name = name.slice(1, -1);
  280. const parts = name.split('=');
  281. name = parts[0].trim();
  282. if (parts[1] !== undefined)
  283. defaultValue = parts.slice(1).join('=').trim();
  284. if (name === '') {
  285. spec.problems.push({
  286. code: 'spec:name:empty-name',
  287. message: 'empty name',
  288. line: spec.source[0].number,
  289. critical: true,
  290. });
  291. return spec;
  292. }
  293. if (defaultValue === '') {
  294. spec.problems.push({
  295. code: 'spec:name:empty-default',
  296. message: 'empty default value',
  297. line: spec.source[0].number,
  298. critical: true,
  299. });
  300. return spec;
  301. }
  302. // has "=" and is not a string, except for "=>"
  303. if (!isQuoted(defaultValue) && /=(?!>)/.test(defaultValue)) {
  304. spec.problems.push({
  305. code: 'spec:name:invalid-default',
  306. message: 'invalid default value syntax',
  307. line: spec.source[0].number,
  308. critical: true,
  309. });
  310. return spec;
  311. }
  312. }
  313. spec.optional = optional;
  314. spec.name = name;
  315. tokens.name = nameToken;
  316. if (defaultValue !== undefined)
  317. spec.default = defaultValue;
  318. [tokens.postName, tokens.description] = splitSpace(source.slice(tokens.name.length));
  319. return spec;
  320. };
  321. }
  322. /**
  323. * Makes no changes to `spec.lines[].tokens` but joins them into `spec.description`
  324. * following given spacing srtategy
  325. * @param {Spacing} spacing tells how to handle the whitespace
  326. */
  327. function descriptionTokenizer(spacing = 'compact') {
  328. const join = getJoiner(spacing);
  329. return (spec) => {
  330. spec.description = join(spec.source);
  331. return spec;
  332. };
  333. }
  334. function getJoiner(spacing) {
  335. if (spacing === 'compact')
  336. return compactJoiner;
  337. if (spacing === 'preserve')
  338. return preserveJoiner;
  339. return spacing;
  340. }
  341. function compactJoiner(lines) {
  342. return lines
  343. .map(({ tokens: { description } }) => description.trim())
  344. .filter((description) => description !== '')
  345. .join(' ');
  346. }
  347. const lineNo = (num, { tokens }, i) => tokens.type === '' ? num : i;
  348. const getDescription = ({ tokens }) => (tokens.delimiter === '' ? tokens.start : tokens.postDelimiter.slice(1)) +
  349. tokens.description;
  350. function preserveJoiner(lines) {
  351. if (lines.length === 0)
  352. return '';
  353. // skip the opening line with no description
  354. if (lines[0].tokens.description === '' &&
  355. lines[0].tokens.delimiter === exports.Markers.start)
  356. lines = lines.slice(1);
  357. // skip the closing line with no description
  358. const lastLine = lines[lines.length - 1];
  359. if (lastLine !== undefined &&
  360. lastLine.tokens.description === '' &&
  361. lastLine.tokens.end.endsWith(exports.Markers.end))
  362. lines = lines.slice(0, -1);
  363. // description starts at the last line of type definition
  364. lines = lines.slice(lines.reduce(lineNo, 0));
  365. return lines.map(getDescription).join('\n');
  366. }
  367. function getParser({ startLine = 0, fence = '```', spacing = 'compact', tokenizers = [
  368. tagTokenizer(),
  369. typeTokenizer(spacing),
  370. nameTokenizer(),
  371. descriptionTokenizer(spacing),
  372. ], } = {}) {
  373. if (startLine < 0 || startLine % 1 > 0)
  374. throw new Error('Invalid startLine');
  375. const parseSource = getParser$2({ startLine });
  376. const parseBlock = getParser$3({ fence });
  377. const parseSpec = getParser$1({ tokenizers });
  378. const joinDescription = getJoiner(spacing);
  379. const notEmpty = (line) => line.tokens.description.trim() != '';
  380. return function (source) {
  381. const blocks = [];
  382. for (const line of splitLines(source)) {
  383. const lines = parseSource(line);
  384. if (lines === null)
  385. continue;
  386. if (lines.find(notEmpty) === undefined)
  387. continue;
  388. const sections = parseBlock(lines);
  389. const specs = sections.slice(1).map(parseSpec);
  390. blocks.push({
  391. description: joinDescription(sections[0]),
  392. tags: specs,
  393. source: lines,
  394. problems: specs.reduce((acc, spec) => acc.concat(spec.problems), []),
  395. });
  396. }
  397. return blocks;
  398. };
  399. }
  400. function join(tokens) {
  401. return (tokens.start +
  402. tokens.delimiter +
  403. tokens.postDelimiter +
  404. tokens.tag +
  405. tokens.postTag +
  406. tokens.type +
  407. tokens.postType +
  408. tokens.name +
  409. tokens.postName +
  410. tokens.description +
  411. tokens.end +
  412. tokens.lineEnd);
  413. }
  414. function getStringifier() {
  415. return (block) => block.source.map(({ tokens }) => join(tokens)).join('\n');
  416. }
  417. var __rest$2 = (window && window.__rest) || function (s, e) {
  418. var t = {};
  419. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  420. t[p] = s[p];
  421. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  422. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  423. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  424. t[p[i]] = s[p[i]];
  425. }
  426. return t;
  427. };
  428. const zeroWidth$1 = {
  429. start: 0,
  430. tag: 0,
  431. type: 0,
  432. name: 0,
  433. };
  434. const getWidth = (w, { tokens: t }) => ({
  435. start: t.delimiter === exports.Markers.start ? t.start.length : w.start,
  436. tag: Math.max(w.tag, t.tag.length),
  437. type: Math.max(w.type, t.type.length),
  438. name: Math.max(w.name, t.name.length),
  439. });
  440. const space = (len) => ''.padStart(len, ' ');
  441. function align$1() {
  442. let intoTags = false;
  443. let w;
  444. function update(line) {
  445. const tokens = Object.assign({}, line.tokens);
  446. if (tokens.tag !== '')
  447. intoTags = true;
  448. const isEmpty = tokens.tag === '' &&
  449. tokens.name === '' &&
  450. tokens.type === '' &&
  451. tokens.description === '';
  452. // dangling '*/'
  453. if (tokens.end === exports.Markers.end && isEmpty) {
  454. tokens.start = space(w.start + 1);
  455. return Object.assign(Object.assign({}, line), { tokens });
  456. }
  457. switch (tokens.delimiter) {
  458. case exports.Markers.start:
  459. tokens.start = space(w.start);
  460. break;
  461. case exports.Markers.delim:
  462. tokens.start = space(w.start + 1);
  463. break;
  464. default:
  465. tokens.delimiter = '';
  466. tokens.start = space(w.start + 2); // compensate delimiter
  467. }
  468. if (!intoTags) {
  469. tokens.postDelimiter = tokens.description === '' ? '' : ' ';
  470. return Object.assign(Object.assign({}, line), { tokens });
  471. }
  472. const nothingAfter = {
  473. delim: false,
  474. tag: false,
  475. type: false,
  476. name: false,
  477. };
  478. if (tokens.description === '') {
  479. nothingAfter.name = true;
  480. tokens.postName = '';
  481. if (tokens.name === '') {
  482. nothingAfter.type = true;
  483. tokens.postType = '';
  484. if (tokens.type === '') {
  485. nothingAfter.tag = true;
  486. tokens.postTag = '';
  487. if (tokens.tag === '') {
  488. nothingAfter.delim = true;
  489. }
  490. }
  491. }
  492. }
  493. tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
  494. if (!nothingAfter.tag)
  495. tokens.postTag = space(w.tag - tokens.tag.length + 1);
  496. if (!nothingAfter.type)
  497. tokens.postType = space(w.type - tokens.type.length + 1);
  498. if (!nothingAfter.name)
  499. tokens.postName = space(w.name - tokens.name.length + 1);
  500. return Object.assign(Object.assign({}, line), { tokens });
  501. }
  502. return (_a) => {
  503. var { source } = _a, fields = __rest$2(_a, ["source"]);
  504. w = source.reduce(getWidth, Object.assign({}, zeroWidth$1));
  505. return rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) }));
  506. };
  507. }
  508. var __rest$1 = (window && window.__rest) || function (s, e) {
  509. var t = {};
  510. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  511. t[p] = s[p];
  512. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  513. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  514. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  515. t[p[i]] = s[p[i]];
  516. }
  517. return t;
  518. };
  519. const pull = (offset) => (str) => str.slice(offset);
  520. const push = (offset) => {
  521. const space = ''.padStart(offset, ' ');
  522. return (str) => str + space;
  523. };
  524. function indent(pos) {
  525. let shift;
  526. const pad = (start) => {
  527. if (shift === undefined) {
  528. const offset = pos - start.length;
  529. shift = offset > 0 ? push(offset) : pull(-offset);
  530. }
  531. return shift(start);
  532. };
  533. const update = (line) => (Object.assign(Object.assign({}, line), { tokens: Object.assign(Object.assign({}, line.tokens), { start: pad(line.tokens.start) }) }));
  534. return (_a) => {
  535. var { source } = _a, fields = __rest$1(_a, ["source"]);
  536. return rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) }));
  537. };
  538. }
  539. var __rest = (window && window.__rest) || function (s, e) {
  540. var t = {};
  541. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  542. t[p] = s[p];
  543. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  544. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  545. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  546. t[p[i]] = s[p[i]];
  547. }
  548. return t;
  549. };
  550. function crlf(ending) {
  551. function update(line) {
  552. return Object.assign(Object.assign({}, line), { tokens: Object.assign(Object.assign({}, line.tokens), { lineEnd: ending === 'LF' ? '' : '\r' }) });
  553. }
  554. return (_a) => {
  555. var { source } = _a, fields = __rest(_a, ["source"]);
  556. return rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) }));
  557. };
  558. }
  559. function flow(...transforms) {
  560. return (block) => transforms.reduce((block, t) => t(block), block);
  561. }
  562. const zeroWidth = {
  563. line: 0,
  564. start: 0,
  565. delimiter: 0,
  566. postDelimiter: 0,
  567. tag: 0,
  568. postTag: 0,
  569. name: 0,
  570. postName: 0,
  571. type: 0,
  572. postType: 0,
  573. description: 0,
  574. end: 0,
  575. lineEnd: 0,
  576. };
  577. const headers = { lineEnd: 'CR' };
  578. const fields = Object.keys(zeroWidth);
  579. const repr = (x) => (isSpace(x) ? `{${x.length}}` : x);
  580. const frame = (line) => '|' + line.join('|') + '|';
  581. const align = (width, tokens) => Object.keys(tokens).map((k) => repr(tokens[k]).padEnd(width[k]));
  582. function inspect({ source }) {
  583. var _a, _b;
  584. if (source.length === 0)
  585. return '';
  586. const width = Object.assign({}, zeroWidth);
  587. for (const f of fields)
  588. width[f] = ((_a = headers[f]) !== null && _a !== void 0 ? _a : f).length;
  589. for (const { number, tokens } of source) {
  590. width.line = Math.max(width.line, number.toString().length);
  591. for (const k in tokens)
  592. width[k] = Math.max(width[k], repr(tokens[k]).length);
  593. }
  594. const lines = [[], []];
  595. for (const f of fields)
  596. lines[0].push(((_b = headers[f]) !== null && _b !== void 0 ? _b : f).padEnd(width[f]));
  597. for (const f of fields)
  598. lines[1].push('-'.padEnd(width[f], '-'));
  599. for (const { number, tokens } of source) {
  600. const line = number.toString().padStart(width.line);
  601. lines.push([line, ...align(width, tokens)]);
  602. }
  603. return lines.map(frame).join('\n');
  604. }
  605. function parse(source, options = {}) {
  606. return getParser(options)(source);
  607. }
  608. const stringify = getStringifier();
  609. const transforms = {
  610. flow: flow,
  611. align: align$1,
  612. indent: indent,
  613. crlf: crlf,
  614. };
  615. const tokenizers = {
  616. tag: tagTokenizer,
  617. type: typeTokenizer,
  618. name: nameTokenizer,
  619. description: descriptionTokenizer,
  620. };
  621. const util = { rewireSpecs, rewireSource, seedBlock, seedTokens };
  622. exports.inspect = inspect;
  623. exports.parse = parse;
  624. exports.stringify = stringify;
  625. exports.tokenizers = tokenizers;
  626. exports.transforms = transforms;
  627. exports.util = util;
  628. Object.defineProperty(exports, '__esModule', { value: true });
  629. return exports;
  630. }({}));