Justify text according to a size as opposed to string length? ASP.NET - asp.net

I have listbox with text in it, and I was asked to see if I could just justify its contents after the dash. My resulting code produced something like this:
Which works fine for scenarios where the text to the left of the dash is less than the max length found from the other items in the listbox (i.e. (B20) is less than (B15-B19), which is the longest entry found, so add some whitespace before the dash).
The issue, though, is that if the text before the dash is same length, it still looks like it isn't justified. Example:
Is there a way to truly line up all the dashes? I would imagine I would have to look at the actual pixel length of the characters before the dash as opposed to the length?
Notes:
I am using ASP.NET Webforms
VB.NET
The text for each item in the listbox is all one string
Right now, my method to accomplish what you see in the first picture is as follows:
Public Sub JustifyDisplayName()
Const ACCOUNT_FOR_DASH As Integer = 4
Dim maxCharCount As Integer = 0
Dim whiteSpace As String = HttpUtility.HtmlDecode(" ")
'Find which one is the longest code
For Each element As TextEntry In Me
If element.Value.Length > maxCharCount Then
maxCharCount = element.Value.Length
End If
Next
'Now, extend the '-' to the max for all items
For Each element As TextEntry In Me
'See how much white space we need to inject
Dim paddingNeeded As Integer = maxCharCount - element.Value.Length
Dim tempDisplay As StringBuilder = New StringBuilder(element.Value)
If paddingNeeded > 0 Then
tempDisplay.Append(CChar(whiteSpace), paddingNeeded + ACCOUNT_FOR_DASH)
tempDisplay.Append(" - " & element.Description)
End If
tempDisplay.Append(" - " & element.Description)
element.DrillDownDisplayNameJustified = tempDisplay.ToString()
Next
End Sub
Thanks.

If you used a fixed-width font, you could make this all much easier. In addition to good ol' Courier, I believe there are others.
If you don't, you're not going to be able to get exactly the right width. You could get close, but you won't get it exactly, because the difference in length between (H60-H95) and (I00-I99) as they are rendered may not evenly divide into increments of one .
But if you really want to give this a try, you'll have to use the System.Drawing namespace, the Graphics class, and a method on Graphics called MeasureString. This will be just to get the lengths of the strings in your selected font, though: System.Drawing doesn't apply to web apps.

If you could append spaces to short items before the dash so that you always have the same number of characters before the dash, you may consider using Monospaced Fonts, where each character occupies the same width - Ref: Similar Question.

Related

How to replace certain part of dynamic string

I want to replace a certain part of dynamic string in vb.net. I will try to explain it in this example:
I have a STRING like this:
&12=1005&14=96&230=28&1116=0074005&1271=45&1272%3d001002003%2612%1276=1
and I want this part 3d001002003 to be changed with some other text that I have entered in a Textbox (or any other element).
Problem is that this STRING is sometimes different in character size:
&12=1005&14=96&230=28&1116=0074005&1271=45&1272%3d001002003%2612%1276=1
&12=15&14=96&230=28&1116=0075&1271=45&1272%3d021022023%26276=1... and so on.
Only constant thing in this STRING is that part which needs to be changed always starts with 3d and always has 11 characters. So, something what I'm looking for is to find the part of string that starts with 3d and contains 11 characters and then replace it with some other content from Textbox.
Thanks in advance!
try using below regex
^3d(?!.* )(?=.*[\w-])[\w -]{11}$
(starting with 3d with following total 11 characters)
OR
^%3d[0-9]{9}%
(starting with %3d with following total 9 numeric(assuming only numeric in-between) ending with % = total 11)
in vb.net
example:
Console.WriteLine(Regex.Replace("&12=15&14=96&230=28&1116=0075&1271=45&1272%3d021022023%26276=1", "%3d[0-9]{9}%", "%R%", RegexOptions.IgnoreCase))

Having issue with fixed length data while displaying into front end

I am using MultiLineLabel component to display fixed length data in to front end,
But it has issue while displaying the data
when data line contains multiple spaces in between e.g.
1234232 44343 4343343
11111111111144343 4343343
Here the first line getting truncated
1234232 44343 4343343
11111111111144343 4343343
as i saw this component its using <p></p>
to display data and <P> has property it will truncate the spaces on display.
Can somebody assist me how can display my fixed length data on front end ?
There is nothing to do with the <p>. This is a common property of HTML - multiple spaces are collapsed into one.
You can pre-process the String you pass to MultiLineLabel with: Strings.replace(original, " ", " ");

.NET regular expression for reddit style bullets, blockquotes, etc

I'm writing an application that will take user input and convert certain character strings to HTML tags in much the same way that reddit does. I have regular expressions for bold, italics, numbered lists, strikethrough, superscript all working properly, but doing the same for blockquotes and bulleted lists are causing problems.
What I have:
* Text (start of line, asterisk, space then text to the next line break)
r = New Regex("(?s)^|\n\*\s(.+?)\n", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
strOutput = r.Replace(strOutput, "<ul><li>$1</li></ul>")
r = Nothing
This appears to be putting bullets in random places.
Likewise, blockquote would be:
> Text (start of line, greater than symbol, space then text to next line break)
r = New Regex("(^?|\n?)\>\s(.+?)\n", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
strOutput = r.Replace(strOutput, "<blockquote>$1</blockquote>")
r = Nothing
Any ideas?
By simplifying your alternations for new line/start of string I was able to get these to work:
(^|\n)\*\s(.+?)\n
(^|\n)\>\s(.+?)\n
For example, looking for "zero or one start of string" with ^? doesn't make a whole lot of sense to me, especially when alternately matching \n.

Drawing.Font appears thinner with each use

I am dynamically adding text to an existing image. What I am finding strange though is that with each use of the pen/brush/font I am using, the text appears to get thinner.
It may be easier to see a snippet of the code.
There are some variables in use in the code below, that are not declared in the code below - this is a snippet of a large chunk of code much of which is irrelevant to the question. This part is what writes the text.
Ultimately all the resources are created as using blocks.
then we get down to the AddTextToGraphicsPath() method - which is shown below. This simply applies the text to the path.
Using fiTextFont As New Font("Arial"), FontStyle.Bold)
Using brush As Brush = New SolidBrush(ColorTranslator.FromHtml("#000000"))
Using pen As Pen = New Pen(ColorTranslator.FromHtml("transparent"))
Using oImage As Image = Image.FromFile(fName)
Using grfx As Graphics = Graphics.FromImage(oImage)
For i As Integer = 0 To loopCount
Using gPath As GraphicsPath = New GraphicsPath()
grfx.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
grfx.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
grfx.CompositingQuality = CompositingQuality.HighQuality
Dim sFormat As New StringFormat(StringFormat.GenericTypographic)
sFormat.Alignment = StringAlignment.Center
Dim textSplit() As String = fiText.Split(vbCrLf)
AddTextToGraphicsPath(gPath, grfx, textSplit(0).Replace(vbLf, ""), fiTextFont, fxPos, fyPos, pen, brush, Nothing, sFormat)
AddTextToGraphicsPath(gPath, grfx, textSplit(1).Replace(vbLf, ""), fiTextFont, fxPos, fyPos + fiTextFont.Size - 2, pen, brush, Nothing, sFormat)
End Using
Next
End Using
End Using
End Using
End Using
End Using
And here is the method which applies the text to the path.
Private Shared Sub AddTextToGraphicsPath(ByRef gPath As GraphicsPath, ByRef grfx As Graphics, ByRef text As String, ByRef font As Font, ByRef x As Single, ByRef y As Single, ByRef pen As Pen, ByRef brush As Brush, ByRef matrix As Matrix, ByRef sFormat As StringFormat)
gPath.AddString(text, font.FontFamily, font.Style, font.Size, New PointF(x, y), sFormat)
If (matrix IsNot Nothing) Then gPath.Transform(matrix)
grfx.DrawPath(pen, gPath)
grfx.FillPath(brush, gPath)
End Sub
Eveything works perfectly well - text is applied in the correct position and with the correct font etc, though the second line seems to be a lot lighter in weight.
If i set the font to Bold the first line is bold, second "appears" to be regular, though stepping through the code i can see that the font does not change.
And the resulting image looks a little something like the example below:
UPDATE
I have now tried the same code, but created new font,pen, brush for each of the calls to AddTestToGraphicsPath and it still does the same; so wondering if this is an issue with GraphicsPath.AddString() ?
Ok - This had been driving me mad for the last couple of days.
Typically, within an hour or so of posting this question I managed to resolve the issue.
I needed to perform a reset on the GraphicsPath before applying my string.
Not 100% sure WHY this causes an issue, though it for sure resolved the issue.
I believe that the reason it happens is that the strings path data from the first path is still present when adding the second string. the grfx.FillPath method is then applying a fill twice to the first one.
So just before adding the string I simply put gPath.Reset() - this ensures that the graphicspath - which is passed by ByRef is reset for the next string to be added.

Character Support Issue - How to Translate Higher ASCII Characters to Lower ASCII Characters

So I have an ASP.Net (vb.net) application. It has a textbox and the user is pasting text from Microsoft Word into it. So things like the long dash (charcode 150) are coming through as input. Other examples would be the smart quotes or accented characters. In my app I'm encoding them in xml and passing that to the database as an xml parameter to a sql stored procedure. It gets inserted in the database just as the user entered it.
The problem is the app that reads this data doesn't like these characters. So I need to translate them into the lower ascii (7bit I think) character set. How do I do that? How do I determine what encoding they are in so I can do something like the following. And would just requesting the ASCII equivalent translate them intelligently or do I have to write some code for that?
Also maybe it might be easier to solve this problem in the web page to begin with. When you copy the selection of characters from Word it puts several formats in the clipboard. The straight text one is the one I want. Is there a way to have the html textbox get that text when the user pastes into it? Do I have to set the encoding of the web page somehow?
System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding(1251).GetBytes(text))
Code from the app that encodes the input into xml:
Protected Function RequestStringItem( _
ByVal strName As System.String) As System.String
Dim strValue As System.String
strValue = Me.Request.Item(strName)
If Not (strValue Is Nothing) Then
RequestStringItem = strValue.Trim()
Else
RequestStringItem = ""
End If
End Function
' I get the input from the textboxes into an array like this
m_arrInsertDesc(intIndex) = RequestStringItem("txtInsertDesc" & strValue)
m_arrInsertFolder(intIndex) = RequestInt32Item("cboInsertFolder" & strValue)
' create xml file for inserts
strmInsertList = New System.IO.MemoryStream()
wrtInsertList = New System.Xml.XmlTextWriter(strmInsertList, System.Text.Encoding.Unicode)
' start document and add root element
wrtInsertList.WriteStartDocument()
wrtInsertList.WriteStartElement("Root")
' cycle through inserts
For intIndex = 0 To m_intInsertCount - 1
' if there is an insert description
If m_arrInsertDesc(intIndex).Length > 0 Then
' if the insert description is of the appropriate length
If m_arrInsertDesc(intIndex).Length <= 96 Then
' add element to xml
wrtInsertList.WriteStartElement("Insert")
wrtInsertList.WriteAttributeString("insertdesc", m_arrInsertDesc(intIndex))
wrtInsertList.WriteAttributeString("insertfolder", m_arrInsertFolder(intIndex).ToString())
wrtInsertList.WriteEndElement()
' if insert description is too long
Else
m_strError = "ERROR: INSERT DESCRIPTION TOO LONG"
Exit Function
End If
End If
Next
' close root element and document
wrtInsertList.WriteEndElement()
wrtInsertList.WriteEndDocument()
wrtInsertList.Close()
' when I add the xml as a parameter to the stored procedure I do this
cmdAddRequest.Parameters.Add("#insert_list", OdbcType.NText).Value = System.Text.Encoding.Unicode.GetString(strmInsertList.ToArray())
How big is the range of these input characters? 256? (each char fits into a single byte). If that's true, it wouldn't be hard to implement a 256 value lookup table. I haven't toyed with BASIC in years, but basically you'd DIM an array of 256 bytes and fill in the array with translated values, i.e. the 'a'th byte would get 'a' (since it's OK as is) but the 150'th byte would get a hyphen.
This seems to work for long dash to short dash and smart quotes to regular quotes. As my html pages has the following as the content type. But it converts all the accented characters to questions marks. Which is not what the Text version of the clipboard has. So I'm closer, I just think I have the target encoding wrong.
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(m_arrFolderDesc(intIndex)))
Edit: Found the correct target encoding for my purposes which is 1252.
System.Text.Encoding.GetEncoding(1252).GetString(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(m_arrFolderDesc(intIndex)))
If you convert to a non-unicode character set, you will lose some characters in the process. If the legacy app reading the data doesn't need to do any string transformations, you might want to consider using UTF-7, and converting it back once it gets back into the unicode world - this will preserve all special characters.

Resources