Getting garbage when reading string from std::smatch - c++

I'm trying to fix a memory issue, I think, for several hours now and I can't understand the issue of the problem.
I have a classes StaticTag and ExtendsTag that I create with result of std::smatch (<regex>). Method creating StaticTag always works, but method creating ExtendsTag never works. The only difference is regular expression which works all the time because the substring is matched. Problem here is even printing a captured group which mostly all the time gives me a garbage with suffix of correct string. Here is the code.
Execution of two methods find_static_tag and find_extends_tag (the latter does not work):
StaticTag static_tag;
if (Regex::find_static_tag(this->_content, static_tag)) {
}
ExtendsTag extends_tag;
if (Regex::find_extends_tag(this->_content, extends_tag)) {
}
Both methods presented below:
bool Regex::find_extends_tag(std::string in, ExtendsTag& tag) {
std::string pattern = "\\{%\\s*extends\\s+\"(\\S+)\"\\s*%\\}";
std::smatch match;
if (Regex::find_first(pattern, in, match)) {
std::cout << match[1] << std::endl;
tag = ExtendsTag(match[1], match.position(), match.length());
return true;
}
return false;
}
bool Regex::find_static_tag(std::string in, StaticTag& tag) {
std::string pattern = "\\{%\\s*static\\s+\"(\\S+)\"\\s*%\\}";
std::smatch match;
if (Regex::find_first(pattern, in, match)) {
std::cout << match[1] << std::endl;
tag = StaticTag(match[1], match.position(), match.length());
return true;
}
return false;
}
They need to match: {% static "style.css" %} and {% extends "master.html" %}.
Usually I got something like this instead of "master.html": �0e.html.
I think it might be memory issue, but I don't know where to start because two methods looks identical for me. It is not about creating objects of StaticTag and ExtendsTag, it fails printing match[1] in find_extends_tag method.
EDIT: Look like when I change from static to extends in the second method the result is the same. Is this something wrong with <regex> then?
Thank you for your help in advance!
The file I am trying to parse:
{% extends "master.html" %}
{% block content %}
<p>Hello ios/index.html</p>
<img src="{% static "html-css.png" %}"/>
{% endblock %}
EDIT 2:
Not sure why it started to work. I took out implementation of Regex::find_first(pattern, in, match) and put it directly in find_static_tag and find_extends_tag and it started to work correctly.
Here is implementation of find_extends_tag that works always:
bool Regex::find_extends_tag(std::string in, ExtendsTag& tag) {
std::smatch match;
if (std::regex_search(in, match, std::regex("\\{%\\s*extends\\s+\"(\\S+)\"\\s*%\\}"))) {
tag = ExtendsTag(match[1], match.position(), match.length());
return true;
}
return false;
}
Not sure what's the difference here.

Related

can't get xhtml <script> content with libxml++ using xpath expression

#include <libxml++/libxml++.h>
xmlpp::NodeSet xmlP(std::string xml_string, std::string xpath) {
xmlpp::DomParser doc;
// 'response' contains your HTML
doc.parse_memory(xml_string);
xmlpp::Document* document = doc.get_document();
xmlpp::Element* root = document->get_root_node();
xmlpp::NodeSet elemns = root->find(xpath);
xmlpp::Node* element = elemns[0];
std::cout << elemns.size() << std::endl;
std::cout << element->get_line() << std::endl;
//const auto nodeText = dynamic_cast<const xmlpp::TextNode*>(element);
const auto nodeText = dynamic_cast<const xmlpp::ContentNode*>(element);
if (nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
{
std::cout << nodeText->get_content() << std::endl;
}
}
The xml_string is something like this :
std::string xml_strings("
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<title>Demo page</title></head>
<body>
<div class=\"item\">
<div class=\"row\">
<div class=\"col-xs-8\">Item</div>
<div class=\"col-xs-4 value\">
<script type=\"text/javascript\">fruit('orange');</script>
</div></div></div>
</body></html>");
The function called with the page and the xpath expression like this : xmlpp::NodeSet xmlNodes = xmlP(xml_strings, "/html/body/div/div/div[2]/script");
The problem is i couldn't get the text inside the <script>, i tried dynamic_cast'ing to ContentNode, nothing helped...
is libxml++ worth it or i need to solve my problem with another xml library?
Please, i appreciate all suggestions that can get me the text value from the <script> tag.
I tried reproducing your issue locally and could not get root->find(xpath) to produce any nodes.
According to this issue, you need to tell XPath which namespace your nodes are under, even if it is the default namespace.
I changed the XPath string and find invocation as follows:
std::string xpath("/x:html/x:body/x:div/x:div/x:div[2]/x:script");
xmlpp::Node::PrefixNsMap nsMap = {{"x",root->get_namespace_uri()}};
xmlpp::Node::NodeSet elemns = root->find(xpath, nsMap);
xmlpp::Node* element = elemns[0];
const auto nodeText = dynamic_cast<const xmlpp::Element*>(element);
if (nodeText) {
std::cout << nodeText->get_first_child_text()->get_content() << std::endl;
}

How to use the Regular Express of the end pattern in the next pattern not the entire string?

I am trying to find the categories in a website by using Regular Expression.
I typed (?<=class="category-section" data-id=")(.*)(?=" id="nav)
but it return the whole string to me, and what I see it start from the first pattern after data-id=" until the end pattern has " id="nav
For Example:
<div class="category-section" data-id="Motors" id="nav-1">
<div class="category-section" data-id="Fashion" id="nav-2">
I expected to get Motors and Fashion in the matches but it wil return
Motors" id="nav-1"> <div class="category-section" data-id="Fashion
I dont get it....
Try this:
data-id=".*?"
It will return two matches, then correspond to data-id="Motors" and data-id="Fashion".
So, you can replace the data-id= and " sings to get your desire value, inside attributes.
Edit 1:
By using simple js functions, you can retrieve this value:
<div class="category-section" data-id="Motors" id="nav-1">Content1</div>
<div class="category-section" data-id="Fashion" id="nav-2">Content2</div>
<script>
(function() {
var data = document.getElementsByClassName('category-section');
for (var i = 0; i < data.length; i++) {
console.log(data.item(i).getAttribute('data-id'));
}
})();
</script>
Output:
Motors
Fashion

Drupal7 custom menu code in template adds stray div for no reason

I am hoping someone more knowledgeable here can point out what the problem is.
I am making a custom menu for Drupal7 for a particular theme I am working on, which is using the menu_views module. Everything works pretty nicely until I pass the view menu entry over to menu_views to parse, in which case drupal adds a broken <div class=">...</div> around the parent UL element of the view menu.. I have gone through the code and don't see how this is even happening.. If I comment out the call to the view parsing, then it doesn't add this DIV, but that view parsing shouldnt' be touching the parent UL element?
Here is how the HTML is output:
<ul class="sub-menu collapse" id="parent_">
<div class="> <li class=" first=" " expanded=" " active-trail "=" ">Por nome
<ul class="menu-content collapsed in " id=" ">
<div class="view view-nameofview view-id-nameofview etc ">
<div class="view-content ">
<div class="item-list ">
<ul class="views-summary ">
<li>Á
</li>
</ul>
</div>
</div>
</div>
</ul>
</div>
</ul>
Here is the template code that causes this:
function bstheme_menu_link__main_menu($variables) {
$element = $variables['element'];
// resolve conflict with menu_views module
if (module_exists('menu_views') && $element['#href'] == '<view>') {
return _bstheme_menu_views_menu_link($variables); //<<<< IF I COMMENT OUT THIS THE OUTPUT IS FINE
}
static $item_id = 0;
// Add an ID for easy identifying in jquery and such
$element['#attributes']['id'] = 'menu_'.str_replace(' ', '_',strtolower($element['#title']));
if(!empty($element['#original_link']['menu_name']) && $element['#original_link']['menu_name'] == 'main-menu'){
if($element['#original_link']['has_children'] == 1){
$element['#attributes']['data-target'] = "jquery_updates_this";
$element['#attributes']['data-toggle'] = "collapse";
}
// add class parent and remove leaf
$classes_count = count($element['#attributes']['class']);
for($i=0;$i<$classes_count;++$i){
if($element['#attributes']['class'][$i] == 'expanded'){
//$element['#attributes']['class'][$i] = 'collapse';
}
if($element['#original_link']['plid'] == 0){
if($element['#attributes']['class'][$i] == 'leaf'){
unset($element['#attributes']['class'][$i]);
}
}
else{
if($element['#attributes']['class'][$i] == 'leaf'){
$element['#attributes']['class'][$i] = '';
}
}
}
}
// code to add a span item for the glythicons
$switch = $element['#original_link']['has_children'];
$element['#localized_options']['html'] = TRUE;
if($switch == 1) {
$linktext = $element['#title'] . '<span class="arrow"></span>';
} else {
$linktext = $element['#title'];
}
// if there's a submenu, send the parsing to the custom function instead of the main one to wrap different classes
if ($element['#below']) {
foreach ($element['#below'] as $key => $val) {
if (is_numeric($key)) {
$element['#below'][$key]['#theme'] = 'menu_link__main_menu_inner'; // 2 lavel
}
}
$element['#below']['#theme_wrappers'][0] = 'menu_tree__main_menu_inner'; // 2 lavel
$sub_menu = drupal_render($element['#below']);
$element['#attributes']['class'][] = 'menu-toggle';
}
//$sub_menu = $element['#below'] ? drupal_render($element['#below']) : '';
$output = l($linktext, $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . '</li>'."\n";
}
function _bstheme_menu_views_menu_link(&$variables) {
// Only intercept if this menu link is a view.
$view = _menu_views_replace_menu_item($variables['element']);// <<< MENU VIEWS PARSING
if ($view !== FALSE) {
if (!empty($view)) {
$sub_menu = '';
if ($variables['element']['#below']) {
$sub_menu = render($variables['element']['#below']);
}
return '' . $view . $sub_menu . "\n"; // <<< RETURN PATH
}
return '';
}
return theme('menu_views_menu_link_default', $variables);
}
Any pointers on how to troubleshoot something like this, or if someone has encountered this problem before and has a solution, would be greatly helpful!
From your code, it's apparent you're using Drupal 7.
First things first, you may want to enable theme debug mode. This allows for you to see where the theming function that caused your
You can do so by putting the following line in your settings.php file
$conf['theme_debug'] = TRUE;
Flush your caches after you make this change.
You will now have debug code output to your Drupal HTML source, when you view the site's source. An example of the type of output is shown below:
<!-- THEME DEBUG -->
<!-- CALL: theme('page') -->
<!-- FILE NAME SUGGESTIONS:
x page--front.tpl.php
* page--node.tpl.php
* page.tpl.php
-->
With this debug, you should be able to see exactly which theme functions run, in which order, and by working through them from start to finish, you should be able to determine between which theme is responsible.
At this point, if you want to keep Drupal-best-practices, copy the file name suggestion from the debug output to a folder inside your theme folder. I usually put all template overrides in a sub-directory inside it.
In the case above, if it was page.tpl.php, I'd copy it to /themes/mytheme/templates/, and go hack on it to see whether the offending div is being generated there.
Best of luck, and if you hit a stuck end, I'd be happy to help point you in a direction more specific to your specific user case.
Best,
Karl

angularjs if statements?

So I'm running through the tutorial for AngularJS:
I have an array defined in the controller and i'm returning different points in the array by calling when i'm looping through ng-repeat {{feature.name}} {{feature.description}}
What i don't understand is lets say i have a third point in the array called "importance" and it's a number from 1 to 10. I don't want to display that number in the html but what i do want to do is apply a different color to the feature if that "importance" number in the array is 10 vs 1
so how do i write an if statement to do this:
i.e.
<p style="**insert if statement: {{if feature.importance == 10}} color:red; {{/if}} **">{{feature.description}}</p>
no idea if that's right but that's what i want to do
I do not think there is if statement available.
For your styling purpose, ng-class can be used.
<p ng-class="{important: feature.importance == 10 }">
ng-switch is also convenient.
-- update --
take a look at:
https://stackoverflow.com/a/18021855/1238847
angular1.2.0RC seems to have ng-if support.
Actually there is a ternary operator in Angular 1.2.0.
<p style="{{feature.importance == 10 ? 'color:red' : ''}}">{{feature.description}}</p>
I think the answer needs an update.
Previously you could use ngIf directive from AngularUI project (code here if you still want to download it), bad news is that it's not maintained any more.
The good news is that it has been added to the official AngularJS repo (unstable branch) and soon will be available in the stable one.
<div ng-if="something"> Foo bar </div>
Will not just hide the DIV element, but remove it from DOM as well (when something is falsy).
ng-class is probably the best answer to your issue, but AngularUI has an "if" directive:
http://angular-ui.github.com/
search for:
Remove elements from the DOM completely instead of just hiding it.
I used "ui-if" to decide if I should render a data value as a label or an input, relative to the current month:
<tbody id="allocationTableBody">
<tr ng-repeat="a in data.allocations">
<td>{{a.monthAbrv}}</td>
<td ui-if="$index < currentMonth">{{a.amounts[0]}}</td>
</tr>
</tbody>
In the case where your priority would be a label, you could create a switch filter to use inside of ng-class as shown in a previous SO answer : https://stackoverflow.com/a/8309832/1036025 (for the switch filter code)
<p ng-class="feature.importance|switch:{'Urgent':'red', 'Warning': 'orange', 'Normal': 'green'}">...</p>
You can also try this line of code below
<div class="{{is_foo && foo.bar}}">
which shows foo.bar if is_foo is true.
This first one is a directive that evaluates whether something should be in the DOM only once and adds no watch listeners to the page:
angular.module('setIf',[]).directive('setIf',function () {
return {
transclude: 'element',
priority: 1000,
terminal: true,
restrict: 'A',
compile: function (element, attr, linker) {
return function (scope, iterStartElement, attr) {
if(attr.waitFor) {
var wait = scope.$watch(attr.waitFor,function(nv,ov){
if(nv) {
build();
wait();
}
});
} else {
build();
}
function build() {
iterStartElement[0].doNotMove = true;
var expression = attr.setIf;
var value = scope.$eval(expression);
if (value) {
linker(scope, function (clone) {
iterStartElement.after(clone);
clone.removeAttr('set-if');
clone.removeAttr('wait-for');
});
}
}
};
}
};
});
This second one is a directive that conditionally applies attributes to elements only once without watch listeners:
i.e.
<div set-attr="{ data-id : post.id, data-name : { value : post.name, condition : post.name != 'FOO' } }"></div>
angular.module('setAttr',[]).directive('setAttr', function() {
return {
restrict: 'A',
priority: 100,
link: function(scope,elem,attrs) {
if(attrs.setAttr.indexOf('{') != -1 && attrs.setAttr.indexOf('}') != -1) {
//you could just angular.isObject(scope.$eval(attrs.setAttr)) for the above but I needed it this way
var data = scope.$eval(attrs.setAttr);
angular.forEach(data, function(v,k){
if(angular.isObject(v)) {
if(v.value && v.condition) {
elem.attr(k,v.value);
elem.removeAttr('set-attr');
}
} else {
elem.attr(k,v);
elem.removeAttr('set-attr');
}
});
}
}
}
});
Of course your can use dynamic versions built into angular:
<div ng-class="{ 'myclass' : item.iscool }"></div>
You can also use the new ng-if added by angularjs which basically replaces ui-if created by the angularui team these will conditionally add and remove things from the DOM and add watch listeners to keep evaluating:
<div ng-if="item.iscool"></div>
What also works is:
<span>{{ varWithValue || 'If empty use this string' }}</span>

Tinymce editor gallery plugin Regexp problem?

I am using tinymce editor for inserting contents to mysql.
I have changed wordpress gallery editor plugin according to my system.
If there is gallery code in content. I convert this code to a symbolic photo, so that user understand there is a gallery , in stead of seeing a code. Like wordpress does.
If there is only 1 gallery in content, i convert this code to image successfully, but if there is more than 1 gallery it fails.
How can i convert all {gallery} code into a symbolic image before saving to db and convert these photos back to {gallery} code again while inserting or updating into mysql.
I am so bad on regular expression.
I think do_gallery RegExp has mistake. How should i change this.
initalising editor like:
ed.onBeforeSetContent.add(function(ed, o) {
ed.dom.loadCSS(url + "/css/gallery.css");
o.content = t._do_gallery(o.content);
});
ed.onPostProcess.add(function(ed, o) {
if (o.get)
o.content = t._get_gallery(o.content);
});
My "do and get gallery" codes like that:
_do_gallery : function(co) {
return co.replace(/\{gallery([^\]]*)\}/g, function(a,b){
var image = '<img src="gallery.gif" class="wpGallery mceItem" title="gallery'+tinymce.DOM.encode(b)+'" />';
console.log(image);
return image;
});
},
_get_gallery : function(co) {
function getAttr(s, n) {
n = new RegExp(n + '="([^"]+)"', 'g').exec(s);
return n ? tinymce.DOM.decode(n[1]) : '';
};
return co.replace(/(?:<p{^>}*>)*(<img[^>]+>)(?:<\/p>)*/g, function(a,im) {
var cls = getAttr(im, 'class');
if ( cls.indexOf('wpGallery') != -1 )
return '<p>{'+tinymce.trim(getAttr(im, 'title'))+'}</p>';
return a;
});
}
If Content is:
<p>Blah</p>
<p>{gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p>
<p>test</p>
this is ok
<img src="gallery.gif" class="wpGallery mceItem" title="gallery Name="tekne1" id="82" galeryID="15" sizeId="6" galery_type="liste"" />
But, if content is:
<p>Blah</p>
<p>{gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p>
<p>test</p>
<p>{gallery Name="gallery2" id="88" galeryID="11" sizeId="1" galery_type="slide"}</p>
<p>test2</p>
it logs
<img src="gallery.gif" class="wpGallery mceItem" title="gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p> <p>test</p> <p>{gallery Name="gallery2" id="88" galeryID="11" sizeId="1" galery_type="slide"" />
I hope i could explain my problem
Thank you.
I suspect that your original regex is a typo, looks like a missing Shift when you hit the ]. Try this:
/\{gallery([^\}]*)\}/g
Then the ([^\}]*) part will (greedily) eat up any sequence of characters that aren't }; your original one would consume any sequence of character that didn't include a ] and the result is that you'd grab everything between the first { and the last } rather than just grabbing the text between pairs of braces.