How can I remove html tags for parsing the actual value and then put them back? - html

I am working on highlighting the search result in search difference app and I met some problems.
On the input we get some text inside <pre> tag, that already have some highlighted text using <span> tag.
<ng-container *ngIf="settings?.allowHtmlTransform">
<pre [innerHtml]="row?.value" ></pre>
</ng-container>
My job is to highlight current search result and this is the problem. The row.value I need to parse is something like <div class="NORMAL>Sample <span class="MISSING">Text</span></div>. There are decent amount of highlight classes (ex. MODIFIED, MISSING, EXTRA etc.)
I need to highlight search result (for example "a") but it starts looking inside tags and breaks formatting (for Highlight i use the same <span class="CURRENT">)</span>
The question is how can I parse value without these tags, but when I will return highlighted value they would stay on their place? Maybe there are some beautiful solutions?

It has been 2 weeks since I asked the question and as I got back to work I found solution myself. Maybe anyone find it helpful. So the idea was to split string into parts divided by "<" and ">". And then we can check whether each part is html tag or not and add highlight only to text parts.
So here is the code. There are things to be improved but still it worked well for my case.
class Highlighter {
static hlcolors: Map<IHlType, string> = new Map([
[IHlType.success, 'success'],
[IHlType.highlight, 'currHl']
]);
static getHlVal(value: string, type: IHlType): string {
let clazz = Highlighter.hlcolors.get(type);
return '<span class="' + clazz + '">' + value + '</span>';
}
static hlByPhrase(value: string, type: IHlType, phrase: string): string {
return value.replace(phrase, Highlighter.getHlVal(phrase, type));
}
static parsehl(value: string, type: IHlType, phrase: string){
let temp = [];
let temp1 = value;
while(temp1.length > 0){
let stPos = temp1.indexOf("<");
let enPos = temp1.indexOf(">");
if(stPos === 0){
temp.push(temp1.slice(stPos, enPos+1));
temp1 = temp1.slice(enPos+1);
}
else {
temp.push(temp1.slice(0, stPos));
temp1 = temp1.slice(stPos);
}
}
let res = "";
for(let i = 0; i<temp.length; i++){
if(temp[i].includes("<div") || temp[i].includes("<span") || temp[i].includes("</div") || temp[i].includes("</span"))
res += temp[i];
else res += temp[i].replace(phrase, Highlighter.getHlVal(phrase, type));
}
return res;
}
}

Related

How to get key values from Html in Flutter?

I have the following html string. how to decode this and get key values
<html>
<head></head>
<body>order_id=1289&tracking_id=111028965908&bank_ref_no=916831&order_status="
"Success&failure_message=&payment_mode=Credit Card&card_name=MasterCard&status_code=00&"
"status_message=Approved¤cy=AED&amount=140.0&billing_name=Gx&billing_address=Yd&billing_city=Ud&"
"billing_state=&billing_zip=Uf&billing_country=Andorra&billing_tel=4&billing_email=jasir6#gmail.com&"
"delivery_name=Gx&delivery_address=Yd&delivery_city=Ud&delivery_state=&delivery_zip=Uf&"
"delivery_country=Andorra&delivery_tel=4&merchant_param1=&merchant_param2=&merchant_param3="
"&merchant_param4=&merchant_param5=&vault=N&offer_type=null&offer_code=null&discount_value=0.0&"
"mer_amount=140.0&eci_value=05&card_holder_name=&bank_qsi_no=51000002968&bank_receipt_no=221315916831&"
"merchant_param6=5123450008
</body>
</html>
You can also use this code if you don't want to use plugin to get key-value data
Assign a keyValueMap globally if you want to use it anywhere else
String html = '<html><head></head><body>order_id=1289&tracking_id=111028965908&bank_ref_no=916831&order_status=Success&failure_message=&payment_mode=Credit Card&card_name=MasterCard&status_code=00&"status_message=Approved¤cy=AED&amount=140.0&billing_name=Gx&billing_address=Yd&billing_city=Ud&billing_state=&billing_zip=Uf&billing_country=Andorra&billing_tel=4&billing_email=jasir6#gmail.com&delivery_name=Gx&delivery_address=Yd&delivery_city=Ud&delivery_state=&delivery_zip=Uf&delivery_country=Andorra&delivery_tel=4&merchant_param1=&merchant_param2=&merchant_param3= &merchant_param4=&merchant_param5=&vault=N&offer_type=null&offer_code=null&discount_value=0.0&mer_amount=140.0&eci_value=05&card_holder_name=&bank_qsi_no=51000002968&bank_receipt_no=221315916831&merchant_param6=5123450008</body></html>';
onTap: () {
String temp;
const start = "<body>";
const end = "</body>";
Map<String, dynamic> keyValueMap = {};
if (html.contains(start)) {
final startIndex = html.indexOf(start);
final endIndex = html.indexOf(end, startIndex + start.length);
temp = html.substring(startIndex + start.length, endIndex);
List splitText = temp.split("&");
for (var element in splitText) {
element.runtimeType;
if (element.contains('=')) {
keyValueMap[element.split("=")[0] ?? ""] = element.split("=")[1] ?? "";
}
}
///You'll get all key value in [keyValueMap]
}
},
Use some Html decode plugins. Please go to pub.dev and search flutter_widget_from_html_core, flutter_widget_from_html, html_editor_enhanced,
so many plugins there in pub.dev.

XPath text/replace to find text which may contain soft-hyphen

Searching for a text: Bescheinigungen my XPath should also return elements which include a soft-hyphen like: Beschei\u00ADnigungen.
I tried this:
//*[text()[replace(., "\u00AD", "")="Bescheinigungen"]]
Doesn't work. Need some help, please.
Okay, had to use some 'helper' code to make it work:
public static WebElement findByText(WebDriver driver, String text) {
List<WebElement> elements = driver.findElements(By.xpath("//*[text()]"));
return elements.stream().filter(element -> {
String elementText = element.getText();
if (elementText != null && !elementText.isEmpty()) {
return text.equals(elementText.replace("\u00AD", ""));
}
return false;
}).findFirst().orElseThrow(NotFoundException::new);
}

Can we search or filter " data-tag='to-do' " in onenote API ? If yes then how we can do this?

How can we use OneNote tags (like data-tag='to-do') with search or filter in OneNote API. I tried using provide operators but found no success.
I tried in this way --
$url = "https://www.onenote.com/api/v1.0/me/notes";
//$url .= "/pages?search=hello";
$url .= "/pages?filter=data-tag eq 'to-do'";
I want to search data-tag and then extract the data from OneNote pages which contains the data-tag='to-do'.
Any help is appreciated and thanks in advance.
You'll have to run through all your pages.
For each pages, you can retrieve its content with a GET call to https://www.onenote.com/api/v1.0/me/notes/pages/%s/content?includeIds=true
From there you get a string that you can parse.
I'll advise you to use jsoup.
With jsoup you can then write (assuming contentcontains your page's content):
Document doc = Jsoup.parse(content);
Elements todos=doc.select("[data-tag^=\"to-do\"]");
for(Element todo:todos) {
System.out.println(todo.ownText());
}
Sadly OneNote API doesn't support it yet, so I've written my custom parser which extracts notes with data-tags from page content. Here it is:
public class OneNoteParser
{
static public List<Note> ExtractTaggedNotes(string pageContent, string tag = "*")
{
List<Note> allNotes = new List<Note>();
string[] dataTagString = { "data-tag=\""};
string[] dirtyNotes = pageContent.Split(dataTagString, StringSplitOptions.RemoveEmptyEntries);
//First one in this array can be dropped as it doesn't contain todo
for (int i = 1; i < dirtyNotes.Length; i )
{
string curStr = dirtyNotes[i];
Note curNote = new Note();
// Firstly we need to extract all the tags from it (sample html: data-tag="to-do:completed,important" ....)
string allTags = curStr.Substring(0,curStr.IndexOf("\""));
curNote.Tags = new List<string>(allTags.Split(','));
// Now we have to jump to the next ">" symbol and start finding the text after it
curStr = curStr.Substring(curStr.IndexOf(">"));
int depth = 1;
bool addAllowed = false;
for (int j = 0; j < curStr.Length - 1; j )
{
// Finding next tag opener "<" symbol
if (curStr[j] == '<')
{
addAllowed = false;
// Checking if it is not "</" closer
if (curStr[j 1] == '/')
{
// Means this is a tag closer. Decreasing depth
depth--;
}
else
{
// Means this is an tag opener. Increasing depth
depth ;
}
}
else if (curStr[j] == '>')
{
addAllowed = true;
if (j > 0 && curStr[j - 1] == '/')
{
// Means this is a tag closer. Decreasing depth
depth--;
}
}
else
{
if (depth < 1)
{
// Found end of the tag. Saving index and exiting for loop
break;
}
if (addAllowed)
curNote.Text = curStr[j]; // Appending letter to string
}
}
// Filtering by tag and adding to final list
if (tag == "*" || curNote.Tags.Any(str => str.Contains(tag)))//curNote.Tags.Contains(tag, StringComparer.CurrentCultureIgnoreCase))
allNotes.Add(curNote);
}
return allNotes;
}
}
And here is the class Note
public class Note
{
public string Text;
public List<string> Tags;
public Note()
{
Tags = new List<string>();
}
}
To extract todo-s simply call this function:
OneNoteParser.ExtractTaggedNotes(pageContent, "to-do");
Also you can extract other tags like this:
OneNoteParser.ExtractTaggedNotes(pageContent, "important");
OneNoteParser.ExtractTaggedNotes(pageContent, "highlight");
//...

Remove Double Quotes around the String in CSV file

I am using Angular UI-grid to display data in tabular form and i also added a functionality to export the visible data in CSV file but my problem is that in exported file all the string are enclose with double quotes.
Can anyone tell me how to remove those unnecessary double-quotes ?
Any help is appreciated
The behavior that you are referring to comes from the function formatFieldAsCsv(field) within the uiGridExporterService service. There is no API that will allow you to change this with a setting.
What we can do however is use a decorator to override this default behavior without having to modify the ui-grid module itself.
I have demonstrated this in a working plunker.
In the snippet below, I have assigned qualifier to replace the quotations that were initially in use. With this, you can either leave the function as is and have no qualifier at all, or you can change it's value to whatever you like, and that will become the prefix/suffix of each field.
app.config(['$provide', function ($provide) {
$provide.decorator('uiGridExporterService', [
'$delegate',
function myServiceDecorator($delegate) {
$delegate.formatFieldAsCsv = formatFieldAsCsv;
return $delegate;
}
]);
function formatFieldAsCsv(field) {
var qualifier = '';
if (field.value === null) { // we want to catch anything null-ish, hence just == not ===
return '';
}
if (typeof(field.value) === 'number') {
return field.value;
}
if (typeof(field.value) === 'boolean') {
return (field.value ? 'TRUE' : 'FALSE');
}
if (typeof(field.value) === 'string') {
return qualifier + field.value.replace(/"/g, '""') + qualifier;
}
return JSON.stringify(field.value);
}
}]);
http://plnkr.co/edit/8qskcFt7EHSlTQFo4ZUG?p=preview

MVC View adding in quotations to html attribute

I am working on a small project and in the partial navigation view I am checking if a page is selected and highlighting the menu.
var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString().ToLower();
var home = string.Empty;
var content = string.Empty;
switch(controller) {
case "home":
home = "class=current";
break;
case "content":
content = "class=current";
break;
}
In the view I am then doing:
<li #home>Home</li>
Originally in my code I had
home = "class='current'";
Notice I had quotations around it, but when I executed the code the html source looks like
So when I remove the quatations and run it again, since it's adding them in by default, it works, even though the debugger looks like
So the project is working, my question is why is it by default adding in the quotations?
I'm not certain that MVC is adding the quotes, that is probably the Chrome DevTools doing it. If you "View page source", I don't think you will see the quotes.
Just FYI, because of these kinds of things I usually don't include the attribute in such strings, just the value...
<li class="#home">
MVC doesn't add quotes for #home. If you decompile this page, you could get codes like below:
public class _Page_Views_Home_Index_cshtml : WebViewPage<object>
{
// Methods
public override void Execute()
{
((dynamic) base.ViewBag).Title = "Home Page";
base.BeginContext("~/Views/Home/Index.cshtml", 0x27, 2, true);
this.WriteLiteral("\r\n");
base.EndContext("~/Views/Home/Index.cshtml", 0x27, 2, true);
string str = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
string str2 = string.Empty;
string str3 = string.Empty;
string str4 = str;
if (str4 != null)
{
if (!(str4 == "Home"))
{
if (str4 == "content")
{
str3 = "class=current";
}
}
else
{
str2 = "class=current";
}
}
base.BeginContext("~/Views/Home/Index.cshtml", 0x1a6, 9, true);
this.WriteLiteral("\r\n\r\n<div ");
base.EndContext("~/Views/Home/Index.cshtml", 0x1a6, 9, true);
base.BeginContext("~/Views/Home/Index.cshtml", 0x1b0, 4, false);
this.Write(str2);
....
}
}
The Write methods will finally calls WebUtility.HtmlDecode method, this method replaces special chars, but will not add quotes.
Hope this helps.