mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
Introduce textclass categories
The categories are ascribed by \DeclareCategory{<category>} in the layout file header. UI follows.
This commit is contained in:
parent
2b0a7a5e01
commit
f18af303fe
@ -64,7 +64,13 @@
|
||||
|
||||
\newcommand{\AddLayout}[5][\default]{
|
||||
\def\default{#2}
|
||||
\immediate\write\layouts{"#2" "#1" "#3" "#4" "#5"}}
|
||||
\@ifundefined{category@#2}{%
|
||||
\immediate\write\layouts{"#2" "#1" "#3" "#4" "#5" ""}%
|
||||
}{%
|
||||
\immediate\write\layouts{"#2" "#1" "#3" "#4" "#5" "\@nameuse{category@#2}"}%
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
\newcommand{\AddVariable}[2]{
|
||||
\immediate\write\vars{chk_#1='#2'}}
|
||||
@ -148,6 +154,12 @@
|
||||
{\AddLayout[\firstelement]{\layoutname}{#2}{false}{\missingelements}}
|
||||
}
|
||||
|
||||
\newcommand{\DeclareCategory}[2]{
|
||||
\@ifundefined{category@#1}
|
||||
{\global\@namedef{category@#1}{#2}}%
|
||||
{}% we have already defined this one.
|
||||
}
|
||||
|
||||
% Only for compatibility. Will be removed later.
|
||||
\let\DeclareSGMLClass=\DeclareDocBookClass
|
||||
|
||||
|
@ -1006,17 +1006,29 @@ def checkOtherEntries():
|
||||
def processLayoutFile(file, bool_docbook):
|
||||
''' process layout file and get a line of result
|
||||
|
||||
Declare lines look like this: (article.layout, scrbook.layout, svjog.layout)
|
||||
Declare lines look like this:
|
||||
|
||||
\DeclareLaTeXClass[<requirements>]{<description>}
|
||||
|
||||
Optionally, a \DeclareCategory line follows:
|
||||
|
||||
\DeclareCategory{<category>}
|
||||
|
||||
So for example (article.layout, scrbook.layout, svjog.layout)
|
||||
|
||||
\DeclareLaTeXClass{article}
|
||||
\DeclareCategory{Articles}
|
||||
|
||||
\DeclareLaTeXClass[scrbook]{book (koma-script)}
|
||||
\DeclareCategory{Books}
|
||||
|
||||
\DeclareLaTeXClass[svjour,svjog.clo]{article (Springer - svjour/jog)}
|
||||
|
||||
we expect output:
|
||||
we'd expect this output:
|
||||
|
||||
"article" "article" "article" "false" "article.cls"
|
||||
"scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls"
|
||||
"svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls,svjog.clo"
|
||||
"article" "article" "article" "false" "article.cls" "Articles"
|
||||
"scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls" "Books"
|
||||
"svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls,svjog.clo" ""
|
||||
'''
|
||||
def checkForClassExtension(x):
|
||||
'''if the extension for a latex class is not
|
||||
@ -1028,8 +1040,12 @@ def processLayoutFile(file, bool_docbook):
|
||||
classname = file.split(os.sep)[-1].split('.')[0]
|
||||
# return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article}
|
||||
p = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
|
||||
q = re.compile(r'\DeclareCategory{(.*)}')
|
||||
classdeclaration = ""
|
||||
categorydeclaration = '""'
|
||||
for line in open(file).readlines():
|
||||
res = p.search(line)
|
||||
qres = q.search(line)
|
||||
if res != None:
|
||||
(classtype, optAll, opt, opt1, desc) = res.groups()
|
||||
avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype]
|
||||
@ -1042,7 +1058,15 @@ def processLayoutFile(file, bool_docbook):
|
||||
prereq_latex = ','.join(prereq_list)
|
||||
prereq_docbook = {'true':'', 'false':'docbook'}[bool_docbook]
|
||||
prereq = {'LaTeX':prereq_latex, 'DocBook':prereq_docbook}[classtype]
|
||||
return '"%s" "%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai, prereq)
|
||||
classdeclaration = '"%s" "%s" "%s" "%s" "%s"' % (classname, opt, desc, avai, prereq)
|
||||
if categorydeclaration != "":
|
||||
return classdeclaration + " " + categorydeclaration
|
||||
if qres != None:
|
||||
categorydeclaration = '"%s"' % (qres.groups()[0])
|
||||
if classdeclaration != "":
|
||||
return classdeclaration + " " + categorydeclaration
|
||||
if classdeclaration != "":
|
||||
return classdeclaration + " " + categorydeclaration
|
||||
logger.warning("Layout file " + file + " has no \DeclareXXClass line. ")
|
||||
return ""
|
||||
|
||||
@ -1112,6 +1136,7 @@ def checkLatexConfig(check_config, bool_docbook):
|
||||
# build the list of available layout files and convert it to commands
|
||||
# for chkconfig.ltx
|
||||
declare = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
|
||||
category = re.compile(r'\DeclareCategory{(.*)}')
|
||||
empty = re.compile(r'^\s*$')
|
||||
testclasses = list()
|
||||
for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
|
||||
@ -1120,14 +1145,23 @@ def checkLatexConfig(check_config, bool_docbook):
|
||||
if not os.path.isfile(file):
|
||||
continue
|
||||
classname = file.split(os.sep)[-1].split('.')[0]
|
||||
decline = ""
|
||||
catline = ""
|
||||
for line in open(file).readlines():
|
||||
if not empty.match(line) and line[0] != '#':
|
||||
if decline == "":
|
||||
logger.warning("Failed to find valid \Declare line for layout file `" + file + "'.\n\t=> Skipping this file!")
|
||||
nodeclaration = True
|
||||
# A class, but no category declaration. Just break.
|
||||
break
|
||||
if declare.search(line) == None:
|
||||
if declare.search(line) != None:
|
||||
decline = "\\TestDocClass{%s}{%s}" % (classname, line[1:].strip())
|
||||
testclasses.append(decline)
|
||||
elif category.search(line) != None:
|
||||
catline = "\\DeclareCategory{%s}{%s}" % (classname, category.search(line).groups()[0])
|
||||
testclasses.append(catline)
|
||||
if catline == "" or decline == "":
|
||||
continue
|
||||
testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
|
||||
break
|
||||
if nodeclaration:
|
||||
continue
|
||||
@ -1151,7 +1185,7 @@ def checkLatexConfig(check_config, bool_docbook):
|
||||
if rmcopy:
|
||||
removeFiles( [ 'chkconfig.ltx' ] )
|
||||
#
|
||||
# currently, values in chhkconfig are only used to set
|
||||
# currently, values in chkconfig are only used to set
|
||||
# \font_encoding
|
||||
values = {}
|
||||
for line in open('chkconfig.vars').readlines():
|
||||
|
@ -41,12 +41,13 @@ namespace lyx {
|
||||
|
||||
LayoutFile::LayoutFile(string const & fn, string const & cln,
|
||||
string const & desc, string const & prereq,
|
||||
bool texclassavail)
|
||||
string const & category, bool texclassavail)
|
||||
{
|
||||
name_ = fn;
|
||||
latexname_ = cln;
|
||||
description_ = desc;
|
||||
prerequisites_ = prereq;
|
||||
category_ = category;
|
||||
tex_class_avail_ = texclassavail;
|
||||
}
|
||||
|
||||
@ -141,9 +142,13 @@ bool LayoutFileList::read()
|
||||
break;
|
||||
string const prereq = lex.getString();
|
||||
LYXERR(Debug::TCLASS, "Prereq: " << prereq);
|
||||
if (!lex.next())
|
||||
break;
|
||||
string const category = lex.getString();
|
||||
LYXERR(Debug::TCLASS, "Category: " << category);
|
||||
// This code is run when we have
|
||||
// fname, clname, desc, prereq, and avail
|
||||
LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, avail);
|
||||
LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, category, avail);
|
||||
if (lyxerr.debugging(Debug::TCLASS)) {
|
||||
// only system layout files are loaded here so no
|
||||
// buffer path is needed.
|
||||
@ -182,7 +187,8 @@ void LayoutFileList::reset(LayoutFileIndex const & classname) {
|
||||
LayoutFile * tc = classmap_[classname];
|
||||
LayoutFile * tmpl =
|
||||
new LayoutFile(tc->name(), tc->latexname(), tc->description(),
|
||||
tc->prerequisites(), tc->isTeXClassAvailable());
|
||||
tc->prerequisites(), tc->category(),
|
||||
tc->isTeXClassAvailable());
|
||||
classmap_[classname] = tmpl;
|
||||
delete tc;
|
||||
}
|
||||
@ -227,7 +233,7 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
|
||||
// the last parameter to true will suppress a warning message about missing
|
||||
// tex class.
|
||||
LayoutFile * tc = new LayoutFile(textclass, textclass,
|
||||
"Unknown text class " + textclass, textclass + ".cls", true);
|
||||
"Unknown text class " + textclass, textclass + ".cls", "", true);
|
||||
|
||||
if (!tc->load(tempLayout.absFileName())) {
|
||||
// The only way this happens is because the hardcoded layout file
|
||||
@ -272,7 +278,12 @@ LayoutFileIndex
|
||||
ifstream ifs(layout_file.toFilesystemEncoding().c_str());
|
||||
static regex const reg("^#\\s*\\\\Declare(LaTeX|DocBook)Class\\s*"
|
||||
"(?:\\[([^,]*)(?:,.*)*\\])*\\s*\\{(.*)\\}\\s*");
|
||||
static regex const catreg("^#\\s*\\\\DeclareCategory\\{(.*)\\}");
|
||||
string line;
|
||||
string class_name;
|
||||
string class_prereq;
|
||||
string category;
|
||||
bool have_declaration = false;
|
||||
while (getline(ifs, line)) {
|
||||
// look for the \DeclareXXXClass line
|
||||
smatch sub;
|
||||
@ -280,10 +291,19 @@ LayoutFileIndex
|
||||
// returns: whole string, classtype (not used here), class name, description
|
||||
LASSERT(sub.size() == 4, /**/);
|
||||
// now, create a TextClass with description containing path information
|
||||
string class_name(sub.str(2) == "" ? textclass : sub.str(2));
|
||||
string class_prereq(class_name + ".cls");
|
||||
class_name = (sub.str(2) == "" ? textclass : sub.str(2));
|
||||
class_prereq = class_name + ".cls";
|
||||
have_declaration = true;
|
||||
}
|
||||
else if (regex_match(line, sub, catreg)) {
|
||||
category = sub.str(1);
|
||||
}
|
||||
if (have_declaration && !category.empty())
|
||||
break;
|
||||
}
|
||||
if (have_declaration) {
|
||||
LayoutFile * tmpl =
|
||||
new LayoutFile(textclass, class_name, textclass, class_prereq, true);
|
||||
new LayoutFile(textclass, class_name, textclass, class_prereq, category, true);
|
||||
//FIXME: The prerequisites are available from the layout file and
|
||||
// can be extracted from the above regex, but for now this
|
||||
// field is simply set to class_name + ".cls"
|
||||
@ -301,7 +321,6 @@ LayoutFileIndex
|
||||
return textclass;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If .layout is not in local directory, or an invalid layout is found, return null
|
||||
return string();
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ private:
|
||||
std::string const & className = std::string(),
|
||||
std::string const & description = std::string(),
|
||||
std::string const & prerequisites = std::string(),
|
||||
std::string const & category = std::string(),
|
||||
bool texclassavail = false);
|
||||
/// The only class that should create a LayoutFile is
|
||||
/// LayoutFileList, which calls the private constructor.
|
||||
|
@ -1228,11 +1228,11 @@ bool TextClass::readFloat(Lexer & lexrc)
|
||||
}
|
||||
|
||||
|
||||
string const & TextClass::prerequisites() const
|
||||
string const & TextClass::prerequisites(string const & sep) const
|
||||
{
|
||||
if (contains(prerequisites_, ',')) {
|
||||
vector<string> const pres = getVectorFromString(prerequisites_);
|
||||
prerequisites_ = getStringFromVector(pres, "\n\t");
|
||||
prerequisites_ = getStringFromVector(pres, sep);
|
||||
}
|
||||
return prerequisites_;
|
||||
}
|
||||
|
@ -189,11 +189,13 @@ public:
|
||||
///
|
||||
std::string const & name() const { return name_; }
|
||||
///
|
||||
std::string const & category() const { return category_; }
|
||||
///
|
||||
std::string const & description() const { return description_; }
|
||||
///
|
||||
std::string const & latexname() const { return latexname_; }
|
||||
///
|
||||
std::string const & prerequisites() const;
|
||||
std::string const & prerequisites(std::string const & sep = "\n\t") const;
|
||||
/// Can be LaTeX, DocBook, etc.
|
||||
OutputType outputType() const { return outputType_; }
|
||||
/// Can be latex, docbook ... (the name of a format)
|
||||
@ -231,6 +233,8 @@ protected:
|
||||
mutable LayoutList layoutlist_;
|
||||
/// Layout file name
|
||||
std::string name_;
|
||||
/// Class category
|
||||
std::string category_;
|
||||
/// document class name
|
||||
std::string latexname_;
|
||||
/// document class description
|
||||
|
Loading…
Reference in New Issue
Block a user