Replace occurrences of a string inside a HTML string using Objective C - objective-c

I have a HTML string in Objective C. NSString *contentString;
How do I replace the occurrences of a string inside this HTML string while preserving the HTML tags ?
I would use the statement contentString = [contentString stringByReplacingOccurrencesOfString: #"string" withString : #"new string"]; but that will also replace the text within HTML tags. I need to preserve those. I am facing a similar problem while using 3rd party HTML parsers.
The contents of contentString are :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:epub="http://www.idpf.org/2007/ops" lang="en"><head><link
rel="stylesheet" type="text/css" href="../RESOURCE/core.css" /><link
rel="stylesheet" type="text/css" href="../RESOURCE/inserts.css" /><link
rel="stylesheet" type="text/css" href="../RESOURCE/jquery-ui.css"
/><link rel="stylesheet" type="text/css"
href="../RESOURCE/jquery.qtip.css" /><link type="text/css"
rel="stylesheet" href="../RESOURCE/template-opus.css"
data-wundr-theme="true" /><link type="text/css" rel="stylesheet"
href="../RESOURCE/font-scheme-opus.css?1395092689.864661"
data-wundr-font-scheme="true" /><link type="text/css" rel="stylesheet"
href="../RESOURCE/color-scheme-opus.css?1395092689.864992"
data-wundr-color-scheme="true" /><link type="text/css" rel="stylesheet"
href="../RESOURCE/paragraph-styles.css?1395092689.865252"
data-wundr-paragraph-style="true" /></head><body
data-wundr-page="content"><div class="wundr-guides" style="display:
none;"></div><div class="wundr-page-guide" style="display:
none;"></div><article data-wundr="chapter"
class="wundr-padding-regular"><header><h2
class="pw-par-style-chapter-number pw-par-style-big-letter"
data-wundr-key="chapter-number">1</h2><h1
class="pw-par-style" data-wundr-key="chapter-title"
contenteditable="true"
data-wundr-dummy="true">Chapter</h1></header><section
class="pw-par-style-body" data-wundr-epub-type="subchapter"
contenteditable="true"><p data-wundr-dummy="true">Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Praesent nec mauris lorem. Quisque
luctus velit cursus elit sodales vulputate. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Quisque diam augue, varius vitae auctor eu,
malesuada in purus. Quisque dapibus justo sed nisi gravida malesuada.
Sed consequat enim condimentum lorem semper a iaculis mi consequat.
Donec euismod lobortis est, at tincidunt enim tempor id. Nunc id nunc
quis enim vehicula bibendum sed ut orci. Donec vehicula semper leo, a
auctor tortor bibendum sed. Quisque cursus sapien a eros convallis eget
molestie ligula dignissim. Fusce ullamcorper posuere augue et fermentum.
Integer at dolor sed lorem porttitor iaculis. Sed vitae felis id dolor
vulputate hendrerit ut sed nisl.</p><p data-wundr-dummy="true">Lorem
ipsum dolor sit amet, consectetur adipiscing elit. Praesent nec mauris
lorem. Quisque luctus velit cursus elit sodales vulputate. Lorem ipsum
dolor sit amet, consectetur adipiscing elit. Quisque diam augue, varius
vitae auctor eu, malesuada in purus. Quisque dapibus justo sed nisi
gravida malesuada. Sed consequat enim condimentum lorem semper a iaculis
mi consequat. Donec euismod lobortis est, at tincidunt enim tempor id.
Nunc id nunc quis enim vehicula bibendum sed ut orci. Donec vehicula
semper leo, a auctor tortor bibendum sed. Quisque cursus sapien a eros
convallis eget molestie ligula dignissim. Fusce ullamcorper posuere
augue et fermentum. Integer at dolor sed lorem porttitor iaculis. Sed
vitae felis id dolor vulputate hendrerit ut sed
nisl.</p></section></article><div></div></body></html>

Use some basic logic (Probably Just a Bool) to check if you are inside or outside of an html tag. Only stringByReplacingOccurrencesOfString if you are outside an html tag. Some of the snippets in this code will help you.
http://www.developerfeed.com/how-remove-html-tags-string-ios
+ (NSString *)flattenHtml: (NSString *) html {
NSScanner *theScanner;
NSString *text = nil;
theScanner = [NSScanner scannerWithString: html];
while ([theScanner isAtEnd] == NO) {
[theScanner scanUpToString: #"<" intoString: NULL];
[theScanner scanUpToString: #">" intoString: &text];
// Only Replace if you are outside of an html tag
} // while
return html;
}

Try using some javascript on it after loading it into the web view. That would also allow you to load some tools that could help like jQuery to make the job easier.

Related

PyQuery find() in pandas

I have a pandas dataframe with multiple columns. I am working on a specific column named "Text_annotated" whose structure is like :
Text_annotated
<html> Lorem ipsum dolor sit amet, <phrase>consectetur adipiscing elit</phrase>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <phrase>Ut enim ad minim veniam</phrase>, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</html>
<html> Faucibus vitae aliquet nec ullamcorper sit amet risus nullam. Pellentesque sit amet porttitor eget dolor morbi. <phrase>Tincidunt praesent semper feugiat nibh sed pulvinar. Lobortis elementum nibh tellus molestie nunc non blandit.</phrase> Tellus at urna condimentum mattis.</html>
<html>Pulvinar etiam non quam lacus. Amet purus gravida quis blandit. Scelerisque eu ultrices vitae auctor eu augue ut. Tincidunt lobortis feugiat vivamus at augue eget arcu dictum varius. Pellentesque adipiscing commodo elit at imperdiet.</html>
and I want to extract only the text between the <phrase></phrase> tags. For this reason, I decided to use PyQuery. So far I have tried
text_phrases= df['Text_annotated'].tolist()
doc = pq(f"{text_phrases}")
phrase_macro = doc.find("phrase").text()
which returns a pyquery.pyquery.PyQuery where each "newline" contains only one result e.g.
consectetur adipiscing elit
Ut enim ad minim veniam
Tincidunt praesent semper feugiat nibh sed pulvinar. Lobortis elementum nibh tellus molestie nunc non blandit.
Thus, my question is whether it's possible to group the results for each row in the df separated by a comma e.g.
consectetur adipiscing elit, Ut enim ad minim veniam
Tincidunt praesent semper feugiat nibh sed pulvinar. Lobortis elementum nibh tellus molestie nunc non blandit.
(I have also tried to iterate over the objects phrases_res = [h.text() for h in doc('phrase').items()] which didn't work)
Any help/suggestion is much appreciated.
PS. Each row is just wrapped with a <html> tag, without any other particular structure.
EDIT: Tried also to "separate" somehow according to the html tag, but returned the previous result.
rows = doc('html')
for row in rows.text():
phrase_res = doc.find("phrase").text()
new_df['Phrases_res'] = phrase_res
new_df.head(5)
You can use pandas.Series.str.findall with a regex expression to return a list of all the strings between two delimiters.
Try this :
import pandas as pd
pd.options.display.max_colwidth = None
data = ['<html> Lorem ipsum dolor sit amet, <phrase>consectetur adipiscing elit</phrase>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <phrase>Ut enim ad minim veniam</phrase>, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</html>',
'<html> Faucibus vitae aliquet nec ullamcorper sit amet risus nullam. Pellentesque sit amet porttitor eget dolor morbi. <phrase>Tincidunt praesent semper feugiat nibh sed pulvinar. Lobortis elementum nibh tellus molestie nunc non blandit.</phrase> Tellus at urna condimentum mattis.</html>',
'<html>Pulvinar etiam non quam lacus. Amet purus gravida quis blandit. Scelerisque eu ultrices vitae auctor eu augue ut. Tincidunt lobortis feugiat vivamus at augue eget arcu dictum varius. Pellentesque adipiscing commodo elit at imperdiet.</html>']
df = pd.DataFrame(data, columns=['Text_annotated'])
df['Phrases'] = df['Text_annotated'].str.findall(r"<phrase>(.*?)</phrase>")
>>> display(df)

Can I use CSS tables to place an image and text side-by-side, without knowing the image width in advance?

I want to have a vertical stack of blocks; each block has an image on the left and text (heading and paragraphs) on the right.
I would like the image to be its natural width and the text to use the remaining width in the parent element.
This is similar to a table, but the images in different blocks have different widths. So the first "column" in the table is not of constant width.
Floating the image left does not work, because if the text has a greater height than the image, the text wraps underneath the image.
CSS tables don't seem to work, because the CSS does not know the differing image widths from block to block.
My "block" element CSS includes 'display: table-row;'. My image element and my text element CSS include 'display: table-cell;'. The result is that some images are their natural sizes; others are smaller than their natural sizes.
This seems to be related to the amount of text: one line of text gets a natural size image; two lines squeezes the image a few pixels; 15 lines squeezes the image to about one-half size.
I would welcome suggestions for how to accomplish my goal.
I think that can be resolved by display flex. Documentation W3C: https://www.w3schools.com/css/css3_flexbox.asp
Try this:
HTML
<div class="row" style="width: 100%">
<img src="https://image.shutterstock.com/image-photo/salesman-offering-cheese-samples-customers-600w-414153787.jpg"/>
<div>
<h2>Head</h2>
<p>
Suspendisse eu scelerisque odio. Quisque hendrerit malesuada risus ut imperdiet. Nulla facilisi. Aenean bibendum risus et mi rutrum convallis. Phasellus ornare orci leo, eget faucibus tortor egestas at. Aliquam iaculis, metus dignissim vulputate dignissim, est metus condimentum nulla, at maximus neque tellus non erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse porttitor, magna ut lacinia blandit, est ligula sagittis nulla, nec interdum erat velit sit amet velit. Sed ut ante at enim accumsan ultricies porta quis neque. Vestibulum volutpat ipsum eget libero malesuada volutpat. Praesent sed porta tellus. Praesent ac volutpat justo.
</p>
</div>
</div>
<div class="row" style="width: 70%">
<img src="https://image.shutterstock.com/image-photo/salesman-holding-cutting-board-assorted-260nw-407934532.jpg"/>
<div>
<h2>Head</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse luctus massa nec fermentum egestas. Sed feugiat, nisl vitae dictum accumsan, felis odio elementum eros, imperdiet faucibus mi nisi convallis dolor. Mauris interdum maximus neque, in convallis erat facilisis porttitor. Sed ac tortor imperdiet, efficitur nisi nec, efficitur massa. Integer consectetur nec nunc ac porta. Proin non ultricies lorem, rhoncus laoreet ligula. Donec condimentum mauris id urna placerat dapibus. Cras consequat, quam vitae semper luctus, mi tortor finibus augue, sed vestibulum odio lorem at tellus. Fusce eu urna eget ante mollis vestibulum. Nullam ante eros, convallis vitae hendrerit at, volutpat id dui.
</p>
</div>
</div>
<div class="row" style="width: 80%">
<img src="https://image.shutterstock.com/image-photo/salesman-offering-cheese-samples-customers-600w-414153787.jpg"/>
<div>
<h2>Head</h2>
<p>
Suspendisse eu scelerisque odio. Quisque hendrerit malesuada risus ut imperdiet. Nulla facilisi. Aenean bibendum risus et mi rutrum convallis. Phasellus ornare orci leo, eget faucibus tortor egestas at. Aliquam iaculis, metus dignissim vulputate dignissim, est metus condimentum nulla, at maximus neque tellus non erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse porttitor, magna ut lacinia blandit, est ligula sagittis nulla, nec interdum erat velit sit amet velit. Sed ut ante at enim accumsan ultricies porta quis neque. Vestibulum volutpat ipsum eget libero malesuada volutpat. Praesent sed porta tellus. Praesent ac volutpat justo.
</p>
</div>
</div>
CSS:
.row {
display: flex;
}
.row img {
flex-grow: 1;
height: max-content;
}
.row div {
margin-left: 10px;
}
https://jsfiddle.net/ymuxdtg6/

Is is possible to load more testdata with liquibase

I want to load a whole html file as testdata with liquibase. So far I've used the approach with loading testdata from csv file, but it is not designed to handle huge html's.
Is there a way to achieve it?
Here is an example to make it clear:
I have a table named Movie. The fields are: id, title, description. In a databaseChangeLog section I point to a file where I store the testdata:
<loadData encoding="UTF-8"
file="config/liquibase/testdata/movie.csv"
separator=";"
tableName="movie"/>
The content is as follows:
id;title;description
1;Titanic;great movie
2;Forrest Gump;another great movie
Now I want to change the description to something that is closer to the real usecase. Lets say this HTML:
<div id="lipsum">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce porta pulvinar lacus eget egestas. Ut quis efficitur turpis. Nunc tincidunt turpis lorem, eget vestibulum nisi sodales at. Quisque in tortor et sapien ornare venenatis. Integer pulvinar nec ipsum malesuada porta. Sed massa metus, condimentum non varius ornare, sollicitudin at dui. Praesent porta, ante et interdum convallis, tellus augue tempus nisl, sit amet mollis augue nisl vel metus.
</p>
<p>
Nam quis libero rhoncus, facilisis magna ut, bibendum urna. Nullam sit amet volutpat turpis. Praesent eget aliquet orci. Duis dignissim tellus erat, eget fermentum augue dapibus sed. Quisque vitae est ipsum. Quisque sit amet libero eget nisi faucibus maximus vel a sem. Proin maximus neque arcu, sit amet eleifend dolor ornare at. Suspendisse laoreet lobortis tellus sed consequat. Nunc commodo ligula eget neque porta consectetur. Mauris sagittis elit in sodales luctus.
</p>
</div>
The content won't fit into the csv file. I could delete all the newlines, but it makes the file unmaintainable.
loadData has a column attribute which in turn has a valueClobFile attribute where you could put in a path to a (html) file.
Checkout these two files in the liquibase integration tests that show a use of this:
batchInsert.changelog.xml
batchInsert.csv

justify align for rtl text on react-native

How could I align the RTL text to justify on react-native? As the react-native website says we could set align of text to 'auto', 'left', 'right', 'center', 'justify' but the justify one is not working on RTL text.
text justify not support in react native android native. but there is a trick that you justify your text with WebView Component...
here is a sample code:
<WebView
source={{
html:
"<style>p{text-align:justify}</style>" +
"<p>" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus commodo tortor ut ipsum pharetra sodales. Praesent sed diam non lacus convallis dapibus. Sed vulputate erat risus, ac hendrerit eros egestas id. Etiam pellentesque auctor ipsum, non cursus nisi gravida sed. Ut eget pretium risus. Curabitur a lectus odio. Etiam felis urna, pharetra ut odio in, tristique suscipit tortor. Cras vitae risus odio. Etiam a leo elit. Duis molestie fermentum mi vitae pretium. Morbi luctus semper quam, et suscipit nisi convallis dictum. Fusce sit amet est dapibus, interdum ante non, lacinia metus. Donec at nulla non ante consectetur vulputate. Cras tristique porttitor ligula quis posuere. Integer nec laoreet felis, at tempor leo. Ut et convallis quam." +
"</p>"
}}
/>
if you want call your body texts from your server compile to html and use your source in it (this is not a good but only way)

JQuery UI tab slow response with 500+ row table

I am currently running into an issue with JQuery UI tabs causing the browser to slow down a lot when I load a large table into a tab. I am running JQuery 1.4.2 and JQuery UI 1.8.4. Clicking anywhere within the tab with this large table causes the CPU to jump up to 50%. The slowness is more apparent if you have a column of checkboxes to click on. But it is also apparent when you attempt to highlight any text in the table.
So far I have tested the following:
1) JQuery UI tabs with a 500 row table.
2) JQuery UI tabs with 500 rows of data (replaced table with p and span tags).
3) Just a 500 row table
Case #1 is the slowest.
Case #2 is more responsive, but the table layout is now gone.
Case #3 is the fastest with no lag time at all.
I've tried using the FireBug profiler to see what could be executing, but it returned with no activity. At this point I am stumped.
Here is a code snippet for Case #1:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Tabs + 500 row table</title>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<link href="css/jquery-ui-1.8.custom.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript">
$(document).ready(function() {
$("#tabs").tabs();
});
</script>
</head>
<body>
<div id="tabs">
<ul>
<li>500 Rows</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div id="tabs-1">
<!-- Insert Large data table here. 500+ rows -->
<!--
Small sample starter table. Pasting a 500 row table here would be too much.
<table>
<tr>
<td><input type="checkbox"/></td>
<td>column 2</td>
<td>column 3</td>
<td>column 4</td>
<td>column 5</td>
<td>column 6</td>
</tr>
</table>
-->
</div>
<div id="tabs-2">
<p>Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.</p>
</div>
<div id="tabs-3">
<p>Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.</p>
<p>Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.</p>
</div>
</div>
</body>
</html>
I have managed to resolve this with a sort of "hack". I simply removed the ui-widget class from the tabs after loading the tabs and I no longer have high cpu usage with huge tables.
$("#tabs").removeClass("ui-widget");
I was able to safely remove this because this class adds very little to the actual style of the tabs other than setting the font type and size.
Could this be related to the bug mentioned here: http://bugs.jqueryui.com/ticket/6757
in the CSS change
.ui-widget :active {
outline: none;
}
to
.ui-widget:active {
outline: none;
}