Skip to content

Commit c2cc416

Browse files
committed
Merge branch 'feature/bug_cite_option' of https://github.com/albert-github/doxygen into albert-github-feature/bug_cite_option
2 parents def79ca + 235da96 commit c2cc416

17 files changed

+352
-67
lines changed

doc/commands.dox

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ Commands to create links
24772477
\sa section \ref cmdref "\\ref".
24782478

24792479
<hr>
2480-
\section cmdcite \\cite \<label\>
2480+
\section cmdcite \\cite['{'[option]'}'] \<label\>
24812481

24822482
\addindex \\cite
24832483
Adds a bibliographic reference in the text and in the list of bibliographic
@@ -2488,6 +2488,18 @@ Commands to create links
24882488
output formats a fixed representation is used. Note that using this
24892489
command requires the \c bibtex tool to be present in the search path.
24902490

2491+
There are a number of options possible:
2492+
- `number`, `shortauthor`, `year`, these options are mutually exclusive,
2493+
in case none of these is specified `number` is assumed.
2494+
- `number` create a numerical reference
2495+
- `shortauthor` just the surname of the first author is given, and in case
2496+
multiple authors are present the text "et al." is added
2497+
- `year`, the year of publication is mentioned (when specified in the bibtex
2498+
file.
2499+
- `nopar`, no (square) brackets are added
2500+
- `nocite`, no link to a citation in the bibliography is made (and the
2501+
reference is not added to the bibliography based on this item)
2502+
24912503
<hr>
24922504
\section cmdendlink \\endlink
24932505

src/cite.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,22 @@ class CiteInfoImpl : public CiteInfo
5858
{
5959
public:
6060
CiteInfoImpl(const QCString &label, const QCString &text=QCString())
61-
: m_label(label), m_text(text) { }
61+
: m_label(label), m_text(text), m_shortAuthor(QCString()), m_year(QCString()) { }
6262

6363
QCString label() const override { return m_label; }
6464
QCString text() const override { return m_text; }
65+
QCString shortAuthor() const override { return m_shortAuthor; }
66+
QCString year() const override { return m_year; }
6567

6668
void setText(const QCString &s) { m_text = s; }
69+
void setShortAuthor(const QCString &s) { m_shortAuthor = s; }
70+
void setYear(const QCString &s) { m_year = s; }
6771

6872
private:
6973
QCString m_label;
7074
QCString m_text;
75+
QCString m_shortAuthor;
76+
QCString m_year;
7177
};
7278

7379
struct CitationManager::Private
@@ -457,20 +463,32 @@ void CitationManager::generatePage()
457463
if (insideBib && ((i=line.find("name=\"CITEREF_"))!=-1 || (i=line.find("name=\"#CITEREF_"))!=-1))
458464
{
459465
int j=line.find("\">[");
460-
int k=line.find("]</a>");
466+
int j1=line.find("<!--[");
467+
int k=line.find("]<!--");
468+
int k1=line.find("]-->");
461469
if (j!=-1 && k!=-1)
462470
{
463471
size_t ui=static_cast<size_t>(i);
464-
size_t uj=static_cast<size_t>(j);
465-
size_t uk=static_cast<size_t>(k);
466-
QCString label = line.mid(ui+14,uj-ui-14);
467-
QCString number = line.mid(uj+2,uk-uj-1);
468-
line = line.left(ui+14) + label + line.right(line.length()-uj);
472+
size_t uj0=static_cast<size_t>(j);
473+
size_t uj=static_cast<size_t>(j1);
474+
size_t uk=static_cast<size_t>(k1);
475+
QCString label = line.mid(ui+14,uj0-ui-14);
476+
StringVector optList = split(line.mid(uj+5,uk-uj-5).str(),",");
477+
QCString number = optList[0].c_str();
478+
QCString shortAuthor = optList[1].c_str();
479+
QCString year;
480+
if (optList.size() == 3)
481+
{
482+
year = optList[2].c_str();
483+
}
484+
line = line.left(ui+14) + label + line.right(line.length()-uj0);
469485
auto it = p->entries.find(label.lower().str());
470486
//printf("label='%s' number='%s' => %p\n",qPrint(label),qPrint(number),it->second.get());
471487
if (it!=p->entries.end())
472488
{
473489
it->second->setText(number);
490+
it->second->setShortAuthor(shortAuthor);
491+
it->second->setYear(year.stripWhiteSpace());
474492
}
475493
}
476494
}

src/cite.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ struct CiteInfo
2929

3030
virtual QCString label() const = 0;
3131
virtual QCString text() const = 0;
32+
virtual QCString shortAuthor() const = 0;
33+
virtual QCString year() const = 0;
34+
35+
enum CiteOptionType {
36+
UNKNOWN = 0x00,
37+
NUMBER = 0x01,
38+
SHORTAUTHOR = 0x02,
39+
YEAR = 0x04,
40+
41+
NOPAR_BIT = 0x001000, //< Don't use square brackets
42+
NOCITE_BIT = 0x100000, //< Don't create a link
43+
};
3244
};
3345

3446
/**

src/commentscan.l

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3367,15 +3367,22 @@ static bool handleImage(yyscan_t yyscanner,const QCString &s, const StringVector
33673367
return FALSE;
33683368
}
33693369

3370-
static bool handleCite(yyscan_t yyscanner,const QCString &s, const StringVector &)
3370+
static bool handleCite(yyscan_t yyscanner,const QCString &s, const StringVector &optList)
33713371
{
33723372
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
33733373
if (!yyextra->spaceBeforeCmd.isEmpty())
33743374
{
33753375
addOutput(yyscanner,yyextra->spaceBeforeCmd);
33763376
yyextra->spaceBeforeCmd.clear();
33773377
}
3378-
addOutput(yyscanner,"@"+s+" ");
3378+
if (optList.empty())
3379+
{
3380+
addOutput(yyscanner,"@"+s+" ");
3381+
}
3382+
else
3383+
{
3384+
addOutput(yyscanner,"@"+s+"{"+QCString(join(optList,","))+"} ");
3385+
}
33793386
BEGIN(CiteLabel);
33803387
return FALSE;
33813388
}

src/docbookvisitor.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "fileinfo.h"
3636
#include "portable.h"
3737
#include "codefragment.h"
38+
#include "cite.h"
3839

3940
#if 0
4041
#define DB_VIS_C DB_VIS_C1(m_t)
@@ -602,9 +603,23 @@ void DocbookDocVisitor::operator()(const DocCite &cite)
602603
{
603604
DB_VIS_C
604605
if (m_hide) return;
605-
if (!cite.file().isEmpty()) startLink(cite.file(),filterId(cite.anchor()));
606-
filter(cite.text());
607-
if (!cite.file().isEmpty()) endLink();
606+
int opt = cite.option();
607+
if (!cite.file().isEmpty())
608+
{
609+
if (!(opt & CiteInfo::NOCITE_BIT)) startLink(cite.file(),filterId(cite.anchor()));
610+
611+
filter(cite.getText());
612+
613+
if (!(opt & CiteInfo::NOCITE_BIT)) endLink();
614+
}
615+
else
616+
{
617+
if (!(opt & CiteInfo::NOPAR_BIT)) filter("[");
618+
filter(cite.target());
619+
if (!(opt & CiteInfo::NOPAR_BIT)) filter("]");
620+
621+
}
622+
608623
}
609624

610625
//--------------------------------------

src/docnode.cpp

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ void DocRef::parse()
900900

901901
//---------------------------------------------------------------------------
902902

903-
DocCite::DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &) : DocNode(parser,parent)
903+
DocCite::DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &,int opt) : DocNode(parser,parent)
904904
{
905905
size_t numBibFiles = Config_getList(CITE_BIB_FILES).size();
906906
//printf("DocCite::DocCite(target=%s)\n",qPrint(target));
@@ -909,17 +909,17 @@ DocCite::DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target
909909
const CitationManager &ct = CitationManager::instance();
910910
const CiteInfo *cite = ct.find(target);
911911
//printf("cite=%p text='%s' numBibFiles=%d\n",cite,cite?qPrint(cite->text):"<null>",numBibFiles);
912+
m_option = opt;
913+
m_target = target;
912914
if (numBibFiles>0 && cite && !cite->text().isEmpty()) // ref to citation
913915
{
914-
m_text = cite->text();
915916
m_ref = "";
916917
m_anchor = ct.anchorPrefix()+cite->label();
917918
m_file = convertNameToFile(ct.fileName(),FALSE,TRUE);
918919
//printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n",
919920
// qPrint(m_text),qPrint(m_ref),qPrint(m_file),qPrint(m_anchor));
920921
return;
921922
}
922-
m_text = target;
923923
if (numBibFiles==0)
924924
{
925925
warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"\\cite command found but no bib files specified via CITE_BIB_FILES!");
@@ -936,6 +936,27 @@ DocCite::DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target
936936
}
937937
}
938938

939+
QCString DocCite::getText() const
940+
{
941+
QCString txt;
942+
int opt = m_option;
943+
const CitationManager &ct = CitationManager::instance();
944+
const CiteInfo *citeInfo = ct.find(m_target);
945+
946+
if (!(opt & CiteInfo::NOPAR_BIT)) txt += "[";
947+
948+
if (citeInfo)
949+
{
950+
if (opt & CiteInfo::NUMBER) txt += citeInfo->text();
951+
else if (opt & CiteInfo::SHORTAUTHOR) txt += citeInfo->shortAuthor();
952+
else if (opt & CiteInfo::YEAR) txt += citeInfo->year();
953+
}
954+
955+
if (!(opt & CiteInfo::NOPAR_BIT)) txt += "]";
956+
return txt;
957+
}
958+
959+
939960
//---------------------------------------------------------------------------
940961

941962
DocLink::DocLink(DocParser *parser,DocNodeVariant *parent,const QCString &target) : DocCompoundNode(parser,parent)
@@ -3304,31 +3325,102 @@ Token DocPara::handleParamSection(const QCString &cmdName,
33043325
void DocPara::handleCite(char cmdChar,const QCString &cmdName)
33053326
{
33063327
AUTO_TRACE();
3328+
QCString saveCmdName = cmdName;
33073329
// get the argument of the cite command.
33083330
Token tok=parser()->tokenizer.lex();
3309-
if (!tok.is(TokenRetval::TK_WHITESPACE))
3331+
3332+
int option = CiteInfo::UNKNOWN;
3333+
bool nopar_bit = false;
3334+
bool nocite_bit = false;
3335+
if (tok.is(TokenRetval::TK_WORD) && parser()->context.token->name=="{")
3336+
{
3337+
parser()->tokenizer.setStateOptions();
3338+
parser()->tokenizer.lex();
3339+
StringVector optList=split(parser()->context.token->name.str(),",");
3340+
for (auto const &opt : optList)
3341+
{
3342+
if (opt == "number")
3343+
{
3344+
if (option != CiteInfo::UNKNOWN)
3345+
{
3346+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", saveCmdName, opt);
3347+
}
3348+
else
3349+
{
3350+
option = CiteInfo::NUMBER;
3351+
}
3352+
}
3353+
else if (opt == "year")
3354+
{
3355+
if (option != CiteInfo::UNKNOWN)
3356+
{
3357+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", saveCmdName, opt);
3358+
}
3359+
else
3360+
{
3361+
option = CiteInfo::YEAR;
3362+
}
3363+
}
3364+
else if (opt == "shortauthor")
3365+
{
3366+
if (option != CiteInfo::UNKNOWN)
3367+
{
3368+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", saveCmdName, opt);
3369+
}
3370+
else
3371+
{
3372+
option = CiteInfo::SHORTAUTHOR;
3373+
}
3374+
}
3375+
else if (opt == "nopar") nopar_bit = true;
3376+
else if (opt == "nocite") nocite_bit = true;
3377+
else
3378+
{
3379+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unkown option specified with \\{}, discarding '{}'", saveCmdName, opt);
3380+
}
3381+
}
3382+
3383+
if (option == CiteInfo::UNKNOWN) option = CiteInfo::NUMBER;
3384+
if (nopar_bit) option |= CiteInfo::NOPAR_BIT;
3385+
if (nocite_bit) option |= CiteInfo::NOCITE_BIT;
3386+
3387+
parser()->tokenizer.setStatePara();
3388+
tok=parser()->tokenizer.lex();
3389+
if (!tok.is(TokenRetval::TK_WHITESPACE))
3390+
{
3391+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\{} command",
3392+
saveCmdName);
3393+
return;
3394+
}
3395+
}
3396+
else if (!tok.is(TokenRetval::TK_WHITESPACE))
33103397
{
33113398
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
3312-
cmdChar,cmdName);
3399+
cmdChar,saveCmdName);
33133400
return;
33143401
}
3402+
else
3403+
{
3404+
option = CiteInfo::NUMBER;
3405+
}
3406+
33153407
parser()->tokenizer.setStateCite();
33163408
tok=parser()->tokenizer.lex();
33173409
if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
33183410
{
3319-
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
3320-
"argument of command '{:c}{}'",cmdChar,cmdName);
3411+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"THE ONE unexpected end of comment block while parsing the "
3412+
"argument of command '{:c}{}'",cmdChar,saveCmdName);
33213413
return;
33223414
}
33233415
else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
33243416
{
33253417
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
3326-
tok.to_string(),cmdChar,cmdName);
3418+
tok.to_string(),cmdChar,saveCmdName);
33273419
return;
33283420
}
33293421
parser()->context.token->sectionId = parser()->context.token->name;
33303422
children().append<DocCite>(
3331-
parser(),thisVariant(),parser()->context.token->name,parser()->context.context);
3423+
parser(),thisVariant(),parser()->context.token->name,parser()->context.context,option);
33323424

33333425
parser()->tokenizer.setStatePara();
33343426
}

src/docnode.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,19 +243,22 @@ class DocAnchor : public DocNode
243243
class DocCite : public DocNode
244244
{
245245
public:
246-
DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &context);
246+
DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &context, int opt);
247247
QCString file() const { return m_file; }
248248
QCString relPath() const { return m_relPath; }
249249
QCString ref() const { return m_ref; }
250250
QCString anchor() const { return m_anchor; }
251-
QCString text() const { return m_text; }
251+
QCString target() const { return m_target; }
252+
int option() const { return m_option; }
253+
QCString getText() const;
252254

253255
private:
254256
QCString m_file;
255257
QCString m_relPath;
256258
QCString m_ref;
257259
QCString m_anchor;
258-
QCString m_text;
260+
QCString m_target;
261+
int m_option;
259262
};
260263

261264

0 commit comments

Comments
 (0)