From: Bo Peng Date: Wed, 25 Apr 2007 16:12:54 +0000 (+0000) Subject: Fix a few rename inconsistencies discovered by JMarc in insets and mathed, step 2 X-Git-Tag: 1.6.10~10086 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=176715bd567758b914a8ebaa2eb8c32f9770a8c7;p=lyx.git Fix a few rename inconsistencies discovered by JMarc in insets and mathed, step 2 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17992 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp new file mode 100644 index 0000000000..e7f3fc86fd --- /dev/null +++ b/src/insets/InsetCitation.cpp @@ -0,0 +1,470 @@ +/** + * \file InsetCitation.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * \author Herbert Voß + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "InsetCitation.h" + +#include "buffer.h" +#include "bufferparams.h" +#include "debug.h" +#include "dispatchresult.h" +#include "funcrequest.h" +#include "LaTeXFeatures.h" + +#include "frontends/controllers/biblio.h" + +#include "support/fs_extras.h" +#include "support/lstrings.h" + +#include + +#include +#include + + +namespace lyx { + +using support::ascii_lowercase; +using support::contains; +using support::FileName; +using support::getStringFromVector; +using support::getVectorFromString; +using support::ltrim; +using support::rtrim; +using support::split; +using support::tokenPos; + +using std::endl; +using std::replace; +using std::string; +using std::ostream; +using std::vector; +using std::map; + +namespace fs = boost::filesystem; + + +namespace { + +docstring const getNatbibLabel(Buffer const & buffer, + string const & citeType, string const & keyList, + docstring const & before, docstring const & after, + biblio::CiteEngine engine) +{ + // Only start the process off after the buffer is loaded from file. + if (!buffer.fully_loaded()) + return docstring(); + + // Cache the labels + typedef std::map CachedMap; + static CachedMap cached_keys; + + // and cache the timestamp of the bibliography files. + static std::map bibfileStatus; + + biblio::InfoMap infomap; + + vector const & bibfilesCache = buffer.getBibfilesCache(); + // compare the cached timestamps with the actual ones. + bool changed = false; + for (vector::const_iterator it = bibfilesCache.begin(); + it != bibfilesCache.end(); ++ it) { + FileName const f = *it; + try { + std::time_t lastw = fs::last_write_time(f.toFilesystemEncoding()); + if (lastw != bibfileStatus[f]) { + changed = true; + bibfileStatus[f] = lastw; + } + } + catch (fs::filesystem_error & fserr) { + changed = true; + lyxerr << "Couldn't find or read bibtex file " + << f << endl; + LYXERR(Debug::DEBUG) << "Fs error: " + << fserr.what() << endl; + } + } + + // build the keylist only if the bibfiles have been changed + if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) { + typedef vector > InfoType; + InfoType bibkeys; + buffer.fillWithBibKeys(bibkeys); + + InfoType::const_iterator bit = bibkeys.begin(); + InfoType::const_iterator bend = bibkeys.end(); + + for (; bit != bend; ++bit) + infomap[bit->first] = bit->second; + + cached_keys[&buffer] = infomap; + } else + // use the cached keys + infomap = cached_keys[&buffer]; + + if (infomap.empty()) + return docstring(); + + // the natbib citation-styles + // CITET: author (year) + // CITEP: (author,year) + // CITEALT: author year + // CITEALP: author, year + // CITEAUTHOR: author + // CITEYEAR: year + // CITEYEARPAR: (year) + // jurabib supports these plus + // CITE: author/ + + // We don't currently use the full or forceUCase fields. + string cite_type = biblio::asValidLatexCommand(citeType, engine); + if (cite_type[0] == 'C') + cite_type = string(1, 'c') + cite_type.substr(1); + if (cite_type[cite_type.size() - 1] == '*') + cite_type = cite_type.substr(0, cite_type.size() - 1); + + docstring before_str; + if (!before.empty()) { + // In CITET and CITEALT mode, the "before" string is + // attached to the label associated with each and every key. + // In CITEP, CITEALP and CITEYEARPAR mode, it is attached + // to the front of the whole only. + // In other modes, it is not used at all. + if (cite_type == "citet" || + cite_type == "citealt" || + cite_type == "citep" || + cite_type == "citealp" || + cite_type == "citeyearpar") + before_str = before + ' '; + // In CITE (jurabib), the "before" string is used to attach + // the annotator (of legal texts) to the author(s) of the + // first reference. + else if (cite_type == "cite") + before_str = '/' + before; + } + + docstring after_str; + if (!after.empty()) { + // The "after" key is appended only to the end of the whole. + after_str = ", " + after; + } + + // One day, these might be tunable (as they are in BibTeX). + char const op = '('; // opening parenthesis. + char const cp = ')'; // closing parenthesis. + // puctuation mark separating citation entries. + char const * const sep = ";"; + + docstring const op_str(' ' + docstring(1, op)); + docstring const cp_str(docstring(1, cp) + ' '); + docstring const sep_str(from_ascii(sep) + ' '); + + docstring label; + vector keys = getVectorFromString(keyList); + vector::const_iterator it = keys.begin(); + vector::const_iterator end = keys.end(); + for (; it != end; ++it) { + // get the bibdata corresponding to the key + docstring const author(biblio::getAbbreviatedAuthor(infomap, *it)); + docstring const year(biblio::getYear(infomap, *it)); + + // Something isn't right. Fail safely. + if (author.empty() || year.empty()) + return docstring(); + + // authors1/; ... ; + // authors_last, + if (cite_type == "cite" && engine == biblio::ENGINE_JURABIB) { + if (it == keys.begin()) + label += author + before_str + sep_str; + else + label += author + sep_str; + + // (authors1 ( year); ... ; + // authors_last ( year, ) + } else if (cite_type == "citet") { + switch (engine) { + case biblio::ENGINE_NATBIB_AUTHORYEAR: + label += author + op_str + before_str + + year + cp + sep_str; + break; + case biblio::ENGINE_NATBIB_NUMERICAL: + // FIXME UNICODE + label += author + op_str + before_str + + '#' + from_utf8(*it) + cp + sep_str; + break; + case biblio::ENGINE_JURABIB: + label += before_str + author + op_str + + year + cp + sep_str; + break; + case biblio::ENGINE_BASIC: + break; + } + + // author, year; author, year; ... + } else if (cite_type == "citep" || + cite_type == "citealp") { + if (engine == biblio::ENGINE_NATBIB_NUMERICAL) { + // FIXME UNICODE + label += from_utf8(*it) + sep_str; + } else { + label += author + ", " + year + sep_str; + } + + // (authors1 year; + // authors_last year, ) + } else if (cite_type == "citealt") { + switch (engine) { + case biblio::ENGINE_NATBIB_AUTHORYEAR: + label += author + ' ' + before_str + + year + sep_str; + break; + case biblio::ENGINE_NATBIB_NUMERICAL: + // FIXME UNICODE + label += author + ' ' + before_str + + '#' + from_utf8(*it) + sep_str; + break; + case biblio::ENGINE_JURABIB: + label += before_str + author + ' ' + + year + sep_str; + break; + case biblio::ENGINE_BASIC: + break; + } + + // author; author; ... + } else if (cite_type == "citeauthor") { + label += author + sep_str; + + // year; year; ... + } else if (cite_type == "citeyear" || + cite_type == "citeyearpar") { + label += year + sep_str; + } + } + label = rtrim(rtrim(label), sep); + + if (!after_str.empty()) { + if (cite_type == "citet") { + // insert "after" before last ')' + label.insert(label.size() - 1, after_str); + } else { + bool const add = + !(engine == biblio::ENGINE_NATBIB_NUMERICAL && + (cite_type == "citeauthor" || + cite_type == "citeyear")); + if (add) + label += after_str; + } + } + + if (!before_str.empty() && (cite_type == "citep" || + cite_type == "citealp" || + cite_type == "citeyearpar")) { + label = before_str + label; + } + + if (cite_type == "citep" || cite_type == "citeyearpar") + label = op + label + cp; + + return label; +} + + +docstring const getBasicLabel(docstring const & keyList, docstring const & after) +{ + docstring keys(keyList); + docstring label; + + if (contains(keys, ',')) { + // Final comma allows while loop to cover all keys + keys = ltrim(split(keys, label, ',')) + ','; + while (contains(keys, ',')) { + docstring key; + keys = ltrim(split(keys, key, ',')); + label += ", " + key; + } + } else + label = keys; + + if (!after.empty()) + label += ", " + after; + + return '[' + label + ']'; +} + +} // anon namespace + + +InsetCitation::InsetCitation(InsetCommandParams const & p) + : InsetCommand(p, "citation") +{} + + +docstring const InsetCitation::generateLabel(Buffer const & buffer) const +{ + docstring const before = getParam("before"); + docstring const after = getParam("after"); + + docstring label; + biblio::CiteEngine const engine = buffer.params().getEngine(); + if (engine != biblio::ENGINE_BASIC) { + // FIXME UNICODE + label = getNatbibLabel(buffer, getCmdName(), to_utf8(getParam("key")), + before, after, engine); + } + + // Fallback to fail-safe + if (label.empty()) { + label = getBasicLabel(getParam("key"), after); + } + + return label; +} + + +docstring const InsetCitation::getScreenLabel(Buffer const & buffer) const +{ + biblio::CiteEngine const engine = buffer.params().getEngine(); + if (cache.params == params() && cache.engine == engine) + return cache.screen_label; + + // The label has changed, so we have to re-create it. + docstring const glabel = generateLabel(buffer); + + unsigned int const maxLabelChars = 45; + + docstring label = glabel; + if (label.size() > maxLabelChars) { + label.erase(maxLabelChars-3); + label += "..."; + } + + cache.engine = engine; + cache.params = params(); + cache.generated_label = glabel; + cache.screen_label = label; + + return label; +} + + +int InsetCitation::plaintext(Buffer const & buffer, odocstream & os, + OutputParams const &) const +{ + docstring str; + + if (cache.params == params() && + cache.engine == buffer.params().getEngine()) + str = cache.generated_label; + else + str = generateLabel(buffer); + + os << str; + return str.size(); +} + + +namespace { + +docstring const cleanupWhitespace(docstring const & citelist) +{ + docstring::const_iterator it = citelist.begin(); + docstring::const_iterator end = citelist.end(); + // Paranoia check: make sure that there is no whitespace in here + // -- at least not behind commas or at the beginning + docstring result; + char_type last = ','; + for (; it != end; ++it) { + if (*it != ' ') + last = *it; + if (*it != ' ' || last != ',') + result += *it; + } + return result; +} + +// end anon namyspace +} + +int InsetCitation::docbook(Buffer const &, odocstream & os, + OutputParams const &) const +{ + os << "" + << cleanupWhitespace(getParam("key")) + << ""; + return 0; +} + + +int InsetCitation::textString(Buffer const & buf, odocstream & os, + OutputParams const & op) const +{ + return plaintext(buf, os, op); +} + + +// Have to overwrite the default InsetCommand method in order to check that +// the \cite command is valid. Eg, the user has natbib enabled, inputs some +// citations and then changes his mind, turning natbib support off. The output +// should revert to \cite[]{} +int InsetCitation::latex(Buffer const & buffer, odocstream & os, + OutputParams const &) const +{ + biblio::CiteEngine cite_engine = buffer.params().getEngine(); + // FIXME UNICODE + docstring const cite_str = from_utf8( + biblio::asValidLatexCommand(getCmdName(), cite_engine)); + + os << "\\" << cite_str; + + docstring const & before = getParam("before"); + docstring const & after = getParam("after"); + if (!before.empty() && cite_engine != biblio::ENGINE_BASIC) + os << '[' << before << "][" << after << ']'; + else if (!after.empty()) + os << '[' << after << ']'; + + os << '{' << cleanupWhitespace(getParam("key")) << '}'; + + return 0; +} + + +void InsetCitation::validate(LaTeXFeatures & features) const +{ + switch (features.bufferParams().getEngine()) { + case biblio::ENGINE_BASIC: + break; + case biblio::ENGINE_NATBIB_AUTHORYEAR: + case biblio::ENGINE_NATBIB_NUMERICAL: + features.require("natbib"); + break; + case biblio::ENGINE_JURABIB: + features.require("jurabib"); + break; + } +} + + +void InsetCitation::replaceContents(string const & from, string const & to) +{ + if (tokenPos(getContents(), ',', from) != -1) { + vector items = getVectorFromString(getContents()); + replace(items.begin(), items.end(), from, to); + setContents(getStringFromVector(items)); + } +} + + +} // namespace lyx diff --git a/src/insets/InsetCitation.h b/src/insets/InsetCitation.h new file mode 100644 index 0000000000..f0fd1d7a73 --- /dev/null +++ b/src/insets/InsetCitation.h @@ -0,0 +1,83 @@ +// -*- C++ -*- +/** + * \file InsetCitation.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * \author Herbert Voß + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef INSET_CITE_H +#define INSET_CITE_H + + +#include "InsetCommand.h" + +#include "frontends/controllers/biblio.h" + + +namespace lyx { + + +/** Used to insert citations + */ +class InsetCitation : public InsetCommand { +public: + /// + InsetCitation(InsetCommandParams const &); + /// + docstring const getScreenLabel(Buffer const &) const; + /// + EDITABLE editable() const { return IS_EDITABLE; } + /// + InsetBase::Code lyxCode() const { return InsetBase::CITE_CODE; } + /// + int latex(Buffer const &, odocstream &, + OutputParams const &) const; + /// + int plaintext(Buffer const &, odocstream &, + OutputParams const &) const; + /// + int docbook(Buffer const &, odocstream &, + OutputParams const &) const; + /// the string that is passed to the TOC + virtual int textString(Buffer const &, odocstream &, + OutputParams const &) const; + /// + void validate(LaTeXFeatures &) const; + /// + void replaceContents(std::string const & from, std::string const & to); + +private: + virtual std::auto_ptr doClone() const + { + return std::auto_ptr(new InsetCitation(params())); + } + + /// This function does the donkey work of creating the pretty label + docstring const generateLabel(Buffer const &) const; + + class Cache { + public: + /// + Cache() : engine(biblio::ENGINE_BASIC), params("cite") {} + /// + biblio::CiteEngine engine; + /// + InsetCommandParams params; + /// + docstring generated_label; + /// + docstring screen_label; + }; + /// + mutable Cache cache; +}; + + +} // namespace lyx + +#endif // INSET_CITE_H diff --git a/src/insets/InsetCite.cpp b/src/insets/InsetCite.cpp deleted file mode 100644 index e7f3fc86fd..0000000000 --- a/src/insets/InsetCite.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/** - * \file InsetCitation.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Angus Leeming - * \author Herbert Voß - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "InsetCitation.h" - -#include "buffer.h" -#include "bufferparams.h" -#include "debug.h" -#include "dispatchresult.h" -#include "funcrequest.h" -#include "LaTeXFeatures.h" - -#include "frontends/controllers/biblio.h" - -#include "support/fs_extras.h" -#include "support/lstrings.h" - -#include - -#include -#include - - -namespace lyx { - -using support::ascii_lowercase; -using support::contains; -using support::FileName; -using support::getStringFromVector; -using support::getVectorFromString; -using support::ltrim; -using support::rtrim; -using support::split; -using support::tokenPos; - -using std::endl; -using std::replace; -using std::string; -using std::ostream; -using std::vector; -using std::map; - -namespace fs = boost::filesystem; - - -namespace { - -docstring const getNatbibLabel(Buffer const & buffer, - string const & citeType, string const & keyList, - docstring const & before, docstring const & after, - biblio::CiteEngine engine) -{ - // Only start the process off after the buffer is loaded from file. - if (!buffer.fully_loaded()) - return docstring(); - - // Cache the labels - typedef std::map CachedMap; - static CachedMap cached_keys; - - // and cache the timestamp of the bibliography files. - static std::map bibfileStatus; - - biblio::InfoMap infomap; - - vector const & bibfilesCache = buffer.getBibfilesCache(); - // compare the cached timestamps with the actual ones. - bool changed = false; - for (vector::const_iterator it = bibfilesCache.begin(); - it != bibfilesCache.end(); ++ it) { - FileName const f = *it; - try { - std::time_t lastw = fs::last_write_time(f.toFilesystemEncoding()); - if (lastw != bibfileStatus[f]) { - changed = true; - bibfileStatus[f] = lastw; - } - } - catch (fs::filesystem_error & fserr) { - changed = true; - lyxerr << "Couldn't find or read bibtex file " - << f << endl; - LYXERR(Debug::DEBUG) << "Fs error: " - << fserr.what() << endl; - } - } - - // build the keylist only if the bibfiles have been changed - if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) { - typedef vector > InfoType; - InfoType bibkeys; - buffer.fillWithBibKeys(bibkeys); - - InfoType::const_iterator bit = bibkeys.begin(); - InfoType::const_iterator bend = bibkeys.end(); - - for (; bit != bend; ++bit) - infomap[bit->first] = bit->second; - - cached_keys[&buffer] = infomap; - } else - // use the cached keys - infomap = cached_keys[&buffer]; - - if (infomap.empty()) - return docstring(); - - // the natbib citation-styles - // CITET: author (year) - // CITEP: (author,year) - // CITEALT: author year - // CITEALP: author, year - // CITEAUTHOR: author - // CITEYEAR: year - // CITEYEARPAR: (year) - // jurabib supports these plus - // CITE: author/ - - // We don't currently use the full or forceUCase fields. - string cite_type = biblio::asValidLatexCommand(citeType, engine); - if (cite_type[0] == 'C') - cite_type = string(1, 'c') + cite_type.substr(1); - if (cite_type[cite_type.size() - 1] == '*') - cite_type = cite_type.substr(0, cite_type.size() - 1); - - docstring before_str; - if (!before.empty()) { - // In CITET and CITEALT mode, the "before" string is - // attached to the label associated with each and every key. - // In CITEP, CITEALP and CITEYEARPAR mode, it is attached - // to the front of the whole only. - // In other modes, it is not used at all. - if (cite_type == "citet" || - cite_type == "citealt" || - cite_type == "citep" || - cite_type == "citealp" || - cite_type == "citeyearpar") - before_str = before + ' '; - // In CITE (jurabib), the "before" string is used to attach - // the annotator (of legal texts) to the author(s) of the - // first reference. - else if (cite_type == "cite") - before_str = '/' + before; - } - - docstring after_str; - if (!after.empty()) { - // The "after" key is appended only to the end of the whole. - after_str = ", " + after; - } - - // One day, these might be tunable (as they are in BibTeX). - char const op = '('; // opening parenthesis. - char const cp = ')'; // closing parenthesis. - // puctuation mark separating citation entries. - char const * const sep = ";"; - - docstring const op_str(' ' + docstring(1, op)); - docstring const cp_str(docstring(1, cp) + ' '); - docstring const sep_str(from_ascii(sep) + ' '); - - docstring label; - vector keys = getVectorFromString(keyList); - vector::const_iterator it = keys.begin(); - vector::const_iterator end = keys.end(); - for (; it != end; ++it) { - // get the bibdata corresponding to the key - docstring const author(biblio::getAbbreviatedAuthor(infomap, *it)); - docstring const year(biblio::getYear(infomap, *it)); - - // Something isn't right. Fail safely. - if (author.empty() || year.empty()) - return docstring(); - - // authors1/; ... ; - // authors_last, - if (cite_type == "cite" && engine == biblio::ENGINE_JURABIB) { - if (it == keys.begin()) - label += author + before_str + sep_str; - else - label += author + sep_str; - - // (authors1 ( year); ... ; - // authors_last ( year, ) - } else if (cite_type == "citet") { - switch (engine) { - case biblio::ENGINE_NATBIB_AUTHORYEAR: - label += author + op_str + before_str + - year + cp + sep_str; - break; - case biblio::ENGINE_NATBIB_NUMERICAL: - // FIXME UNICODE - label += author + op_str + before_str + - '#' + from_utf8(*it) + cp + sep_str; - break; - case biblio::ENGINE_JURABIB: - label += before_str + author + op_str + - year + cp + sep_str; - break; - case biblio::ENGINE_BASIC: - break; - } - - // author, year; author, year; ... - } else if (cite_type == "citep" || - cite_type == "citealp") { - if (engine == biblio::ENGINE_NATBIB_NUMERICAL) { - // FIXME UNICODE - label += from_utf8(*it) + sep_str; - } else { - label += author + ", " + year + sep_str; - } - - // (authors1 year; - // authors_last year, ) - } else if (cite_type == "citealt") { - switch (engine) { - case biblio::ENGINE_NATBIB_AUTHORYEAR: - label += author + ' ' + before_str + - year + sep_str; - break; - case biblio::ENGINE_NATBIB_NUMERICAL: - // FIXME UNICODE - label += author + ' ' + before_str + - '#' + from_utf8(*it) + sep_str; - break; - case biblio::ENGINE_JURABIB: - label += before_str + author + ' ' + - year + sep_str; - break; - case biblio::ENGINE_BASIC: - break; - } - - // author; author; ... - } else if (cite_type == "citeauthor") { - label += author + sep_str; - - // year; year; ... - } else if (cite_type == "citeyear" || - cite_type == "citeyearpar") { - label += year + sep_str; - } - } - label = rtrim(rtrim(label), sep); - - if (!after_str.empty()) { - if (cite_type == "citet") { - // insert "after" before last ')' - label.insert(label.size() - 1, after_str); - } else { - bool const add = - !(engine == biblio::ENGINE_NATBIB_NUMERICAL && - (cite_type == "citeauthor" || - cite_type == "citeyear")); - if (add) - label += after_str; - } - } - - if (!before_str.empty() && (cite_type == "citep" || - cite_type == "citealp" || - cite_type == "citeyearpar")) { - label = before_str + label; - } - - if (cite_type == "citep" || cite_type == "citeyearpar") - label = op + label + cp; - - return label; -} - - -docstring const getBasicLabel(docstring const & keyList, docstring const & after) -{ - docstring keys(keyList); - docstring label; - - if (contains(keys, ',')) { - // Final comma allows while loop to cover all keys - keys = ltrim(split(keys, label, ',')) + ','; - while (contains(keys, ',')) { - docstring key; - keys = ltrim(split(keys, key, ',')); - label += ", " + key; - } - } else - label = keys; - - if (!after.empty()) - label += ", " + after; - - return '[' + label + ']'; -} - -} // anon namespace - - -InsetCitation::InsetCitation(InsetCommandParams const & p) - : InsetCommand(p, "citation") -{} - - -docstring const InsetCitation::generateLabel(Buffer const & buffer) const -{ - docstring const before = getParam("before"); - docstring const after = getParam("after"); - - docstring label; - biblio::CiteEngine const engine = buffer.params().getEngine(); - if (engine != biblio::ENGINE_BASIC) { - // FIXME UNICODE - label = getNatbibLabel(buffer, getCmdName(), to_utf8(getParam("key")), - before, after, engine); - } - - // Fallback to fail-safe - if (label.empty()) { - label = getBasicLabel(getParam("key"), after); - } - - return label; -} - - -docstring const InsetCitation::getScreenLabel(Buffer const & buffer) const -{ - biblio::CiteEngine const engine = buffer.params().getEngine(); - if (cache.params == params() && cache.engine == engine) - return cache.screen_label; - - // The label has changed, so we have to re-create it. - docstring const glabel = generateLabel(buffer); - - unsigned int const maxLabelChars = 45; - - docstring label = glabel; - if (label.size() > maxLabelChars) { - label.erase(maxLabelChars-3); - label += "..."; - } - - cache.engine = engine; - cache.params = params(); - cache.generated_label = glabel; - cache.screen_label = label; - - return label; -} - - -int InsetCitation::plaintext(Buffer const & buffer, odocstream & os, - OutputParams const &) const -{ - docstring str; - - if (cache.params == params() && - cache.engine == buffer.params().getEngine()) - str = cache.generated_label; - else - str = generateLabel(buffer); - - os << str; - return str.size(); -} - - -namespace { - -docstring const cleanupWhitespace(docstring const & citelist) -{ - docstring::const_iterator it = citelist.begin(); - docstring::const_iterator end = citelist.end(); - // Paranoia check: make sure that there is no whitespace in here - // -- at least not behind commas or at the beginning - docstring result; - char_type last = ','; - for (; it != end; ++it) { - if (*it != ' ') - last = *it; - if (*it != ' ' || last != ',') - result += *it; - } - return result; -} - -// end anon namyspace -} - -int InsetCitation::docbook(Buffer const &, odocstream & os, - OutputParams const &) const -{ - os << "" - << cleanupWhitespace(getParam("key")) - << ""; - return 0; -} - - -int InsetCitation::textString(Buffer const & buf, odocstream & os, - OutputParams const & op) const -{ - return plaintext(buf, os, op); -} - - -// Have to overwrite the default InsetCommand method in order to check that -// the \cite command is valid. Eg, the user has natbib enabled, inputs some -// citations and then changes his mind, turning natbib support off. The output -// should revert to \cite[]{} -int InsetCitation::latex(Buffer const & buffer, odocstream & os, - OutputParams const &) const -{ - biblio::CiteEngine cite_engine = buffer.params().getEngine(); - // FIXME UNICODE - docstring const cite_str = from_utf8( - biblio::asValidLatexCommand(getCmdName(), cite_engine)); - - os << "\\" << cite_str; - - docstring const & before = getParam("before"); - docstring const & after = getParam("after"); - if (!before.empty() && cite_engine != biblio::ENGINE_BASIC) - os << '[' << before << "][" << after << ']'; - else if (!after.empty()) - os << '[' << after << ']'; - - os << '{' << cleanupWhitespace(getParam("key")) << '}'; - - return 0; -} - - -void InsetCitation::validate(LaTeXFeatures & features) const -{ - switch (features.bufferParams().getEngine()) { - case biblio::ENGINE_BASIC: - break; - case biblio::ENGINE_NATBIB_AUTHORYEAR: - case biblio::ENGINE_NATBIB_NUMERICAL: - features.require("natbib"); - break; - case biblio::ENGINE_JURABIB: - features.require("jurabib"); - break; - } -} - - -void InsetCitation::replaceContents(string const & from, string const & to) -{ - if (tokenPos(getContents(), ',', from) != -1) { - vector items = getVectorFromString(getContents()); - replace(items.begin(), items.end(), from, to); - setContents(getStringFromVector(items)); - } -} - - -} // namespace lyx diff --git a/src/insets/InsetCite.h b/src/insets/InsetCite.h deleted file mode 100644 index f0fd1d7a73..0000000000 --- a/src/insets/InsetCite.h +++ /dev/null @@ -1,83 +0,0 @@ -// -*- C++ -*- -/** - * \file InsetCitation.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Angus Leeming - * \author Herbert Voß - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef INSET_CITE_H -#define INSET_CITE_H - - -#include "InsetCommand.h" - -#include "frontends/controllers/biblio.h" - - -namespace lyx { - - -/** Used to insert citations - */ -class InsetCitation : public InsetCommand { -public: - /// - InsetCitation(InsetCommandParams const &); - /// - docstring const getScreenLabel(Buffer const &) const; - /// - EDITABLE editable() const { return IS_EDITABLE; } - /// - InsetBase::Code lyxCode() const { return InsetBase::CITE_CODE; } - /// - int latex(Buffer const &, odocstream &, - OutputParams const &) const; - /// - int plaintext(Buffer const &, odocstream &, - OutputParams const &) const; - /// - int docbook(Buffer const &, odocstream &, - OutputParams const &) const; - /// the string that is passed to the TOC - virtual int textString(Buffer const &, odocstream &, - OutputParams const &) const; - /// - void validate(LaTeXFeatures &) const; - /// - void replaceContents(std::string const & from, std::string const & to); - -private: - virtual std::auto_ptr doClone() const - { - return std::auto_ptr(new InsetCitation(params())); - } - - /// This function does the donkey work of creating the pretty label - docstring const generateLabel(Buffer const &) const; - - class Cache { - public: - /// - Cache() : engine(biblio::ENGINE_BASIC), params("cite") {} - /// - biblio::CiteEngine engine; - /// - InsetCommandParams params; - /// - docstring generated_label; - /// - docstring screen_label; - }; - /// - mutable Cache cache; -}; - - -} // namespace lyx - -#endif // INSET_CITE_H diff --git a/src/insets/InsetPageBreak.cpp b/src/insets/InsetPageBreak.cpp deleted file mode 100644 index 65683cba6f..0000000000 --- a/src/insets/InsetPageBreak.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * \file InsetPagebreak.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "InsetPagebreak.h" - -#include "debug.h" -#include "gettext.h" -#include "LColor.h" -#include "lyxtext.h" -#include "metricsinfo.h" -#include "outputparams.h" -#include "TextMetrics.h" - -#include "frontends/FontMetrics.h" -#include "frontends/Painter.h" - - -namespace lyx { - -using frontend::Painter; - -using std::endl; -using std::ostream; - - -void InsetPagebreak::read(Buffer const &, LyXLex &) -{ - /* Nothing to read */ -} - - -void InsetPagebreak::write(Buffer const &, ostream & os) const -{ - os << "\n" << getCmdName() << '\n'; -} - - -bool InsetPagebreak::metrics(MetricsInfo & mi, Dimension & dim) const -{ - dim.asc = defaultRowHeight(); - dim.des = defaultRowHeight(); - dim.wid = mi.base.textwidth; - bool const changed = dim_ != dim; - dim_ = dim; - return changed; -} - - -void InsetPagebreak::draw(PainterInfo & pi, int x, int y) const -{ - LyXFont font; - font.setColor(LColor::pagebreak); - font.decSize(); - - int w = 0; - int a = 0; - int d = 0; - theFontMetrics(font).rectText(insetLabel(), w, a, d); - - int const text_start = int(x + (dim_.wid - w) / 2); - int const text_end = text_start + w; - - pi.pain.rectText(text_start, y + d, insetLabel(), font, - LColor::none, LColor::none); - - pi.pain.line(x, y, text_start, y, - LColor::pagebreak, Painter::line_onoffdash); - pi.pain.line(text_end, y, int(x + dim_.wid), y, - LColor::pagebreak, Painter::line_onoffdash); -} - - -int InsetPagebreak::latex(Buffer const &, odocstream & os, - OutputParams const &) const -{ - os << from_ascii(getCmdName()) << "{}"; - return 0; -} - - -int InsetPagebreak::plaintext(Buffer const &, odocstream & os, - OutputParams const &) const -{ - os << '\n'; - return PLAINTEXT_NEWLINE; -} - - -int InsetPagebreak::docbook(Buffer const &, odocstream & os, - OutputParams const &) const -{ - os << '\n'; - return 0; -} - - -} // namespace lyx diff --git a/src/insets/InsetPageBreak.h b/src/insets/InsetPageBreak.h deleted file mode 100644 index b018f5883e..0000000000 --- a/src/insets/InsetPageBreak.h +++ /dev/null @@ -1,94 +0,0 @@ -// -*- C++ -*- -/** - * \file InsetPagebreak.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef INSET_PAGEBREAK_H -#define INSET_PAGEBREAK_H - - -#include "Inset.h" -#include "gettext.h" - - -namespace lyx { - -class InsetPagebreak : public InsetOld { -public: - InsetPagebreak() {} - - InsetBase::Code lyxCode() const { return InsetBase::PAGEBREAK_CODE; } - - bool metrics(MetricsInfo &, Dimension &) const; - - void draw(PainterInfo & pi, int x, int y) const; - - int latex(Buffer const &, odocstream &, - OutputParams const &) const; - - int plaintext(Buffer const &, odocstream &, - OutputParams const &) const; - - int docbook(Buffer const &, odocstream &, - OutputParams const &) const; - - void read(Buffer const &, LyXLex & lex); - - virtual void write(Buffer const & buf, std::ostream & os) const; - /// We don't need \begin_inset and \end_inset - bool directWrite() const { return true; } - - bool display() const { return true; } - - virtual docstring insetLabel() const { return _("Page Break"); } - - virtual std::string getCmdName() const { return "\\newpage"; } - -private: - virtual std::auto_ptr doClone() const - { - return std::auto_ptr(new InsetPagebreak); - } -}; - - -class InsetClearPage : public InsetPagebreak { -public: - InsetClearPage() {} - - docstring insetLabel() const { return _("Clear Page"); } - - std::string getCmdName() const { return "\\clearpage"; } - -private: - virtual std::auto_ptr doClone() const - { - return std::auto_ptr(new InsetClearPage); - } -}; - - -class InsetClearDoublePage : public InsetPagebreak { -public: - InsetClearDoublePage() {} - - docstring insetLabel() const { return _("Clear Double Page"); } - - std::string getCmdName() const { return "\\cleardoublepage"; } - -private: - virtual std::auto_ptr doClone() const - { - return std::auto_ptr(new InsetClearDoublePage); - } -}; - -} // namespace lyx - -#endif // INSET_PAGEBREAK_H diff --git a/src/insets/InsetPagebreak.cpp b/src/insets/InsetPagebreak.cpp new file mode 100644 index 0000000000..65683cba6f --- /dev/null +++ b/src/insets/InsetPagebreak.cpp @@ -0,0 +1,106 @@ +/** + * \file InsetPagebreak.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "InsetPagebreak.h" + +#include "debug.h" +#include "gettext.h" +#include "LColor.h" +#include "lyxtext.h" +#include "metricsinfo.h" +#include "outputparams.h" +#include "TextMetrics.h" + +#include "frontends/FontMetrics.h" +#include "frontends/Painter.h" + + +namespace lyx { + +using frontend::Painter; + +using std::endl; +using std::ostream; + + +void InsetPagebreak::read(Buffer const &, LyXLex &) +{ + /* Nothing to read */ +} + + +void InsetPagebreak::write(Buffer const &, ostream & os) const +{ + os << "\n" << getCmdName() << '\n'; +} + + +bool InsetPagebreak::metrics(MetricsInfo & mi, Dimension & dim) const +{ + dim.asc = defaultRowHeight(); + dim.des = defaultRowHeight(); + dim.wid = mi.base.textwidth; + bool const changed = dim_ != dim; + dim_ = dim; + return changed; +} + + +void InsetPagebreak::draw(PainterInfo & pi, int x, int y) const +{ + LyXFont font; + font.setColor(LColor::pagebreak); + font.decSize(); + + int w = 0; + int a = 0; + int d = 0; + theFontMetrics(font).rectText(insetLabel(), w, a, d); + + int const text_start = int(x + (dim_.wid - w) / 2); + int const text_end = text_start + w; + + pi.pain.rectText(text_start, y + d, insetLabel(), font, + LColor::none, LColor::none); + + pi.pain.line(x, y, text_start, y, + LColor::pagebreak, Painter::line_onoffdash); + pi.pain.line(text_end, y, int(x + dim_.wid), y, + LColor::pagebreak, Painter::line_onoffdash); +} + + +int InsetPagebreak::latex(Buffer const &, odocstream & os, + OutputParams const &) const +{ + os << from_ascii(getCmdName()) << "{}"; + return 0; +} + + +int InsetPagebreak::plaintext(Buffer const &, odocstream & os, + OutputParams const &) const +{ + os << '\n'; + return PLAINTEXT_NEWLINE; +} + + +int InsetPagebreak::docbook(Buffer const &, odocstream & os, + OutputParams const &) const +{ + os << '\n'; + return 0; +} + + +} // namespace lyx diff --git a/src/insets/InsetPagebreak.h b/src/insets/InsetPagebreak.h new file mode 100644 index 0000000000..b018f5883e --- /dev/null +++ b/src/insets/InsetPagebreak.h @@ -0,0 +1,94 @@ +// -*- C++ -*- +/** + * \file InsetPagebreak.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef INSET_PAGEBREAK_H +#define INSET_PAGEBREAK_H + + +#include "Inset.h" +#include "gettext.h" + + +namespace lyx { + +class InsetPagebreak : public InsetOld { +public: + InsetPagebreak() {} + + InsetBase::Code lyxCode() const { return InsetBase::PAGEBREAK_CODE; } + + bool metrics(MetricsInfo &, Dimension &) const; + + void draw(PainterInfo & pi, int x, int y) const; + + int latex(Buffer const &, odocstream &, + OutputParams const &) const; + + int plaintext(Buffer const &, odocstream &, + OutputParams const &) const; + + int docbook(Buffer const &, odocstream &, + OutputParams const &) const; + + void read(Buffer const &, LyXLex & lex); + + virtual void write(Buffer const & buf, std::ostream & os) const; + /// We don't need \begin_inset and \end_inset + bool directWrite() const { return true; } + + bool display() const { return true; } + + virtual docstring insetLabel() const { return _("Page Break"); } + + virtual std::string getCmdName() const { return "\\newpage"; } + +private: + virtual std::auto_ptr doClone() const + { + return std::auto_ptr(new InsetPagebreak); + } +}; + + +class InsetClearPage : public InsetPagebreak { +public: + InsetClearPage() {} + + docstring insetLabel() const { return _("Clear Page"); } + + std::string getCmdName() const { return "\\clearpage"; } + +private: + virtual std::auto_ptr doClone() const + { + return std::auto_ptr(new InsetClearPage); + } +}; + + +class InsetClearDoublePage : public InsetPagebreak { +public: + InsetClearDoublePage() {} + + docstring insetLabel() const { return _("Clear Double Page"); } + + std::string getCmdName() const { return "\\cleardoublepage"; } + +private: + virtual std::auto_ptr doClone() const + { + return std::auto_ptr(new InsetClearDoublePage); + } +}; + +} // namespace lyx + +#endif // INSET_PAGEBREAK_H diff --git a/src/mathed/CommandInset.cpp b/src/mathed/CommandInset.cpp new file mode 100644 index 0000000000..23de2c5d52 --- /dev/null +++ b/src/mathed/CommandInset.cpp @@ -0,0 +1,82 @@ +/** + * \file CommandInset.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "CommandInset.h" +#include "MathArray.h" +#include "MathStream.h" +#include "dispatchresult.h" +#include "funcrequest.h" + +#include + + +namespace lyx { + +using std::auto_ptr; +using std::string; + +CommandInset::CommandInset(docstring const & name) + : InsetMathNest(2), name_(name), set_label_(false) +{ + lock_ = true; +} + + +auto_ptr CommandInset::doClone() const +{ + return auto_ptr(new CommandInset(*this)); +} + + +bool CommandInset::metrics(MetricsInfo & mi, Dimension & dim) const +{ + if (!set_label_) { + set_label_ = true; + button_.update(screenLabel(), true); + } + button_.metrics(mi, dim); + if (dim_ == dim) + return false; + dim_ = dim; + return true; +} + + +InsetBase * CommandInset::editXY(LCursor & cur, int /*x*/, int /*y*/) +{ + edit(cur, true); + return this; +} + + +void CommandInset::draw(PainterInfo & pi, int x, int y) const +{ + button_.draw(pi, x, y); + setPosCache(pi, x, y); +} + + +void CommandInset::write(WriteStream & os) const +{ + os << '\\' << name_.c_str(); + if (cell(1).size()) + os << '[' << cell(1) << ']'; + os << '{' << cell(0) << '}'; +} + + +docstring const CommandInset::screenLabel() const +{ + return name_; +} + +} // namespace lyx diff --git a/src/mathed/CommandInset.h b/src/mathed/CommandInset.h new file mode 100644 index 0000000000..bac6ddcbe1 --- /dev/null +++ b/src/mathed/CommandInset.h @@ -0,0 +1,57 @@ +// -*- C++ -*- +/** + * \file CommandInset.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + + +#ifndef COMMAND_INSET_H +#define COMMAND_INSET_H + +#include "InsetMathNest.h" + +#include "insets/RenderButton.h" + + +namespace lyx { + + +/// Inset for things like \name[options]{contents} +class CommandInset : public InsetMathNest { +public: + /// + explicit CommandInset(docstring const & name); + /// + bool metrics(MetricsInfo & mi, Dimension & dim) const; + /// + void draw(PainterInfo & pi, int x, int y) const; + /// + InsetBase * editXY(LCursor &, int, int); + /// + void write(WriteStream & os) const; + // + // void infoize(odocstream & os) const; + /// + virtual docstring const screenLabel() const; + /// + docstring const & commandname() const { return name_; } +private: + virtual std::auto_ptr doClone() const; + + /// + docstring name_; + /// + mutable bool set_label_; + /// + mutable RenderButton button_; +}; + + +} // namespace lyx + +#endif diff --git a/src/mathed/InsetMathCommand.cpp b/src/mathed/InsetMathCommand.cpp deleted file mode 100644 index 23de2c5d52..0000000000 --- a/src/mathed/InsetMathCommand.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file CommandInset.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "CommandInset.h" -#include "MathArray.h" -#include "MathStream.h" -#include "dispatchresult.h" -#include "funcrequest.h" - -#include - - -namespace lyx { - -using std::auto_ptr; -using std::string; - -CommandInset::CommandInset(docstring const & name) - : InsetMathNest(2), name_(name), set_label_(false) -{ - lock_ = true; -} - - -auto_ptr CommandInset::doClone() const -{ - return auto_ptr(new CommandInset(*this)); -} - - -bool CommandInset::metrics(MetricsInfo & mi, Dimension & dim) const -{ - if (!set_label_) { - set_label_ = true; - button_.update(screenLabel(), true); - } - button_.metrics(mi, dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; -} - - -InsetBase * CommandInset::editXY(LCursor & cur, int /*x*/, int /*y*/) -{ - edit(cur, true); - return this; -} - - -void CommandInset::draw(PainterInfo & pi, int x, int y) const -{ - button_.draw(pi, x, y); - setPosCache(pi, x, y); -} - - -void CommandInset::write(WriteStream & os) const -{ - os << '\\' << name_.c_str(); - if (cell(1).size()) - os << '[' << cell(1) << ']'; - os << '{' << cell(0) << '}'; -} - - -docstring const CommandInset::screenLabel() const -{ - return name_; -} - -} // namespace lyx diff --git a/src/mathed/InsetMathCommand.h b/src/mathed/InsetMathCommand.h deleted file mode 100644 index bac6ddcbe1..0000000000 --- a/src/mathed/InsetMathCommand.h +++ /dev/null @@ -1,57 +0,0 @@ -// -*- C++ -*- -/** - * \file CommandInset.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - - -#ifndef COMMAND_INSET_H -#define COMMAND_INSET_H - -#include "InsetMathNest.h" - -#include "insets/RenderButton.h" - - -namespace lyx { - - -/// Inset for things like \name[options]{contents} -class CommandInset : public InsetMathNest { -public: - /// - explicit CommandInset(docstring const & name); - /// - bool metrics(MetricsInfo & mi, Dimension & dim) const; - /// - void draw(PainterInfo & pi, int x, int y) const; - /// - InsetBase * editXY(LCursor &, int, int); - /// - void write(WriteStream & os) const; - // - // void infoize(odocstream & os) const; - /// - virtual docstring const screenLabel() const; - /// - docstring const & commandname() const { return name_; } -private: - virtual std::auto_ptr doClone() const; - - /// - docstring name_; - /// - mutable bool set_label_; - /// - mutable RenderButton button_; -}; - - -} // namespace lyx - -#endif diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp deleted file mode 100644 index 1cde0ecfd8..0000000000 --- a/src/mathed/InsetMathMacro.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/** - * \file MathMacro.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Alejandro Aguilar Sierra - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "MathMacro.h" -#include "MathSupport.h" -#include "MathExtern.h" -#include "MathStream.h" - -#include "buffer.h" -#include "cursor.h" -#include "debug.h" -#include "BufferView.h" -#include "LaTeXFeatures.h" -#include "frontends/Painter.h" - - -namespace lyx { - -using std::string; -using std::max; -using std::auto_ptr; -using std::endl; -using std::vector; - - -/// This class is the value of a macro argument, technically -/// a wrapper of the cells of MathMacro. -class MathMacroArgumentValue : public InsetMathDim { -public: - /// - MathMacroArgumentValue(MathArray const * value, docstring const & macroName) - : value_(value), macroName_(macroName) {} - /// - bool metrics(MetricsInfo & mi, Dimension & dim) const; - /// - void draw(PainterInfo &, int x, int y) const; - -private: - std::auto_ptr doClone() const; - MathArray const * value_; - docstring macroName_; -}; - - -auto_ptr MathMacroArgumentValue::doClone() const -{ - return auto_ptr(new MathMacroArgumentValue(*this)); -} - - -bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const -{ - // unlock outer macro in arguments, and lock it again later - MacroTable::globalMacros().get(macroName_).unlock(); - value_->metrics(mi, dim); - MacroTable::globalMacros().get(macroName_).lock(); - metricsMarkers2(dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; -} - - -void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const -{ - // unlock outer macro in arguments, and lock it again later - MacroTable::globalMacros().get(macroName_).unlock(); - value_->draw(pi, x, y); - MacroTable::globalMacros().get(macroName_).lock(); -} - - -MathMacro::MathMacro(docstring const & name, int numargs) - : InsetMathNest(numargs), name_(name) -{} - - -auto_ptr MathMacro::doClone() const -{ - return auto_ptr(new MathMacro(*this)); -} - - -docstring MathMacro::name() const -{ - return name_; -} - - -void MathMacro::cursorPos(BufferView const & bv, - CursorSlice const & sl, bool boundary, int & x, int & y) const -{ - // We may have 0 arguments, but InsetMathNest requires at least one. - if (nargs() > 0) - InsetMathNest::cursorPos(bv, sl, boundary, x, y); -} - - -bool MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const -{ - if (!MacroTable::globalMacros().has(name())) { - mathed_string_dim(mi.base.font, "Unknown: " + name(), dim); - } else { - MacroData const & macro = MacroTable::globalMacros().get(name()); - if (macro.locked()) { - mathed_string_dim(mi.base.font, "Self reference: " + name(), dim); - expanded_ = MathArray(); - } else if (editing(mi.base.bv)) { - // FIXME UNICODE - asArray(macro.def(), tmpl_); - LyXFont font = mi.base.font; - augmentFont(font, from_ascii("lyxtex")); - tmpl_.metrics(mi, dim); - // FIXME UNICODE - dim.wid += mathed_string_width(font, name()) + 10; - // FIXME UNICODE - int ww = mathed_string_width(font, from_ascii("#1: ")); - for (idx_type i = 0; i < nargs(); ++i) { - MathArray const & c = cell(i); - c.metrics(mi); - dim.wid = max(dim.wid, c.width() + ww); - dim.des += c.height() + 10; - } - } else { - // create MathMacroArgumentValue object pointing to the cells of the macro - MacroData const & macro = MacroTable::globalMacros().get(name()); - vector values(nargs()); - for (size_t i = 0; i != nargs(); ++i) - values[i].insert(0, MathAtom(new MathMacroArgumentValue(&cells_[i], name()))); - macro.expand(values, expanded_); - - MacroTable::globalMacros().get(name()).lock(); - expanded_.metrics(mi, dim); - MacroTable::globalMacros().get(name()).unlock(); - } - } - metricsMarkers2(dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; -} - - -void MathMacro::draw(PainterInfo & pi, int x, int y) const -{ - if (!MacroTable::globalMacros().has(name())) { - // FIXME UNICODE - drawStrRed(pi, x, y, "Unknown: " + name()); - } else { - MacroData const & macro = MacroTable::globalMacros().get(name()); - if (macro.locked()) { - // FIXME UNICODE - drawStrRed(pi, x, y, "Self reference: " + name()); - } else if (editing(pi.base.bv)) { - LyXFont font = pi.base.font; - augmentFont(font, from_ascii("lyxtex")); - int h = y - dim_.ascent() + 2 + tmpl_.ascent(); - pi.pain.text(x + 3, h, name(), font); - int const w = mathed_string_width(font, name()); - tmpl_.draw(pi, x + w + 12, h); - h += tmpl_.descent(); - Dimension ldim; - docstring t = from_ascii("#1: "); - mathed_string_dim(font, t, ldim); - for (idx_type i = 0; i < nargs(); ++i) { - MathArray const & c = cell(i); - h += max(c.ascent(), ldim.asc) + 5; - c.draw(pi, x + ldim.wid, h); - char_type str[] = { '#', '1', ':', '\0' }; - str[1] += static_cast(i); - pi.pain.text(x + 3, h, str, font); - h += max(c.descent(), ldim.des) + 5; - } - } else { - MacroTable::globalMacros().get(name()).lock(); - expanded_.draw(pi, x, y); - MacroTable::globalMacros().get(name()).unlock(); - } - } - drawMarkers2(pi, x, y); -} - - -void MathMacro::drawSelection(PainterInfo & pi, int x, int y) const -{ - // We may have 0 arguments, but InsetMathNest requires at least one. - if (nargs() > 0) - InsetMathNest::drawSelection(pi, x, y); -} - - -void MathMacro::validate(LaTeXFeatures & features) const -{ - if (name() == "binom" || name() == "mathcircumflex") - features.require(to_utf8(name())); -} - - -InsetBase * MathMacro::editXY(LCursor & cur, int x, int y) -{ - // We may have 0 arguments, but InsetMathNest requires at least one. - if (nargs() > 0) { - // Prevent crash due to cold coordcache - // FIXME: This is only a workaround, the call of - // InsetMathNest::editXY is correct. The correct fix would - // ensure that the coordcache of the arguments is valid. - if (!editing(&cur.bv())) { - edit(cur, true); - return this; - } - return InsetMathNest::editXY(cur, x, y); - } - return this; -} - - -bool MathMacro::idxFirst(LCursor & cur) const -{ - cur.updateFlags(Update::Force); - return InsetMathNest::idxFirst(cur); -} - - -bool MathMacro::idxLast(LCursor & cur) const -{ - cur.updateFlags(Update::Force); - return InsetMathNest::idxLast(cur); -} - - -bool MathMacro::notifyCursorLeaves(LCursor & cur) -{ - cur.updateFlags(Update::Force); - return InsetMathNest::notifyCursorLeaves(cur); -} - - -void MathMacro::maple(MapleStream & os) const -{ - updateExpansion(); - lyx::maple(expanded_, os); -} - - -void MathMacro::mathmlize(MathStream & os) const -{ - updateExpansion(); - lyx::mathmlize(expanded_, os); -} - - -void MathMacro::octave(OctaveStream & os) const -{ - updateExpansion(); - lyx::octave(expanded_, os); -} - - -void MathMacro::updateExpansion() const -{ - //expanded_.substitute(*this); -} - - -void MathMacro::infoize(odocstream & os) const -{ - os << "Macro: " << name(); -} - - -void MathMacro::infoize2(odocstream & os) const -{ - os << "Macro: " << name(); - -} - - -} // namespace lyx diff --git a/src/mathed/InsetMathMacro.h b/src/mathed/InsetMathMacro.h deleted file mode 100644 index b4ff0a4041..0000000000 --- a/src/mathed/InsetMathMacro.h +++ /dev/null @@ -1,90 +0,0 @@ -// -*- C++ -*- -/** - * \file MathMacro.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Alejandro Aguilar Sierra - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef MATH_MACRO_H -#define MATH_MACRO_H - -#include "InsetMathNest.h" -#include "MathArray.h" -#include "InsetMathNest.h" -#include "MathMacroTable.h" - - -namespace lyx { - - -/// This class contains the data for a macro. -class MathMacro : public InsetMathNest { -public: - /// A macro can be built from an existing template - MathMacro(docstring const & name, int numargs); - /// - void draw(PainterInfo & pi, int x, int y) const; - /// - void drawExpanded(PainterInfo & pi, int x, int y) const; - /// draw selection background - void drawSelection(PainterInfo & pi, int x, int y) const; - /// draw decorations. - void drawDecoration(PainterInfo & pi, int x, int y) const - { drawMarkers2(pi, x, y); } - /// - bool metrics(MetricsInfo & mi, Dimension & dim) const; - /// get cursor position - void cursorPos(BufferView const & bv, CursorSlice const & sl, - bool boundary, int & x, int & y) const; - /// - InsetBase * editXY(LCursor & cur, int x, int y); - /// target pos when we enter the inset from the left by pressing "Right" - bool idxFirst(LCursor &) const; - /// target pos when we enter the inset from the right by pressing "Left" - bool idxLast(LCursor &) const; - /// - virtual bool notifyCursorLeaves(LCursor &); - /// - docstring name() const; - /// - void setExpansion(MathArray const & exp, MathArray const & args) const; - - /// - void validate(LaTeXFeatures &) const; - - /// - void maple(MapleStream &) const; - /// - void mathmlize(MathStream &) const; - /// - void octave(OctaveStream &) const; - /// - void infoize(odocstream &) const; - /// - void infoize2(odocstream &) const; - -private: - virtual std::auto_ptr doClone() const; - /// - void updateExpansion() const; - /// - void expand() const; - - /// name of macro - docstring name_; - /// the unexpanded macro defintition - mutable MathArray tmpl_; - /// the macro substituted with our args - mutable MathArray expanded_; -}; - - - - -} // namespace lyx -#endif diff --git a/src/mathed/MathArray.cpp b/src/mathed/MathArray.cpp new file mode 100644 index 0000000000..805f8b5495 --- /dev/null +++ b/src/mathed/MathArray.cpp @@ -0,0 +1,485 @@ +/** + * \file MathArray.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "MathArray.h" +#include "InsetMathFont.h" +#include "InsetMathScript.h" +#include "MathMacro.h" +#include "MathMacroTable.h" +#include "MathStream.h" +#include "MathSupport.h" +#include "ReplaceData.h" + +#include "BufferView.h" +#include "buffer.h" +#include "cursor.h" +#include "debug.h" +#include "LColor.h" + +#include "frontends/FontMetrics.h" +#include "frontends/Painter.h" + +#include + + +namespace lyx { + +using std::abs; +using std::endl; +using std::min; +using std::ostringstream; +using std::string; +using std::vector; + + +MathArray::MathArray(const_iterator from, const_iterator to) + : base_type(from, to) +{} + + +MathAtom & MathArray::operator[](pos_type pos) +{ + BOOST_ASSERT(pos < size()); + return base_type::operator[](pos); +} + + +MathAtom const & MathArray::operator[](pos_type pos) const +{ + BOOST_ASSERT(pos < size()); + return base_type::operator[](pos); +} + + +void MathArray::insert(size_type pos, MathAtom const & t) +{ + base_type::insert(begin() + pos, t); +} + + +void MathArray::insert(size_type pos, MathArray const & ar) +{ + BOOST_ASSERT(pos <= size()); + base_type::insert(begin() + pos, ar.begin(), ar.end()); +} + + +void MathArray::append(MathArray const & ar) +{ + insert(size(), ar); +} + + +void MathArray::erase(size_type pos) +{ + if (pos < size()) + erase(pos, pos + 1); +} + + +void MathArray::erase(iterator pos1, iterator pos2) +{ + base_type::erase(pos1, pos2); +} + + +void MathArray::erase(iterator pos) +{ + base_type::erase(pos); +} + + +void MathArray::erase(size_type pos1, size_type pos2) +{ + base_type::erase(begin() + pos1, begin() + pos2); +} + + +void MathArray::dump2() const +{ + odocstringstream os; + NormalStream ns(os); + for (const_iterator it = begin(); it != end(); ++it) + ns << *it << ' '; + lyxerr << to_utf8(os.str()); +} + + +void MathArray::dump() const +{ + odocstringstream os; + NormalStream ns(os); + for (const_iterator it = begin(); it != end(); ++it) + ns << '<' << *it << '>'; + lyxerr << to_utf8(os.str()); +} + + +void MathArray::validate(LaTeXFeatures & features) const +{ + for (const_iterator it = begin(); it != end(); ++it) + (*it)->validate(features); +} + + +bool MathArray::match(MathArray const & ar) const +{ + return size() == ar.size() && matchpart(ar, 0); +} + + +bool MathArray::matchpart(MathArray const & ar, pos_type pos) const +{ + if (size() < ar.size() + pos) + return false; + const_iterator it = begin() + pos; + for (const_iterator jt = ar.begin(); jt != ar.end(); ++jt, ++it) + if (asString(*it) != asString(*jt)) + return false; + return true; +} + + +void MathArray::replace(ReplaceData & rep) +{ + for (size_type i = 0; i < size(); ++i) { + if (find1(rep.from, i)) { + // match found + lyxerr << "match found!" << endl; + erase(i, i + rep.from.size()); + insert(i, rep.to); + } + } + +#ifdef WITH_WARNINGS +#warning temporarily disabled + // for (const_iterator it = begin(); it != end(); ++it) + // it->nucleus()->replace(rep); +#endif +} + + +bool MathArray::find1(MathArray const & ar, size_type pos) const +{ + lyxerr << "finding '" << ar << "' in '" << *this << "'" << endl; + for (size_type i = 0, n = ar.size(); i < n; ++i) + if (asString(operator[](pos + i)) != asString(ar[i])) + return false; + return true; +} + + +MathArray::size_type MathArray::find(MathArray const & ar) const +{ + for (int i = 0, last = size() - ar.size(); i < last; ++i) + if (find1(ar, i)) + return i; + return size(); +} + + +MathArray::size_type MathArray::find_last(MathArray const & ar) const +{ + for (int i = size() - ar.size(); i >= 0; --i) + if (find1(ar, i)) + return i; + return size(); +} + + +bool MathArray::contains(MathArray const & ar) const +{ + if (find(ar) != size()) + return true; + for (const_iterator it = begin(); it != end(); ++it) + if ((*it)->contains(ar)) + return true; + return false; +} + + +void MathArray::touch() const +{ +} + + +bool MathArray::metrics(MetricsInfo & mi, Dimension & dim) const +{ + dim = dim_; + metrics(mi); + if (dim_ == dim) + return false; + dim = dim_; + return true; +} + + +namespace { + +bool isInside(DocIterator const & it, MathArray const & ar, + pos_type p1, pos_type p2) +{ + for (size_t i = 0; i != it.depth(); ++i) { + CursorSlice const & sl = it[i]; + if (sl.inset().inMathed() && &sl.cell() == &ar) + return p1 <= sl.pos() && sl.pos() < p2; + } + return false; +} + +} + + + +void MathArray::metrics(MetricsInfo & mi) const +{ + frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); + dim_ = fm.dimension('I'); + int xascent = fm.dimension('x').ascent(); + if (xascent >= dim_.asc) + xascent = (2 * dim_.asc) / 3; + minasc_ = xascent; + mindes_ = (3 * xascent) / 4; + slevel_ = (4 * xascent) / 5; + sshift_ = xascent / 4; + kerning_ = 0; + + if (empty()) + return; + + dim_.asc = 0; + dim_.wid = 0; + Dimension d; + //BufferView & bv = *mi.base.bv; + //Buffer const & buf = *bv.buffer(); + for (size_t i = 0, n = size(); i != n; ++i) { + MathAtom const & at = operator[](i); +#if 0 + MathMacro const * mac = at->asMacro(); + if (mac && buf.hasMacro(mac->name())) { + MacroData const & tmpl = buf.getMacro(mac->name()); + int numargs = tmpl.numargs(); + if (i + numargs > n) + numargs = n - i - 1; + lyxerr << "metrics:found macro: " << mac->name() + << " numargs: " << numargs << endl; + if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) { + MathArray args(begin() + i + 1, begin() + i + numargs + 1); + MathArray exp; + tmpl.expand(args, exp); + mac->setExpansion(exp, args); + mac->metricsExpanded(mi, d); + dim_.wid += mac->widthExpanded(); + i += numargs; + continue; + } + } +#endif + at->metrics(mi, d); + dim_ += d; + if (i == n - 1) + kerning_ = at->kerning(); + } +} + + +void MathArray::draw(PainterInfo & pi, int x, int y) const +{ + //lyxerr << "MathArray::draw: x: " << x << " y: " << y << endl; + BufferView & bv = *pi.base.bv; + setXY(bv, x, y); + + if (empty()) { + pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); + return; + } + + // don't draw outside the workarea + if (y + descent() <= 0 + || y - ascent() >= bv.workHeight() + || x + width() <= 0 + || x >= bv. workWidth()) + return; + + for (size_t i = 0, n = size(); i != n; ++i) { + MathAtom const & at = operator[](i); +#if 0 + Buffer const & buf = bv.buffer(); + // special macro handling + MathMacro const * mac = at->asMacro(); + if (mac && buf.hasMacro(mac->name())) { + MacroData const & tmpl = buf.getMacro(mac->name()); + int numargs = tmpl.numargs(); + if (i + numargs > n) + numargs = n - i - 1; + if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) { + mac->drawExpanded(pi, x, y); + x += mac->widthExpanded(); + i += numargs; + continue; + } + } +#endif + bv.coordCache().insets().add(at.nucleus(), x, y); + at->drawSelection(pi, x, y); + at->draw(pi, x, y); + x += at->width(); + } +} + + +void MathArray::metricsT(TextMetricsInfo const & mi, Dimension & dim) const +{ + dim.clear(); + Dimension d; + for (const_iterator it = begin(); it != end(); ++it) { + (*it)->metricsT(mi, d); + dim += d; + } +} + + +void MathArray::drawT(TextPainter & pain, int x, int y) const +{ + //lyxerr << "x: " << x << " y: " << y << ' ' << pain.workAreaHeight() << endl; + + // FIXME: Abdel 16/10/2006 + // This drawT() method is never used, this is dead code. + + for (const_iterator it = begin(), et = end(); it != et; ++it) { + (*it)->drawT(pain, x, y); + //x += (*it)->width_; + x += 2; + } +} + + +int MathArray::pos2x(size_type pos) const +{ + return pos2x(pos, 0); +} + + +int MathArray::pos2x(size_type pos, int glue) const +{ + int x = 0; + size_type target = min(pos, size()); + for (size_type i = 0; i < target; ++i) { + const_iterator it = begin() + i; + if ((*it)->getChar() == ' ') + x += glue; + //lyxerr << "char: " << (*it)->getChar() + // << "width: " << (*it)->width() << std::endl; + x += (*it)->width(); + } + return x; +} + + +MathArray::size_type MathArray::x2pos(int targetx) const +{ + return x2pos(targetx, 0); +} + + +MathArray::size_type MathArray::x2pos(int targetx, int glue) const +{ + const_iterator it = begin(); + int lastx = 0; + int currx = 0; + // find first position after targetx + for (; currx < targetx && it < end(); ++it) { + lastx = currx; + if ((*it)->getChar() == ' ') + currx += glue; + currx += (*it)->width(); + } + + /** + * If we are not at the beginning of the array, go to the left + * of the inset if one of the following two condition holds: + * - the current inset is editable (so that the cursor tip is + * deeper than us): in this case, we want all intermediate + * cursor slices to be before insets; + * - the mouse is closer to the left side of the inset than to + * the right one. + * See bug 1918 for details. + **/ + if (it != begin() && currx >= targetx + && ((*boost::prior(it))->asNestInset() + || abs(lastx - targetx) < abs(currx - targetx))) { + --it; + } + + return it - begin(); +} + + +int MathArray::dist(BufferView const & bv, int x, int y) const +{ + int xx = 0; + int yy = 0; + + const int xo_ = xo(bv); + const int yo_ = yo(bv); + + if (x < xo_) + xx = xo_ - x; + else if (x > xo_ + width()) + xx = x - xo_ - width(); + + if (y < yo_ - ascent()) + yy = yo_ - ascent() - y; + else if (y > yo_ + descent()) + yy = y - yo_ - descent(); + + return xx + yy; +} + + +void MathArray::setXY(BufferView & bv, int x, int y) const +{ + //lyxerr << "setting position cache for MathArray " << this << std::endl; + bv.coordCache().arrays().add(this, x, y); +} + + +int MathArray::xo(BufferView const & bv) const +{ + return bv.coordCache().getArrays().x(this); +} + + +int MathArray::yo(BufferView const & bv) const +{ + return bv.coordCache().getArrays().y(this); +} + + +std::ostream & operator<<(std::ostream & os, MathArray const & ar) +{ + odocstringstream oss; + NormalStream ns(oss); + ns << ar; + return os << to_utf8(oss.str()); +} + + +odocstream & operator<<(odocstream & os, MathArray const & ar) +{ + NormalStream ns(os); + ns << ar; + return os; +} + + +} // namespace lyx diff --git a/src/mathed/MathArray.h b/src/mathed/MathArray.h new file mode 100644 index 0000000000..5582a46828 --- /dev/null +++ b/src/mathed/MathArray.h @@ -0,0 +1,188 @@ +// -*- C++ -*- +/** + * \file MathArray.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Alejandro Aguilar Sierra + * \author André Pönitz + * \author Lars Gullik Bjønnes + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATH_DATA_H +#define MATH_DATA_H + +#include + +#include "MathAtom.h" +#include "dimension.h" + +#include "support/docstream.h" + + +namespace lyx { + +class BufferView; +class LaTeXFeatures; +class ReplaceData; +class MetricsInfo; +class PainterInfo; +class TextMetricsInfo; +class TextPainter; + + +class MathArray : private std::vector { +public: + /// re-use inhertited stuff + typedef std::vector base_type; + using base_type::const_iterator; + using base_type::iterator; + using base_type::size_type; + using base_type::difference_type; + using base_type::size; + using base_type::empty; + using base_type::clear; + using base_type::begin; + using base_type::end; + using base_type::push_back; + using base_type::pop_back; + using base_type::back; + using base_type::front; + /// + typedef size_type idx_type; + typedef size_type pos_type; + +public: + /// + MathArray() {} + /// + MathArray(const_iterator from, const_iterator to); + /// + void append(MathArray const & ar); + + /// inserts single atom at position pos + void insert(size_type pos, MathAtom const & at); + /// inserts multiple atoms at position pos + void insert(size_type pos, MathArray const & ar); + + /// erase range from pos1 to pos2 + void erase(iterator pos1, iterator pos2); + /// erase single atom + void erase(iterator pos); + /// erase range from pos1 to pos2 + void erase(size_type pos1, size_type pos2); + /// erase single atom + void erase(size_type pos); + + /// + void dump() const; + /// + void dump2() const; + /// + void replace(ReplaceData &); + /// + void substitute(MathArray const & m); + + /// looks for exact match + bool match(MathArray const & ar) const; + /// looks for inclusion match starting at pos + bool matchpart(MathArray const & ar, pos_type pos) const; + /// looks for containment, return == size mean not found + size_type find(MathArray const & ar) const; + /// looks for containment, return == size mean not found + size_type find_last(MathArray const & ar) const; + /// + bool contains(MathArray const & ar) const; + /// + void validate(LaTeXFeatures &) const; + + /// checked write access + MathAtom & operator[](pos_type); + /// checked read access + MathAtom const & operator[](pos_type) const; + /// rebuild cached metrics information + void metrics(MetricsInfo & mi) const; + /// rebuild cached metrics information + bool metrics(MetricsInfo & mi, Dimension & dim) const; + /// redraw cell using cache metrics information + void draw(PainterInfo & pi, int x, int y) const; + /// rebuild cached metrics information + void metricsT(TextMetricsInfo const & mi, Dimension & dim) const; + /// redraw cell using cache metrics information + void drawT(TextPainter & pi, int x, int y) const; + /// mark cell for re-drawing + void touch() const; + + /// access to cached x coordinate of last drawing + int xo(BufferView const & bv) const; + /// access to cached y coordinate of last drawing + int yo(BufferView const & bv) const; + /// access to cached x coordinate of mid point of last drawing + int xm(BufferView const & bv) const { return xo(bv) + dim_.wid / 2; } + /// access to cached y coordinate of mid point of last drawing + int ym(BufferView const & bv) const { return yo(bv) + (dim_.des - dim_.asc) / 2; } + /// write access to coordinate; + void setXY(BufferView & bv, int x, int y) const; + /// returns x coordinate of given position in the array + int pos2x(size_type pos) const; + /// returns position of given x coordinate + int pos2x(size_type pos, int glue) const; + /// returns position of given x coordinate + size_type x2pos(int pos) const; + /// returns position of given x coordinate fstarting from a certain pos + size_type x2pos(int targetx, int glue) const; + /// returns distance of this cell to the point given by x and y + // assumes valid position and size cache + int dist(BufferView const & bv, int x, int y) const; + + /// ascent of this cell above the baseline + int ascent() const { return dim_.asc; } + /// descent of this cell below the baseline + int descent() const { return dim_.des; } + /// height of the cell + int height() const { return dim_.asc + dim_.des; } + /// width of this cell + int width() const { return dim_.wid; } + /// dimensions of cell + Dimension const & dim() const { return dim_; } + /// dimensions of cell + void setDim(Dimension const & d) const { dim_ = d; } + /// minimum ascent offset for superscript + int minasc() const { return minasc_; } + /// minimum descent offset for subscript + int mindes() const { return mindes_; } + /// level above/below which super/subscript should extend + int slevel() const { return slevel_; } + /// additional super/subscript shift + int sshift() const { return sshift_; } + /// superscript kerning + int kerning() const { return kerning_; } + /// + void swap(MathArray & ar) { base_type::swap(ar); } + +protected: + /// cached dimensions of cell + mutable Dimension dim_; + /// cached values for super/subscript placement + mutable int minasc_; + mutable int mindes_; + mutable int slevel_; + mutable int sshift_; + mutable int kerning_; + +private: + /// is this an exact match at this position? + bool find1(MathArray const & ar, size_type pos) const; +}; + +/// +std::ostream & operator<<(std::ostream & os, MathArray const & ar); +/// +odocstream & operator<<(odocstream & os, MathArray const & ar); + + +} // namespace lyx + +#endif diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp deleted file mode 100644 index 805f8b5495..0000000000 --- a/src/mathed/MathData.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/** - * \file MathArray.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "MathArray.h" -#include "InsetMathFont.h" -#include "InsetMathScript.h" -#include "MathMacro.h" -#include "MathMacroTable.h" -#include "MathStream.h" -#include "MathSupport.h" -#include "ReplaceData.h" - -#include "BufferView.h" -#include "buffer.h" -#include "cursor.h" -#include "debug.h" -#include "LColor.h" - -#include "frontends/FontMetrics.h" -#include "frontends/Painter.h" - -#include - - -namespace lyx { - -using std::abs; -using std::endl; -using std::min; -using std::ostringstream; -using std::string; -using std::vector; - - -MathArray::MathArray(const_iterator from, const_iterator to) - : base_type(from, to) -{} - - -MathAtom & MathArray::operator[](pos_type pos) -{ - BOOST_ASSERT(pos < size()); - return base_type::operator[](pos); -} - - -MathAtom const & MathArray::operator[](pos_type pos) const -{ - BOOST_ASSERT(pos < size()); - return base_type::operator[](pos); -} - - -void MathArray::insert(size_type pos, MathAtom const & t) -{ - base_type::insert(begin() + pos, t); -} - - -void MathArray::insert(size_type pos, MathArray const & ar) -{ - BOOST_ASSERT(pos <= size()); - base_type::insert(begin() + pos, ar.begin(), ar.end()); -} - - -void MathArray::append(MathArray const & ar) -{ - insert(size(), ar); -} - - -void MathArray::erase(size_type pos) -{ - if (pos < size()) - erase(pos, pos + 1); -} - - -void MathArray::erase(iterator pos1, iterator pos2) -{ - base_type::erase(pos1, pos2); -} - - -void MathArray::erase(iterator pos) -{ - base_type::erase(pos); -} - - -void MathArray::erase(size_type pos1, size_type pos2) -{ - base_type::erase(begin() + pos1, begin() + pos2); -} - - -void MathArray::dump2() const -{ - odocstringstream os; - NormalStream ns(os); - for (const_iterator it = begin(); it != end(); ++it) - ns << *it << ' '; - lyxerr << to_utf8(os.str()); -} - - -void MathArray::dump() const -{ - odocstringstream os; - NormalStream ns(os); - for (const_iterator it = begin(); it != end(); ++it) - ns << '<' << *it << '>'; - lyxerr << to_utf8(os.str()); -} - - -void MathArray::validate(LaTeXFeatures & features) const -{ - for (const_iterator it = begin(); it != end(); ++it) - (*it)->validate(features); -} - - -bool MathArray::match(MathArray const & ar) const -{ - return size() == ar.size() && matchpart(ar, 0); -} - - -bool MathArray::matchpart(MathArray const & ar, pos_type pos) const -{ - if (size() < ar.size() + pos) - return false; - const_iterator it = begin() + pos; - for (const_iterator jt = ar.begin(); jt != ar.end(); ++jt, ++it) - if (asString(*it) != asString(*jt)) - return false; - return true; -} - - -void MathArray::replace(ReplaceData & rep) -{ - for (size_type i = 0; i < size(); ++i) { - if (find1(rep.from, i)) { - // match found - lyxerr << "match found!" << endl; - erase(i, i + rep.from.size()); - insert(i, rep.to); - } - } - -#ifdef WITH_WARNINGS -#warning temporarily disabled - // for (const_iterator it = begin(); it != end(); ++it) - // it->nucleus()->replace(rep); -#endif -} - - -bool MathArray::find1(MathArray const & ar, size_type pos) const -{ - lyxerr << "finding '" << ar << "' in '" << *this << "'" << endl; - for (size_type i = 0, n = ar.size(); i < n; ++i) - if (asString(operator[](pos + i)) != asString(ar[i])) - return false; - return true; -} - - -MathArray::size_type MathArray::find(MathArray const & ar) const -{ - for (int i = 0, last = size() - ar.size(); i < last; ++i) - if (find1(ar, i)) - return i; - return size(); -} - - -MathArray::size_type MathArray::find_last(MathArray const & ar) const -{ - for (int i = size() - ar.size(); i >= 0; --i) - if (find1(ar, i)) - return i; - return size(); -} - - -bool MathArray::contains(MathArray const & ar) const -{ - if (find(ar) != size()) - return true; - for (const_iterator it = begin(); it != end(); ++it) - if ((*it)->contains(ar)) - return true; - return false; -} - - -void MathArray::touch() const -{ -} - - -bool MathArray::metrics(MetricsInfo & mi, Dimension & dim) const -{ - dim = dim_; - metrics(mi); - if (dim_ == dim) - return false; - dim = dim_; - return true; -} - - -namespace { - -bool isInside(DocIterator const & it, MathArray const & ar, - pos_type p1, pos_type p2) -{ - for (size_t i = 0; i != it.depth(); ++i) { - CursorSlice const & sl = it[i]; - if (sl.inset().inMathed() && &sl.cell() == &ar) - return p1 <= sl.pos() && sl.pos() < p2; - } - return false; -} - -} - - - -void MathArray::metrics(MetricsInfo & mi) const -{ - frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); - dim_ = fm.dimension('I'); - int xascent = fm.dimension('x').ascent(); - if (xascent >= dim_.asc) - xascent = (2 * dim_.asc) / 3; - minasc_ = xascent; - mindes_ = (3 * xascent) / 4; - slevel_ = (4 * xascent) / 5; - sshift_ = xascent / 4; - kerning_ = 0; - - if (empty()) - return; - - dim_.asc = 0; - dim_.wid = 0; - Dimension d; - //BufferView & bv = *mi.base.bv; - //Buffer const & buf = *bv.buffer(); - for (size_t i = 0, n = size(); i != n; ++i) { - MathAtom const & at = operator[](i); -#if 0 - MathMacro const * mac = at->asMacro(); - if (mac && buf.hasMacro(mac->name())) { - MacroData const & tmpl = buf.getMacro(mac->name()); - int numargs = tmpl.numargs(); - if (i + numargs > n) - numargs = n - i - 1; - lyxerr << "metrics:found macro: " << mac->name() - << " numargs: " << numargs << endl; - if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) { - MathArray args(begin() + i + 1, begin() + i + numargs + 1); - MathArray exp; - tmpl.expand(args, exp); - mac->setExpansion(exp, args); - mac->metricsExpanded(mi, d); - dim_.wid += mac->widthExpanded(); - i += numargs; - continue; - } - } -#endif - at->metrics(mi, d); - dim_ += d; - if (i == n - 1) - kerning_ = at->kerning(); - } -} - - -void MathArray::draw(PainterInfo & pi, int x, int y) const -{ - //lyxerr << "MathArray::draw: x: " << x << " y: " << y << endl; - BufferView & bv = *pi.base.bv; - setXY(bv, x, y); - - if (empty()) { - pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); - return; - } - - // don't draw outside the workarea - if (y + descent() <= 0 - || y - ascent() >= bv.workHeight() - || x + width() <= 0 - || x >= bv. workWidth()) - return; - - for (size_t i = 0, n = size(); i != n; ++i) { - MathAtom const & at = operator[](i); -#if 0 - Buffer const & buf = bv.buffer(); - // special macro handling - MathMacro const * mac = at->asMacro(); - if (mac && buf.hasMacro(mac->name())) { - MacroData const & tmpl = buf.getMacro(mac->name()); - int numargs = tmpl.numargs(); - if (i + numargs > n) - numargs = n - i - 1; - if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) { - mac->drawExpanded(pi, x, y); - x += mac->widthExpanded(); - i += numargs; - continue; - } - } -#endif - bv.coordCache().insets().add(at.nucleus(), x, y); - at->drawSelection(pi, x, y); - at->draw(pi, x, y); - x += at->width(); - } -} - - -void MathArray::metricsT(TextMetricsInfo const & mi, Dimension & dim) const -{ - dim.clear(); - Dimension d; - for (const_iterator it = begin(); it != end(); ++it) { - (*it)->metricsT(mi, d); - dim += d; - } -} - - -void MathArray::drawT(TextPainter & pain, int x, int y) const -{ - //lyxerr << "x: " << x << " y: " << y << ' ' << pain.workAreaHeight() << endl; - - // FIXME: Abdel 16/10/2006 - // This drawT() method is never used, this is dead code. - - for (const_iterator it = begin(), et = end(); it != et; ++it) { - (*it)->drawT(pain, x, y); - //x += (*it)->width_; - x += 2; - } -} - - -int MathArray::pos2x(size_type pos) const -{ - return pos2x(pos, 0); -} - - -int MathArray::pos2x(size_type pos, int glue) const -{ - int x = 0; - size_type target = min(pos, size()); - for (size_type i = 0; i < target; ++i) { - const_iterator it = begin() + i; - if ((*it)->getChar() == ' ') - x += glue; - //lyxerr << "char: " << (*it)->getChar() - // << "width: " << (*it)->width() << std::endl; - x += (*it)->width(); - } - return x; -} - - -MathArray::size_type MathArray::x2pos(int targetx) const -{ - return x2pos(targetx, 0); -} - - -MathArray::size_type MathArray::x2pos(int targetx, int glue) const -{ - const_iterator it = begin(); - int lastx = 0; - int currx = 0; - // find first position after targetx - for (; currx < targetx && it < end(); ++it) { - lastx = currx; - if ((*it)->getChar() == ' ') - currx += glue; - currx += (*it)->width(); - } - - /** - * If we are not at the beginning of the array, go to the left - * of the inset if one of the following two condition holds: - * - the current inset is editable (so that the cursor tip is - * deeper than us): in this case, we want all intermediate - * cursor slices to be before insets; - * - the mouse is closer to the left side of the inset than to - * the right one. - * See bug 1918 for details. - **/ - if (it != begin() && currx >= targetx - && ((*boost::prior(it))->asNestInset() - || abs(lastx - targetx) < abs(currx - targetx))) { - --it; - } - - return it - begin(); -} - - -int MathArray::dist(BufferView const & bv, int x, int y) const -{ - int xx = 0; - int yy = 0; - - const int xo_ = xo(bv); - const int yo_ = yo(bv); - - if (x < xo_) - xx = xo_ - x; - else if (x > xo_ + width()) - xx = x - xo_ - width(); - - if (y < yo_ - ascent()) - yy = yo_ - ascent() - y; - else if (y > yo_ + descent()) - yy = y - yo_ - descent(); - - return xx + yy; -} - - -void MathArray::setXY(BufferView & bv, int x, int y) const -{ - //lyxerr << "setting position cache for MathArray " << this << std::endl; - bv.coordCache().arrays().add(this, x, y); -} - - -int MathArray::xo(BufferView const & bv) const -{ - return bv.coordCache().getArrays().x(this); -} - - -int MathArray::yo(BufferView const & bv) const -{ - return bv.coordCache().getArrays().y(this); -} - - -std::ostream & operator<<(std::ostream & os, MathArray const & ar) -{ - odocstringstream oss; - NormalStream ns(oss); - ns << ar; - return os << to_utf8(oss.str()); -} - - -odocstream & operator<<(odocstream & os, MathArray const & ar) -{ - NormalStream ns(os); - ns << ar; - return os; -} - - -} // namespace lyx diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h deleted file mode 100644 index 5582a46828..0000000000 --- a/src/mathed/MathData.h +++ /dev/null @@ -1,188 +0,0 @@ -// -*- C++ -*- -/** - * \file MathArray.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Alejandro Aguilar Sierra - * \author André Pönitz - * \author Lars Gullik Bjønnes - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef MATH_DATA_H -#define MATH_DATA_H - -#include - -#include "MathAtom.h" -#include "dimension.h" - -#include "support/docstream.h" - - -namespace lyx { - -class BufferView; -class LaTeXFeatures; -class ReplaceData; -class MetricsInfo; -class PainterInfo; -class TextMetricsInfo; -class TextPainter; - - -class MathArray : private std::vector { -public: - /// re-use inhertited stuff - typedef std::vector base_type; - using base_type::const_iterator; - using base_type::iterator; - using base_type::size_type; - using base_type::difference_type; - using base_type::size; - using base_type::empty; - using base_type::clear; - using base_type::begin; - using base_type::end; - using base_type::push_back; - using base_type::pop_back; - using base_type::back; - using base_type::front; - /// - typedef size_type idx_type; - typedef size_type pos_type; - -public: - /// - MathArray() {} - /// - MathArray(const_iterator from, const_iterator to); - /// - void append(MathArray const & ar); - - /// inserts single atom at position pos - void insert(size_type pos, MathAtom const & at); - /// inserts multiple atoms at position pos - void insert(size_type pos, MathArray const & ar); - - /// erase range from pos1 to pos2 - void erase(iterator pos1, iterator pos2); - /// erase single atom - void erase(iterator pos); - /// erase range from pos1 to pos2 - void erase(size_type pos1, size_type pos2); - /// erase single atom - void erase(size_type pos); - - /// - void dump() const; - /// - void dump2() const; - /// - void replace(ReplaceData &); - /// - void substitute(MathArray const & m); - - /// looks for exact match - bool match(MathArray const & ar) const; - /// looks for inclusion match starting at pos - bool matchpart(MathArray const & ar, pos_type pos) const; - /// looks for containment, return == size mean not found - size_type find(MathArray const & ar) const; - /// looks for containment, return == size mean not found - size_type find_last(MathArray const & ar) const; - /// - bool contains(MathArray const & ar) const; - /// - void validate(LaTeXFeatures &) const; - - /// checked write access - MathAtom & operator[](pos_type); - /// checked read access - MathAtom const & operator[](pos_type) const; - /// rebuild cached metrics information - void metrics(MetricsInfo & mi) const; - /// rebuild cached metrics information - bool metrics(MetricsInfo & mi, Dimension & dim) const; - /// redraw cell using cache metrics information - void draw(PainterInfo & pi, int x, int y) const; - /// rebuild cached metrics information - void metricsT(TextMetricsInfo const & mi, Dimension & dim) const; - /// redraw cell using cache metrics information - void drawT(TextPainter & pi, int x, int y) const; - /// mark cell for re-drawing - void touch() const; - - /// access to cached x coordinate of last drawing - int xo(BufferView const & bv) const; - /// access to cached y coordinate of last drawing - int yo(BufferView const & bv) const; - /// access to cached x coordinate of mid point of last drawing - int xm(BufferView const & bv) const { return xo(bv) + dim_.wid / 2; } - /// access to cached y coordinate of mid point of last drawing - int ym(BufferView const & bv) const { return yo(bv) + (dim_.des - dim_.asc) / 2; } - /// write access to coordinate; - void setXY(BufferView & bv, int x, int y) const; - /// returns x coordinate of given position in the array - int pos2x(size_type pos) const; - /// returns position of given x coordinate - int pos2x(size_type pos, int glue) const; - /// returns position of given x coordinate - size_type x2pos(int pos) const; - /// returns position of given x coordinate fstarting from a certain pos - size_type x2pos(int targetx, int glue) const; - /// returns distance of this cell to the point given by x and y - // assumes valid position and size cache - int dist(BufferView const & bv, int x, int y) const; - - /// ascent of this cell above the baseline - int ascent() const { return dim_.asc; } - /// descent of this cell below the baseline - int descent() const { return dim_.des; } - /// height of the cell - int height() const { return dim_.asc + dim_.des; } - /// width of this cell - int width() const { return dim_.wid; } - /// dimensions of cell - Dimension const & dim() const { return dim_; } - /// dimensions of cell - void setDim(Dimension const & d) const { dim_ = d; } - /// minimum ascent offset for superscript - int minasc() const { return minasc_; } - /// minimum descent offset for subscript - int mindes() const { return mindes_; } - /// level above/below which super/subscript should extend - int slevel() const { return slevel_; } - /// additional super/subscript shift - int sshift() const { return sshift_; } - /// superscript kerning - int kerning() const { return kerning_; } - /// - void swap(MathArray & ar) { base_type::swap(ar); } - -protected: - /// cached dimensions of cell - mutable Dimension dim_; - /// cached values for super/subscript placement - mutable int minasc_; - mutable int mindes_; - mutable int slevel_; - mutable int sshift_; - mutable int kerning_; - -private: - /// is this an exact match at this position? - bool find1(MathArray const & ar, size_type pos) const; -}; - -/// -std::ostream & operator<<(std::ostream & os, MathArray const & ar); -/// -odocstream & operator<<(odocstream & os, MathArray const & ar); - - -} // namespace lyx - -#endif diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp new file mode 100644 index 0000000000..1cde0ecfd8 --- /dev/null +++ b/src/mathed/MathMacro.cpp @@ -0,0 +1,290 @@ +/** + * \file MathMacro.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Alejandro Aguilar Sierra + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "MathMacro.h" +#include "MathSupport.h" +#include "MathExtern.h" +#include "MathStream.h" + +#include "buffer.h" +#include "cursor.h" +#include "debug.h" +#include "BufferView.h" +#include "LaTeXFeatures.h" +#include "frontends/Painter.h" + + +namespace lyx { + +using std::string; +using std::max; +using std::auto_ptr; +using std::endl; +using std::vector; + + +/// This class is the value of a macro argument, technically +/// a wrapper of the cells of MathMacro. +class MathMacroArgumentValue : public InsetMathDim { +public: + /// + MathMacroArgumentValue(MathArray const * value, docstring const & macroName) + : value_(value), macroName_(macroName) {} + /// + bool metrics(MetricsInfo & mi, Dimension & dim) const; + /// + void draw(PainterInfo &, int x, int y) const; + +private: + std::auto_ptr doClone() const; + MathArray const * value_; + docstring macroName_; +}; + + +auto_ptr MathMacroArgumentValue::doClone() const +{ + return auto_ptr(new MathMacroArgumentValue(*this)); +} + + +bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const +{ + // unlock outer macro in arguments, and lock it again later + MacroTable::globalMacros().get(macroName_).unlock(); + value_->metrics(mi, dim); + MacroTable::globalMacros().get(macroName_).lock(); + metricsMarkers2(dim); + if (dim_ == dim) + return false; + dim_ = dim; + return true; +} + + +void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const +{ + // unlock outer macro in arguments, and lock it again later + MacroTable::globalMacros().get(macroName_).unlock(); + value_->draw(pi, x, y); + MacroTable::globalMacros().get(macroName_).lock(); +} + + +MathMacro::MathMacro(docstring const & name, int numargs) + : InsetMathNest(numargs), name_(name) +{} + + +auto_ptr MathMacro::doClone() const +{ + return auto_ptr(new MathMacro(*this)); +} + + +docstring MathMacro::name() const +{ + return name_; +} + + +void MathMacro::cursorPos(BufferView const & bv, + CursorSlice const & sl, bool boundary, int & x, int & y) const +{ + // We may have 0 arguments, but InsetMathNest requires at least one. + if (nargs() > 0) + InsetMathNest::cursorPos(bv, sl, boundary, x, y); +} + + +bool MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const +{ + if (!MacroTable::globalMacros().has(name())) { + mathed_string_dim(mi.base.font, "Unknown: " + name(), dim); + } else { + MacroData const & macro = MacroTable::globalMacros().get(name()); + if (macro.locked()) { + mathed_string_dim(mi.base.font, "Self reference: " + name(), dim); + expanded_ = MathArray(); + } else if (editing(mi.base.bv)) { + // FIXME UNICODE + asArray(macro.def(), tmpl_); + LyXFont font = mi.base.font; + augmentFont(font, from_ascii("lyxtex")); + tmpl_.metrics(mi, dim); + // FIXME UNICODE + dim.wid += mathed_string_width(font, name()) + 10; + // FIXME UNICODE + int ww = mathed_string_width(font, from_ascii("#1: ")); + for (idx_type i = 0; i < nargs(); ++i) { + MathArray const & c = cell(i); + c.metrics(mi); + dim.wid = max(dim.wid, c.width() + ww); + dim.des += c.height() + 10; + } + } else { + // create MathMacroArgumentValue object pointing to the cells of the macro + MacroData const & macro = MacroTable::globalMacros().get(name()); + vector values(nargs()); + for (size_t i = 0; i != nargs(); ++i) + values[i].insert(0, MathAtom(new MathMacroArgumentValue(&cells_[i], name()))); + macro.expand(values, expanded_); + + MacroTable::globalMacros().get(name()).lock(); + expanded_.metrics(mi, dim); + MacroTable::globalMacros().get(name()).unlock(); + } + } + metricsMarkers2(dim); + if (dim_ == dim) + return false; + dim_ = dim; + return true; +} + + +void MathMacro::draw(PainterInfo & pi, int x, int y) const +{ + if (!MacroTable::globalMacros().has(name())) { + // FIXME UNICODE + drawStrRed(pi, x, y, "Unknown: " + name()); + } else { + MacroData const & macro = MacroTable::globalMacros().get(name()); + if (macro.locked()) { + // FIXME UNICODE + drawStrRed(pi, x, y, "Self reference: " + name()); + } else if (editing(pi.base.bv)) { + LyXFont font = pi.base.font; + augmentFont(font, from_ascii("lyxtex")); + int h = y - dim_.ascent() + 2 + tmpl_.ascent(); + pi.pain.text(x + 3, h, name(), font); + int const w = mathed_string_width(font, name()); + tmpl_.draw(pi, x + w + 12, h); + h += tmpl_.descent(); + Dimension ldim; + docstring t = from_ascii("#1: "); + mathed_string_dim(font, t, ldim); + for (idx_type i = 0; i < nargs(); ++i) { + MathArray const & c = cell(i); + h += max(c.ascent(), ldim.asc) + 5; + c.draw(pi, x + ldim.wid, h); + char_type str[] = { '#', '1', ':', '\0' }; + str[1] += static_cast(i); + pi.pain.text(x + 3, h, str, font); + h += max(c.descent(), ldim.des) + 5; + } + } else { + MacroTable::globalMacros().get(name()).lock(); + expanded_.draw(pi, x, y); + MacroTable::globalMacros().get(name()).unlock(); + } + } + drawMarkers2(pi, x, y); +} + + +void MathMacro::drawSelection(PainterInfo & pi, int x, int y) const +{ + // We may have 0 arguments, but InsetMathNest requires at least one. + if (nargs() > 0) + InsetMathNest::drawSelection(pi, x, y); +} + + +void MathMacro::validate(LaTeXFeatures & features) const +{ + if (name() == "binom" || name() == "mathcircumflex") + features.require(to_utf8(name())); +} + + +InsetBase * MathMacro::editXY(LCursor & cur, int x, int y) +{ + // We may have 0 arguments, but InsetMathNest requires at least one. + if (nargs() > 0) { + // Prevent crash due to cold coordcache + // FIXME: This is only a workaround, the call of + // InsetMathNest::editXY is correct. The correct fix would + // ensure that the coordcache of the arguments is valid. + if (!editing(&cur.bv())) { + edit(cur, true); + return this; + } + return InsetMathNest::editXY(cur, x, y); + } + return this; +} + + +bool MathMacro::idxFirst(LCursor & cur) const +{ + cur.updateFlags(Update::Force); + return InsetMathNest::idxFirst(cur); +} + + +bool MathMacro::idxLast(LCursor & cur) const +{ + cur.updateFlags(Update::Force); + return InsetMathNest::idxLast(cur); +} + + +bool MathMacro::notifyCursorLeaves(LCursor & cur) +{ + cur.updateFlags(Update::Force); + return InsetMathNest::notifyCursorLeaves(cur); +} + + +void MathMacro::maple(MapleStream & os) const +{ + updateExpansion(); + lyx::maple(expanded_, os); +} + + +void MathMacro::mathmlize(MathStream & os) const +{ + updateExpansion(); + lyx::mathmlize(expanded_, os); +} + + +void MathMacro::octave(OctaveStream & os) const +{ + updateExpansion(); + lyx::octave(expanded_, os); +} + + +void MathMacro::updateExpansion() const +{ + //expanded_.substitute(*this); +} + + +void MathMacro::infoize(odocstream & os) const +{ + os << "Macro: " << name(); +} + + +void MathMacro::infoize2(odocstream & os) const +{ + os << "Macro: " << name(); + +} + + +} // namespace lyx diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h new file mode 100644 index 0000000000..b4ff0a4041 --- /dev/null +++ b/src/mathed/MathMacro.h @@ -0,0 +1,90 @@ +// -*- C++ -*- +/** + * \file MathMacro.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Alejandro Aguilar Sierra + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATH_MACRO_H +#define MATH_MACRO_H + +#include "InsetMathNest.h" +#include "MathArray.h" +#include "InsetMathNest.h" +#include "MathMacroTable.h" + + +namespace lyx { + + +/// This class contains the data for a macro. +class MathMacro : public InsetMathNest { +public: + /// A macro can be built from an existing template + MathMacro(docstring const & name, int numargs); + /// + void draw(PainterInfo & pi, int x, int y) const; + /// + void drawExpanded(PainterInfo & pi, int x, int y) const; + /// draw selection background + void drawSelection(PainterInfo & pi, int x, int y) const; + /// draw decorations. + void drawDecoration(PainterInfo & pi, int x, int y) const + { drawMarkers2(pi, x, y); } + /// + bool metrics(MetricsInfo & mi, Dimension & dim) const; + /// get cursor position + void cursorPos(BufferView const & bv, CursorSlice const & sl, + bool boundary, int & x, int & y) const; + /// + InsetBase * editXY(LCursor & cur, int x, int y); + /// target pos when we enter the inset from the left by pressing "Right" + bool idxFirst(LCursor &) const; + /// target pos when we enter the inset from the right by pressing "Left" + bool idxLast(LCursor &) const; + /// + virtual bool notifyCursorLeaves(LCursor &); + /// + docstring name() const; + /// + void setExpansion(MathArray const & exp, MathArray const & args) const; + + /// + void validate(LaTeXFeatures &) const; + + /// + void maple(MapleStream &) const; + /// + void mathmlize(MathStream &) const; + /// + void octave(OctaveStream &) const; + /// + void infoize(odocstream &) const; + /// + void infoize2(odocstream &) const; + +private: + virtual std::auto_ptr doClone() const; + /// + void updateExpansion() const; + /// + void expand() const; + + /// name of macro + docstring name_; + /// the unexpanded macro defintition + mutable MathArray tmpl_; + /// the macro substituted with our args + mutable MathArray expanded_; +}; + + + + +} // namespace lyx +#endif diff --git a/src/mathed/MathReplace.h b/src/mathed/MathReplace.h deleted file mode 100644 index dc8eb6b68f..0000000000 --- a/src/mathed/MathReplace.h +++ /dev/null @@ -1,32 +0,0 @@ -// -*- C++ -*- -/** - * \file ReplaceData.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef MATH_REPLACE_H -#define MATH_REPLACE_H - - -#include "MathArray.h" - - -namespace lyx { - -class ReplaceData { -public: - /// - MathArray from; - /// - MathArray to; -}; - - -} // namespace lyx - -#endif diff --git a/src/mathed/ReplaceData.h b/src/mathed/ReplaceData.h new file mode 100644 index 0000000000..dc8eb6b68f --- /dev/null +++ b/src/mathed/ReplaceData.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +/** + * \file ReplaceData.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATH_REPLACE_H +#define MATH_REPLACE_H + + +#include "MathArray.h" + + +namespace lyx { + +class ReplaceData { +public: + /// + MathArray from; + /// + MathArray to; +}; + + +} // namespace lyx + +#endif