Exemplo n.º 1
0
static ERL_NIF_TERM element_to(ErlNifEnv* env, int argc,
			       const ERL_NIF_TERM argv[],
			       int as_string)
{
  ErlNifBinary output;
  ERL_NIF_TERM result;
  struct buf *rbuf;

  if (argc == 1) {
    rbuf = init_buf(env);
    if (make_element(env, rbuf, argv[0])) {
      if (as_string) {
	(rbuf->b)[rbuf->len] = 0;
	result = enif_make_string(env, (char *) rbuf->b, ERL_NIF_LATIN1);
	destroy_buf(env, rbuf);
	return result;
      }	else {
	if (ENIF_ALLOC_BINARY(rbuf->len, &output)) {
	  memcpy(output.data, rbuf->b, rbuf->len);
	  result = enif_make_binary(env, &output);
	  destroy_buf(env, rbuf);
	  return result;
	};
      };
    };
    destroy_buf(env, rbuf);
  };
  
  return enif_make_badarg(env);
}
Exemplo n.º 2
0
static int make_elements(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM els)
{
  ERL_NIF_TERM head, tail;
  int ret = 0;

  while (enif_get_list_cell(env, els, &head, &tail)) {
    ret = make_element(env, rbuf, head);
    if (ret) {
      els = tail;
    } else {
      break;
    };
  };

  return ret;
}
Exemplo n.º 3
0
//
// Generate indexes using our own internal method:
//
void generate_indexes()
{
   for(boost::tiny_xml::element_list::const_iterator i = indexes.begin(); i != indexes.end(); ++i)
   {
      boost::tiny_xml::element_ptr node = *i;
      const std::string* category = find_attr(node, "type");
      bool has_title = false;

      for(boost::tiny_xml::element_list::const_iterator k = (*i)->elements.begin(); k != (*i)->elements.end(); ++k)
      {
         if((**k).name == "title")
         {
            has_title = true;
            break;
         }
      }

      boost::tiny_xml::element_ptr navbar = make_element("para");
      node->elements.push_back(navbar);

      index_entry_set::const_iterator m = index_entries.begin();
      index_entry_set::const_iterator n = m;
      boost::tiny_xml::element_ptr vlist = make_element("variablelist");
      node->elements.push_back(vlist);
      while(n != index_entries.end())
      {
         char current_letter = std::toupper((*n)->key[0]);
         std::string id_name = get_next_index_id();
         boost::tiny_xml::element_ptr entry = add_attribute(make_element("varlistentry"), "id", id_name);
         boost::tiny_xml::element_ptr term = make_element("term");
         term->content = std::string(1, current_letter);
         entry->elements.push_back(term);
         boost::tiny_xml::element_ptr item = make_element("listitem");
         entry->elements.push_back(item);
         while((n != index_entries.end()) && (std::toupper((*n)->key[0]) == current_letter))
            ++n;
         std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> range(m, n);
         item->elements.push_back(generate_entry(range, category));
         if(item->elements.size() && (*item->elements.begin())->elements.size())
         {
            vlist->elements.push_back(entry);
            boost::tiny_xml::element_ptr p = make_element("");
            p->content = " ";
            if(navbar->elements.size())
            {
               navbar->elements.push_back(p);
            }
            p = add_attribute(make_element("link"), "linkend", id_name);
            p->content = current_letter;
            navbar->elements.push_back(p);
         }
         m = n;
      }

      node->name = internal_index_type;
      boost::tiny_xml::element_ptr p(node->parent);
      while(p->name.empty())
         p = boost::tiny_xml::element_ptr(p->parent);
      check_index_type_and_placement(p->name, node->name);
      node->attributes.clear();
      if(!has_title)
      {
         boost::tiny_xml::element_ptr t = make_element("title");
         t->content = "Index";
         node->elements.push_front(t);
      }
   }
}
Exemplo n.º 4
0
boost::tiny_xml::element_ptr generate_entry(const Range& range, const std::string* pcategory, int level = 0, const boost::regex* primary_key = 0)
{
   boost::tiny_xml::element_ptr list = add_attribute(add_attribute(::add_attribute(make_element("itemizedlist"), "mark", "none"), "spacing", "compact"), "role", "index");

   for(typename boost::range_iterator<Range>::type i = boost::begin(range); i != boost::end(range);)
   {
      std::string key = (*i)->key;
      index_entry_set entries;
      bool preferred = false;
      std::string id;
      bool collapse = false;
      
      //
      // Create a regular expression for comparing key to other key's:
      //
      boost::regex key_regex;
      if(level == 0)
      {
         key_regex = make_primary_key_matcher(key);
         primary_key = &key_regex;
      }
      //
      // Begin by consolidating entries with identical keys but possibly different categories:
      //
      while((i != boost::end(range)) && ((*i)->key == key))
      {
         if((0 == pcategory) || (pcategory->size() == 0) || (pcategory && (**i).category == *pcategory))
         {
            entries.insert((*i)->sub_keys.begin(), (*i)->sub_keys.end());
            if((*i)->preferred)
               preferred = true;
            if((*i)->id.size())
            {
               if(id.size())
               {
                  std::cerr << "WARNING: two identical index terms have different link destinations!!" << std::endl;
               }
               id = (*i)->id;
            }
         }
         ++i;
      }
      //
      // Only actually generate content if we have anything in the entries set:
      //
      if(entries.size() || id.size())
      {
         //
         // See if we can collapse any sub-entries into this one:
         //
         if(entries.size() == 1)
         {
            if((regex_match((*entries.begin())->key, *primary_key) || ((*entries.begin())->key == key)) 
               && ((*entries.begin())->id.size()) 
               && ((*entries.begin())->id != id))
            {
               collapse = true;
               id = (*entries.begin())->id;
            }
         }
         //
         // See if this key is the same as the primary key, if it is then make it prefered:
         //
         if(level && regex_match(key, *primary_key))
         {
            preferred = true;
         }
         boost::tiny_xml::element_ptr item = make_element("listitem");
         boost::tiny_xml::element_ptr para = make_element("para");
         item->elements.push_back(para);
         list->elements.push_back(item);
         if(preferred)
         {
            para->elements.push_back(make_element("emphasis"));
            para = para->elements.back();
         }
         if(id.size())
         {
            boost::tiny_xml::element_ptr link = add_attribute(make_element("link"), "linkend", id);
            para->elements.push_back(link);
            para = link;
         }
         std::string classname = (boost::format("index-entry-level-%1%") % level).str();
         para->elements.push_back(add_attribute(make_element("phrase"), "role", classname));
         para = para->elements.back();
         para->content = key;
         if(!collapse && entries.size())
         {
            std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> subrange(entries.begin(), entries.end());
            item->elements.push_back(generate_entry(subrange, 0, level+1, primary_key));
         }
      }
   }
   return list;
}