Javascript First letter uppercase restlower of two lines "." - uppercase

I want to first letter to be in upper case other in lower. But after ".", it must be upper again..
function firstToUpperCase( str ) {
return str.substr(0, 1).toUpperCase() + str.substr(1);
}
var str = 'prompt("Enter text to convert: ")
var Upcase = firstToUpperCase( str );
document.write(Upcase);

Here's a simplistic answer based on what you provided. It does not take whitespace into account following the period since you didn't mention that in the specs.
function firstToUpperCase(str) {
var parts = str.split(".");
for (i = 0; i < parts.length; i++) {
parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1).toLowerCase();
}
return parts.join(".");
}
If you're trying to deal with sentences, something like this might be a little better, though it does not preserve exact whitespace:
function firstToUpperCase(str) {
var parts = str.split(".");
for (i = 0; i < parts.length; i++) {
sentence = parts[i].trim();
parts[i] = sentence.substring(0, 1).toUpperCase() + sentence.substring(1).toLowerCase();
}
return parts.join(". ");

Related

EA - Table template for single element manipulation

I'm trying to design a template that generates a document based on the following Diagram.
For each System (1 or 2) there is a Chapter, which will be further populated with subchapters for every "Element type C".
Example of chapter structure
The template I'm using is this one:
And it calls a table:
While scripting the fragment of this, for each element type C, I'm checking the connection type ( connection Y) to see if the element is related and can be added to the bottom half of the table. If so, the ID of element Type B is added to an XML structure.
The code I'm using is the following:
function arrange_data_in_xml(objectid) {
//Get the repository type
var repotype = Repository.RepositoryType();
//Create the xml structure
var xmlDOM = new COMObject("MSXML2.DOMDocument.6.0");
xmlDOM.validateOnParse = false;
xmlDOM.async = false;
var node = xmlDOM.createProcessingInstruction("xml", "version='1.0' encoding='ISO-8859-1'");
xmlDOM.appendChild(node);
var xmlRoot = xmlDOM.createElement("EADATA");
xmlDOM.appendChild(xmlRoot);
var xmlDataSet = xmlDOM.createElement("Dataset_0");
xmlRoot.appendChild(xmlDataSet);
var xmlData = xmlDOM.createElement("Data");
xmlDataSet.appendChild(xmlData);
var part1A = Repository.GetElementSet(sqlquery, 2);
//Session.Output(part1A.Count)
//This cycle will iterate over each Element Type B
for (var i = 0; i < part1A.Count; i++) {
var ElementTypeBrow = ""
var countElementTypeB = 0;
Session.Output("DEBUG 0 " + part1A.GetAt(i).ElementID + " -- " + part1A.GetAt(i).Name + " -- " + objectid)
var xmlRow = xmlDOM.createElement("Row");
xmlData.appendChild(xmlRow);
var xmlName = xmlDOM.createElement("Object_ID");
xmlName.text = part1A.GetAt(i).ElementID;
xmlRow.appendChild(xmlName);
var xmlName = xmlDOM.createElement("ElementTypeCName");
xmlName.text = part1A.GetAt(i).Name;
xmlRow.appendChild(xmlName);
for (var k = 0; k < part1A.GetAt(i).TaggedValues.Count; k++) {
var tv = part1A.GetAt(i).TaggedValues.GetAt(k);
if (tv.Name == 'Proprety X') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue1");
xmlName.text = tv.Value;
xmlRow.appendChild(xmlName);
} else if (tv.Name == 'Proprety Y') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue2");
xmlName.text = tv.Value;
xmlRow.appendChild(xmlName);
}
}
for (var j = 0; j < part1A.GetAt(i).Connectors.Count; j++) {
var connector = part1A.GetAt(i).Connectors.GetAt(j);
if (connector.Stereotype == 'Connection type Z') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue3");
xmlName.text = Repository.GetElementByID(connector.SupplierID).Name;
xmlRow.appendChild(xmlName);
} else if (connector.Stereotype == 'Connection type Y') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue4");
xmlName.text = Repository.GetElementByID(connector.ClientID).Name;
xmlRow.appendChild(xmlName);
} else if (connector.Stereotype == 'Connection type X'') {
var ElementTypeB = Repository.GetElementByID(connector.SupplierID)
//Check if the ElementTypeB is connected to the current interface
if (check_interface(ElementTypeB.ElementID) == objectid) {
//Session.Output("DEBUG 1 " + part1A.GetAt(i).Name + " - " + ElementTypeB.Name)
var ElementTypeBalias = ""
if (ElementTypeB.Alias != "") {ElementTypeBalias = " (" + ElementTypeB.Alias + ")"}
ElementTypeBrow = ElementTypeB.Name + ElementTypeBalias + " \n" + ElementTypeBrow
countElementTypeB = countElementTypeB + 1
}
}
}
//Session.Output("DEBUG 1 " +ElementTypeBrow + " - " + countElementTypeBs + " - " + ElementTypeB.Name)
var xmlName = xmlDOM.createElement("ApplicableElementTypeB-Hyperlink");
if (countElementTypeBs > 1) {
xmlName.text = ElementTypeBrow.trimStart();
} else {
xmlName.text = ElementTypeB.ElementGUID+ElementTypeBrow;
}
xmlRow.appendChild(xmlName);
}
return xmlDOM.xml;
}
The problem that I'm having now is the result list of elements is taken as one, ie all of the elements of the bottom half of the table are as one.
Is there a way to manipulate each element individually (for example create a hyperlink for each entry)?
I've tried to rearrange the XML stucture. But the problem remains.
Fragments like this expect there contents in the form of a table, with rows and columns.
Currently you are only returning a single row, but somehow you would like to split the different values for ElementTypeBName-Hyperlink into different rows.
I think you have two possibilities here:
Return each ElementTypeBName-Hyperlink element with a different name e.g. ElementTypeBName-Hyperlink1, ElementTypeBName-Hyperlink2,... and then use each of those in your table template.
Downside of this approach is that it isn't flexible at all, and only useful if you have more or less the same number of ElementB names.
Split your template into two templates. One template for the upper part, and one for the lower part.
Another observation is that you are taking the complicated (and slow) route. For requirements like this, it's much easier to create an SQL template instead of a script template.

Word JS APIs: extending a Range

While working on answering this question I would really like to have been able to extend a Range by a specific number of characters. In the COM API I would have used Range.MoveEnd(). Is there any equivalent that I didn't find in the JS API?
Background: The question referenced is about finding search terms with more than 255 characters - which is a limit in Word for the desktop. The search fails.
The simple way to go about it would be to search the first 254 characters, then expand the found Range by the remaining number of characters and comparing that Range.Text to the full search term.
Not finding any equivalent for expanding a Range in this manner, I had to resort to:
breaking down the search term into < 255 character pieces
search for each piece one-by-one
determine whether each searched piece was adjacent to the previous
then expand a Range to include the adjacent piece
and repeat until all pieces were found
Thus, my question...
async function basicSearch() {
await Word.run(async (context) => {
let maxNrChars = 254;
let searchterm = "";
let shortSearch = true; //search string < 255 chars
let fullSearchterm = "Video provides a powerful way to help you prove your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also type a keyword to search online for the video that best fits your document. Aösdlkvaösd faoweifu aösdlkcj aösdofi "
let searchTermNrChars = fullSearchterm.length;
let nrSearchCycles = Number((searchTermNrChars / maxNrChars).toFixed(0));
let nrRemainingChars = searchTermNrChars - (nrSearchCycles * maxNrChars);
//console.log("Number of characters in search term: " + searchTermNrChars
// + "\nnumber of search cycles required: " + nrSearchCycles
// + "\nremaining number of characters: " + nrRemainingChars);
//numerous ranges are required to extend original found range
let bodyRange = context.document.body.getRange();
bodyRange.load('End');
let completeRange = null;
let resultRange = null;
let extendedRange = null;
let followupRange = null;
let cycleCounter = 0;
let resultText = "";
if (searchTermNrChars > maxNrChars) {
searchterm = fullSearchterm.substring(0, maxNrChars);
cycleCounter++;
shortSearch = false;
}
else { searchterm = fullSearchterm; }
let results = context.document.body.search(searchterm);
results.load({ select: 'font/highlightColor, text' });
await context.sync();
// short search term, highlight...
if (shortSearch) {
for (let i = 0; i < results.items.length; i++) {
results.items[i].font.highlightColor = "yellow";
}
}
else {
//console.log("Long search");
for (let i = 0; i < results.items.length; i++) {
resultRange = results.items[i];
resultRange.load('End');
extendedRange = resultRange.getRange('End').expandTo(bodyRange.getRange('End'));
await context.sync();
//search for the remainder of the long search term
for (let cycle = 1; cycle < nrSearchCycles; cycle++) {
searchterm = fullSearchterm.substring((cycle * maxNrChars), maxNrChars);
//console.log(searchterm + " in cycle " + cycle);
let CycleResults = extendedRange.search(searchterm);
CycleResults.load({ select: 'text, Start, End' });
await context.sync();
followupRange = CycleResults.items[0];
//directly adjacent?
let isAfter = followupRange.compareLocationWith(resultRange);
if (isAfter.value == Word.LocationRelation.adjacentAfter) {
resultRange.expandTo(followupRange);
extendedRange = resultRange.getRange('End').expandTo(bodyRange.getRange('End'));
}
await context.sync();
}
if (nrRemainingChars > 0) {
console.log("In remaining chars");
searchterm = fullSearchterm.substring(searchTermNrChars - nrRemainingChars);
console.log(searchterm);
let xresults = extendedRange.search(searchterm);
xresults.load('end, text');
await context.sync();
let xresult = xresults.items[0];
let isAfter = xresult.compareLocationWith(resultRange);
await context.sync();
console.log(isAfter.value);
if (isAfter.value == Word.LocationRelation.adjacentAfter) {
completeRange = resultRange.expandTo(xresult);
completeRange.load('text');
//completeRange.select();
await context.sync();
resultText = completeRange.text.substring(0, fullSearchterm.length);
console.log("Result" + cycleCounter + ": " + resultText);
}
}
else {
//No remeaining chars
resultRange.load('text');
//resultRange.select();
await context.sync();
resultText = resultRange.text.substring(0, fullSearchterm.length);
completeRange = resultRange;
}
//long search successful?
if (resultText == fullSearchterm) {
completeRange.font.highlightColor = "yellow";
}
else {
console.log("Else! " + resultText + " / " + fullSearchterm);
}
completeRange = null;
}
}
});
That was something we had in the original design, but it was actually removed from the API as it can easily lead to unexpected outcomes (i.e. hidden character inconsistencies, footnotes, etc.), and we could not cover those cases with the resources at hand. We decided to remove it.
That been said I think you can achieve something similar to range.MoveEnd() with Word.js, you just need to define to the end of what ;). One way of doing it is to use the range.expandTo(endRange) method. Again, The interesting thing is how to get the "endRange", so the following example shows how to do it if "end" means the end of the paragraph, probably in your scenario will suffice.
async function run() {
await Word.run(async (context) => {
//assume the range at the end of your 255 characters.
var startRange = context.document.getSelection().getRange("end");
//This one is the range at the end of the paragraph including the selection.
var endRange = context.document.getSelection().paragraphs.getLast().getRange("end");
var deltaRange = startRange.expandTo(endRange);
context.load(deltaRange);
await context.sync();
// this will print the characters after the range all the way to the end of the paragraph.
console.log(deltaRange.text);
});
}
hope this helps or at least sets you up in the right direction.

Swift Type 'string.index' has no subscript members

I'm currently converting C++ code to Swift and I've gotten stuck on one part. The parameter passed into the function is a string and the area where I'm stuck is when attempting to set a variable based on the second to last character of a string to check for a certain character.
The error shows up on this line:
line[i-1]
I've tried casting this value to an Int but this didn't work:
Int(line[i - 1])
I've also tried to see if the string's startIndex function which takes a Int would work but it didn't:
line.startIndex[i - 1]
Here is the full function:
func scanStringForSpecificCharacters(line: String){
var maxOpen: Int = 0;
var minOpen: Int = 0;
minOpen = 0;
maxOpen = 0;
var i = 0
while i < line.characters.count {
for character in line.characters {
//var c: Character = line[i];
if character == "(" {
maxOpen += 1;
if i == 0 || line[i - 1] != ":" {
minOpen += 1;
}
}
else if character == ")"{
minOpen = max(0,minOpen-1);
if i == 0 || line[i-1] != ":"{
maxOpen -= 1;
}
if maxOpen < 0{
break;
}
}
}
if maxOpen >= 0 && minOpen == 0{
print("YES")
}else{
print("NO")
}
}
}
Strings in Swift aren't indexed collections and instead you can access one of four different views: characters, UTF8, UTF16, or unicodescalars.
This is because Swift supports unicode, where an individual characters may actually be composed of multiple unicode scalars.
Here's a post that really helped me wrap my head around this: https://oleb.net/blog/2016/08/swift-3-strings/
Anyway, to answer you question you'll need to create an index using index(after:), index(before:), or index(_, offsetBy:).
In your case you'd want to do something like this:
line.index(line.endIndex, offsetBy: -2) // second to last character
Also, you'll probably find it easier to iterate directly using a String.Index type rather than Int:
let line = "hello"
var i = line.startIndex
while i < line.endIndex {
print(line[i])
i = line.index(after: i)
}
// prints ->
// h
// e
// l
// l
// o
Working with Strings in Swift was changed several times during it's evolution and it doesn't look like C++ at all. You cannot subscript string to obtain individual characters, you should use index class for that. I recommend you read this article:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
As already pointed out in the other answers, the compiler error
is caused by the problem that you cannot index a Swift String with
integers.
Another problem in your code is that you have a nested loop which is
probably not intended.
Actually I would try to avoid string indexing at all and only
enumerate the characters, if possible. In your case, you can
easily keep track of the preceding character in a separate variable:
var lastChar: Character = " " // Anything except ":"
for char in line.characters {
if char == "(" {
maxOpen += 1;
if lastChar != ":" {
minOpen += 1;
}
}
// ...
lastChar = char
}
Or, since you only need to know if the preceding character is
a colon:
var lastIsColon = false
for char in string.characters {
if char == "(" {
maxOpen += 1;
if !lastIsColon {
minOpen += 1;
}
}
// ...
lastIsColon = char == ":"
}
Another possible approach is to iterate over the string and a shifted
view of the string in parallel:
for (lastChar, char) in zip([" ".characters, line.characters].joined(), line.characters) {
// ...
}
As others have already explained, trying to index into Swift strings is a pain.
As a minimal change to your code, I would recommend that you just create an array of the characters in your line up front:
let linechars = Array(line.characters)
And then anywhere you need to index into the line, use linechars:
This:
if i == 0 || line[i-1] != ":" {
becomes:
if i == 0 || linechars[i-1] != ":" {

CTRL+V unformatted on Tinymce

I am trying to copy html text and paste it into an unformatted way in TinyMCE by simply using CTRL + C, CTRL + V.
I have had a hard time to do this as TinyMCE constantly tries to keep the initial formatting. I am using Rails.
Would you know any work around this?
You may configure tinymce to strip all unwanted tags when pasting.
To do this use the tinymce config param paste_preprocess:
paste_preprocess : function(pl, o) {
o.content = window.strip_tags( o.content,'<p><div><ul><ol><li><br>' );
},
with the function strip_tags as follows:
// Strips HTML and PHP tags from a string
// returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
// example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
// returns 2: '<p>Kevin van Zonneveld</p>'
// example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
// returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
// example 4: strip_tags('1 < 5 5 > 1');
// returns 4: '1 < 5 5 > 1'
function strip_tags (str, allowed_tags)
{
var key = '', allowed = false;
var matches = []; var allowed_array = [];
var allowed_tag = '';
var i = 0;
var k = '';
var html = '';
var replacer = function (search, replace, str) {
return str.split(search).join(replace);
};
// Build allowes tags associative array
if (allowed_tags) {
allowed_array = allowed_tags.match(/([a-zA-Z0-9]+)/gi);
}
str += '';
// Match tags
matches = str.match(/(<\/?[\S][^>]*>)/gi);
// Go through all HTML tags
for (key in matches) {
if (isNaN(key)) {
// IE7 Hack
continue;
}
// Save HTML tag
html = matches[key].toString();
// Is tag not in allowed list? Remove from str!
allowed = false;
// Go through all allowed tags
for (k in allowed_array) { // Init
allowed_tag = allowed_array[k];
i = -1;
if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag) ;}
// Determine
if (i == 0) { allowed = true;
break;
}
}
if (!allowed) {
str = replacer(html, "", str); // Custom replace. No regexing
}
}
return str;
}
You may want to have a closer look at this SO-Thread too: TinyMCE Paste As Plain Text

C sharp delimiter

In a given sentence i want to split into 10 character string. The last word should not be incomplete in the string. Splitting should be done based on space or , or .
For example:
this is ram.he works at mcity.
now the substring of 10 chars is,
this is ra.
but the output should be,
this is.
Last word should not be incomplete
You can use a regular expression that checks that the character after the match is not a word character:
string input = "this is ram.he";
Match match = Regex.Match(input, #"^.{0,10}(?!\w)");
string result;
if (match.Success)
{
result = match.Value;
}
else
{
result = string.Empty;
}
Result:
this is
An alternative approach is to build the string up token by token until adding another token would exceed the character limit:
StringBuilder sb = new StringBuilder();
foreach (Match match in Regex.Matches(input, #"\w+|\W+"))
{
if (sb.Length + match.Value.Length > 10) { break; }
sb.Append(match.Value);
}
string result = sb.ToString();
Not sure if this is the sort of thing you were looking for. Note that this could be done a lot cleaner, but should get you started ... (may want to use StringBuilder instead of String).
char[] delimiterChars = { ',', '.',' ' };
string s = "this is ram.he works at mcity.";
string step1 = s.Substring(0, 10); // Get first 10 chars
string[] step2a = step1.Split(delimiterChars); // Get words
string[] step2b = s.Split(delimiterChars); // Get words
string sFinal = "";
for (int i = 0; i < step2a.Count()-1; i++) // copy count-1 words
{
if (i == 0)
{
sFinal = step2a[i];
}
else
{
sFinal = sFinal + " " + step2a[i];
}
}
// Check if last word is a complete word.
if (step2a[step2a.Count() - 1] == step2b[step2a.Count() - 1])
{
sFinal = sFinal + " " + step2b[step2a.Count() - 1] + ".";
}
else
{
sFinal = sFinal + ".";
}