Support for CJK quotation marks

File format change

Fixes: #2712
This commit is contained in:
Juergen Spitzmueller 2016-12-26 14:03:48 +01:00
parent 229f3863f9
commit 89ce0c9069
12 changed files with 444 additions and 34 deletions

View File

@ -11,6 +11,11 @@ adjustments are made to tex2lyx and bugs are fixed in lyx2lyx.
----------------------- -----------------------
2016-12-26 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 523: Implement cjk quotation marks.
- cjk (corner marks): \begin_inset Quotes j..
- cjkangle (angle brackets): \begin_inset Quotes k..
2016-12-25 Jürgen Spitzmüller <spitz@lyx.org> 2016-12-25 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 522: Implement dynamic quotation marks. * Format incremented to 522: Implement dynamic quotation marks.
\begin_inset Quotes x.. \begin_inset Quotes x..

View File

@ -3446,7 +3446,7 @@ Action Inserts quotes according to the type and quote-language preference.
\end_layout \end_layout
\begin_layout Description \begin_layout Description
Notion Currently English, Swedish, German, Polish, French, Danish quotes are distinguished. Notion Currently 15 different quote styles are distinguished (see params).
\end_layout \end_layout
\begin_layout Description \begin_layout Description
@ -3454,7 +3454,7 @@ Syntax quote-insert [<LEVEL>] [<SIDE>] [<STYLE>]
\end_layout \end_layout
\begin_layout Description \begin_layout Description
Params <LEVEL>: 'inner' for (i.e., secondary, usually single) quotes, otherwise outer (i.e., primary, usually double) quotes will be used. <SIDE>: 'opening' for opening quotes, 'closing' for closing quotes, otherwise the side will be guessed from the context. <STYLE>: 'british' for `British' quote style (with ``inner quotation'') 'danish' for >>Danish<< quote style (with >inner quotation<) 'english' for ``English'' quote style (with `inner quotation') 'french' for <<french>> quote style (with ``inner quotation'') 'frenchin' for <<frenchin>> quote style (with <<inner quotation>>) ["in" = Imprimerie Nationale] 'german' for ,,German`` quote style (with ,inner quotation`) 'plain' for "Plain" quote style (with 'inner quotation') 'polish' for ,,Polish'' quote style (with ,inner quotation') 'swedish' for ''Swedish'' quote style (with 'inner quotation') 'swedishg' for >>swedishg>> quote style (with 'inner quotation') ["g" = Guillemets] 'swiss' for <<Swiss>> quote style (with <inner quotation>) 'russian' for <<Russian>> quote style (with ,,inner quotation``) 'dynamic' for Dynamic quotation marks which inherit the global document style If no quote style is specified, the document-wide will be used. Params <LEVEL>: 'inner' for (i.e., secondary, usually single) quotes, otherwise outer (i.e., primary, usually double) quotes will be used. <SIDE>: 'opening' for opening quotes, 'closing' for closing quotes, otherwise the side will be guessed from the context. <STYLE>: 'british' for `British' quote style (with ``inner quotation'') 'cjk' for Chinese/Japanese/Korean corner bracket quotation marks 'cjk-angle' for Chinese/Japanese/Korean angle bracket quotation marks 'danish' for >>Danish<< quote style (with >inner quotation<) 'english' for ``English'' quote style (with `inner quotation') 'french' for <<french>> quote style (with ``inner quotation'') 'frenchin' for <<frenchin>> quote style (with <<inner quotation>>) ["in" = Imprimerie Nationale] 'german' for ,,German`` quote style (with ,inner quotation`) 'plain' for "Plain" quote style (with 'inner quotation') 'polish' for ,,Polish'' quote style (with ,inner quotation') 'swedish' for ''Swedish'' quote style (with 'inner quotation') 'swedishg' for >>swedishg>> quote style (with 'inner quotation') ["g" = Guillemets] 'swiss' for <<Swiss>> quote style (with <inner quotation>) 'russian' for <<Russian>> quote style (with ,,inner quotation``) 'dynamic' for Dynamic quotation marks which inherit the global document style If no quote style is specified, the document-wide will be used.
\end_layout \end_layout
\begin_layout Subsection* \begin_layout Subsection*

View File

@ -1,5 +1,5 @@
#LyX 2.3 created this file. For more info see http://www.lyx.org/ #LyX 2.3 created this file. For more info see http://www.lyx.org/
\lyxformat 522 \lyxformat 523
\begin_document \begin_document
\begin_header \begin_header
\save_transient_properties true \save_transient_properties true
@ -101,7 +101,7 @@ enumitem
\use_package mathtools 0 \use_package mathtools 0
\use_package mhchem 1 \use_package mhchem 1
\use_package stackrel 0 \use_package stackrel 0
\use_package stmaryrd 0 \use_package stmaryrd 1
\use_package undertilde 0 \use_package undertilde 0
\cite_engine basic \cite_engine basic
\cite_engine_type default \cite_engine_type default
@ -17086,8 +17086,8 @@ Quote Style
There are There are
\change_deleted -712698321 1482666221 \change_deleted -712698321 1482666221
six six
\change_inserted -712698321 1482666222 \change_inserted -712698321 1482756786
twelve 14
\change_unchanged \change_unchanged
choices: choices:
\end_layout \end_layout
@ -17851,7 +17851,7 @@ g., in Russia)
\begin_layout Labeling \begin_layout Labeling
\labelwidthstring <<Outer>> and <<inner>>: \labelwidthstring <<Outer>> and <<inner>>:
\change_inserted -712698321 1482666852 \change_inserted -712698321 1482756796
\family sans \family sans
\begin_inset Quotes wld \begin_inset Quotes wld
@ -17896,6 +17896,158 @@ these inner
\end_inset \end_inset
quotation marks (another style common in Sweden) quotation marks (another style common in Sweden)
\end_layout
\begin_layout Labeling
\labelwidthstring <<Outer>> and <<inner>>:
\change_inserted -712698321 1482757086
\begin_inset Quotes jld
\end_inset
\family sans
Outer
\family default
\begin_inset Quotes jrd
\end_inset
\family sans
\begin_inset space ~
\end_inset
and
\begin_inset space ~
\end_inset
\family default
\begin_inset Quotes jls
\end_inset
\family sans
inner
\family default
\begin_inset Quotes jrs
\end_inset
Produces
\begin_inset Quotes jld
\end_inset
these outer
\begin_inset Quotes jrd
\end_inset
and
\begin_inset Quotes jls
\end_inset
these inner
\begin_inset Quotes jrs
\end_inset
quotation marks (as common, e.
\begin_inset space \thinspace{}
\end_inset
g., in Japan)
\begin_inset Foot
status collapsed
\begin_layout Plain Layout
\change_inserted -712698321 1482757158
Note that these characters are just emulated with similar-looking math symbols
in many encodings that do not cover these glyphs.
\change_unchanged
\end_layout
\end_inset
\end_layout
\begin_layout Labeling
\labelwidthstring <<Outer>> and <<inner>>:
\change_inserted -712698321 1482757171
\begin_inset Quotes kld
\end_inset
\family sans
Outer
\family default
\begin_inset Quotes krd
\end_inset
\family sans
\begin_inset space ~
\end_inset
and
\begin_inset space ~
\end_inset
\family default
\begin_inset Quotes kls
\end_inset
\family sans
inner
\family default
\begin_inset Quotes krs
\end_inset
Produces
\begin_inset Quotes kld
\end_inset
these outer
\begin_inset Quotes krd
\end_inset
and
\begin_inset Quotes kls
\end_inset
these inner
\begin_inset Quotes krs
\end_inset
quotation marks (as common, e.
\begin_inset space \thinspace{}
\end_inset
g., in North Korea and China)
\begin_inset Foot
status collapsed
\begin_layout Plain Layout
\change_inserted -712698321 1482757171
Note that these characters are just emulated with similar-looking math symbols
in many encodings that do not cover these glyphs.
\end_layout
\end_inset
\change_unchanged \change_unchanged
\end_layout \end_layout

View File

@ -44,19 +44,21 @@
# (UK) -- try to select the entry that is most generic -- here # (UK) -- try to select the entry that is most generic -- here
# English. # English.
# * The QuoteStyle arguments correspond to the following styles: # * The QuoteStyle arguments correspond to the following styles:
# PRIMARY SECONDARY # PRIMARY SECONDARY
# - british: `text' ``text'' (6_9 -- 66_99) # - british: `text' ``text'' (6_9 -- 66_99)
# - danish: >>text<< >text< (inward guillemets) # - cjk: corner brackets white corner br.
# - english: ``text'' `text' (66_99 -- 6_9) # - cjk-angle: double angle br. angle br.
# - french: <<text>> ``text'' (outward guillemets -- 66_99) # - danish: >>text<< >text< (inward guillemets)
# - frenchin: <<text>> <<text>> (French Imprimerie Nationale style) # - english: ``text'' `text' (66_99 -- 6_9)
# - german: ,,text`` ,text` (99/66 -- 9/6) # - french: <<text>> ``text'' (outward guillemets -- 66_99)
# - polish: ,,text'' ,text' (99/99 -- 9/9) # - frenchin: <<text>> <<text>> (French Imprimerie Nationale style)
# - russian: <<text>> ,,text`` (outward guillemets -- 99/66) # - german: ,,text`` ,text` (99/66 -- 9/6)
# - swedish: ''text'' 'text' (99_99 -- 9_9) # - polish: ,,text'' ,text' (99/99 -- 9/9)
# - swedishg: >>text>> 'text' (Swedish Guillemets) # - russian: <<text>> ,,text`` (outward guillemets -- 99/66)
# - swiss: <<text>> <text> (outward guillemets) # - swedish: ''text'' 'text' (99_99 -- 9_9)
# - plain: "text" 'text' (non-typographical quotes) # - swedishg: >>text>> 'text' (Swedish Guillemets)
# - swiss: <<text>> <text> (outward guillemets)
# - plain: "text" 'text' (non-typographical quotes)
# Note that the option names have been selected (rather arbitrarily) # Note that the option names have been selected (rather arbitrarily)
# because the respective styles are common in the respective countries. # because the respective styles are common in the respective countries.
# Of course this does not imply any fixed relation to those countries. # Of course this does not imply any fixed relation to those countries.
@ -381,9 +383,9 @@ End
Language chinese-traditional Language chinese-traditional
GuiName "Chinese (traditional)" GuiName "Chinese (traditional)"
HasGuiSupport true HasGuiSupport true
QuoteStyle english QuoteStyle cjk
Encoding utf8-cjk Encoding utf8-cjk
LangCode zh_TW LangCode zh_TW
Requires CJK Requires CJK
End End
@ -718,6 +720,7 @@ Language japanese
Requires japanese Requires japanese
InternalEncoding true InternalEncoding true
FontEncoding None FontEncoding None
QuoteStyle cjk
End End
# uses CJK package # uses CJK package
@ -726,6 +729,7 @@ Language japanese-cjk
Encoding euc-jp Encoding euc-jp
LangCode ja_JP LangCode ja_JP
Requires CJK Requires CJK
QuoteStyle cjk
End End
# not supported by babel # not supported by babel
@ -759,7 +763,7 @@ End
Language korean Language korean
GuiName "Korean" GuiName "Korean"
Encoding euc-kr Encoding euc-kr
QuoteStyle english QuoteStyle cjkangle
LangCode ko_KR LangCode ko_KR
Requires CJK Requires CJK
End End

View File

@ -753,7 +753,7 @@ def revert_britishquotes(document):
# opening mark # opening mark
newval = newval.replace("d", "s") newval = newval.replace("d", "s")
else: else:
# inner marks # closing mark
newval = newval.replace("s", "d") newval = newval.replace("s", "d")
document.body[i] = document.body[i].replace(val, newval) document.body[i] = document.body[i].replace(val, newval)
i += 1 i += 1
@ -865,7 +865,7 @@ def revert_dynamicquotes(document):
else: else:
style = get_value(document.header, "\\quotes_style", i) style = get_value(document.header, "\\quotes_style", i)
s = "" s = "e"
if style == "english": if style == "english":
s = "e" s = "e"
elif style == "swedish": elif style == "swedish":
@ -901,6 +901,140 @@ def revert_dynamicquotes(document):
i += 1 i += 1
def revert_cjkquotes(document):
" Revert cjk quote insets "
# Get global style
style = "english"
i = find_token(document.header, "\\quotes_style", 0)
if i == -1:
document.warning("Malformed document! Missing \\quotes_style")
else:
style = get_value(document.header, "\\quotes_style", i)
global_cjk = style.find("cjk") != -1
if global_cjk:
document.header[i] = "\\quotes_style english"
# transform dynamic insets
s = "j"
if style == "cjkangle":
s = "k"
i = 0
while True:
i = find_token(document.body, '\\begin_inset Quotes x', i)
if i == -1:
break
document.body[i] = document.body[i].replace("x", s)
i += 1
cjk_langs = ["chinese-simplified", "chinese-traditional", "japanese", "japanese-cjk", "korean"]
i = 0
j = 0
while True:
k = find_token(document.body, '\\begin_inset Quotes j', i)
if k == -1:
break
l = find_end_of_inset(document.body, k)
if l == -1:
document.warning("Malformed LyX document: Can't find end of Quote inset at line " + str(k))
i = k
continue
cjk = False
parent = get_containing_layout(document.body, k)
ql = find_token_backwards(document.body, "\\lang", k)
if ql == -1 or ql < parent[1]:
cjk = document.language in cjk_langs
elif document.body[ql].split()[1] in cjk_langs:
cjk = True
val = get_value(document.body, "\\begin_inset Quotes", i)[7:]
replace = []
if val[2] == "s":
# inner marks
if val[1] == "l":
# inner opening mark
if cjk:
replace = [u"\u300E"]
else:
replace = ["\\begin_inset Formula $\\llceil$", "\\end_inset"]
else:
# inner closing mark
if cjk:
replace = [u"\u300F"]
else:
replace = ["\\begin_inset Formula $\\rrfloor$", "\\end_inset"]
else:
# outer marks
if val[1] == "l":
# outer opening mark
if cjk:
replace = [u"\u300C"]
else:
replace = ["\\begin_inset Formula $\\lceil$", "\\end_inset"]
else:
# outer closing mark
if cjk:
replace = [u"\u300D"]
else:
replace = ["\\begin_inset Formula $\\rfloor$", "\\end_inset"]
document.body[k:l+1] = replace
i = l
i = 0
j = 0
while True:
k = find_token(document.body, '\\begin_inset Quotes k', i)
if k == -1:
return
l = find_end_of_inset(document.body, k)
if l == -1:
document.warning("Malformed LyX document: Can't find end of Quote inset at line " + str(k))
i = k
continue
cjk = False
parent = get_containing_layout(document.body, k)
ql = find_token_backwards(document.body, "\\lang", k)
if ql == -1 or ql < parent[1]:
cjk = document.language in cjk_langs
elif document.body[ql].split()[1] in cjk_langs:
cjk = True
val = get_value(document.body, "\\begin_inset Quotes", i)[7:]
replace = []
if val[2] == "s":
# inner marks
if val[1] == "l":
# inner opening mark
if cjk:
replace = [u"\u3008"]
else:
replace = ["\\begin_inset Formula $\\langle$", "\\end_inset"]
else:
# inner closing mark
if cjk:
replace = [u"\u3009"]
else:
replace = ["\\begin_inset Formula $\\rangle$", "\\end_inset"]
else:
# outer marks
if val[1] == "l":
# outer opening mark
if cjk:
replace = [u"\u300A"]
else:
replace = ["\\begin_inset Formula $\\langle\\kern -2.5pt\\langle$$", "\\end_inset"]
else:
# outer closing mark
if cjk:
replace = [u"\u300B"]
else:
replace = ["\\begin_inset Formula $\\rangle\\kern -2.5pt\\rangle$", "\\end_inset"]
document.body[k:l+1] = replace
i = l
## ##
# Conversion hub # Conversion hub
# #
@ -920,10 +1054,12 @@ convert = [
[519, [convert_quotestyle]], [519, [convert_quotestyle]],
[520, []], [520, []],
[521, [convert_frenchquotes]], [521, [convert_frenchquotes]],
[522, []] [522, []],
[523, []]
] ]
revert = [ revert = [
[522, [revert_cjkquotes]],
[521, [revert_dynamicquotes]], [521, [revert_dynamicquotes]],
[520, [revert_britishquotes, revert_swedishgquotes, revert_frenchquotes, revert_frenchinquotes, revert_russianquotes, revert_swissquotes]], [520, [revert_britishquotes, revert_swedishgquotes, revert_frenchquotes, revert_frenchinquotes, revert_russianquotes, revert_swissquotes]],
[519, [revert_plainquote]], [519, [revert_plainquote]],

View File

@ -73,7 +73,7 @@ static char const * const string_paragraph_separation[] = {
static char const * const string_quotes_style[] = { static char const * const string_quotes_style[] = {
"english", "swedish", "german", "polish", "swiss", "danish", "plain", "english", "swedish", "german", "polish", "swiss", "danish", "plain",
"british", "swedishg", "french", "frenchin", "russian", "" "british", "swedishg", "french", "frenchin", "russian", "cjk", "cjkangle", ""
}; };
@ -147,6 +147,8 @@ QuotesStyleTranslator const init_quotesstyletranslator()
translator.addPair(string_quotes_style[9], InsetQuotesParams::FrenchQuotes); translator.addPair(string_quotes_style[9], InsetQuotesParams::FrenchQuotes);
translator.addPair(string_quotes_style[10], InsetQuotesParams::FrenchINQuotes); translator.addPair(string_quotes_style[10], InsetQuotesParams::FrenchINQuotes);
translator.addPair(string_quotes_style[11], InsetQuotesParams::RussianQuotes); translator.addPair(string_quotes_style[11], InsetQuotesParams::RussianQuotes);
translator.addPair(string_quotes_style[12], InsetQuotesParams::CJKQuotes);
translator.addPair(string_quotes_style[13], InsetQuotesParams::CJKAngleQuotes);
return translator; return translator;
} }

View File

@ -401,14 +401,15 @@ void LyXAction::init()
/*! /*!
* \var lyx::FuncCode lyx::LFUN_QUOTE_INSERT * \var lyx::FuncCode lyx::LFUN_QUOTE_INSERT
* \li Action: Inserts quotes according to the type and quote-language preference. * \li Action: Inserts quotes according to the type and quote-language preference.
* \li Notion: Currently English, Swedish, German, Polish, French, Danish quotes * \li Notion: Currently 15 different quote styles are distinguished (see params).
are distinguished.
* \li Syntax: quote-insert [<LEVEL>] [<SIDE>] [<STYLE>] * \li Syntax: quote-insert [<LEVEL>] [<SIDE>] [<STYLE>]
* \li Params: <LEVEL>: 'inner' for (i.e., secondary, usually single) quotes, otherwise * \li Params: <LEVEL>: 'inner' for (i.e., secondary, usually single) quotes, otherwise
* outer (i.e., primary, usually double) quotes will be used. * outer (i.e., primary, usually double) quotes will be used.
* <SIDE>: 'opening' for opening quotes, 'closing' for closing quotes, * <SIDE>: 'opening' for opening quotes, 'closing' for closing quotes,
* otherwise the side will be guessed from the context. * otherwise the side will be guessed from the context.
* <STYLE>: 'british' for `British' quote style (with ``inner quotation'') * <STYLE>: 'british' for `British' quote style (with ``inner quotation'')
* 'cjk' for Chinese/Japanese/Korean corner bracket quotation marks
* 'cjk-angle' for Chinese/Japanese/Korean angle bracket quotation marks
* 'danish' for >>Danish<< quote style (with >inner quotation<) * 'danish' for >>Danish<< quote style (with >inner quotation<)
* 'english' for ``English'' quote style (with `inner quotation') * 'english' for ``English'' quote style (with `inner quotation')
* 'french' for <<french>> quote style (with ``inner quotation'') * 'french' for <<french>> quote style (with ``inner quotation'')

View File

@ -1687,6 +1687,8 @@ void MenuDefinition::expandQuotes(BufferView const * bv)
MenuDefinition fqs; MenuDefinition fqs;
MenuDefinition iqs; MenuDefinition iqs;
MenuDefinition rqs; MenuDefinition rqs;
MenuDefinition jqs;
MenuDefinition kqs;
MenuDefinition xqs; MenuDefinition xqs;
InsetQuotesParams::QuoteStyle globalqs = InsetQuotesParams::QuoteStyle globalqs =
bv->buffer().masterBuffer()->params().quotes_style; bv->buffer().masterBuffer()->params().quotes_style;
@ -1758,6 +1760,10 @@ void MenuDefinition::expandQuotes(BufferView const * bv)
iqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); iqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
else if (prefixIs(style, 'r') && !prefixIs(qtype, "r")) else if (prefixIs(style, 'r') && !prefixIs(qtype, "r"))
rqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); rqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
else if (prefixIs(style, 'j') && !prefixIs(qtype, "j"))
jqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
else if (prefixIs(style, 'k') && !prefixIs(qtype, "k"))
kqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
} }
if (!xqs.empty()) { if (!xqs.empty()) {
@ -1837,6 +1843,18 @@ void MenuDefinition::expandQuotes(BufferView const * bv)
item.setSubmenu(rqs); item.setSubmenu(rqs);
add(item); add(item);
} }
if (!jqs.empty()) {
MenuItem item(MenuItem::Submenu,
toqstr(quoteparams.getGuiLabel(InsetQuotesParams::CJKQuotes)));
item.setSubmenu(jqs);
add(item);
}
if (!kqs.empty()) {
MenuItem item(MenuItem::Submenu,
toqstr(quoteparams.getGuiLabel(InsetQuotesParams::CJKAngleQuotes)));
item.setSubmenu(kqs);
add(item);
}
} }

View File

@ -18,6 +18,7 @@
#include "BufferView.h" #include "BufferView.h"
#include "Cursor.h" #include "Cursor.h"
#include "Dimension.h" #include "Dimension.h"
#include "Encoding.h"
#include "Font.h" #include "Font.h"
#include "FuncStatus.h" #include "FuncStatus.h"
#include "FuncRequest.h" #include "FuncRequest.h"
@ -64,10 +65,12 @@ namespace {
* f <<french>> (``inner quotation'') * f <<french>> (``inner quotation'')
* i <<frenchin>> (<<inner quotation>>) ["in" = Imprimerie Nationale] * i <<frenchin>> (<<inner quotation>>) ["in" = Imprimerie Nationale]
* r <<russian>> (,,inner quotation``) * r <<russian>> (,,inner quotation``)
* j [U+300C]cjk[U+300D] ([U+300E]inner quotation[U+300F]) [CORNER BRACKETS]
* k [U+300A]cjkangle[U+300B] ([U+3008]inner quotation[U+3009]) [ANGLE BRACKETS]
* x dynamic style (inherits document settings) * x dynamic style (inherits document settings)
*/ */
char const * const style_char = "esgpcaqbwfirx"; char const * const style_char = "esgpcaqbwfirjkx";
char const * const side_char = "lr" ; char const * const side_char = "lr" ;
char const * const level_char = "sd"; char const * const level_char = "sd";
@ -186,6 +189,20 @@ char_type InsetQuotesParams::getQuoteChar(QuoteStyle const & style, QuoteLevel c
right_secondary = 0x201c; // `` right_secondary = 0x201c; // ``
break; break;
} }
case CJKQuotes:{
left_primary = 0x300c; // LEFT CORNER BRACKET
right_primary = 0x300d; // RIGHT CORNER BRACKET
left_secondary = 0x300e; // LEFT WHITE CORNER BRACKET
right_secondary = 0x300f; // RIGHT WHITE CORNER BRACKET
break;
}
case CJKAngleQuotes:{
left_primary = 0x300a; // LEFT DOUBLE ANGLE BRACKET
right_primary = 0x300b; // RIGHT DOUBLE ANGLE BRACKET
left_secondary = 0x3008; // LEFT ANGLE BRACKET
right_secondary = 0x3009; // RIGHT ANGLE BRACKET
break;
}
case DynamicQuotes: case DynamicQuotes:
default: default:
// should not happen // should not happen
@ -299,6 +316,33 @@ docstring InsetQuotesParams::getLaTeXQuote(char_type c, string const & op) const
res = "\\textquotedbl"; res = "\\textquotedbl";
break; break;
} }
// The following are fakes
// This is just to get something symbolic
// in encodings where this chars would not be used ayway
case 0x300c: // LEFT CORNER BRACKET
res = "\\ensuremath{\\lceil}";
break;
case 0x300d: // RIGHT CORNER BRACKET
res = "\\ensuremath{\\rfloor}";
break;
case 0x300e: // LEFT WHITE CORNER BRACKET
res = "\\ensuremath{\\llceil}";
break;
case 0x300f: // RIGHT WHITE CORNER BRACKET
res = "\\ensuremath{\\rrfloor}";
break;
case 0x300a: // LEFT DOUBLE ANGLE BRACKET
res = "\\ensuremath{\\langle\\kern-2.5pt\\langle}";
break;
case 0x300b: // RIGHT DOUBLE ANGLE BRACKET
res = "\\ensuremath{\\rangle\\kern-2.5pt\\rangle}";
break;
case 0x3008: // LEFT ANGLE BRACKET
res = "\\ensuremath{\\langle}";
break;
case 0x3009: // RIGHT ANGLE BRACKET
res = "\\ensuremath{\\rangle}";
break;
default: default:
break; break;
} }
@ -348,6 +392,30 @@ docstring InsetQuotesParams::getHTMLQuote(char_type c) const
case 0x0022: // " case 0x0022: // "
res = "&quot;"; res = "&quot;";
break; break;
case 0x300c: // LEFT CORNER BRACKET
res = "&#x300c;";
break;
case 0x300d: // RIGHT CORNER BRACKET
res = "&#x300d;";
break;
case 0x300e: // LEFT WHITE CORNER BRACKET
res = "&#x300e;";
break;
case 0x300f: // RIGHT WHITE CORNER BRACKET
res = "&#x300f;";
break;
case 0x300a: // LEFT DOUBLE ANGLE BRACKET
res = "&#x300a;";
break;
case 0x300b: // RIGHT DOUBLE ANGLE BRACKET
res = "&#x300b;";
break;
case 0x3008: // LEFT ANGLE BRACKET
res = "&#x3008;";
break;
case 0x3009: // RIGHT ANGLE BRACKET
res = "&#x3009;";
break;
default: default:
break; break;
} }
@ -550,6 +618,10 @@ InsetQuotesParams::QuoteStyle InsetQuotes::getStyle(string const & s)
qs = InsetQuotesParams::FrenchINQuotes; qs = InsetQuotesParams::FrenchINQuotes;
else if (s == "russian") else if (s == "russian")
qs = InsetQuotesParams::RussianQuotes; qs = InsetQuotesParams::RussianQuotes;
else if (s == "cjk")
qs = InsetQuotesParams::CJKQuotes;
else if (s == "cjkangle")
qs = InsetQuotesParams::CJKAngleQuotes;
else if (s == "dynamic") else if (s == "dynamic")
qs = InsetQuotesParams::DynamicQuotes; qs = InsetQuotesParams::DynamicQuotes;
@ -700,6 +772,12 @@ void InsetQuotes::latex(otexstream & os, OutputParams const & runparams) const
// (spacing and kerning is then handled respectively) // (spacing and kerning is then handled respectively)
qstr = docstring(1, quotechar); qstr = docstring(1, quotechar);
} }
else if (style == InsetQuotesParams::CJKQuotes || style == InsetQuotesParams::CJKAngleQuotes) {
if (runparams.encoding && runparams.encoding->encodable(quotechar))
qstr = docstring(1, quotechar);
else
qstr = quoteparams.getLaTeXQuote(quotechar, "int");
}
else if ((style == InsetQuotesParams::SwissQuotes else if ((style == InsetQuotesParams::SwissQuotes
|| style == InsetQuotesParams::FrenchQuotes || style == InsetQuotesParams::FrenchQuotes
|| style == InsetQuotesParams::FrenchINQuotes) || style == InsetQuotesParams::FrenchINQuotes)
@ -750,7 +828,7 @@ void InsetQuotes::latex(otexstream & os, OutputParams const & runparams) const
os << qstr; os << qstr;
if (prefixIs(qstr, from_ascii("\\"))) if (prefixIs(qstr, from_ascii("\\")) && !suffixIs(qstr, '}'))
// properly terminate the command depending on the context // properly terminate the command depending on the context
os << termcmd; os << termcmd;
} }
@ -876,6 +954,13 @@ void InsetQuotes::validate(LaTeXFeatures & features) const
features.require("textquotedbl"); features.require("textquotedbl");
break; break;
} }
// we fake these from math
case 0x300e: // LEFT WHITE CORNER BRACKET
case 0x300f: // RIGHT WHITE CORNER BRACKET
if (!features.runparams().encoding
|| !features.runparams().encoding->encodable(type))
features.require("stmaryrd");
break;
default: default:
break; break;
} }

View File

@ -52,6 +52,10 @@ public:
/// ///
RussianQuotes, RussianQuotes,
/// ///
CJKQuotes,
///
CJKAngleQuotes,
///
DynamicQuotes DynamicQuotes
}; };
/// ///

View File

@ -97,6 +97,9 @@ Format LaTeX feature LyX feature
- Inner quotes are now ``..''. - Inner quotes are now ``..''.
- Former french style is now - Former french style is now
called "swiss" called "swiss"
523 CJK Quote Styles InsetQuote
- cjk (corner brackets) \begin_inset Quotes j..
- cjkangle (angle brackets) \begin_inset Quotes k..
General General

View File

@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in // Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own. // independent branches. Instead add your own.
#define LYX_FORMAT_LYX 522 // spitz: dynamic quotes styles #define LYX_FORMAT_LYX 523 // spitz: cjk quotes styles
#define LYX_FORMAT_TEX2LYX 522 #define LYX_FORMAT_TEX2LYX 523
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER #ifndef _MSC_VER