xref: /Universal-ctags/parsers/yamlfrontmatter.c (revision 532866040b26c111e1e2a75f9383272afb02abfe)
1*53286604SMasatake YAMATO /*
2*53286604SMasatake YAMATO *
3*53286604SMasatake YAMATO *   Copyright (c) 2022, Masatake YAMATO
4*53286604SMasatake YAMATO *   Copyright (c) 2022, Red Hat, K.K.
5*53286604SMasatake YAMATO *
6*53286604SMasatake YAMATO *   This source code is released for free distribution under the terms of the
7*53286604SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
8*53286604SMasatake YAMATO *
9*53286604SMasatake YAMATO * This module contains functions for extracting language objects in FrontMatter
10*53286604SMasatake YAMATO * using Yaml.
11*53286604SMasatake YAMATO *
12*53286604SMasatake YAMATO * https://gohugo.io/content-management/front-matter
13*53286604SMasatake YAMATO */
14*53286604SMasatake YAMATO 
15*53286604SMasatake YAMATO /*
16*53286604SMasatake YAMATO *   INCLUDE FILES
17*53286604SMasatake YAMATO */
18*53286604SMasatake YAMATO #include "general.h"	/* must always come first */
19*53286604SMasatake YAMATO 
20*53286604SMasatake YAMATO #include "frontmatter.h"
21*53286604SMasatake YAMATO #include "yaml.h"
22*53286604SMasatake YAMATO 
23*53286604SMasatake YAMATO #include "entry.h"
24*53286604SMasatake YAMATO #include "gcc-attr.h"
25*53286604SMasatake YAMATO #include "parse.h"
26*53286604SMasatake YAMATO #include "read.h"
27*53286604SMasatake YAMATO #include "subparser.h"
28*53286604SMasatake YAMATO #include "trace.h"
29*53286604SMasatake YAMATO 
30*53286604SMasatake YAMATO 
31*53286604SMasatake YAMATO /*
32*53286604SMasatake YAMATO *   DATA DECLARATIONS
33*53286604SMasatake YAMATO */
34*53286604SMasatake YAMATO enum yamlfrontmatterDetectingState {
35*53286604SMasatake YAMATO 	DSTAT_LAST_KEY,
36*53286604SMasatake YAMATO 	DSTAT_LAST_VALUE,
37*53286604SMasatake YAMATO 	DSTAT_INITIAL,
38*53286604SMasatake YAMATO };
39*53286604SMasatake YAMATO 
40*53286604SMasatake YAMATO struct sYamlFrontMatterSubparser {
41*53286604SMasatake YAMATO 	yamlSubparser yaml;
42*53286604SMasatake YAMATO 	enum yamlfrontmatterDetectingState detection_state;
43*53286604SMasatake YAMATO };
44*53286604SMasatake YAMATO 
45*53286604SMasatake YAMATO 
46*53286604SMasatake YAMATO /*
47*53286604SMasatake YAMATO *   FUNCTION PROTOTYPES
48*53286604SMasatake YAMATO */
49*53286604SMasatake YAMATO static bool yamlFrontmattterInitTagEntry (tagEntryInfo *e, char *name, void *data);
50*53286604SMasatake YAMATO 
51*53286604SMasatake YAMATO 
52*53286604SMasatake YAMATO /*
53*53286604SMasatake YAMATO *   DATA DEFINITIONS
54*53286604SMasatake YAMATO */
55*53286604SMasatake YAMATO 
56*53286604SMasatake YAMATO static langType frontMatterLang;
57*53286604SMasatake YAMATO 
58*53286604SMasatake YAMATO static tagYpathTable ypathTables [] = {
59*53286604SMasatake YAMATO 	{
60*53286604SMasatake YAMATO 		"title",
61*53286604SMasatake YAMATO 		DSTAT_LAST_VALUE,
62*53286604SMasatake YAMATO 		.initTagEntry = yamlFrontmattterInitTagEntry,
63*53286604SMasatake YAMATO 	},
64*53286604SMasatake YAMATO };
65*53286604SMasatake YAMATO 
66*53286604SMasatake YAMATO 
67*53286604SMasatake YAMATO /*
68*53286604SMasatake YAMATO *   FUNCTION DEFINITIONS
69*53286604SMasatake YAMATO */
70*53286604SMasatake YAMATO 
yamlfrontmatterStateMachine(struct sYamlFrontMatterSubparser * yamlfrontmatter,yaml_token_t * token)71*53286604SMasatake YAMATO static void	yamlfrontmatterStateMachine (struct sYamlFrontMatterSubparser *yamlfrontmatter,
72*53286604SMasatake YAMATO 								 yaml_token_t *token)
73*53286604SMasatake YAMATO {
74*53286604SMasatake YAMATO #ifdef DO_TRACING
75*53286604SMasatake YAMATO 	ypathPrintTypeStack (YAML(yamlfrontmatter));
76*53286604SMasatake YAMATO #endif
77*53286604SMasatake YAMATO 
78*53286604SMasatake YAMATO 	switch (token->type)
79*53286604SMasatake YAMATO 	{
80*53286604SMasatake YAMATO 	case YAML_KEY_TOKEN:
81*53286604SMasatake YAMATO 		yamlfrontmatter->detection_state = DSTAT_LAST_KEY;
82*53286604SMasatake YAMATO 		break;
83*53286604SMasatake YAMATO 	case YAML_SCALAR_TOKEN:
84*53286604SMasatake YAMATO 		switch (yamlfrontmatter->detection_state)
85*53286604SMasatake YAMATO 		{
86*53286604SMasatake YAMATO 		case DSTAT_LAST_KEY:
87*53286604SMasatake YAMATO 			ypathFillKeywordOfTokenMaybe (YAML(yamlfrontmatter), token, getInputLanguage ());
88*53286604SMasatake YAMATO 			/* FALL THROUGH */
89*53286604SMasatake YAMATO 		case DSTAT_LAST_VALUE:
90*53286604SMasatake YAMATO 			TRACE_PRINT("token-callback: %s: %s",
91*53286604SMasatake YAMATO 						(yamlfrontmatter->detection_state == DSTAT_LAST_KEY)? "key": "value",
92*53286604SMasatake YAMATO 						(char*)token->data.scalar.value);
93*53286604SMasatake YAMATO 			ypathHandleToken (YAML(yamlfrontmatter), token, yamlfrontmatter->detection_state,
94*53286604SMasatake YAMATO 							  ypathTables, ARRAY_SIZE (ypathTables));
95*53286604SMasatake YAMATO 			break;
96*53286604SMasatake YAMATO 		default:
97*53286604SMasatake YAMATO 			break;
98*53286604SMasatake YAMATO 		}
99*53286604SMasatake YAMATO 
100*53286604SMasatake YAMATO 		yamlfrontmatter->detection_state = DSTAT_INITIAL;
101*53286604SMasatake YAMATO 
102*53286604SMasatake YAMATO 		break;
103*53286604SMasatake YAMATO 	case YAML_VALUE_TOKEN:
104*53286604SMasatake YAMATO 		yamlfrontmatter->detection_state = DSTAT_LAST_VALUE;
105*53286604SMasatake YAMATO 		break;
106*53286604SMasatake YAMATO 
107*53286604SMasatake YAMATO 	default:
108*53286604SMasatake YAMATO 		yamlfrontmatter->detection_state = DSTAT_INITIAL;
109*53286604SMasatake YAMATO 		break;
110*53286604SMasatake YAMATO 	}
111*53286604SMasatake YAMATO }
112*53286604SMasatake YAMATO 
newTokenCallback(yamlSubparser * s,yaml_token_t * token)113*53286604SMasatake YAMATO static void newTokenCallback (yamlSubparser *s, yaml_token_t *token)
114*53286604SMasatake YAMATO {
115*53286604SMasatake YAMATO 	if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN
116*53286604SMasatake YAMATO 		|| token->type == YAML_BLOCK_MAPPING_START_TOKEN)
117*53286604SMasatake YAMATO 		ypathPushType (s, token);
118*53286604SMasatake YAMATO 
119*53286604SMasatake YAMATO 	yamlfrontmatterStateMachine ((struct sYamlFrontMatterSubparser *)s, token);
120*53286604SMasatake YAMATO 
121*53286604SMasatake YAMATO 	if (token->type == YAML_BLOCK_END_TOKEN)
122*53286604SMasatake YAMATO 		ypathPopType (s);
123*53286604SMasatake YAMATO 	else if (token->type == YAML_STREAM_END_TOKEN)
124*53286604SMasatake YAMATO 		ypathPopAllTypes (s);
125*53286604SMasatake YAMATO }
126*53286604SMasatake YAMATO 
yamlFrontmattterInitTagEntry(tagEntryInfo * e,char * name,void * data CTAGS_ATTR_UNUSED)127*53286604SMasatake YAMATO static bool yamlFrontmattterInitTagEntry (tagEntryInfo *e, char *name, void * data CTAGS_ATTR_UNUSED)
128*53286604SMasatake YAMATO {
129*53286604SMasatake YAMATO 	initForeignTagEntry (e, name, frontMatterLang, FRONTMATTER_TITLE_KIND);
130*53286604SMasatake YAMATO 	return true;
131*53286604SMasatake YAMATO }
132*53286604SMasatake YAMATO 
yamlFrontMatterInputStart(subparser * s)133*53286604SMasatake YAMATO static void yamlFrontMatterInputStart(subparser *s)
134*53286604SMasatake YAMATO {
135*53286604SMasatake YAMATO 	((struct sYamlFrontMatterSubparser*)s)->detection_state = DSTAT_INITIAL;
136*53286604SMasatake YAMATO 	((yamlSubparser*)s)->ypathTypeStack = NULL;
137*53286604SMasatake YAMATO }
138*53286604SMasatake YAMATO 
yamlFrontMatterInputEnd(subparser * s)139*53286604SMasatake YAMATO static void yamlFrontMatterInputEnd(subparser *s)
140*53286604SMasatake YAMATO {
141*53286604SMasatake YAMATO 	Assert (((yamlSubparser*)s)->ypathTypeStack == NULL);
142*53286604SMasatake YAMATO }
143*53286604SMasatake YAMATO 
findYamlFrontMatterTags(void)144*53286604SMasatake YAMATO static void findYamlFrontMatterTags (void)
145*53286604SMasatake YAMATO {
146*53286604SMasatake YAMATO 	scheduleRunningBaseparser (0);
147*53286604SMasatake YAMATO }
148*53286604SMasatake YAMATO 
yamlFrontMatterInitialize(langType language)149*53286604SMasatake YAMATO static void yamlFrontMatterInitialize (langType language)
150*53286604SMasatake YAMATO {
151*53286604SMasatake YAMATO 	ypathCompileTables (language, ypathTables, ARRAY_SIZE (ypathTables), 0);
152*53286604SMasatake YAMATO 	frontMatterLang = getNamedLanguage ("FrontMatter", 0);
153*53286604SMasatake YAMATO }
154*53286604SMasatake YAMATO 
yamlFrontMatterFinalize(langType language,bool initialized)155*53286604SMasatake YAMATO static void yamlFrontMatterFinalize (langType language, bool initialized)
156*53286604SMasatake YAMATO {
157*53286604SMasatake YAMATO 	if (initialized)
158*53286604SMasatake YAMATO 		ypathCompiledCodeDelete (ypathTables, ARRAY_SIZE (ypathTables));
159*53286604SMasatake YAMATO }
160*53286604SMasatake YAMATO 
YamlFrontMatter(void)161*53286604SMasatake YAMATO extern parserDefinition* YamlFrontMatter (void)
162*53286604SMasatake YAMATO {
163*53286604SMasatake YAMATO 	static struct sYamlFrontMatterSubparser yamlfrontmatterSubparser = {
164*53286604SMasatake YAMATO 		.yaml = {
165*53286604SMasatake YAMATO 			.subparser = {
166*53286604SMasatake YAMATO 				.direction = SUBPARSER_SUB_RUNS_BASE,
167*53286604SMasatake YAMATO 				.inputStart = yamlFrontMatterInputStart,
168*53286604SMasatake YAMATO 				.inputEnd = yamlFrontMatterInputEnd,
169*53286604SMasatake YAMATO 			},
170*53286604SMasatake YAMATO 			.newTokenNotfify = newTokenCallback
171*53286604SMasatake YAMATO 		},
172*53286604SMasatake YAMATO 	};
173*53286604SMasatake YAMATO 	static parserDependency dependencies [] = {
174*53286604SMasatake YAMATO 		{ DEPTYPE_SUBPARSER, "Yaml", &yamlfrontmatterSubparser },
175*53286604SMasatake YAMATO 		{ DEPTYPE_FOREIGNER, "FrontMatter", NULL },
176*53286604SMasatake YAMATO 	};
177*53286604SMasatake YAMATO 
178*53286604SMasatake YAMATO 	parserDefinition* const def = parserNew ("YamlFrontMatter");
179*53286604SMasatake YAMATO 
180*53286604SMasatake YAMATO 	def->dependencies = dependencies;
181*53286604SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
182*53286604SMasatake YAMATO 
183*53286604SMasatake YAMATO 	def->kindTable	= NULL;
184*53286604SMasatake YAMATO 	def->kindCount = 0;
185*53286604SMasatake YAMATO 	def->parser	= findYamlFrontMatterTags;
186*53286604SMasatake YAMATO 	def->initialize = yamlFrontMatterInitialize;
187*53286604SMasatake YAMATO 	def->finalize = yamlFrontMatterFinalize;
188*53286604SMasatake YAMATO 
189*53286604SMasatake YAMATO 	/* This parser runs ONLY as a part of FrontMatter parser.
190*53286604SMasatake YAMATO 	 * User may not want to enable/disable this parser directly. */
191*53286604SMasatake YAMATO 	def->invisible = true;
192*53286604SMasatake YAMATO 
193*53286604SMasatake YAMATO 	return def;
194*53286604SMasatake YAMATO }
195