Skip to content

Commit

Permalink
TexBeamer: make at most one tag for frametitles having the same name
Browse files Browse the repository at this point in the history
Close #2421.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
  • Loading branch information
masatake committed Apr 4, 2020
1 parent 6d8a923 commit f67e271
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 17 deletions.
6 changes: 0 additions & 6 deletions Units/simple-texBeamer.d/expected.tags
@@ -1,15 +1,9 @@
Concept input.tex /^\\begin{frame}{Concept}$/;" frametitle
Concept input.tex /^\\begin{frame}{Concept}{kind}$/;" frametitle
kind input.tex /^\\begin{frame}{Concept}{kind}$/;" framesubtitle frametitle:Concept
Concept input.tex /^\\begin{frame}\\frametitle{Concept}$/;" frametitle
field input.tex /^ \\framesubtitle{field}$/;" framesubtitle frametitle:Concept
Concept input.tex /^\\begin{frame}{Concept}$/;" frametitle
extra input.tex /^ \\framesubtitle{extra}$/;" framesubtitle frametitle:Concept
Concept input.tex /^\\begin{frame}[fragile]{Concept}{pseudo tag}$/;" frametitle
pseudo tag input.tex /^\\begin{frame}[fragile]{Concept}{pseudo tag}$/;" framesubtitle frametitle:Concept
Options input.tex /^\\begin{frame}<1-2>\\frametitle{Options}$/;" frametitle
Optlib input.tex /^\\begin{frame}<1-2>[fragile]\\frametitle{Optlib}$/;" frametitle
Optlib input.tex /^\\begin{frame}<1-2>[fragile]\\frametitle{Optlib}\\framesubtitle{Line oriented parser}$/;" frametitle
Line oriented parser input.tex /^\\begin{frame}<1-2>[fragile]\\frametitle{Optlib}\\framesubtitle{Line oriented parser}$/;" framesubtitle frametitle:Optlib
Optlib input.tex /^\\begin{frame}[<+->][plain]{Optlib}\\framesubtitle{Multiline parser}$/;" frametitle
Multiline parser input.tex /^\\begin{frame}[<+->][plain]{Optlib}\\framesubtitle{Multiline parser}$/;" framesubtitle frametitle:Optlib
8 changes: 7 additions & 1 deletion parsers/tex-beamer.c
Expand Up @@ -63,13 +63,16 @@ static struct TexParseStrategy frametitle_strategy[] = {
.kindIndex = K_FRAMETITLE,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = false,
},
{
.type = '{',
.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,
.kindIndex = K_FRAMETITLE,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = true,
.scopeIndex = CORK_NIL, /* root scope */
},
{
.type = 0
Expand All @@ -90,6 +93,7 @@ static struct TexParseStrategy framesubtitle_strategy[] = {
.kindIndex = K_FRAMESUBTITLE,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = false,
},
{
.type = 0
Expand Down Expand Up @@ -121,7 +125,8 @@ static struct TexParseStrategy frame_env_strategy [] = {
.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,
.kindIndex = K_FRAMETITLE,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = true,
.scopeIndex = CORK_NIL, /* root scope */
},
{
/* This should not be optoinal. */
Expand All @@ -130,6 +135,7 @@ static struct TexParseStrategy frame_env_strategy [] = {
.kindIndex = K_FRAMESUBTITLE,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = false,
},
{
.type = 0
Expand Down
67 changes: 57 additions & 10 deletions parsers/tex.c
Expand Up @@ -271,11 +271,44 @@ static int getScopeInfo(texKind kind, vString *const parentName)
/*
* Tag generation functions
*/

struct symbolData {
langType lang;
int kind;
int *corkQueue;
};

static bool findTheName (unsigned int corkIndex, tagEntryInfo *entry, void *data)
{
struct symbolData *symbolData = data;

if (entry->langType == symbolData->lang && entry->kindIndex == symbolData->kind)
{
/* TODO: The case operation should be removed */
*symbolData->corkQueue = (unsigned int)corkIndex;
return false;
}
return true;
}

static int makeTexTag (tokenInfo *const token, int kind,
int roleIndex)
int roleIndex, bool unique, int scopeIndex)
{
int corkQueue = CORK_NIL;
const char *const name = vStringValue (token->string);

if (unique)
{
struct symbolData data = {
.lang = getInputLanguage(),
.kind = kind,
.corkQueue = &corkQueue,
};
/* TODO: The case operation should be removed */
if (foreachEntriesInScope ((unsigned int)scopeIndex, name, findTheName, (void *)&data) == false)
return *data.corkQueue;
}

tagEntryInfo e;
initTagEntry (&e, name, kind);

Expand All @@ -284,13 +317,17 @@ static int makeTexTag (tokenInfo *const token, int kind,

vString *parentName = NULL;


if (unique)
e.extensionFields.scopeIndex = scopeIndex;

/* Filling e.extensionFields.scopeKindIndex and
* e.extensionFields.scopeName can be filled with the value calculated
* from getScopeInfo() with the kind parameter only if the kind is defined
* in the Tex parser.
* Is a subparser indirectly calls this function, getScopeInfo() doesn't
* work well. So in the a context of a subparser, the scope fields should
* not be filled here.
* e.extensionFields.scopeName can be filled from "kind" parameter
* of this function only when Tex parser calls this function. The
* fields cannot be filled with a kind defined in a subparser.
* Subparsers may fill the scope after running strategy. So in the
* context of a subparser, filling the scope fields here is not
* needed.
*/
if (Lang_tex == getInputLanguage ())
{
Expand All @@ -307,6 +344,10 @@ static int makeTexTag (tokenInfo *const token, int kind,

corkQueue = makeTagEntry (&e);
vStringDelete (parentName); /* NULL is o.k. */

if (unique)
registerEntry (corkQueue);

return corkQueue;
}

Expand Down Expand Up @@ -549,7 +590,8 @@ static bool parseWithStrategy (tokenInfo *token,
if (!exclusive && capture_name && vStringLength (name->string) > 0)
{
if (s->kindIndex != KIND_GHOST_INDEX)
s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex);
s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,
s->unique, s->scopeIndex);

if (s->name)
vStringCopy(s->name, name->string);
Expand Down Expand Up @@ -605,7 +647,8 @@ static bool parseWithStrategy (tokenInfo *token,
vStringStripTrailing (name->string);

if (s->kindIndex != KIND_GHOST_INDEX)
s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex);
s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,
s->unique, s->scopeIndex);

if (s->name)
vStringCopy(s->name, name->string);
Expand Down Expand Up @@ -669,6 +712,7 @@ static bool parseTagFull (tokenInfo *const token, texKind kind, int roleIndex, b
.kindIndex = kind,
.roleIndex = roleIndex,
.name = taggedName,
.unique = false,
},
{
.type = 0
Expand All @@ -682,6 +726,7 @@ static bool parseTagFull (tokenInfo *const token, texKind kind, int roleIndex, b
strategy [0].roleIndex = roleIndex;
strategy [0].flags |= TEX_NAME_FLAG_EXCLUSIVE;
strategy [0].name = taggedName;
strategy [0].unique = false;
}
else
{
Expand Down Expand Up @@ -765,6 +810,7 @@ static bool parseNewcommand (tokenInfo *const token, bool *tokenUnprocessed)
.kindIndex = TEXTAG_COMMAND,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = false,
},
{
.type = '[',
Expand Down Expand Up @@ -806,6 +852,7 @@ static bool parseNewcounter (tokenInfo *const token, bool *tokenUnprocessed)
.kindIndex = TEXTAG_COUNTER,
.roleIndex = ROLE_DEFINITION_INDEX,
.name = NULL,
.unique = false,
},
{
.type = '[',
Expand Down Expand Up @@ -1046,6 +1093,6 @@ extern parserDefinition* TexParser (void)
def->finalize = finalize;
def->keywordTable = TexKeywordTable;
def->keywordCount = ARRAY_SIZE (TexKeywordTable);
def->useCork = CORK_QUEUE;
def->useCork = CORK_QUEUE | CORK_SYMTAB;
return def;
}
7 changes: 7 additions & 0 deletions parsers/tex.h
Expand Up @@ -65,6 +65,13 @@ struct TexParseStrategy {
/* Store the string surrounded by one of paris.
* If you don't need to store the string, set NULL here. */
vString *name;

/* If true, make at most one tag for the name in the scope specified
* with scopeIndex. When making a tag, scopeIndex is set to
* extensionFields.scopeIndex only if unique is true.
* scopeIndex is never referred if unique if false. */
bool unique;
int scopeIndex;
};

typedef struct sTexSubparser texSubparser;
Expand Down

0 comments on commit f67e271

Please sign in to comment.