1*3bbeaff4SMasatake YAMATO /*
2*3bbeaff4SMasatake YAMATO *
3*3bbeaff4SMasatake YAMATO * Copyright (c) 2022, Masatake YAMATO
4*3bbeaff4SMasatake YAMATO *
5*3bbeaff4SMasatake YAMATO * This source code is released for free distribution under the terms of the
6*3bbeaff4SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
7*3bbeaff4SMasatake YAMATO *
8*3bbeaff4SMasatake YAMATO * This module contains functions for generating tags for R Markdown files.
9*3bbeaff4SMasatake YAMATO * https://bookdown.org/yihui/rmarkdown/
10*3bbeaff4SMasatake YAMATO *
11*3bbeaff4SMasatake YAMATO */
12*3bbeaff4SMasatake YAMATO
13*3bbeaff4SMasatake YAMATO /*
14*3bbeaff4SMasatake YAMATO * INCLUDE FILES
15*3bbeaff4SMasatake YAMATO */
16*3bbeaff4SMasatake YAMATO #include "general.h" /* must always come first */
17*3bbeaff4SMasatake YAMATO #include "markdown.h"
18*3bbeaff4SMasatake YAMATO
19*3bbeaff4SMasatake YAMATO #include "entry.h"
20*3bbeaff4SMasatake YAMATO #include "parse.h"
21*3bbeaff4SMasatake YAMATO
22*3bbeaff4SMasatake YAMATO #include <ctype.h>
23*3bbeaff4SMasatake YAMATO #include <string.h>
24*3bbeaff4SMasatake YAMATO
25*3bbeaff4SMasatake YAMATO /*
26*3bbeaff4SMasatake YAMATO * DATA DEFINITIONS
27*3bbeaff4SMasatake YAMATO */
28*3bbeaff4SMasatake YAMATO typedef enum {
29*3bbeaff4SMasatake YAMATO K_CHUNK_LABEL = 0,
30*3bbeaff4SMasatake YAMATO } rmarkdownKind;
31*3bbeaff4SMasatake YAMATO
32*3bbeaff4SMasatake YAMATO static kindDefinition RMarkdownKinds[] = {
33*3bbeaff4SMasatake YAMATO { true, 'l', "chunklabel", "chunk labels"},
34*3bbeaff4SMasatake YAMATO };
35*3bbeaff4SMasatake YAMATO
36*3bbeaff4SMasatake YAMATO struct sRMarkdownSubparser {
37*3bbeaff4SMasatake YAMATO markdownSubparser markdown;
38*3bbeaff4SMasatake YAMATO };
39*3bbeaff4SMasatake YAMATO
40*3bbeaff4SMasatake YAMATO /*
41*3bbeaff4SMasatake YAMATO * FUNCTION DEFINITIONS
42*3bbeaff4SMasatake YAMATO */
43*3bbeaff4SMasatake YAMATO
findRMarkdownTags(void)44*3bbeaff4SMasatake YAMATO static void findRMarkdownTags (void)
45*3bbeaff4SMasatake YAMATO {
46*3bbeaff4SMasatake YAMATO scheduleRunningBaseparser (0);
47*3bbeaff4SMasatake YAMATO }
48*3bbeaff4SMasatake YAMATO
49*3bbeaff4SMasatake YAMATO #define skip_space(CP) while (*CP == ' ' || *CP == '\t') CP++;
50*3bbeaff4SMasatake YAMATO
makeRMarkdownTag(vString * name,int kindIndex,bool anonymous)51*3bbeaff4SMasatake YAMATO static void makeRMarkdownTag (vString *name, int kindIndex, bool anonymous)
52*3bbeaff4SMasatake YAMATO {
53*3bbeaff4SMasatake YAMATO tagEntryInfo e;
54*3bbeaff4SMasatake YAMATO initTagEntry (&e, vStringValue (name), kindIndex);
55*3bbeaff4SMasatake YAMATO if (anonymous)
56*3bbeaff4SMasatake YAMATO markTagExtraBit (&e, XTAG_ANONYMOUS);
57*3bbeaff4SMasatake YAMATO makeTagEntry (&e);
58*3bbeaff4SMasatake YAMATO }
59*3bbeaff4SMasatake YAMATO
extractLanguageForCodeBlock(markdownSubparser * s,const char * langMarker,vString * langName)60*3bbeaff4SMasatake YAMATO static bool extractLanguageForCodeBlock (markdownSubparser *s,
61*3bbeaff4SMasatake YAMATO const char *langMarker,
62*3bbeaff4SMasatake YAMATO vString *langName)
63*3bbeaff4SMasatake YAMATO {
64*3bbeaff4SMasatake YAMATO const char *cp = langMarker;
65*3bbeaff4SMasatake YAMATO
66*3bbeaff4SMasatake YAMATO if (*cp != '{')
67*3bbeaff4SMasatake YAMATO return false;
68*3bbeaff4SMasatake YAMATO cp++;
69*3bbeaff4SMasatake YAMATO
70*3bbeaff4SMasatake YAMATO const char *end = strpbrk(cp, " \t,}");
71*3bbeaff4SMasatake YAMATO if (!end)
72*3bbeaff4SMasatake YAMATO return false;
73*3bbeaff4SMasatake YAMATO
74*3bbeaff4SMasatake YAMATO if (end - cp == 0)
75*3bbeaff4SMasatake YAMATO return false;
76*3bbeaff4SMasatake YAMATO
77*3bbeaff4SMasatake YAMATO vStringNCatS (langName, cp, end - cp);
78*3bbeaff4SMasatake YAMATO
79*3bbeaff4SMasatake YAMATO cp = end;
80*3bbeaff4SMasatake YAMATO if (*cp == ',' || *cp == '}')
81*3bbeaff4SMasatake YAMATO {
82*3bbeaff4SMasatake YAMATO vString *name = anonGenerateNew("__anon", K_CHUNK_LABEL);
83*3bbeaff4SMasatake YAMATO makeRMarkdownTag (name, K_CHUNK_LABEL, true);
84*3bbeaff4SMasatake YAMATO vStringDelete (name);
85*3bbeaff4SMasatake YAMATO return true;
86*3bbeaff4SMasatake YAMATO }
87*3bbeaff4SMasatake YAMATO
88*3bbeaff4SMasatake YAMATO skip_space(cp);
89*3bbeaff4SMasatake YAMATO
90*3bbeaff4SMasatake YAMATO vString *chunk_label = vStringNew ();
91*3bbeaff4SMasatake YAMATO bool anonymous = false;
92*3bbeaff4SMasatake YAMATO while (isalnum((unsigned char)*cp) || *cp == '-')
93*3bbeaff4SMasatake YAMATO vStringPut (chunk_label, *cp++);
94*3bbeaff4SMasatake YAMATO
95*3bbeaff4SMasatake YAMATO if (vStringLength (chunk_label) == 0)
96*3bbeaff4SMasatake YAMATO {
97*3bbeaff4SMasatake YAMATO anonGenerate (chunk_label, "__anon", K_CHUNK_LABEL);
98*3bbeaff4SMasatake YAMATO anonymous = true;
99*3bbeaff4SMasatake YAMATO }
100*3bbeaff4SMasatake YAMATO
101*3bbeaff4SMasatake YAMATO skip_space(cp);
102*3bbeaff4SMasatake YAMATO if (*cp == ',' || *cp == '}')
103*3bbeaff4SMasatake YAMATO makeRMarkdownTag (chunk_label, K_CHUNK_LABEL, anonymous);
104*3bbeaff4SMasatake YAMATO
105*3bbeaff4SMasatake YAMATO vStringDelete (chunk_label);
106*3bbeaff4SMasatake YAMATO return true;
107*3bbeaff4SMasatake YAMATO }
108*3bbeaff4SMasatake YAMATO
RMarkdownParser(void)109*3bbeaff4SMasatake YAMATO extern parserDefinition* RMarkdownParser (void)
110*3bbeaff4SMasatake YAMATO {
111*3bbeaff4SMasatake YAMATO static const char *const extensions [] = { "rmd", NULL };
112*3bbeaff4SMasatake YAMATO static struct sRMarkdownSubparser rmarkdownSubparser = {
113*3bbeaff4SMasatake YAMATO .markdown = {
114*3bbeaff4SMasatake YAMATO .subparser = {
115*3bbeaff4SMasatake YAMATO .direction = SUBPARSER_SUB_RUNS_BASE,
116*3bbeaff4SMasatake YAMATO },
117*3bbeaff4SMasatake YAMATO .extractLanguageForCodeBlock = extractLanguageForCodeBlock,
118*3bbeaff4SMasatake YAMATO },
119*3bbeaff4SMasatake YAMATO };
120*3bbeaff4SMasatake YAMATO static parserDependency dependencies [] = {
121*3bbeaff4SMasatake YAMATO [0] = { DEPTYPE_SUBPARSER, "Markdown", &rmarkdownSubparser },
122*3bbeaff4SMasatake YAMATO };
123*3bbeaff4SMasatake YAMATO
124*3bbeaff4SMasatake YAMATO parserDefinition* const def = parserNew ("RMarkdown");
125*3bbeaff4SMasatake YAMATO
126*3bbeaff4SMasatake YAMATO
127*3bbeaff4SMasatake YAMATO def->dependencies = dependencies;
128*3bbeaff4SMasatake YAMATO def->dependencyCount = ARRAY_SIZE(dependencies);
129*3bbeaff4SMasatake YAMATO def->kindTable = RMarkdownKinds;
130*3bbeaff4SMasatake YAMATO def->kindCount = ARRAY_SIZE (RMarkdownKinds);
131*3bbeaff4SMasatake YAMATO def->extensions = extensions;
132*3bbeaff4SMasatake YAMATO def->parser = findRMarkdownTags;
133*3bbeaff4SMasatake YAMATO return def;
134*3bbeaff4SMasatake YAMATO }
135