Avoiding formatting of DOORS object text using DXL - ibm-doors

I am writing DXL script in which few object text has borders(like one complete row of table is copied).
I have to emphasize the "shall" word in shall.
But using findPlainText() method, it changes the formatting of object text which have borders.
Initially the objects before scripts run is:
After running the script to make "shall" word Bold, i wrote DXL script:
void Change_Shall(Object o, string objText)
{
int off=0
int len=0
string StartUpperText = ""
string FontText = ""
string StartText = ""
string FindText = ""
bool IsChanged = false
string OriginalObjText = objText
string UpperFontObjText = upper(objText)
while (findPlainText(UpperFontObjText, "SHALL", off, len, true, false))
{
StartUpperText = UpperFontObjText[0:off-1]
UpperFontObjText = UpperFontObjText[off+len:]
FindText = OriginalObjText[off:off+len-1]
StartText = OriginalObjText[0:off-1]
OriginalObjText = OriginalObjText[off+len:]
if(FontText == "")
FontText = StartText "{\\b " FindText "}"
else
FontText = FontText StartText "{\\b " FindText "}"
//print FindText "\t\t" UpperFontObjText "\n"
IsChanged = true
off = 0
len = 0
}
if(IsChanged == true)
o."Object Text" = richText FontText OriginalObjText
}
The object text with border after this script runs get changes like
How can formatting of object text with borders be avoided and border is preserved in the object text.

I'm not sure how you're getting "Object Text" from Object o, but my guess is you're using o."Object Text" "" to cast it as a string. Is that right?
If so, then that is stripping all the rich text (including your borders) before you do anything to it. Try using string objText = richTextWithOle o."Object Text", or string objText = richText o."Object Text", and then try removing the unnecessary parameter to your function string objText, as a reference to this already comes along with Object o
I'm assuming based on how your table looks that it is a RichText table, in which case I believe your code will still work, it's just that I suspect you're starting with a string stripped of richText and adding richtext to it. Sometimes Word OLE objects with tables can look like that too, in which case you'd have to use COM to manipulate the OLE.
Hope this helps.

Related

How to split uncode string into characters

I have strings like
"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8",
"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb",
"\U0aa6\U0abe\U0ab5\U0acb",
"\U0a96\U0a82\U0aa1"
But I want to split this strings by unicode character
I dont know hot to do. I know components seprated by function but it's no use here.
\nAny help would be apperiaciated
If the strings you're getting really contain \U characters, you need to parse them manually and extract the unicode scalar values. Something like this:
let strings = [
"\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8",
"\\U0a97\\U0ac1\\U0ab8\\U0acd\\U0ab8\\U0acb",
"\\U0aa6\\U0abe\\U0ab5\\U0acb",
"\\U0a96\\U0a82\\U0aa1"
]
for str in strings {
let chars = str.components(separatedBy: "\\U")
var string = ""
for ch in chars {
if let val = Int(ch, radix: 16), let uni = Unicode.Scalar(val) {
string.unicodeScalars.append(uni)
}
}
print(string)
}
You can map your array, split its elements at non hexa digit values, compact map them into UInt32 values, initializate unicode scalars with them and map the resulting elements of your array into a UnicodeScalarView and init a new string with it:
let arr = [
#"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8"#,
#"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb"#,
#"\U0aa6\U0abe\U0ab5\U0acb"#,
#"\U0a96\U0a82\U0aa1"#]
let strings = arr.map {
$0.split { !$0.isHexDigit }
.compactMap { UInt32($0, radix: 16) }
.compactMap(Unicode.Scalar.init)
}.map { String(String.UnicodeScalarView($0)) }
print(strings)
This will print
["બહુવચન", "ગુસ્સો", "દાવો", "ખંડ"]
So, the string that comes back already has the "\" because in order to use components you'd need to have an additional escaping "\" so that you'd be able to do:
var listofCodes = ["\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8", "\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8"]
var unicodeArray :[String] = []
listofCodes.forEach { string in
unicodeArray
.append(contentsOf: string.components(separatedBy: "\\"))
unicodeArray.removeAll(where: {value in value == ""})
}
print(unicodeArray)
I will revise this answer once you specify how you are obtaining these strings, as is I get a non-valid string error from the start.

Syntax-highlighting Text With a Custom List of Keywords

I'm working on a macOS application. I need to syntax-highlight text that is placed over TextView (NSTextView) with a list of selected words. For simplicity, I'm actually testing the same feature on the iPhone Simulator. Anyway, a list of words to highlight comes as a form of an array. The following is what I have.
func HighlightText {
let tagArray = ["let","var","case"]
let style = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
style.alignment = NSTextAlignment.Left
let words = textView.string!.componentsSeparatedByString(" ") // textView.text (UITextView) or textView.string (NSTextView)
let attStr = NSMutableAttributedString()
for i in 0..<words.count {
let word = words[i]
if HasElements.containsElements(tagArray,text: word,ignore: true) {
let attr = [
NSForegroundColorAttributeName: syntaxcolor,
NSParagraphStyleAttributeName: style,
]
let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr)
attStr.appendAttributedString(str)
} else {
let attr = [
NSForegroundColorAttributeName: NSColor.blackColor(),
NSParagraphStyleAttributeName: style,
]
let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr)
attStr.appendAttributedString(str)
}
}
textView.textStorage?.setAttributedString(attStr)
}
class HasElements {
static func containsElements(array:Array<String>,text:String,ignore:Bool) -> Bool {
var has = false
for str in array {
if str == text {
has = true
}
}
return has
}
}
The simple methodology here is to separate the entire string of text into words with a white space (" ") and puts each word in an array (words). The containsElements function simply tells whether or not the selected word contains one of the keywords in the array (tagArray). If it returns true, the word is put in an NSMutableAttributedString with a highlight color. Otherwise, it's put in the same attributed string with a plain color.
The problem with this simple methodology is that a separated word puts the last word and /n and the next word together. For example, if I have a string like
let base = 3
let power = 10
var answer = 1
, only the first 'let' will be highlighted as the code puts 3 and the next let together like '3\nlet.' If I separate any word containing \n with a fast enumeration, the code won't detect each new paragraph well. I appreciate any advice to make it better. Just FYI, I'm going to leave this topic open to both macOS and iOS.
Muchos thankos
Couple different options. String has a function called componentsSeparatedByCharactersInSet that allows you to separate by a character set you define. Unfortunately this won't work since you want to separate by \n which is more than one character.
You could split the words twice.
let firstSplit = textView.text!.componentsSeparatedByString(" ")
var words = [String]()
for word in firstSplit {
let secondSplit = word.componentsSeparatedByString("\n")
words.appendContentsOf(secondSplit)
}
But then you wouldn't have any sense of the line breaks.. You'd need to re add them back in.
Finally, the easiest hack is simply:
let newString = textView.text!.stringByReplacingOccurrencesOfString("\n", withString: "\n ")
let words = newString.componentsSeparatedByString(" ")
So basically you add your own spaces.

Add string to beginning of another string

Basic question
I have 2 strings. I want to add one string to another? Here's an example:
var secondString= "is your name."
var firstString = "Mike, "
Here I have 2 strings. I want to add firstString to secondString, NOT vice versa. (Which would be: firstString += secondString.)
More detail
I have 5 string
let first = "7898"
let second = "00"
let third = "5481"
let fourth = "4782"
var fullString = "\(third):\(fourth)"
I know for sure that third and fourth will be in fullString, but I don't know about first and second.
So I will make an if statement checking if second has 00. If it does, first and second won't go in fullString. If it doesn't, second will go intofullString`.
Then I will check if first has 00. If it does, then first won't go inside of fullString, and if not, it will go.
The thing is, I need them in the same order: first, second, third fourth. So in the if statement, I need a way to potentially add first and second at the beginning of fullString.
Re. your basic question:
secondString = "\(firstString)\(secondString)"
or
secondString = firstString + secondString
Here is a way to insert string at the beginning "without resetting" per your comment (first at front of second):
let range = second.startIndex..<second.startIndex
second.replaceRange(range, with: first)
Re. your "more detail" question:
var fullString: String
if second == "00" {
fullString = third + fourth
} else if first == "00" {
fullString = second + third + fourth
} else {
fullString = first + second + third + fourth
}
From the Apple documentation:
String values can be added together (or concatenated) with the addition operator (+) to create a new String value:
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome now equals "hello there"
You can also append a String value to an existing String variable with the addition assignment operator (+=):
var instruction = "look over"
instruction += string2
// instruction now equals "look over there"
You can append a Character value to a String variable with the String type’s append() method:
let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"
So you are pretty much free to add these in any way shape or form.
Which includes
secondstring += firststring
Edit to accommodate the new information:
Strings in Swift are mutable which means you can always add to a string in-place without recreating any objects.
Something like (pseudo-code)
if(second != "00")
{
fullstring = second + fullstring
//only do something with first if second != 00
if(first != "00")
{
fullstring = first + fullstring
}
}

(DOORS/DXL) Script for Split Object text in some atributtes using Tab

I'm using for for a year but now I have to modify small scripts and I'm a newbie with DXL. I have searched in before questions but I don't know how I can do it.
I have to develope a script that analyzes all objects in the same formal module to extract from each "object text" different strings separated by tab, to be written in other different attributes of the same object.
The formal module contents has been imported from Word. In that way that normal text format is defined as "object text" and every Title style is associated to a given level heading. In that way each object is provided with object heading or object text (but not both at the same time). Objects with object heading doesn't require any further action. However for objects provided with object text, I have to extract from object text some atributes separated by tabs.
For example a typical object text could be:
NNNN TEXT/TABLE/OLE OBJECT/ANY OTHER STRING (XXXXXX) (YYYYYY)
After apply the script it should be converted as:
Attribute 1: NNNN
Object Text: TEXT/TABLE/OLE OBJECT/ANY OTHER STRING
Attribute 2: XXXXXX
Attribute 3: YYYYYY
I have small script as example but I have passed all the morning trying to modify it to get I need but I can't do it:
Object o = current
//bool get_text(Object o) {return o."Object Heading" "" != ""}
string get_text(Object o)
{
if (o."Object Heading" "" != "")
return "Object Heading"
else
return "Object Text"
}
Regexp r_id = regexp "(http://0-9a-z/.+) "
for o in current Module do
{
string texto = o.(get_text(o))
if (r_id text)
{
o."Attribute 1" = textmatch 1
string input = richTextWithOle(o.(get_text(o)))
string output = cutRichText(input, 0, length(textmatch 1))
o.(get_text(o)) = richText(output)
}
}
This was a complicated one, but I think I have it figured out. Thanks for posting this because I may find it useful in the future as well.
I tried this out and it seems to work:
Object o
string get_text(Object o)
{
if (o."Object Heading" "" != "")
return "Object Heading"
else
return "Object Text"
}
char cTab = '\t' //The tab character to find
Buffer b = create
string tmp = "" //Needed to concatenate buffer parts
int offset = 0
for o in current Module do
{
string attr = get_text(o)
b = o.attr //Put the contents in the buffer
offset = contains(b, cTab) //Find the first tab
o."Attribute 1" = b[0:offset-1] //Set the first Attribute
b = b[offset+1:] //Remove the first attribute from the text
offset = contains(b, cTab)
if(offset > -1)
{
if(attr == "Object Heading") o.attr = b[0:offset-1]
b = b[offset+1:]
offset = contains(b, cTab)
if(offset > -1)
{
o."Attribute 2" = b[1:offset-2] //Set the second Attribute without the ()
b = b[offset+1:]
o."Attribute 3" = b[1:length(b)-2] //Set the third Attribute without the ()
} else {
o."Attribute 2" = b[1:length(b)-2] //Set the second Attribute without the ()
}
} else {
if(attr == "Object Heading") o.attr = b[0:]
}
if(attr == "Object Text")
{
b = richTextWithOle(o.attr) "" //This section removes the attributes from the contents without losing the rich text formatting and OLEs that may be present.
string word = o."Attribute 1"
offset = contains(b, word, 0)
tmp = b[0:offset-1] "" b[(offset+length(word)+5):]
b = tmp
word = "(" o."Attribute 2" ")"
offset = contains(b, word, 0)
if(offset > -1)
{
tmp = b[0:offset-6] "" b[offset+length(word):]
b = tmp
}
word = "(" o."Attribute 3" ")"
offset = contains(b, word, 0)
if(offset > -1)
{
tmp = b[0:offset-6] "" b[offset+length(word):]
}
o.attr = richText(tmp) //Set the Object Text or Heading
}
}
delete b //Release the buffer resources
Let me know if this gives you any trouble or if you want more detailed explination of the code.
EDIT: I updated the above code to take care of the issues you mentioned. It should be all set now. Let me know if you have any more trouble with it.

Extract More than 3 Words After the First Word

In the app I'm working on, I need to extract the first word from a String and put it into another String and the rest of the words in yet another String. I was able to extract the first word using:
String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner"
int spacePos3 = pString.indexOf(" ");
String pFirstWord = pString.substring(0,spacePos3);
Result : KOF0000094
Now I want the "Implementation:ListingRequest:User FO-Partner" to put
in another String.
Thanks for your help in advance
Simplest solution with what you already have.
String restOfString = pString.substring(spacePos3+1)
String pSecondWord = pString.substring(spacePos3 + 1);
String whole = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
String firstWord = "";
String restOfWords = "";
int spacesIndex = whole.indexOf(" ", 0);
restOfWords = whole.substring(spacesIndex, whole.length());
restOfWords = restOfWords.trim();
firstWord = whole.substring(0, spacesIndex);
firstWord = firstWord.trim();
This is simple string parsing... just find the first index of the first space... i.e. in a for loop...
if(string.charAt(i) == Characters.SPACE)
indexOfSpace = i;
Then your first word will be
String part1 = string.substring(0,indexOfSpace);
and the second string will be
String part2 = string.substring(indexOfSpace + 1);
Try using another call to substring(). What is the index of the first character in the string you want? What is the index of the last character?
You already have the index of the first space, which marks the end of the first word, so all you need to do is take the substring from the index immediately after that (so you don't include the space itself) to the end of the string.
You're probably better of using the split function
It would look something like this:
String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
String[] parts = pString.split(" ");
String partone = parts[0];
String partwo = parts[1] + " " +parts[2];
Or something similar, if there are going to be more spaces in the part following the first word you could use a loop or something similar;
You could use split, for instance...
static String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
static String[] pFirstWord = pString.split(" ");
/**
* #param args
*/
public static void main(String[] args) {
for(String word : pFirstWord) {
System.out.println(word);
}
}
This returned...
KOF0000094
Implementation:ListingRequest:User
FO-Partner
So the last string would be pFirstWord[1] + pFirstWord[2]
String class has a split method: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String)
Use that if you want to get all the words.
EDIT: as mentioned in the comments, String.split is not supported in BB Java.
Or this if you just want the first word and the rest of the string:
int index=yourstring.indexOf(" ");
String firstWord = yourstring.substring(0,index);
String rest = yourstring.substring(index+1);

Resources