replacing the fonts with rereplace or replace - coldfusion

i need some help here with regards to replace or maybe rereplace
i am trying to replace the font-family:anything to font-family:swiss7
but if there is a value font-family: BebasNeue; i want that font untouched and do not add font-size, but add the font-size to the other fonts
I am following this tutorial but somehow its not matching as to what I need to achieve
https://www.sitekickr.com/snippets/coldfusion/strip-css-styles

Update: well I thought the question was simpler. If you want to see my original answer just see the edit history for this post. This answer uses a similar principle though where you search for an item that you don't want removed and then push it back in with the replace.
<cfset teststr1 = "font-family: BebasNeue;" />
<cfset teststr2 = "font-family: Verdana" />
<cfset teststr3 = "font-family: BebasNeue; font-family: Times New Roman; color: red" />
<cfset search1 = "(font-family:\s*)((BebasNeue)|[\w ]+)(;)?" />
<cfset replace1 = "font-family: \3swiss7\4" />
<cfset search2 = "BebasNeueswiss7" />
<cfset replace2 = "BebasNeue" />
<cfoutput>
<ol>
<li>#replaceNoCase(reReplaceNoCase(teststr1, search1, replace1, "all"), search2, replace2, "all")#</li>
<li>#replaceNoCase(reReplaceNoCase(teststr2, search1, replace1, "all"), search2, replace2, "all")#</li>
<li>#replaceNoCase(reReplaceNoCase(teststr3, search1, replace1, "all"), search2, replace2, "all")#</li>
</ol>
</cfoutput>
Result:
1. font-family: BebasNeue;
2. font-family: swiss7
3. font-family: BebasNeue; font-family: swiss7; color: red
So essentially you replace all font families with the chosen font type, in this case swiss7, but by including the group selector in the replace you leave the BebasNeue font in the string. An additional step then cleans up the combined font name left behind.

I would suggest a more maintainable approach:
if !findNoCase( styleString, 'BebasNeue'){
styleString = REReplace(style, 'font-family:[^"|^;]*', "font-family:swiss7; font-size:12", "ALL");
}
This should get you want you are after: leave it alone if it is BebasNeue, otherwise, change the font-family to swiss7 and add a font-size. But it is also not so complicated that a regex-newbie couldn't understand what is going on.

Related

How to remove the attributes in div tag without class,id and style rest of attributes need to be delete using coldfusion?

I have attribute like this.
Example:
<div class="issue-document" id="assr_0335-5985_1991_num_76_1_1619" itemprop="hasPart" itemscope="" itemtype="https://facebook.com>
<cfset mystring = 'This is some text. It is true that <div class="issue-document" id="assr_0335-5985_1991_num_76_1_1619" itemprop="hasPart" itemscope="" itemtype="https://facebook.com">Harry Potter</div> is a good, but is better'>
<cfset MyReplace = ReReplaceNoCase(mystring,"<div [^>]*>","","ALL")>
<cfoutput><pre>Original string: #mystring#
Without link: #myreplace#</pre></cfoutput>
I need to remove only itemscope and itemprop like this rest of the attribute like id,class, style i don't want to remove using coldfusion in regular expression. Can any one please help to find the solution.
<cfset myReplace = reReplaceNoCase(mystring, '\b(itemscope|itemprop)="[^"]*"', "", "all")) />
https://trycf.com/gist/8d84d7d355f7c54e5533eeed22d097ba/acf2016?theme=monokai

ColdFusion regex to detect first URL without image extension

I've been digging around stackoverflow this evening but nothing worked so far. What I'm trying to achieve is to extract URL from a string (mainly HTML) that doesn't have any image extension at the end. So if the given HTML string has URL ending with .jpg and then somewhere few lines down another URL without any image extension, regex would get that second one and stop. Alternatively it can return all the 'good' URLs, just leave out the images.
So far I've got:
<cfset c= reMatch('(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,#?^=%&:/~\+##]*[\w\-\#?^=%&/~\+##])?',htmlString)>
I know image detecting part should be somewhere towards the end, but had only managed to freeze the server with my attempts so far.
Sample string to match:
'<tr> <td style="vertical-align: top; padding-right: 12px;"><img src="http://static01.nyt.com/images/2016/01/31/us/why-iowaALT/why-iowaALT-thumbStandard.jpg" /></td> <td> <h6 style="font-size: 10px; font-weight: normal; text-transform: uppercase; color: ##000000; margin: 0; margin-bottom: 2px"></h6> <h1 style="font-weight: normal; font-family: georgia,"times new roman",times,serif; font-size: 23px; margin: 0; margin-bottom: 4px"><a href="http://p.nytimes.com/email/re?location=InCMR7g4BCJTYuyKqXu41s2MxgEX9Okc&user_id=7b8478da99b24f28abb9c2f1be86c807&email_type=eta&task_id=1454290534529254&regi_id=0" style="color: ##004276; text-decoration: none !important;">'
Note: it should be ColdFusion regex version, which is at times a bit limited
Thanks!
Consider that your code works perfectly fine about extracting valid html links and you have them stored in array. All you have to do is go through this array and find does any of urls stored in this array doesn't contain extension -if not, return this value.
list_of_extensions = '(bmp|jpg|png|gif)'; //you can make this list longer
for(my_url in urls){
if(not reFind(list_of_extensions, my_url)){ // you can be more specific in this reFind call
return my_url; // it will return first invalid url
}
}
You can switch to Java for what you are trying to achieve like this:
<!--- Java Regular Expression Pattern Object --->
<cfset local.objPattern = createObject(
"java",
"java.util.regex.Pattern"
).compile(
javaCast( "string", '(?:https?:\/\/)[^"]*(?<!\.jpg)(?=\")' )
)
/>
<!--- Get Pattern Matcher for your html content --->
<cfset local.objMatcher = local.objPattern.matcher(
JavaCast( "string", local.htmlContent )
) />
<!--- Find Matching URLs --->
<cfloop condition="local.objMatcher.find()">
<cfdump var="#local.objMatcher.group()# <br>">
</cfloop>

How to extract slide notes from a PowerPoint file with ColdFusion

I have a .PPT (PowerPoint, transferrable to ODP or PPTX) file with speaker notes on every slide. I want to extract the entire presentation into something dynamic so I can create a speaker cheat sheet for running on a phone or table while I talk (thumbnail of the slide with speaker notes). I do this just often enough to HATE doing it by hand.
This is almost easy enough with <cfpresentation format="html" showNotes="yes"> which splits the PPT up into HTML pages and creates an image for every slide. cfpresentation, however, does not transfer the speaker notes, they are lost in translation.
I have also tried <cfdocument> which has no options for preserving slide notes once it converts to PDF.
Is there a way to get the notes out of the PowerPoint file from within ColdFusion?
The simplest solution:
Convert the PowerPoint presentation to OpenOffice ODP format. That's a ZIP file. CFML can unzip it and inside there's a content.xml file which contains the slides and the notes, so CFML can extract the notes from that format.
Given the CFDOCUMENT functionality, perhaps ColdFusion can even convert the PPT to ODP for you?
There's no way to do this directly in CF. You can do this by dropping to the underlying Java. I stand corrected. Using the showNotes attribute on the <cfpresentation> tag, should add the notes to the HTML.
As an alternative, or if that doesn't work for some reason, you should be able to use Apache POI to do this, although you may need to use a more recent version of poi than shipped with your version of coldfusion, which may require some additional work.
public static LinkedList<String> getNotes(String filePath) {
LinkedList<String> results = new LinkedList<String>();
// read the powerpoint
FileInputStream fis = new FileInputStream(filePath);
SlideShow slideShow = new SlideShow(is);
fis.close();
// get the slides
Slide[] slides = ppt.getSlides();
// loop over the slides
for (Slide slide : slides) {
// get the notes for this slide.
Notes notes = slide.getNotesSheet();
// get the "text runs" that are part of this slide.
TextRun[] textRuns = notes.getTextRuns();
// build a string with the text from all the runs in the slide.
StringBuilder sb = new StringBuilder();
for (TextRun textRun : textRuns) {
sb.append(textRun.getRawText());
}
// add the resulting string to the results.
results.add(sb.toString());
}
return results;
}
Carrying over complex formatting may be a challenge (bulleted lists, bold, italics, links, colors, etc.), as you'll have to dig much deeper into TextRuns, and the related API's and figure how to generate HTML.
CFPRESENTATION (at least as of version 9) does have a showNotes attribute, but you'd still have to parse the output. Depending on the markup of the output, jQuery would make short work of grabbing what you want.
Felt bad that my above answer didn't work out so I dug a little bit. It's a little dated, but it works. PPTUtils, which is based on the apache library that #Antony suggested. I updated this one function to do what you want. You may have to tweak it a bit to do exactly what you want, but I like the fact that this utility returns the data to you in data format rather than in HTML which you'd have to parse.
And just in case, here is the POI API reference I used to find the "getNotes()" function.
<cffunction name="extractText" access="public" returntype="array" output="true" hint="i extract text from a PPT by means of an array of structs containing an array element for each slide in the PowerPoint">
<cfargument name="pathToPPT" required="true" hint="the full path to the powerpoint to convert" />
<cfset var hslf = instance.loader.create("org.apache.poi.hslf.HSLFSlideShow").init(arguments.pathToPPT) />
<cfset var slideshow = instance.loader.create("org.apache.poi.hslf.usermodel.SlideShow").init(hslf) />
<cfset var slides = slideshow.getSlides() />
<cfset var notes = slideshow.getNotes() />
<cfset var retArr = arrayNew(1) />
<cfset var slide = structNew() />
<cfset var i = "" />
<cfset var j = "" />
<cfset var k = "" />
<cfset var thisSlide = "" />
<cfset var thisSlideText = "" />
<cfset var thisSlideRichText = "" />
<cfset var rawText = "" />
<cfset var slideText = "" />
<cfloop from="1" to="#arrayLen(slides)#" index="i">
<cfset slide.slideText = structNew() />
<cfif arrayLen(notes)>
<cfset slide.notes = notes[i].getTextRuns()[1].getRawText() />
<cfelse>
<cfset slide.notes = "" />
</cfif>
<cfset thisSlide = slides[i] />
<cfset slide.slideTitle = thisSlide.getTitle() />
<cfset thisSlideText = thisSlide.getTextRuns() />
<cfset slideText = "" />
<cfloop from="1" to="#arrayLen(thisSlideText)#" index="j">
<cfset thisSlideRichText = thisSlideText[j].getRichTextRuns() />
<cfloop from="1" to="#arrayLen(thisSlideRichText)#" index="k">
<cfset rawText = thisSlideRichText[k].getText() />
<cfset slideText = slideText & rawText />
</cfloop>
</cfloop>
<cfset slide.slideText = duplicate(slideText) />
<cfset arrayAppend(retArr, duplicate(slide)) />
</cfloop>
<cfreturn retArr />
</cffunction>

Coldfusion regex substring YouTube ID

I'm trying to pull a youtube ID from a link like this;
<img src="http://img.youtube.com/vi/OZ3jyvM0jZc/2.jpg" alt="" />
I've only been successful in taking out the ID, but not actually getting it!
<cfset ytID = '<img src="http://img.youtube.com/vi/0Z3jyvM0jZc/2.jpg" alt="" />' />
#reReplace(referer,"(vi=?(\=|\/))([-a-zA-Z0-9_]+)|(vi=\/)([-a-zA-Z0-9_]+)", "\1", "one")#
Output: <img src="http://img.youtube.com/vi//2.jpg" alt="" />
RegEx is not my friend today. What am I missing?
Thanks!
Try with regex:
vi\/([^\/]+) // 0Z3jyvM0jZc
You don't need to escape the forward slashes in CFML regex patterns. So take what The Mask has and use whichever method you prefer (both of these only work if the string is indeed a match):
<cfset ytID = '<img src="http://img.youtube.com/vi/0Z3jyvM0jZc/2.jpg" alt="" />'>
<cfoutput>
<pre>
<cfset sLenPos=REFind("/vi/([^/]+)", ytID, 1, "True")>
#mid(ytID, sLenPos.pos[2], sLenPos.len[2])# == OZ3jyvM0jZc
#reReplace(ytID,".*/vi/([^/]+)/.*", "\1")# == OZ3jyvM0jZc
</pre>
</cfoutput>
The key to keeping this simple is using the [^/]+ to match one or more characters that aren't /
I think regex might be the wrong tool for this job. How about using lists?
<cfset ytStr = '<img src="http://img.youtube.com/vi/0Z3jyvM0jZc/2.jpg" alt="" />'>
<cfset ytID = ListGetAt(ytStr, 4, '/')>
<cfset ytID = '<img src="http://img.youtube.com/vi/0Z3jyvM0jZc/2.jpg" alt="" />'>
<cfset sLenPos=REFind("(vi=?(\=|\/))([-a-zA-Z0-9_]+)|(vi=\/)([-a-zA-Z0-9_]+)", ytID, 1, "True")>
<cfoutput>
#mid(ytID, sLenPos.pos[1], sLenPos.len[1])#
</cfoutput>

scale PDF to single page

Is there a simple way to scale the pdf created by cfdocument or cfpdf to a single page using CF8? My output (a calendar) could possibly extend to page 2 depending on the number of events. I'd rather scale the calendar to fit it in one page. I assume I can create the pdf with cfdocument. Use cfpdf to check the page numbers and loop while totalPages > 1 create the PDF with a lesser scale.
psudo code:
pdfScale = 100
cfdocument scale = "#pdfScale#"
cfpdf action = "getinfo" name = "mypdf"
cfloop while mypdf.totalPages > 1
pdfScale = pdfScale -5
cfdocument scale = "#pdfScale#"
cfpdf action = "getinfo" name = "mypdf"
/cfloop
Am I on the right track or am I missing something to make this easier? Thanks.
Your theory seems sound to me - you should try it and find out. Since that's a rather boring answer, I've also converted your pseudocode to real code:
<cfset pdfScale = 100 />
<cfset pdfObj = "" />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#">document contents</cfdocument>
<cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
<cfloop condition = "pdfInfo.TotalPages gt 1">
<cfset pdfScale -= 5 />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#">document contents</cfdocument>
<cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
</cfloop>
Depending on your setup, you might also want to abstract the creation of the PDF into a function, so that you don't have to re-write all of the content twice on the page. Or you could use an include. Heck, if there is any sort of complex processing going on to render the HTML for the PDF (which I assume there is, since you're making a calendar), then you might even want to pre-render the content and re-use it, like so:
<cfsavecontent variable="docContents">document contents go here</cfsavecontent>
<cfset pdfScale = 100 />
<cfset pdfObj = "" />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#"><cfoutput>#docContents#</cfoutput></cfdocument>
<cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
<cfloop condition = "pdfInfo.TotalPages gt 1">
<cfset pdfScale -= 5 />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#"><cfoutput>#docContents#</cfoutput></cfdocument>
<cfpdf action="getInfo" source="pdfObj" name="pdfInfo" />
</cfloop>