mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-24 21:55:29 +00:00
Support for "qualified citation lists"
These are biblatex-specific multicite commands that allow for multiple pre- and postnotes, as in: \cites(pre)(post)[pre1][post1]{key1}[pre2][post2]{key2}... with an optional general pre- and postnote, which applies to the whole list (like [][] in normal cite commands) and an optional pre- and postnotes for each item, so that pagination can actually be specified in multi-cite references, as in: (cf. Miller 2015, 2; furthermore Smith 2013, 23-23; Jenkins 2012, 103, also refer to chapter 6 in this book) See the biblatex manual, sec. 3.8.3., for details. File format change.
This commit is contained in:
parent
633ad2032e
commit
68ab4023cc
@ -7,6 +7,13 @@ changes happened in particular if possible. A good example would be
|
||||
|
||||
-----------------------
|
||||
|
||||
2017-01-21 Jürgen Spitzmüller <spitz@lyx.org>
|
||||
* Format incremented to 531: Support for qualified citation lists.
|
||||
\begin_inset CommandInset citation
|
||||
New params: pretextlist, posttextlist
|
||||
A tab-separated list consisting of a cite key, a space and the the
|
||||
pre- or postnote associated with that specific key.
|
||||
|
||||
2017-01-13 Jürgen Spitzmüller <spitz@lyx.org>
|
||||
* Format incremented to 530: Support natbib & jurabib package options.
|
||||
|
||||
|
@ -68,6 +68,8 @@ MaxCiteNames 3
|
||||
# dropping the '!' from the prefix (see below), e.g.:
|
||||
# _stardesc Starred command label
|
||||
# _stardesctooltip Tooltip for the starred command checkbox.
|
||||
# * A trailing $ indicates that a command features "qualified citation
|
||||
# lists" (a specific Biblatex feature)
|
||||
|
||||
#
|
||||
# CITE COMMAND DEFINITIONS for either engine type
|
||||
@ -84,8 +86,8 @@ CiteEngine authoryear
|
||||
citeyearpar[][]
|
||||
citeyear=cite*
|
||||
citebyear[][]=citeyear
|
||||
Footcite[][]=smartcite
|
||||
Autocite[][]
|
||||
Footcite$[][]=smartcite
|
||||
Autocite$[][]
|
||||
citetitle*<!_citetitlestar!_citetitlestartooltip>[][]
|
||||
fullcite[][]
|
||||
footfullcite[][]
|
||||
@ -97,8 +99,8 @@ CiteEngine numerical
|
||||
Citep|citealp,citealt*[][]
|
||||
Citet|textcite*[][]
|
||||
supercite
|
||||
Footcite[][]=smartcite
|
||||
Autocite[][]
|
||||
Footcite$[][]=smartcite
|
||||
Autocite$[][]
|
||||
Citeauthor[][]*
|
||||
citeyearpar[][]
|
||||
citeyear|citebyear[][]
|
||||
@ -177,6 +179,10 @@ CiteFormat default
|
||||
!textbefore {%textbefore%[[%textbefore% ]]}
|
||||
# ", postnote"
|
||||
!textafter {%textafter%[[, %textafter%]]}
|
||||
# "prenote " (for qualified lists)
|
||||
!ctextbefore {%curpretext%[[%curpretext% ]]}
|
||||
# ", postnote" (for qualified lists)
|
||||
!ctextafter {%curposttext%[[, %curposttext%]]}
|
||||
# Add a year if it exists (else "??") and possibly a modifier (as in 2017a)
|
||||
!makeyear {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]}
|
||||
# Add a year if it exists (else "??") and indicate a possible modifier (as in 2017[a])
|
||||
@ -239,6 +245,8 @@ CiteFormat authoryear
|
||||
!sep ;
|
||||
!close )
|
||||
|
||||
# "cf. Author et. al Year..."
|
||||
!makecite %!ctextbefore%%!startlink%%!abbrvciteauthor% %!makeyear%%!endlink%%!ctextafter%%!nextcite%
|
||||
# "Author et al. (cf. Year..."
|
||||
!makecitet %!startlink%%!makeauthor%%!endlink% %!open%%!textbefore%%!makeyear%%!nextcitet%
|
||||
# "cf. Author et al. Year..."
|
||||
@ -246,6 +254,8 @@ CiteFormat authoryear
|
||||
# "Author et al., Year..."
|
||||
!makecitealp %!startlink%%!makeauthor%, %!makeyear%%!endlink%%!nextcitealp%
|
||||
|
||||
# "...; Nextauthor Year..."
|
||||
!nextcite {%next%[[%!sep% %!makecite%]]}
|
||||
# "...), [and] Nextauthor (Year..."
|
||||
!nextcitet {%next%[[%!close%%!smartsep%%!startlink%%!makeauthor%%!endlink% %!open%%!makeyear%%!nextcitet%]]}
|
||||
# "...; NextAuthor et al. Year..."
|
||||
@ -268,9 +278,9 @@ CiteFormat authoryear
|
||||
# "cf. Author Year; NextAuthor Year, p. xx" [NB: textbefore position differs from real natbib!]
|
||||
citealt %!makecitealt%%!textafter%
|
||||
# "Footnote: cf. Author A Year; Author B Year, p. xx."
|
||||
footcite {%dialog%[[%_footnote%]][[%_foot%]]}: %!textbefore%%!makecitealp%%!textafter%.
|
||||
footcite {%dialog%[[%_footnote%]][[%_foot%]]}: %!textbefore%%!makecite%%!textafter%.
|
||||
# "Auto: (cf. Author A Year; Author B Year, p. xx)"
|
||||
autocite {%dialog%[[%_autocite%]][[%_auto%]]}: %!open%%!textbefore%%!makecitealp%%!textafter%%!close%
|
||||
autocite {%dialog%[[%_autocite%]][[%_auto%]]}: %!open%%!textbefore%%!makecite%%!textafter%%!close%
|
||||
|
||||
# Fallback style: "Author A (cf. Year),[ and] Author B (Year, p. xx)"
|
||||
cite %!makecitet%%!textafter%%!close%
|
||||
@ -298,6 +308,8 @@ CiteFormat numerical
|
||||
!makecitealt {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt%
|
||||
# "ID..."
|
||||
!hashkey {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]}
|
||||
# "ID"
|
||||
!makekey %!ctextbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!ctextafter%%!nextkey%
|
||||
|
||||
# "...], [and] NextAuthor [ID..."
|
||||
!nextcitet {%next%[[%!close%%!smartsep%%!makeauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%]]}
|
||||
@ -309,6 +321,8 @@ CiteFormat numerical
|
||||
!nexthashkey {%next%[[%!sep% %!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]}
|
||||
# "...); Nextauthor [ID..."
|
||||
!nextcitet {%next%[[%!close%%!smartsep%%!makeauthor% %!open%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%]]}
|
||||
# "..., NextID..."
|
||||
!nextkey {%next%[[%!sep% %!ctextbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!ctextafter%%!nextkey%]]}
|
||||
|
||||
#
|
||||
# ACTUAL STYLE DEFINITIONS
|
||||
|
@ -64,20 +64,22 @@ MaxCiteNames 3
|
||||
# the '!' from the prefix (see below), e.g.:
|
||||
# _stardesc Starred command label
|
||||
# _stardesctooltip Tooltip for the starred command checkbox.
|
||||
# * A trailing $ indicates that a command features "qualified citation
|
||||
# lists" (a specific Biblatex feature)
|
||||
|
||||
#
|
||||
# CITE COMMAND DEFINITIONS for either engine type
|
||||
#
|
||||
CiteEngine authoryear
|
||||
Cite|citealt,citealp[][]
|
||||
Citet[][]=textcite
|
||||
Citep[][]=parencite
|
||||
Cite$|citealt,citealp[][]
|
||||
Citet$[][]=textcite
|
||||
Citep$[][]=parencite
|
||||
Citeauthor*<!_citeauthorstar!_citeauthorstartooltip>[][]
|
||||
citeyearpar[][]=parencite*
|
||||
citeyear[][]=cite*
|
||||
citebyear[][]=citeyear
|
||||
Footcite[][]=smartcite
|
||||
Autocite[][]
|
||||
Footcite$[][]=smartcite
|
||||
Autocite$[][]
|
||||
citetitle*<!_citetitlestar!_citetitlestartooltip>[][]
|
||||
fullcite[][]
|
||||
footfullcite[][]
|
||||
@ -86,11 +88,11 @@ CiteEngine authoryear
|
||||
End
|
||||
|
||||
CiteEngine numerical
|
||||
cite|parencite,citep,citealt,citealp[][]
|
||||
Citet[][]=textcite
|
||||
cite$|parencite,citep,citealt,citealp[][]
|
||||
Citet$[][]=textcite
|
||||
supercite
|
||||
Footcite[][]=smartcite
|
||||
Autocite[][]
|
||||
Footcite$[][]=smartcite
|
||||
Autocite$[][]
|
||||
Citeauthor*<!_citeauthorstar!_citeauthorstartooltip>[][]
|
||||
citeyear|parencite*,citebyear[][]=citeyear*
|
||||
citetitle*<!_citetitlestar!_citetitlestartooltip>[][]
|
||||
@ -182,6 +184,10 @@ CiteFormat default
|
||||
!textbefore {%textbefore%[[%textbefore% ]]}
|
||||
# ", postnote"
|
||||
!textafter {%textafter%[[, %textafter%]]}
|
||||
# "prenote " (for qualified lists)
|
||||
!ctextbefore {%curpretext%[[%curpretext% ]]}
|
||||
# ", postnote" (for qualified lists)
|
||||
!ctextafter {%curposttext%[[, %curposttext%]]}
|
||||
# Add a year if it exists (else "??") and possibly a modifier (as in 2017a)
|
||||
!year {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]}
|
||||
# Add a year if it exists (else "??") and indicate a possible modifier (as in 2017[a])
|
||||
@ -228,14 +234,14 @@ CiteFormat authoryear
|
||||
!close )
|
||||
|
||||
# "cf. Author et. al Year..."
|
||||
!makecite %!startlink%%!abbrvciteauthor% %!year%%!endlink%%!nextcite%
|
||||
!makecite %!ctextbefore%%!startlink%%!abbrvciteauthor% %!year%%!endlink%%!ctextafter%%!nextcite%
|
||||
# Author et al. (cf. Year...
|
||||
!maketextcite %!startlink%%!abbrvciteauthor%%!endlink% %!open%%!textbefore%%!year%%!nexttextcite%
|
||||
!maketextcite {%ifqualified%[[%!textbefore%]]}%!startlink%%!abbrvciteauthor%%!endlink% %!open%{%ifqualified%[[%!ctextbefore%]][[%!textbefore%]]}%!year%%!ctextafter%%!nexttextcite%
|
||||
|
||||
# "...; Nextauthor Year..."
|
||||
!nextcite {%next%[[%!sep% %!makecite%]]}
|
||||
# "...); Nextauthor (Year..."
|
||||
!nexttextcite {%next%[[%!close%%!smartsep%%!startlink%%!abbrvciteauthor%%!endlink% %!open%%!year%%!nexttextcite%]]}
|
||||
!nexttextcite {%next%[[%!close%%!smartsep%%!startlink%%!abbrvciteauthor%%!endlink% %!open%%!ctextbefore%%!year%%!ctextafter%%!nexttextcite%]]}
|
||||
|
||||
# Add a year if it exists (else title, else "??") and possibly a modifier (as in 2017a)
|
||||
!yeartitle {%year%[[%year%{%modifier%[[%modifier%]][[{%export%[[]][[%!dummymod%]]}]]}]][[{%title%[[%title%]][[??]]}]]}
|
||||
@ -283,12 +289,12 @@ CiteFormat numerical
|
||||
# "Author [cf. ID..."
|
||||
!maketextcite %!abbrvciteauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nexttextcite%
|
||||
# "ID"
|
||||
!makekey {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nextkey%]]}
|
||||
!makekey %!ctextbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!ctextafter%%!nextkey%
|
||||
|
||||
# "...); Nextauthor [ID..."
|
||||
!nexttextcite {%next%[[%!close%%!smartsep%%!abbrvciteauthor% %!open%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nexttextcite%]]}
|
||||
!nexttextcite {%next%[[%!close%%!smartsep%%!abbrvciteauthor% %!open%%!ctextbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nexttextcite%]]}
|
||||
# "..., NextID..."
|
||||
!nextkey {%next%[[%!sep% %!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nextkey%]]}
|
||||
!nextkey {%next%[[%!sep% %!ctextbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!ctextafter%%!nextkey%]]}
|
||||
|
||||
#
|
||||
# ACTUAL STYLE DEFINITIONS
|
||||
|
@ -1,5 +1,5 @@
|
||||
#LyX 2.3 created this file. For more info see http://www.lyx.org/
|
||||
\lyxformat 528
|
||||
\lyxformat 530
|
||||
\begin_document
|
||||
\begin_header
|
||||
\save_transient_properties true
|
||||
@ -21598,8 +21598,8 @@ The full syntax is:
|
||||
|
||||
\begin_layout LyX-Code
|
||||
|
||||
\change_inserted -712698321 1483870927
|
||||
LyXName|alias*<!_stardesc!_stardesctooltip>[][]=latexcmd
|
||||
\change_inserted -712698321 1484997816
|
||||
LyXName|alias$*<!_stardesc!_stardesctooltip>[][]=latexcmd
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
@ -22048,11 +22048,50 @@ _stardesc Sta&rred command label
|
||||
|
||||
\begin_layout LyX-Code
|
||||
|
||||
\change_inserted -712698321 1483872184
|
||||
\change_inserted -712698321 1484997832
|
||||
_stardesctooltip Tooltip for the starred command checkbox.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Itemize
|
||||
|
||||
\change_inserted -712698321 1484997948
|
||||
A dollar sign
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\change_inserted -712698321 1484997871
|
||||
$
|
||||
\change_unchanged
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
indicates that this command features
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
qualified citation lists
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
.
|
||||
This is a
|
||||
\family sans
|
||||
Biblatex
|
||||
\family default
|
||||
-specific feature for multi-reference citations where an individual pre-
|
||||
and postnote can be given to each reference in the list.
|
||||
Please refer to the
|
||||
\family sans
|
||||
Biblatex
|
||||
\family default
|
||||
manual for details.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
\begin_inset CommandInset label
|
||||
LatexCommand label
|
||||
@ -22670,7 +22709,7 @@ status collapsed
|
||||
|
||||
\begin_layout Itemize
|
||||
|
||||
\change_inserted -712698321 1483978548
|
||||
\change_inserted -712698321 1484997600
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
@ -22704,6 +22743,36 @@ status collapsed
|
||||
\end_inset
|
||||
|
||||
)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
|
||||
\change_inserted -712698321 1484997681
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\change_inserted -712698321 1484997608
|
||||
{%ifqualified%[[true]][[false]]}
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
: process the
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
true
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
part if the current citation is a qualified citation list (a specific
|
||||
\family sans
|
||||
Biblatex
|
||||
\family default
|
||||
format for multi-reference citations), the false part if this is not the
|
||||
case.
|
||||
\change_unchanged
|
||||
|
||||
\end_layout
|
||||
|
@ -30040,7 +30040,7 @@ key "latexcompanion"
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\change_inserted -712698321 1483891777
|
||||
\change_inserted -712698321 1484998090
|
||||
All styles except for
|
||||
\family sans
|
||||
Basic
|
||||
@ -30056,6 +30056,99 @@ cf.
|
||||
).
|
||||
This text is then also included in the parentheses, if the style requires
|
||||
this.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\change_inserted -712698321 1484998495
|
||||
Note that these pre- and postnotes apply to the whole citation.
|
||||
That is to say, if you refer to multiple references at one, the prenote
|
||||
will precede the first citation in the list, the postnote will follow the
|
||||
last.
|
||||
Some
|
||||
\family sans
|
||||
Biblatex
|
||||
\family default
|
||||
styles allow for adding pre- and postnotes to any individual reference
|
||||
in a multi-citation (so-called
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
qualified citation lists
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
).
|
||||
\SpecialChar LyX
|
||||
supports this.
|
||||
If you use such a style, and if the current reference includes multiple
|
||||
items, the
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Selected Citations
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
window will display three columns:
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Text before
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
,
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Cite key
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
, and
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Text after
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
.
|
||||
If you double-click on an item's
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Text before
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
or
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Text after
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
field, you can add such individual pre- and postnotes.
|
||||
In the
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
General text before
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
and
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
General text after
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
input widgets, you can add pre- and postnotes that apply to the whole list.
|
||||
\change_unchanged
|
||||
|
||||
\end_layout
|
||||
|
@ -1331,10 +1331,10 @@ def revert_biblatex(document):
|
||||
res = "\\" + new_citations[cmd]
|
||||
if pre:
|
||||
res += "[" + pre + "]"
|
||||
elif post:
|
||||
res += "[]"
|
||||
if post:
|
||||
res += "[" + post + "]"
|
||||
elif pre:
|
||||
res += "[]"
|
||||
res += "{" + key + "}"
|
||||
document.body[i:j+1] = put_cmd_in_ert([res])
|
||||
elif cmd not in old_citations:
|
||||
@ -1450,6 +1450,103 @@ def revert_bibpackopts(document):
|
||||
]
|
||||
|
||||
|
||||
def revert_qualicites(document):
|
||||
" Revert qualified citation list commands to ERT "
|
||||
|
||||
# Citation insets that support qualified lists, with their LaTeX code
|
||||
ql_citations = {
|
||||
"cite" : "cites",
|
||||
"Cite" : "Cites",
|
||||
"citet" : "textcites",
|
||||
"Citet" : "Textcites",
|
||||
"citep" : "parencites",
|
||||
"Citep" : "Parencites",
|
||||
"Footcite" : "Smartcites",
|
||||
"footcite" : "smartcites",
|
||||
"Autocite" : "Autocites",
|
||||
"autocite" : "autocites",
|
||||
}
|
||||
|
||||
# Get cite engine
|
||||
engine = "basic"
|
||||
i = find_token(document.header, "\\cite_engine", 0)
|
||||
if i == -1:
|
||||
document.warning("Malformed document! Missing \\cite_engine")
|
||||
else:
|
||||
engine = get_value(document.header, "\\cite_engine", i)
|
||||
|
||||
biblatex = engine in ["biblatex", "biblatex-natbib"]
|
||||
|
||||
i = 0
|
||||
while (True):
|
||||
i = find_token(document.body, "\\begin_inset CommandInset citation", i)
|
||||
if i == -1:
|
||||
break
|
||||
j = find_end_of_inset(document.body, i)
|
||||
if j == -1:
|
||||
document.warning("Can't find end of citation inset at line %d!!" %(i))
|
||||
i += 1
|
||||
continue
|
||||
pres = find_token(document.body, "pretextlist", i, j)
|
||||
posts = find_token(document.body, "posttextlist", i, j)
|
||||
if pres == -1 and posts == -1:
|
||||
# nothing to do.
|
||||
i = j + 1
|
||||
continue
|
||||
pretexts = get_quoted_value(document.body, "pretextlist", pres)
|
||||
posttexts = get_quoted_value(document.body, "posttextlist", posts)
|
||||
k = find_token(document.body, "LatexCommand", i, j)
|
||||
if k == -1:
|
||||
document.warning("Can't find LatexCommand for citation inset at line %d!" %(i))
|
||||
i = j + 1
|
||||
continue
|
||||
cmd = get_value(document.body, "LatexCommand", k)
|
||||
if biblatex and cmd in list(ql_citations.keys()):
|
||||
pre = get_quoted_value(document.body, "before", i, j)
|
||||
post = get_quoted_value(document.body, "after", i, j)
|
||||
key = get_quoted_value(document.body, "key", i, j)
|
||||
if not key:
|
||||
document.warning("Citation inset at line %d does not have a key!" %(i))
|
||||
key = "???"
|
||||
keys = key.split(",")
|
||||
prelist = pretexts.split("\t")
|
||||
premap = dict()
|
||||
for pp in prelist:
|
||||
ppp = pp.split(" ", 1)
|
||||
premap[ppp[0]] = ppp[1]
|
||||
postlist = posttexts.split("\t")
|
||||
postmap = dict()
|
||||
for pp in postlist:
|
||||
ppp = pp.split(" ", 1)
|
||||
postmap[ppp[0]] = ppp[1]
|
||||
# Replace known new commands with ERT
|
||||
if "(" in pre or ")" in pre:
|
||||
pre = "{" + pre + "}"
|
||||
if "(" in post or ")" in post:
|
||||
post = "{" + post + "}"
|
||||
res = "\\" + ql_citations[cmd]
|
||||
if pre:
|
||||
res += "(" + pre + ")"
|
||||
if post:
|
||||
res += "(" + post + ")"
|
||||
elif pre:
|
||||
res += "()"
|
||||
for kk in keys:
|
||||
if premap.get(kk, "") != "":
|
||||
res += "[" + premap[kk] + "]"
|
||||
if postmap.get(kk, "") != "":
|
||||
res += "[" + postmap[kk] + "]"
|
||||
elif premap.get(kk, "") != "":
|
||||
res += "[]"
|
||||
res += "{" + kk + "}"
|
||||
document.body[i:j+1] = put_cmd_in_ert([res])
|
||||
else:
|
||||
# just remove the params
|
||||
del document.body[posttexts]
|
||||
del document.body[pretexts]
|
||||
i += 1
|
||||
|
||||
|
||||
##
|
||||
# Conversion hub
|
||||
#
|
||||
@ -1477,10 +1574,12 @@ convert = [
|
||||
[527, []],
|
||||
[528, []],
|
||||
[529, []],
|
||||
[530, []]
|
||||
[530, []],
|
||||
[531, []]
|
||||
]
|
||||
|
||||
revert = [
|
||||
[530, [revert_qualicites]],
|
||||
[529, [revert_bibpackopts]],
|
||||
[528, [revert_citekeyonly]],
|
||||
[527, [revert_biblatex]],
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "support/regex.h"
|
||||
#include "support/textutils.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
@ -812,6 +813,8 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
|
||||
ret = from_ascii("x"); // any non-empty string will do
|
||||
else if (key == "ifstar" && ci.Starred)
|
||||
ret = from_ascii("x"); // any non-empty string will do
|
||||
else if (key == "ifqualified" && ci.isQualified)
|
||||
ret = from_ascii("x"); // any non-empty string will do
|
||||
else if (key == "entrytype")
|
||||
ret = entry_type_;
|
||||
else if (prefixIs(key, "ifentrytype:")
|
||||
@ -908,6 +911,10 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
|
||||
ret = ci.textBefore;
|
||||
else if (key == "textafter")
|
||||
ret = ci.textAfter;
|
||||
else if (key == "curpretext")
|
||||
ret = ci.getPretexts()[bib_key_];
|
||||
else if (key == "curposttext")
|
||||
ret = ci.getPosttexts()[bib_key_];
|
||||
else if (key == "year")
|
||||
ret = getYear();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define CITATION_H
|
||||
|
||||
#include "support/docstring.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace lyx {
|
||||
@ -32,7 +33,8 @@ class CitationStyle
|
||||
public:
|
||||
///
|
||||
CitationStyle() : name("cite"), cmd("cite"), forceUpperCase(false),
|
||||
hasStarredVersion(false), textAfter(false), textBefore(false) {}
|
||||
hasStarredVersion(false), hasQualifiedList(false),
|
||||
textAfter(false), textBefore(false) {}
|
||||
|
||||
/// the LyX name
|
||||
std::string name;
|
||||
@ -46,6 +48,8 @@ public:
|
||||
bool forceUpperCase;
|
||||
/// starred version (full author list by default)
|
||||
bool hasStarredVersion;
|
||||
/// allows for qualified citation lists (a Biblatex feature)
|
||||
bool hasQualifiedList;
|
||||
/// supports text after the citation
|
||||
bool textAfter;
|
||||
/// supports text before the citation
|
||||
@ -67,7 +71,7 @@ public:
|
||||
Export
|
||||
};
|
||||
///
|
||||
CiteItem() : forceUpperCase(false), Starred(false),
|
||||
CiteItem() : forceUpperCase(false), Starred(false), isQualified(false),
|
||||
context(CiteItem::Everywhere), textAfter(docstring()),
|
||||
textBefore(docstring()), max_size(128), max_key_size(128),
|
||||
richtext(false) {}
|
||||
@ -75,12 +79,22 @@ public:
|
||||
bool forceUpperCase;
|
||||
/// is starred version (full author list by default)
|
||||
bool Starred;
|
||||
/// is a real qualified list
|
||||
bool isQualified;
|
||||
/// where this to be displayed?
|
||||
CiteItem::CiteContext context;
|
||||
/// text after the citation
|
||||
docstring textAfter;
|
||||
/// text before the citation
|
||||
docstring textBefore;
|
||||
/// Qualified lists's pre texts
|
||||
std::map<docstring, docstring> pretexts;
|
||||
///
|
||||
std::map<docstring, docstring> getPretexts() const { return pretexts; }
|
||||
/// Qualified lists's post texts
|
||||
std::map<docstring, docstring> posttexts;
|
||||
///
|
||||
std::map<docstring, docstring> getPosttexts() const { return posttexts; }
|
||||
/// the maximum display size as a label
|
||||
size_t max_size;
|
||||
/// the maximum size of the processed keys
|
||||
|
@ -1097,6 +1097,8 @@ bool TextClass::readCiteEngine(Lexer & lexrc)
|
||||
latex_cmd += ichar;
|
||||
else if (mode == StarDesc)
|
||||
stardesc += ichar;
|
||||
else if (ichar == '$')
|
||||
cs.hasQualifiedList = true;
|
||||
else if (ichar == '*')
|
||||
cs.hasStarredVersion = true;
|
||||
else if (ichar == '[' && cs.textAfter)
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <QMenu>
|
||||
#include <QSettings>
|
||||
#include <QShowEvent>
|
||||
#include <QStandardItemModel>
|
||||
#include <QVariant>
|
||||
|
||||
#include <vector>
|
||||
@ -138,7 +139,7 @@ GuiCitation::GuiCitation(GuiView & lv)
|
||||
this, SLOT(on_okPB_clicked()));
|
||||
|
||||
selectionManager = new GuiSelectionManager(availableLV, selectedLV,
|
||||
addPB, deletePB, upPB, downPB, &available_model_, &selected_model_);
|
||||
addPB, deletePB, upPB, downPB, &available_model_, &selected_model_, 1);
|
||||
connect(selectionManager, SIGNAL(selectionChanged()),
|
||||
this, SLOT(setCitedKeys()));
|
||||
connect(selectionManager, SIGNAL(updateHook()),
|
||||
@ -159,6 +160,12 @@ GuiCitation::GuiCitation(GuiView & lv)
|
||||
connect(instant_, SIGNAL(triggered(bool)),
|
||||
this, SLOT(instantChanged(bool)));
|
||||
|
||||
#if (QT_VERSION < 0x050000)
|
||||
selectedLV->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
|
||||
#else
|
||||
selectedLV->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
#endif
|
||||
|
||||
setFocusProxy(filter_);
|
||||
}
|
||||
|
||||
@ -239,7 +246,7 @@ void GuiCitation::updateControls()
|
||||
// will not have changed.
|
||||
void GuiCitation::updateControls(BiblioInfo const & bi)
|
||||
{
|
||||
QModelIndex idx = selectionManager->getSelectedIndex();
|
||||
QModelIndex idx = selectionManager->getSelectedIndex(1);
|
||||
updateInfo(bi, idx);
|
||||
selectionManager->update();
|
||||
}
|
||||
@ -254,8 +261,31 @@ void GuiCitation::updateFormatting(CitationStyle currentStyle)
|
||||
bool const textbefore = currentStyle.textBefore;
|
||||
bool const textafter = currentStyle.textAfter;
|
||||
|
||||
bool const haveSelection =
|
||||
selectedLV->model()->rowCount() > 0;
|
||||
int const rows = selectedLV->model()->rowCount();
|
||||
|
||||
bool const qualified = currentStyle.hasQualifiedList
|
||||
&& (rows > 1
|
||||
|| !params_["pretextlist"].empty()
|
||||
|| !params_["posttextlist"].empty());
|
||||
selectedLV->horizontalHeader()->setVisible(qualified);
|
||||
selectedLV->setColumnHidden(0, !qualified);
|
||||
selectedLV->setColumnHidden(2, !qualified);
|
||||
if (qualified) {
|
||||
textBeforeLA->setText(qt_("General text befo&re:"));
|
||||
textAfterLA->setText(qt_("General &text after:"));
|
||||
textBeforeED->setToolTip(qt_("Text that precedes the whole reference list. "
|
||||
"For text that precedes individual items, double-click on the respective entry above."));
|
||||
textAfterLA->setToolTip(qt_("General &text after:"));
|
||||
textAfterED->setToolTip(qt_("Text that follows the whole reference list. "
|
||||
"For text that follows individual items, double-click on the respective entry above."));
|
||||
} else {
|
||||
textBeforeLA->setText(qt_("Text befo&re:"));
|
||||
textBeforeED->setToolTip(qt_("Text that precedes the reference (e.g., \"cf.\")"));
|
||||
textAfterLA->setText(qt_("&Text after:"));
|
||||
textAfterED->setToolTip(qt_("Text that follows the reference (e.g., pages)"));
|
||||
}
|
||||
|
||||
bool const haveSelection = rows > 0;
|
||||
|
||||
forceuppercaseCB->setEnabled(force && haveSelection);
|
||||
starredCB->setEnabled(full && haveSelection);
|
||||
@ -306,7 +336,7 @@ void GuiCitation::updateStyles()
|
||||
// Update the styles for the style combo, citationStyleCO.
|
||||
void GuiCitation::updateStyles(BiblioInfo const & bi)
|
||||
{
|
||||
QStringList selected_keys = selected_model_.stringList();
|
||||
QStringList selected_keys = selectedKeys();
|
||||
int curr = selectedLV->model()->rowCount() - 1;
|
||||
|
||||
if (curr < 0 || selected_keys.empty()) {
|
||||
@ -376,7 +406,7 @@ void GuiCitation::fillEntries(BiblioInfo const & bi)
|
||||
bool GuiCitation::isSelected(QModelIndex const & idx)
|
||||
{
|
||||
QString const str = idx.data().toString();
|
||||
return selected_model_.stringList().contains(str);
|
||||
return selectedKeys().contains(str);
|
||||
}
|
||||
|
||||
|
||||
@ -551,6 +581,10 @@ void GuiCitation::applyParams(int const choice, bool full, bool force,
|
||||
params_["key"] = qstring_to_ucs4(cited_keys_.join(","));
|
||||
params_["before"] = qstring_to_ucs4(before);
|
||||
params_["after"] = qstring_to_ucs4(after);
|
||||
if (cs.hasQualifiedList) {
|
||||
params_["pretextlist"] = getStringFromVector(getPreTexts(), from_ascii("\t"));
|
||||
params_["posttextlist"] = getStringFromVector(getPostTexts(), from_ascii("\t"));
|
||||
}
|
||||
dispatchParams();
|
||||
}
|
||||
|
||||
@ -558,7 +592,107 @@ void GuiCitation::applyParams(int const choice, bool full, bool force,
|
||||
void GuiCitation::clearSelection()
|
||||
{
|
||||
cited_keys_.clear();
|
||||
selected_model_.setStringList(cited_keys_);
|
||||
setSelectedKeys(cited_keys_);
|
||||
}
|
||||
|
||||
|
||||
void GuiCitation::setSelectedKeys(QStringList const sl)
|
||||
{
|
||||
selected_model_.clear();
|
||||
selected_model_.setColumnCount(3);
|
||||
QStringList headers;
|
||||
headers << qt_("Text before")
|
||||
<< qt_("Cite key")
|
||||
<< qt_("Text after");
|
||||
selected_model_.setHorizontalHeaderLabels(headers);
|
||||
selectedLV->setColumnHidden(0, true);
|
||||
selectedLV->setColumnHidden(2, true);
|
||||
selectedLV->verticalHeader()->setVisible(false);
|
||||
selectedLV->horizontalHeader()->setVisible(false);
|
||||
QStringList::const_iterator it = sl.begin();
|
||||
QStringList::const_iterator end = sl.end();
|
||||
for (int i = 0; it != end; ++it, ++i) {
|
||||
QStandardItem * si = new QStandardItem();
|
||||
si->setData(*it);
|
||||
si->setText(*it);
|
||||
si->setToolTip(*it);
|
||||
si->setEditable(false);
|
||||
selected_model_.setItem(i, 1, si);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList GuiCitation::selectedKeys()
|
||||
{
|
||||
QStringList res;
|
||||
for (int i = 0; i != selected_model_.rowCount(); ++i) {
|
||||
QStandardItem const * item = selected_model_.item(i, 1);
|
||||
if (item)
|
||||
res.append(item->text());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void GuiCitation::setPreTexts(vector<docstring> const m)
|
||||
{
|
||||
for (docstring const & s: m) {
|
||||
QStandardItem * si = new QStandardItem();
|
||||
docstring key;
|
||||
docstring pre = split(s, key, ' ');
|
||||
si->setData(toqstr(pre));
|
||||
si->setText(toqstr(pre));
|
||||
QModelIndexList qmil =
|
||||
selected_model_.match(selected_model_.index(0, 1),
|
||||
Qt::DisplayRole, toqstr(key), 1,
|
||||
Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
|
||||
if (!qmil.empty())
|
||||
selected_model_.setItem(qmil.front().row(), 0, si);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> GuiCitation::getPreTexts()
|
||||
{
|
||||
vector<docstring> res;
|
||||
for (int i = 0; i != selected_model_.rowCount(); ++i) {
|
||||
QStandardItem const * key = selected_model_.item(i, 1);
|
||||
QStandardItem const * pre = selected_model_.item(i, 0);
|
||||
if (key && pre && !key->text().isEmpty() && !pre->text().isEmpty())
|
||||
res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(pre->text()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void GuiCitation::setPostTexts(vector<docstring> const m)
|
||||
{
|
||||
for (docstring const & s: m) {
|
||||
QStandardItem * si = new QStandardItem();
|
||||
docstring key;
|
||||
docstring post = split(s, key, ' ');
|
||||
si->setData(toqstr(post));
|
||||
si->setText(toqstr(post));
|
||||
QModelIndexList qmil =
|
||||
selected_model_.match(selected_model_.index(0, 1),
|
||||
Qt::DisplayRole, toqstr(key), 1,
|
||||
Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
|
||||
if (!qmil.empty())
|
||||
selected_model_.setItem(qmil.front().row(), 2, si);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> GuiCitation::getPostTexts()
|
||||
{
|
||||
vector<docstring> res;
|
||||
for (int i = 0; i != selected_model_.rowCount(); ++i) {
|
||||
QStandardItem const * key = selected_model_.item(i, 1);
|
||||
QStandardItem const * post = selected_model_.item(i, 2);
|
||||
if (key && post)
|
||||
res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(post->text()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -567,6 +701,7 @@ void GuiCitation::init()
|
||||
// Make the list of all available bibliography keys
|
||||
BiblioInfo const & bi = bibInfo();
|
||||
all_keys_ = to_qstring_list(bi.getKeys());
|
||||
|
||||
available_model_.setStringList(all_keys_);
|
||||
|
||||
// Ditto for the keys cited in this inset
|
||||
@ -575,7 +710,7 @@ void GuiCitation::init()
|
||||
cited_keys_.clear();
|
||||
else
|
||||
cited_keys_ = str.split(",");
|
||||
selected_model_.setStringList(cited_keys_);
|
||||
setSelectedKeys(cited_keys_);
|
||||
|
||||
// Initialize the drop downs
|
||||
fillEntries(bi);
|
||||
@ -585,21 +720,23 @@ void GuiCitation::init()
|
||||
string const & cmd = params_.getCmdName();
|
||||
CitationStyle const cs =
|
||||
citationStyleFromString(cmd, documentBuffer().params());
|
||||
|
||||
forceuppercaseCB->setChecked(cs.forceUpperCase);
|
||||
starredCB->setChecked(cs.hasStarredVersion &&
|
||||
documentBuffer().params().fullAuthorList());
|
||||
textBeforeED->setText(toqstr(params_["before"]));
|
||||
textAfterED->setText(toqstr(params_["after"]));
|
||||
|
||||
setPreTexts(getVectorFromString(params_["pretextlist"], from_ascii("\t")));
|
||||
setPostTexts(getVectorFromString(params_["posttextlist"], from_ascii("\t")));
|
||||
|
||||
// Update the interface
|
||||
updateControls(bi);
|
||||
updateStyles(bi);
|
||||
if (selected_model_.rowCount()) {
|
||||
selectedLV->blockSignals(true);
|
||||
selectedLV->setFocus();
|
||||
QModelIndex idx = selected_model_.index(0, 0);
|
||||
selectedLV->selectionModel()->select(idx,
|
||||
QItemSelectionModel::ClearAndSelect);
|
||||
selectedLV->selectRow(0);
|
||||
selectedLV->blockSignals(false);
|
||||
|
||||
// Find the citation style
|
||||
@ -682,6 +819,28 @@ QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size)
|
||||
{
|
||||
vector<docstring> const keys = to_docstring_vector(cited_keys_);
|
||||
vector<CitationStyle> styles = citeStyles_;
|
||||
int ind = citationStyleCO->currentIndex();
|
||||
if (ind == -1)
|
||||
ind = 0;
|
||||
CitationStyle cs = styles[ind];
|
||||
vector<docstring> pretexts = getPreTexts();
|
||||
vector<docstring> posttexts = getPostTexts();
|
||||
bool const qualified = cs.hasQualifiedList
|
||||
&& (selectedLV->model()->rowCount() > 1
|
||||
|| !pretexts.empty()
|
||||
|| !posttexts.empty());
|
||||
std::map<docstring, docstring> pres;
|
||||
for (docstring const & s: pretexts) {
|
||||
docstring key;
|
||||
docstring val = split(s, key, ' ');
|
||||
pres[key] = val;
|
||||
}
|
||||
std::map<docstring, docstring> posts;
|
||||
for (docstring const & s: posttexts) {
|
||||
docstring key;
|
||||
docstring val = split(s, key, ' ');
|
||||
posts[key] = val;
|
||||
}
|
||||
CiteItem ci;
|
||||
ci.textBefore = qstring_to_ucs4(textBeforeED->text());
|
||||
ci.textAfter = qstring_to_ucs4(textAfterED->text());
|
||||
@ -689,6 +848,9 @@ QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size)
|
||||
ci.Starred = starredCB->isChecked();
|
||||
ci.context = CiteItem::Dialog;
|
||||
ci.max_size = max_size;
|
||||
ci.isQualified = qualified;
|
||||
ci.pretexts = pres;
|
||||
ci.posttexts = posts;
|
||||
vector<docstring> ret = bi.getCiteStrings(keys, styles, documentBuffer(), ci);
|
||||
return to_qstring_list(ret);
|
||||
}
|
||||
@ -696,7 +858,7 @@ QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size)
|
||||
|
||||
void GuiCitation::setCitedKeys()
|
||||
{
|
||||
cited_keys_ = selected_model_.stringList();
|
||||
cited_keys_ = selectedKeys();
|
||||
updateStyles();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include "Citation.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QStandardItemModel>
|
||||
#include <QStringList>
|
||||
#include <QStringListModel>
|
||||
|
||||
@ -34,6 +36,7 @@ namespace frontend {
|
||||
|
||||
class GuiSelectionManager;
|
||||
|
||||
|
||||
class GuiCitation : public DialogView, public Ui::CitationUi
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -114,6 +117,19 @@ private:
|
||||
/// Clear selected keys
|
||||
void clearSelection();
|
||||
|
||||
/// Set selected keys
|
||||
void setSelectedKeys(QStringList const);
|
||||
/// Get selected keys
|
||||
QStringList selectedKeys();
|
||||
/// Set pre texts of qualified lists
|
||||
void setPreTexts(std::vector<docstring> const m);
|
||||
/// Get pre texts of qualified lists
|
||||
std::vector<docstring> getPreTexts();
|
||||
/// Set post texts of qualified lists
|
||||
void setPostTexts(std::vector<docstring> const m);
|
||||
/// Get post texts of qualified lists
|
||||
std::vector<docstring> getPostTexts();
|
||||
|
||||
/// Find keys containing a string.
|
||||
void findKey(
|
||||
BiblioInfo const & bi, //< optimize by passing this
|
||||
@ -171,7 +187,7 @@ private:
|
||||
/// available keys.
|
||||
QStringListModel available_model_;
|
||||
/// selected keys.
|
||||
QStringListModel selected_model_;
|
||||
QStandardItemModel selected_model_;
|
||||
/// All keys.
|
||||
QStringList all_keys_;
|
||||
/// Cited keys.
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "support/debug.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QAbstractListModel>
|
||||
#include <QItemSelection>
|
||||
#include <QListView>
|
||||
@ -42,21 +43,24 @@ namespace frontend {
|
||||
|
||||
GuiSelectionManager::GuiSelectionManager(
|
||||
QAbstractItemView * avail,
|
||||
QListView * sel,
|
||||
QAbstractItemView * sel,
|
||||
QPushButton * add,
|
||||
QPushButton * del,
|
||||
QPushButton * up,
|
||||
QPushButton * down,
|
||||
QAbstractListModel * amod,
|
||||
QAbstractListModel * smod)
|
||||
QAbstractItemModel * smod,
|
||||
int const main_sel_col)
|
||||
: availableLV(avail), selectedLV(sel), addPB(add), deletePB(del),
|
||||
upPB(up), downPB(down), availableModel(amod), selectedModel(smod),
|
||||
selectedHasFocus_(false)
|
||||
selectedHasFocus_(false), main_sel_col_(main_sel_col)
|
||||
{
|
||||
|
||||
selectedLV->setModel(smod);
|
||||
availableLV->setModel(amod);
|
||||
|
||||
selectedLV->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
selectedLV->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
connect(availableLV->selectionModel(),
|
||||
SIGNAL(currentChanged(QModelIndex, QModelIndex)),
|
||||
this, SLOT(availableChanged(QModelIndex, QModelIndex)));
|
||||
@ -69,6 +73,8 @@ GuiSelectionManager::GuiSelectionManager(
|
||||
connect(selectedLV->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
this, SLOT(selectedChanged(QItemSelection, QItemSelection)));
|
||||
connect(selectedLV->itemDelegate(), SIGNAL(commitData(QWidget*)),
|
||||
this, SLOT(selectedEdited()));
|
||||
connect(addPB, SIGNAL(clicked()),
|
||||
this, SLOT(addPB_clicked()));
|
||||
connect(deletePB, SIGNAL(clicked()),
|
||||
@ -94,10 +100,10 @@ void GuiSelectionManager::update()
|
||||
}
|
||||
|
||||
|
||||
QModelIndex GuiSelectionManager::getSelectedIndex() const
|
||||
QModelIndex GuiSelectionManager::getSelectedIndex(int const c) const
|
||||
{
|
||||
QModelIndexList avail = availableLV->selectionModel()->selectedIndexes();
|
||||
QModelIndexList sel = selectedLV->selectionModel()->selectedIndexes();
|
||||
QModelIndexList sel = selectedLV->selectionModel()->selectedRows(c);
|
||||
bool const have_avl = !avail.isEmpty();
|
||||
bool const have_sel = !sel.isEmpty();
|
||||
|
||||
@ -137,7 +143,7 @@ void GuiSelectionManager::updateDelPB()
|
||||
}
|
||||
QModelIndexList const selSels =
|
||||
selectedLV->selectionModel()->selectedIndexes();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
deletePB->setEnabled(sel_nr >= 0);
|
||||
}
|
||||
|
||||
@ -151,7 +157,7 @@ void GuiSelectionManager::updateUpPB()
|
||||
}
|
||||
QModelIndexList const selSels =
|
||||
selectedLV->selectionModel()->selectedIndexes();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
upPB->setEnabled(sel_nr > 0);
|
||||
}
|
||||
|
||||
@ -165,7 +171,7 @@ void GuiSelectionManager::updateDownPB()
|
||||
}
|
||||
QModelIndexList const selSels =
|
||||
selectedLV->selectionModel()->selectedIndexes();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
|
||||
downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
|
||||
}
|
||||
|
||||
@ -176,7 +182,7 @@ bool GuiSelectionManager::isSelected(const QModelIndex & idx)
|
||||
return false;
|
||||
QVariant const & str = availableModel->data(idx, Qt::DisplayRole);
|
||||
QModelIndexList qmil =
|
||||
selectedModel->match(selectedModel->index(0),
|
||||
selectedModel->match(selectedModel->index(0, main_sel_col_),
|
||||
Qt::DisplayRole, str, 1,
|
||||
Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
|
||||
return !qmil.empty();
|
||||
@ -221,6 +227,12 @@ void GuiSelectionManager::selectedChanged(const QModelIndex & idx, const QModelI
|
||||
}
|
||||
|
||||
|
||||
void GuiSelectionManager::selectedEdited()
|
||||
{
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
bool GuiSelectionManager::insertRowToSelected(int i,
|
||||
QMap<int, QVariant> const & itemData)
|
||||
{
|
||||
@ -230,7 +242,23 @@ bool GuiSelectionManager::insertRowToSelected(int i,
|
||||
i = selectedModel->rowCount();
|
||||
if (!selectedModel->insertRow(i))
|
||||
return false;
|
||||
return selectedModel->setItemData(selectedModel->index(i), itemData);
|
||||
return selectedModel->setItemData(selectedModel->index(i, main_sel_col_), itemData);
|
||||
}
|
||||
|
||||
|
||||
bool GuiSelectionManager::insertRowToSelected(int i, QMap<int, QMap<int, QVariant>> & qms)
|
||||
{
|
||||
if (i <= -1)
|
||||
i = 0;
|
||||
if (i > selectedModel->rowCount())
|
||||
i = selectedModel->rowCount();
|
||||
if (!selectedModel->insertRow(i))
|
||||
return false;
|
||||
bool res = true;
|
||||
QMap<int, QMap<int, QVariant>>::const_iterator it = qms.constBegin();
|
||||
for (; it != qms.constEnd(); ++it)
|
||||
res &= selectedModel->setItemData(selectedModel->index(i, it.key()), it.value());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -291,11 +319,14 @@ void GuiSelectionManager::upPB_clicked()
|
||||
int const pos = idx.row();
|
||||
if (pos <= 0)
|
||||
return;
|
||||
|
||||
QMap<int, QVariant> qm = selectedModel->itemData(idx);
|
||||
|
||||
QMap<int, QMap<int, QVariant>> qms;
|
||||
QList<QModelIndex>::const_iterator it = selIdx.constBegin();
|
||||
for (; it != selIdx.constEnd(); ++it)
|
||||
qms[it->column()] = selectedModel->itemData(*it);
|
||||
|
||||
selectedModel->removeRow(pos);
|
||||
insertRowToSelected(pos - 1, qm);
|
||||
insertRowToSelected(pos - 1, qms);
|
||||
|
||||
selectionChanged(); //signal
|
||||
|
||||
@ -317,10 +348,13 @@ void GuiSelectionManager::downPB_clicked()
|
||||
if (pos >= selectedModel->rowCount() - 1)
|
||||
return;
|
||||
|
||||
QMap<int, QVariant> qm = selectedModel->itemData(idx);
|
||||
QMap<int, QMap<int, QVariant>> qms;
|
||||
QList<QModelIndex>::const_iterator it = selIdx.constBegin();
|
||||
for (; it != selIdx.constEnd(); ++it)
|
||||
qms[it->column()] = selectedModel->itemData(*it);
|
||||
|
||||
selectedModel->removeRow(pos);
|
||||
insertRowToSelected(pos + 1, qm);
|
||||
insertRowToSelected(pos + 1, qms);
|
||||
|
||||
selectionChanged(); //signal
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QAbstractItemModel;
|
||||
class QAbstractListModel;
|
||||
class QModelIndex;
|
||||
class QListView;
|
||||
@ -42,13 +43,14 @@ public:
|
||||
///
|
||||
GuiSelectionManager(
|
||||
QAbstractItemView * availableLV,
|
||||
QListView * selectedLV,
|
||||
QAbstractItemView * selectedLV,
|
||||
QPushButton * addPB,
|
||||
QPushButton * delPB,
|
||||
QPushButton * upPB,
|
||||
QPushButton * downPB,
|
||||
QAbstractListModel * availableModel,
|
||||
QAbstractListModel * selectedModel);
|
||||
QAbstractItemModel * selectedModel,
|
||||
int const main_sel_col = 0);
|
||||
/// Sets the state of the various push buttons, depending upon the
|
||||
/// state of the widgets. (E.g., "delete" is enabled only if the
|
||||
/// selection is non-empty.)
|
||||
@ -64,7 +66,7 @@ public:
|
||||
bool selectedFocused() const { return selectedHasFocus_; }
|
||||
/// Returns the selected index. Note that this will depend upon
|
||||
/// selectedFocused().
|
||||
QModelIndex getSelectedIndex() const;
|
||||
QModelIndex getSelectedIndex(int const c = 0) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/// Emitted when the list of selected items has changed.
|
||||
@ -87,11 +89,13 @@ protected:
|
||||
/// been selected (i.e., is also in selectedLV).
|
||||
bool isSelected(const QModelIndex & idx);
|
||||
///
|
||||
bool insertRowToSelected(int i, QMap<int, QVariant> const & itemData);
|
||||
bool insertRowToSelected(int i, QMap<int, QVariant> const & itemData);
|
||||
///
|
||||
bool insertRowToSelected(int i, QMap<int, QMap<int, QVariant>> &);
|
||||
///
|
||||
QAbstractItemView * availableLV;
|
||||
///
|
||||
QListView * selectedLV;
|
||||
QAbstractItemView * selectedLV;
|
||||
///
|
||||
QPushButton * addPB;
|
||||
///
|
||||
@ -103,7 +107,7 @@ protected:
|
||||
///
|
||||
QAbstractListModel * availableModel;
|
||||
///
|
||||
QAbstractListModel * selectedModel;
|
||||
QAbstractItemModel * selectedModel;
|
||||
|
||||
protected Q_SLOTS:
|
||||
///
|
||||
@ -115,6 +119,8 @@ protected Q_SLOTS:
|
||||
///
|
||||
void selectedChanged(QItemSelection const & qis, QItemSelection const &);
|
||||
///
|
||||
void selectedEdited();
|
||||
///
|
||||
virtual void addPB_clicked();
|
||||
///
|
||||
virtual void deletePB_clicked();
|
||||
@ -138,6 +144,8 @@ private:
|
||||
virtual void updateUpPB();
|
||||
///
|
||||
bool selectedHasFocus_;
|
||||
///
|
||||
int main_sel_col_;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
@ -1540,7 +1540,7 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
|
||||
static_cast<InsetCitation const *>(inset);
|
||||
|
||||
Buffer const * buf = &bv->buffer();
|
||||
BufferParams const & bp = buf->params();
|
||||
BufferParams const & bp = buf->masterParams();
|
||||
string const cmd = citinset->params().getCmdName();
|
||||
|
||||
docstring const & key = citinset->getParam("key");
|
||||
@ -1557,7 +1557,18 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
|
||||
|
||||
vector<docstring> const keys = getVectorFromString(key);
|
||||
|
||||
vector<CitationStyle> const citeStyleList = buf->params().citeStyles();
|
||||
vector<CitationStyle> const citeStyleList = bp.citeStyles();
|
||||
|
||||
CitationStyle cs = citinset->getCitationStyle(bp, cmd, citeStyleList);
|
||||
bool const qualified = cs.hasQualifiedList
|
||||
&& (keys.size() > 1
|
||||
|| !citinset->getParam("pretextlist").empty()
|
||||
|| !citinset->getParam("posttextlist").empty());
|
||||
std::map<docstring, docstring> pres =
|
||||
citinset->getQualifiedLists(citinset->getParam("pretextlist"));
|
||||
std::map<docstring, docstring> posts =
|
||||
citinset->getQualifiedLists(citinset->getParam("posttextlist"));
|
||||
|
||||
CiteItem ci;
|
||||
ci.textBefore = citinset->getParam("before");
|
||||
ci.textAfter = citinset->getParam("after");
|
||||
@ -1565,6 +1576,9 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
|
||||
ci.Starred = star;
|
||||
ci.context = CiteItem::Dialog;
|
||||
ci.max_size = 40;
|
||||
ci.isQualified = qualified;
|
||||
ci.pretexts = pres;
|
||||
ci.posttexts = posts;
|
||||
vector<docstring> citeStrings =
|
||||
buf->masterBibInfo().getCiteStrings(keys, citeStyleList, bv->buffer(), ci);
|
||||
|
||||
@ -1581,9 +1595,6 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
|
||||
"changetype " + from_utf8(citationStyleToString(cs)))));
|
||||
}
|
||||
|
||||
// Extra features of the citation styles
|
||||
CitationStyle cs = citinset->getCitationStyle(bp, cmd, citeStyleList);
|
||||
|
||||
if (cs.hasStarredVersion) {
|
||||
docstring starred = _("All authors|h");
|
||||
// Check if we have a custom string/tooltip for the starred version
|
||||
|
@ -234,11 +234,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="selectedLV">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTableView" name="selectedLV"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -290,7 +286,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="textBeforeLA">
|
||||
<property name="text">
|
||||
<string>Text &before:</string>
|
||||
<string>Text befo&re:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>textBeforeED</cstring>
|
||||
@ -483,7 +479,6 @@
|
||||
<tabstop>entriesCO</tabstop>
|
||||
<tabstop>searchOptionsPB</tabstop>
|
||||
<tabstop>availableLV</tabstop>
|
||||
<tabstop>selectedLV</tabstop>
|
||||
<tabstop>addPB</tabstop>
|
||||
<tabstop>deletePB</tabstop>
|
||||
<tabstop>upPB</tabstop>
|
||||
|
@ -69,6 +69,8 @@ ParamInfo const & InsetCitation::findInfo(string const & /* cmdName */)
|
||||
param_info_.add("after", ParamInfo::LATEX_OPTIONAL);
|
||||
param_info_.add("before", ParamInfo::LATEX_OPTIONAL);
|
||||
param_info_.add("key", ParamInfo::LATEX_REQUIRED);
|
||||
param_info_.add("pretextlist", ParamInfo::LATEX_OPTIONAL);
|
||||
param_info_.add("posttextlist", ParamInfo::LATEX_OPTIONAL);
|
||||
}
|
||||
return param_info_;
|
||||
}
|
||||
@ -312,6 +314,20 @@ inline docstring wrapCitation(docstring const & key,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
map<docstring, docstring> InsetCitation::getQualifiedLists(docstring const p) const
|
||||
{
|
||||
vector<docstring> ps =
|
||||
getVectorFromString(p, from_ascii("\t"));
|
||||
std::map<docstring, docstring> res;
|
||||
for (docstring const & s: ps) {
|
||||
docstring key;
|
||||
docstring val = split(s, key, ' ');
|
||||
res[key] = val;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
docstring InsetCitation::generateLabel(bool for_xhtml) const
|
||||
{
|
||||
docstring label;
|
||||
@ -360,12 +376,24 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
|
||||
*/
|
||||
docstring label;
|
||||
vector<docstring> keys = getVectorFromString(key);
|
||||
CitationStyle cs = getCitationStyle(buffer().masterParams(),
|
||||
cite_type, buffer().masterParams().citeStyles());
|
||||
bool const qualified = cs.hasQualifiedList
|
||||
&& (keys.size() > 1
|
||||
|| !getParam("pretextlist").empty()
|
||||
|| !getParam("posttextlist").empty());
|
||||
map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
|
||||
map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
|
||||
|
||||
CiteItem ci;
|
||||
ci.textBefore = getParam("before");
|
||||
ci.textAfter = getParam("after");
|
||||
ci.forceUpperCase = uppercase;
|
||||
ci.Starred = starred;
|
||||
ci.max_size = UINT_MAX;
|
||||
ci.isQualified = qualified;
|
||||
ci.pretexts = pres;
|
||||
ci.posttexts = posts;
|
||||
if (for_xhtml) {
|
||||
ci.max_key_size = UINT_MAX;
|
||||
ci.context = CiteItem::Export;
|
||||
@ -509,13 +537,15 @@ void InsetCitation::forOutliner(docstring & os, size_t const, bool const) const
|
||||
void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
|
||||
{
|
||||
BiblioInfo const & bi = buffer().masterBibInfo();
|
||||
docstring const key = getParam("key");
|
||||
// "keyonly" command: output the plain key and stop.
|
||||
if (getCmdName() == "keyonly") {
|
||||
// Special command to only return the key
|
||||
if (!bi.isBibtex(getParam("key")))
|
||||
// escape chars with bibitems
|
||||
os << escape(cleanupWhitespace(getParam("key")));
|
||||
os << escape(cleanupWhitespace(key));
|
||||
else
|
||||
os << cleanupWhitespace(getParam("key"));
|
||||
os << cleanupWhitespace(key);
|
||||
return;
|
||||
}
|
||||
vector<CitationStyle> citation_styles = buffer().masterParams().citeStyles();
|
||||
@ -524,23 +554,62 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
|
||||
// FIXME UNICODE
|
||||
docstring const cite_str = from_utf8(citationStyleToString(cs, true));
|
||||
|
||||
// check if we have to do a qualified list
|
||||
vector<docstring> keys = getVectorFromString(cleanupWhitespace(key));
|
||||
bool const qualified = cs.hasQualifiedList
|
||||
&& (!getParam("pretextlist").empty()
|
||||
|| !getParam("posttextlist").empty());
|
||||
|
||||
if (runparams.inulemcmd > 0)
|
||||
os << "\\mbox{";
|
||||
|
||||
os << "\\" << cite_str;
|
||||
|
||||
docstring const & before = getParam("before");
|
||||
docstring const & after = getParam("after");
|
||||
if (!before.empty() && cs.textBefore)
|
||||
os << '[' << before << "][" << after << ']';
|
||||
else if (!after.empty() && cs.textAfter)
|
||||
os << '[' << after << ']';
|
||||
if (qualified)
|
||||
os << "s";
|
||||
|
||||
if (!bi.isBibtex(getParam("key")))
|
||||
docstring before = getParam("before");
|
||||
docstring after = getParam("after");
|
||||
if (!before.empty() && cs.textBefore) {
|
||||
if (qualified) {
|
||||
if (contains(before, '(') || contains(before, ')'))
|
||||
// protect parens
|
||||
before = '{' + before + '}';
|
||||
if (contains(after, '(') || contains(after, ')'))
|
||||
// protect parens
|
||||
after = '{' + after + '}';
|
||||
os << '(' << before << ")(" << after << ')';
|
||||
} else
|
||||
os << '[' << before << "][" << after << ']';
|
||||
} else if (!after.empty() && cs.textAfter) {
|
||||
if (qualified) {
|
||||
if (contains(after, '(') || contains(after, ')'))
|
||||
// protect parens
|
||||
after = '{' + after + '}';
|
||||
os << '(' << after << ')';
|
||||
} else
|
||||
os << '[' << after << ']';
|
||||
}
|
||||
|
||||
if (!bi.isBibtex(key))
|
||||
// escape chars with bibitems
|
||||
os << '{' << escape(cleanupWhitespace(getParam("key"))) << '}';
|
||||
else
|
||||
os << '{' << cleanupWhitespace(getParam("key")) << '}';
|
||||
os << '{' << escape(cleanupWhitespace(key)) << '}';
|
||||
else {
|
||||
if (qualified) {
|
||||
map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
|
||||
map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
|
||||
for (docstring const & k: keys) {
|
||||
docstring const bef = pres[k];
|
||||
docstring const aft = posts[k];
|
||||
if (!bef.empty())
|
||||
os << '[' << bef << "][" << aft << ']';
|
||||
else if (!aft.empty())
|
||||
os << '[' << aft << ']';
|
||||
os << '{' << k << '}';
|
||||
}
|
||||
} else
|
||||
os << '{' << cleanupWhitespace(key) << '}';
|
||||
}
|
||||
|
||||
if (runparams.inulemcmd)
|
||||
os << "}";
|
||||
|
@ -86,6 +86,8 @@ public:
|
||||
///
|
||||
CitationStyle getCitationStyle(BufferParams const & bp, std::string const & input,
|
||||
std::vector<CitationStyle> const & valid_styles) const;
|
||||
///
|
||||
std::map<docstring, docstring> getQualifiedLists(docstring const p) const;
|
||||
|
||||
private:
|
||||
/// tries to make a pretty label and makes a basic one if not
|
||||
|
@ -134,7 +134,20 @@ Format LaTeX feature LyX feature
|
||||
\citecite[*] LatexCmd citecite[*]
|
||||
\fullcite LatexCmd fullcite
|
||||
\footfullcite LatexCmd footfullcite
|
||||
\supercite LatexCmd supercite
|
||||
\supercite LatexCmd supercite
|
||||
531 Biblatex "qualified citation lists"
|
||||
\cites(pre)(post)[pre1][post1]{key1}[pre2][post2]{key2}...
|
||||
\begin_inset CommandInset citation
|
||||
LatexCmd cite
|
||||
after "post"
|
||||
before "pre"
|
||||
key "key1,key2..."
|
||||
pretextlist "key1 pre1\tab key2 pre2..."
|
||||
posttextlist "key1 post1\tab key2 post2..."
|
||||
Same for:
|
||||
\Cites, \textcites, \Textcites, \parencites, \Parencites, \smartcites, \Smartcites, \autocites, Autocites
|
||||
|
||||
|
||||
|
||||
|
||||
General
|
||||
|
@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
|
||||
|
||||
// Do not remove the comment below, so we get merge conflict in
|
||||
// independent branches. Instead add your own.
|
||||
#define LYX_FORMAT_LYX 530 // spitz: natbib/jurabib package options
|
||||
#define LYX_FORMAT_TEX2LYX 530
|
||||
#define LYX_FORMAT_LYX 531 // spitz: qualified citation lists
|
||||
#define LYX_FORMAT_TEX2LYX 531
|
||||
|
||||
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
||||
#ifndef _MSC_VER
|
||||
|
Loading…
Reference in New Issue
Block a user