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