⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 format.c

📁 将HTML转换为TXT文件的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
}static charget_link_cell_attributes(const string &href){  if (href.at(0) == '#') {    static const char internal_link_attributes =      Formatting::getAttributes("A.attributes.internal_link", Cell::UNDERLINE);    return internal_link_attributes;  } else {    static const char external_link_attributes =      Formatting::getAttributes("A.attributes.external_link", Cell::UNDERLINE);    return external_link_attributes;  }}// Attributes: NAME HREF REL REV TITLE (ignored)Line *Anchor::line_format() const{  auto_ptr<Line> res(::line_format(texts.get()));  if (!res.get()) return 0;  string href(get_attribute(attributes.get(), "HREF", ""));  if (!href.empty()) res->add_attribute(get_link_cell_attributes(href));  return res.release();}Area *Anchor::format(Area::size_type w, int halign) const{  auto_ptr<Area> res(::format(texts.get(), w, halign));  if (!res.get()) return 0;  string href(get_attribute(attributes.get(), "HREF", ""));  if (!href.empty()) res->add_attribute(get_link_cell_attributes(href));  return res.release();}// Attributes: CLEAR (ignored)Line *LineBreak::line_format() const{  return new Line("\n");}Area *TableHeadingCell::format(Area::size_type w, int halign) const{  Area *a = TableCell::format(w, halign);  if (a) a->add_attribute(Cell::BOLD);  return a;}Area *Caption::format(Area::size_type w, int halign) const{  auto_ptr<Line> l(::line_format(texts.get()));  return l.get() ? make_up(*l, w, halign) : 0;}// Attributes: (none)Line *NoBreak::line_format() const{  Line *l(::line_format(content.get()));  if (!l) return 0;  for (Line::size_type i = 0; i < l->length(); ++i) {    Cell &c((*l)[i]);    if (c.character == ' ') c.character = LATIN1_nbsp;  }  return l;}/* ------------------------------------------------------------------------- *//* * Make up "line" into an Area. Attempt to return an Area no wider than "w". */static Area *make_up(const Line &line, Area::size_type w, int halign){//{//  cout << "make_up(\"";//  for (Line::size_type i = 0; i < line.length(); i++) {//    if (isprint(line[i].character)) cout << line[i].character;//    else cout << "[" << (int) line[i].character << "]";//  }//  cout << "\")" << endl;//}  if (line.empty()) return 0;  auto_ptr<Area> res(new Area);  Line::size_type from = 0;  while (from < line.length()) {    /*     * A sole newline character has a special meaning: Append a blank line.     */    if (line[from].character == '\n') {      res->resize(res->width(), res->height() + 1);      from++;      continue;    }    Line::size_type to = from + 1;    Line::size_type lbp = (Line::size_type) -1; // "Last break position".    /*     * Determine the line break position.     */    while (to < line.length()) {      if (line[to].character == '\n') {        break;      }      char c1 = line[to].character, c2 = line[to - 1].character;      if (c1 == ' ' || c1 == '('/*)*/ || c1 == '['/*]*/ || c1 == '{'/*}*/ || (        (          c2 == '-' ||          c2 == '/' ||          c2 == ':'        ) &&        c1 != ',' &&        c1 != '.' &&        c1 != ';' &&        c1 != ':'      )) {        lbp = to++;        while (to < line.length() && line[to].character == ' ') to++;      } else {        to++;      }      if (to - from > w && lbp != (Area::size_type) -1) { to = lbp; break; }    }    /*     * Copy the "from...to" range from the "line" to the bottom of the "res"     * Area.     */    Area::size_type x = 0;    Area::size_type len = to - from;    if (halign == Area::LEFT || len >= w) { ;                   } else    if (halign == Area::CENTER)           { x += (w - len) / 2; } else    if (halign == Area::RIGHT)            { x += w - len;       }    res->insert(line.cells() + from, len, x, res->height());    /*     * Determine the beginnning of the next line.     */    if (to == line.length()) break;    from = to;    if (line[from].character == '\n') {      ++from;    } else    if (line[from].character == ' ') {      do {        ++from;      } while (from < line.length() && line[from].character == ' ');    }  }  return res.release();}/* ------------------------------------------------------------------------- *//* * Attempt to line-format all "elements". If one of the elements can only be * area-formatted, return null. In that case, "::format()" (below) will * probably work. */static Line *line_format(const list<auto_ptr<Element> > *elements){  auto_ptr<Line> res;  if (elements) {    list<auto_ptr<Element> >::const_iterator i;    for (i = elements->begin(); i != elements->end(); ++i) {      auto_ptr<Line> l((*i)->line_format());      if (!l.get()) {        auto_ptr<Area> a((*i)->format(100, Area::LEFT));        if (a.get()) return 0;        continue;      }      if (res.get()) { *res += *l; } else { res = l; }    }  }  return res.release();}/* ------------------------------------------------------------------------- *//* * Basically, a list of "Text"s is a stream of words that has to be formatted * into an area. But... as an extension to HTML 3.2 we want to allow "Block"s * be embedded in "Text", e.g. * *        <FONT COLOR=red><P>Bla</P><P>Bloh</P></FONT> * * Attempt to line-format the "Text". This will fail if there is a "Block" * inside the "Text". * * The "Text" could not be line-formatted, so... append a line-break and * the area-formatted "Text". */static Area *format(  const list<auto_ptr<Element> > *elements,  Area::size_type                w,  int                            halign){  if (!elements) return 0;  auto_ptr<Area> res;  auto_ptr<Line> line;  list<auto_ptr<Element> >::const_iterator i;  for (i = elements->begin(); i != elements->end(); ++i) {    if (!(*i).get()) continue;    auto_ptr<Line> l((*i)->line_format());    if (l.get()) {      if (line.get()) { *line += *l; } else { line = l; }      continue;    }    auto_ptr<Area> a((*i)->format(w, halign));    if (a.get()) {      if (line.get()) {        auto_ptr<Area> a2(make_up(*line, w, halign));        if (a2.get()) {          if (res.get()) { *res += *a2; } else { res = a2; }        }        line.reset();      }      if (res.get()) { *res += *a; } else { res = a; }    }  }  if (line.get()) {    auto_ptr<Area> a2(make_up(*line, w, halign));    if (a2.get()) {      if (res.get()) { *res += *a2; } else { res = a2; }\    }  }  return res.release();}/* * A copy of the above function, but the formatted text is printed to "os" * rather than into an Area. */static voidformat(  const list<auto_ptr<Element> > *elements,  Area::size_type                indent_left,  Area::size_type                w,  int                            halign,  ostream                        &os){  if (!elements) return;  auto_ptr<Line> line;  list<auto_ptr<Element> >::const_iterator i;  for (i = elements->begin(); i != elements->end(); ++i) {    if (!(*i).get()) continue;    auto_ptr<Line> l((*i)->line_format());    if (l.get()) {      if (line.get()) { *line += *l; } else { line = l; }      continue;    }    auto_ptr<Area> a((*i)->format(w, halign));    if (a.get()) {      if (line.get()) {        auto_ptr<Area> a2(make_up(*line, w, halign));        if (a2.get()) {	  *a2 >>= indent_left;          os << *a2 << flush;        }        line.reset();      }      *a >>= indent_left;      os << *a << flush;    }  }  if (line.get()) {    auto_ptr<Area> a2(make_up(*line, w, halign));    if (a2.get()) {      *a2 >>= indent_left;      os << *a2 << flush;    }  }}/* ------------------------------------------------------------------------- */static Properties formatting_properties;/* ----------------------- *//*static*/ voidFormatting::setProperty(const char *key, const char *value){  formatting_properties.setProperty(key, value);}/* ----------------------- *//*static*/ voidFormatting::loadProperties(istream &is){  formatting_properties.load(is);}/* ----------------------- *//*static*/ const char *Formatting::getString(const char *key, const char *dflt){  return formatting_properties.getProperty(key, dflt);}/* ----------------------- *//* * Property not set                               => 0 * Property contains only white-space             => 0 * Property conains one non-white-space character => { "x" } *//*static*/ vector<string> *Formatting::getStringVector(const char *key, const char *dflt){  const char *p = formatting_properties.getProperty(key, dflt);  if (!p) return 0;  vector<string> *res = 0;  for (;;) {    while (isspace(*p)) ++p;    if (!*p) break;    const char *q = p + 1;    while (*q && !isspace(*q)) ++q;    if (!res) res = new vector<string>;    res->push_back(string(p, q - p));    p = q;  }  return res;}/* ----------------------- *//*static*/ intFormatting::getInt(const char *key, int dflt){  const char *p = formatting_properties.getProperty(key, 0);  return p ? atoi(p) : dflt;}/* ----------------------- *//*static*/ vector<int> *Formatting::getIntVector(const char *key, const char *dflt){  const char *p = formatting_properties.getProperty(key, dflt);  if (!p) return 0;  vector<int> *res = 0;  for (;;) {    while (isspace(*p)) ++p;    if (!*p) break;    if (!res) res = new vector<int>;    res->push_back(atoi(p));    ++p;    while (*p && !isspace(*p)) ++p;  }  return res;}/* ----------------------- *//*static*/ charFormatting::getAttributes(const char *key, char dflt){  auto_ptr<vector<string> > v(getStringVector(key, 0));  if (!v.get() || v->empty()) return dflt;  char res = Cell::NONE;  for (vector<string>::const_iterator i = v->begin(); i != v->end(); ++i) {    if (!cmp_nocase(*i, "NONE"))               res = Cell::NONE;    else if (!cmp_nocase(*i, "BOLD"))          res |= Cell::BOLD;    else if (!cmp_nocase(*i, "UNDERLINE"))     res |= Cell::UNDERLINE;    else if (!cmp_nocase(*i, "STRIKETHROUGH")) res |= Cell::STRIKETHROUGH;    else ;  }  return res;}/* ------------------------------------------------------------------------- */BlockFormat::BlockFormat(  const char      *item_name,  Area::size_type default_vspace_before /* = 0 */ ,  Area::size_type default_vspace_after  /* = 0 */ ,  Area::size_type default_indent_left   /* = 0 */ ,  Area::size_type default_indent_right  /* = 0 */){  char lb[80];  sprintf(lb, "%s.vspace.before", item_name);  vspace_before = Formatting::getInt(lb, default_vspace_before);  sprintf(lb, "%s.vspace.after", item_name);  vspace_after = Formatting::getInt(lb, default_vspace_after);  sprintf(lb, "%s.indent.left", item_name);  indent_left = Formatting::getInt(lb, default_indent_left);  sprintf(lb, "%s.indent.right", item_name);  indent_right = Formatting::getInt(lb, default_indent_right);}Area::size_typeBlockFormat::effective_width(Area::size_type w) const{  /*   * No problem if "w" is wide enough...   */  if (indent_left + 10 + indent_right <= w) {    return w - indent_left - indent_right;  }  /*   * Does reducing the right indent help?   */  if (indent_left + 10 <= w) return 10;  /*   * Do it with right indent == 0.   */  if (indent_left + 1 <= w) return w - indent_left;  /*   * Even that doesn't help, return "1".   */  return 1;}/* ------------------------------------------------------------------------- */ListFormat::ListFormat(  const char      *item_name,  Area::size_type default_vspace_before  /* = 0 */ ,  Area::size_type default_vspace_between /* = 0 */ ,  Area::size_type default_vspace_after   /* = 0 */ ,  const char      *default_indents       /* = "6" */ ,  const char      *default_default_types /* = "DISC CIRCLE SQUARE" */){  char lb[80];  sprintf(lb, "%s.vspace.before", item_name);  vspace_before  = Formatting::getInt(lb, default_vspace_before );  sprintf(lb, "%s.vspace.between", item_name);  vspace_between = Formatting::getInt(lb, default_vspace_between);  sprintf(lb, "%s.vspace.after", item_name);  vspace_after   = Formatting::getInt(lb, default_vspace_after  );  sprintf(lb, "%s.indents", item_name);  indents.reset(Formatting::getIntVector(lb, default_indents));  sprintf(lb, "%s.default_types", item_name);  default_types.reset(Formatting::getStringVector(lb, default_default_types));}Area::size_typeListFormat::get_indent(int nesting) const{  return (    (!indents.get() || indents.get()->empty()) ? 6 :    nesting < indents->size() ? (*indents)[nesting] :    indents->back()  );}intListFormat::get_type(  const list<TagAttribute> *attributes,  int                      nesting,  int                      default_default_type) const{  const char *default_type = (    !default_types.get() || default_types->empty() ? 0 :    nesting < default_types->size() ?    (*default_types)[nesting].c_str() :    default_types->back().c_str()  );  return get_attribute(    attributes, "TYPE",    default_type,         // dflt1    default_default_type, // dflt2, if dflt1 fails    "NO_BULLET", NO_BULLET,    "DISC",      DISC,    "SQUARE",    SQUARE,    "CIRCLE",    CIRCLE,    "CUSTOM1",   CUSTOM1,    "CUSTOM2",   CUSTOM2,    "CUSTOM3",   CUSTOM3,    "1",         ARABIC_NUMBERS,    "a",         LOWER_ALPHA,    "A",         UPPER_ALPHA,    "i",         LOWER_ROMAN,    "I",         UPPER_ROMAN,    0  );}/* ------------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -