Skip to content

Commit c535c4e

Browse files
committed
Implement first batch of semantic markup commands (the easy ones).
1 parent 7b8d9a5 commit c535c4e

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

src/parser.spec.ts

+40
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,46 @@ describe('parser tests', (): void => {
4242
],
4343
]);
4444
});
45+
it('classic markup test II', (): void => {
46+
expect(
47+
parse(
48+
'foo I(bar) baz C( bam ) B( ( boo ) ) U(https://example.com/?foo=bar)HORIZONTALLINE L(foo , https://bar.com) R( a , b )M(foo.bar.baz)HORIZONTALLINEx M(foo.bar.baz.bam)',
49+
{ only_classic_markup: true },
50+
),
51+
).toEqual([
52+
[
53+
{ type: PartType.TEXT, text: 'foo ' },
54+
{ type: PartType.ITALIC, text: 'bar' },
55+
{ type: PartType.TEXT, text: ' baz ' },
56+
{ type: PartType.CODE, text: ' bam ' },
57+
{ type: PartType.TEXT, text: ' ' },
58+
{ type: PartType.BOLD, text: ' ( boo ' },
59+
{ type: PartType.TEXT, text: ' ) ' },
60+
{ type: PartType.URL, url: 'https://example.com/?foo=bar' },
61+
{ type: PartType.HORIZONTAL_LINE },
62+
{ type: PartType.TEXT, text: ' ' },
63+
{ type: PartType.LINK, text: 'foo', url: 'https://bar.com' },
64+
{ type: PartType.TEXT, text: ' ' },
65+
{ type: PartType.RST_REF, text: ' a', ref: 'b ' },
66+
{ type: PartType.MODULE, fqcn: 'foo.bar.baz' },
67+
{ type: PartType.TEXT, text: 'HORIZONTALLINEx ' },
68+
{ type: PartType.MODULE, fqcn: 'foo.bar.baz.bam' },
69+
],
70+
]);
71+
});
72+
it('semantic markup test', (): void => {
73+
expect(parse('foo E(a\\),b) P(foo.bar.baz , bam) baz V( b\\,\\na\\)\\\\m\\, ) ')).toEqual([
74+
[
75+
{ type: PartType.TEXT, text: 'foo ' },
76+
{ type: PartType.ENV_VARIABLE, name: 'a),b' },
77+
{ type: PartType.TEXT, text: ' ' },
78+
{ type: PartType.PLUGIN, plugin: { fqcn: 'foo.bar.baz', type: 'bam' } },
79+
{ type: PartType.TEXT, text: ' baz ' },
80+
{ type: PartType.OPTION_VALUE, value: ' b,na)\\m, ' },
81+
{ type: PartType.TEXT, text: ' ' },
82+
],
83+
]);
84+
});
4585
it('bad parameter parsing (no escaping, throw error)', (): void => {
4686
expect(async () => parse('M(', { errors: 'exception' })).rejects.toThrow(
4787
'While parsing M() at index 1: Cannot find closing ")" after last parameter',

src/parser.ts

+62-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import { ParsingOptions, PluginIdentifier } from './opts';
8-
import { isFQCN } from './ansible';
8+
import { isFQCN, isPluginType } from './ansible';
99

1010
export enum PartType {
1111
ERROR = 0,
@@ -132,6 +132,15 @@ export type AnyPart =
132132

133133
export type Paragraph = AnyPart[];
134134

135+
function parseOptionLike(
136+
value: string,
137+
opts: ParsingOptions,
138+
type: PartType.OPTION_NAME | PartType.RETURN_VALUE,
139+
): OptionNamePart | ReturnValuePart {
140+
// TODO
141+
throw Error('Not yet supported');
142+
}
143+
135144
interface CommandParser {
136145
command: string;
137146
parameters: number;
@@ -219,7 +228,58 @@ const PARSER: CommandParser[] = [
219228
},
220229
},
221230
// Semantic Ansible docs markup:
222-
// TODO
231+
{
232+
command: 'P',
233+
parameters: 2,
234+
escaped_arguments: true,
235+
process: (args) => {
236+
const fqcn = args[0] as string;
237+
if (!isFQCN(fqcn)) {
238+
throw Error(`Plugin name "${fqcn}" is not a FQCN`);
239+
}
240+
const type = args[1] as string;
241+
if (!isPluginType(type)) {
242+
throw Error(`Plugin type "${type}" is not valid`);
243+
}
244+
return <PluginPart>{ type: PartType.PLUGIN, plugin: { fqcn: fqcn, type: type } };
245+
},
246+
},
247+
{
248+
command: 'E',
249+
parameters: 1,
250+
escaped_arguments: true,
251+
process: (args) => {
252+
const env = args[0] as string;
253+
return <EnvVariablePart>{ type: PartType.ENV_VARIABLE, name: env };
254+
},
255+
},
256+
{
257+
command: 'V',
258+
parameters: 1,
259+
escaped_arguments: true,
260+
process: (args) => {
261+
const value = args[0] as string;
262+
return <OptionValuePart>{ type: PartType.OPTION_VALUE, value: value };
263+
},
264+
},
265+
{
266+
command: 'O',
267+
parameters: 1,
268+
escaped_arguments: true,
269+
process: (args, opts) => {
270+
const value = args[0] as string;
271+
return parseOptionLike(value, opts, PartType.OPTION_NAME);
272+
},
273+
},
274+
{
275+
command: 'RV',
276+
parameters: 1,
277+
escaped_arguments: true,
278+
process: (args, opts) => {
279+
const value = args[0] as string;
280+
return parseOptionLike(value, opts, PartType.RETURN_VALUE);
281+
},
282+
},
223283
];
224284

225285
const PARSER_COMMANDS: Map<string, CommandParser> = (() => {

0 commit comments

Comments
 (0)