The right way to print a collection with delimiter in SmallTalk - Squeak? - oop

I have been trying to redefine the printOn method by using this code:
coordinates do: [:elem | aStream print: elem] separatedBy: [aStream print: ' ,']
where "coordinates" stands for the name of the collection (OrderedCollection), but i was expecting to print this when calling to Transcript show:
(2/2) ,(1/1) ,(3/3) ,(-4/4)
I got this instead:
(2/2)','(1/1)','(3/3)','(-4/4)
i. e the quotes was printed as well.
I have tried to play with it, defining a local variable and use it, etc.
Nothing worked.

Don't use #print: to print strings. Use #nextPutAll: to be safe (works for all collections). #print: writes a string representation on the stream and surrounds the argument with quotes, that's why you get quotes in the output.

Related

How do I replace part of a string with a lua filter in Pandoc, to convert from .md to .pdf?

I am writing markdown files in Obsidian.md and trying to convert them via Pandoc and LaTeX to PDF. Text itself works fine doing this, howerver, in Obsidian I use ==equal signs== to highlight something, however this doesn't work in LaTeX.
So I'd like to create a filter that either removes the equal signs entirely, or replaces it with something LaTeX can render, e.g. \hl{something}. I think this would be the same process.
I have a filter that looks like this:
return {
{
Str = function (elem)
if elem.text == "hello" then
return pandoc.Emph {pandoc.Str "hello"}
else
return elem
end
end,
}
}
this works, it replaces any instance of "hello" with an italicized version of the word. HOWEVER, it only works with whole words. e.g. if "hello" were part of a word, it wouldn't touch it. Since the equal signs are read as part of one word, it won't touch those.
How do I modify this (or, please, suggest another filter) so that it CAN replace and change parts of a word?
Thank you!
this works, it replaces any instance of "hello" with an italicized version of the word. HOWEVER, it only works with whole words. e.g. if "hello" were part of a word, it wouldn't touch it. Since the equal signs are read as part of one word, it won't touch those.
How do I modify this (or, please, suggest another filter) so that it CAN replace and change parts of a word?
Thank you!
A string like Hello, World! becomes a list of inlines in pandoc: [ Str "Hello,", Space, Str "World!" ]. Lua filters don't make matching on that particularly convenient: the best method is currently to write a filter for Inlines and then iterate over the list to find matching items.
For a complete example, see https://gist.github.com/tarleb/a0646da1834318d4f71a780edaf9f870.
Assuming we already found the highlighted text and converted it to a Span with with class mark. Then we can convert that to LaTeX with
function Span (span)
if span.classes:includes 'mark' then
return {pandoc.RawInline('latex', '\\hl{')} ..
span.content ..
{pandoc.RawInline('latex', '}')}
end
end
Note that the current development version of pandoc, which will become pandoc 3 at some point, supports highlighted text out of the box when called with
pandoc --from=markdown+mark ...
E.g.,
echo '==Hi Mom!==' | pandoc -f markdown+mark -t latex
⇒ \hl{Hi Mom!}

Does mIRC Scripting have an escape character?

I'm trying to write a simple multi-line Alias that says several predefined strings of characters in mIRC. The problem is that the strings can contain:
{
}
|
which are all used in the scripting language to group sections of code/commands. So I was wondering if there was an escape character I could use.
In lack of that, is there a method, or alternative way to be able to "say" multiple lines of these strings, so that this:
alias test1 {
/msg # samplestring}contains_chars|
/msg # _that|break_continuity}{
}
Outputs this on typing /test1 on a channel:
<MyName> samplestring}contains_chars|
<MyName> _that|break_continuity}{
It doesn't have to use the /msg command specifically, either, as long as the output is the same.
So basically:
Is there an escape character of sorts I can use to differentiate code from a string in mIRC scripting?
Is there a way to tell a script to evaluate all characters in a string as a literal? Think " " quotes in languages like Java.
Is the above even possible using only mIRC scripting?
"In lack of that, is there a method, or alternative way to be able to "say" multiple lines of these strings, so that this:..."
I think you have to have to use msg # every time when you want to message a channel. Alterativelty you can use the /say command to message the active window.
Regarding the other 3 questions:
Yes, for example you can use $chr(123) instead of a {, $chr(125) instead of a } and $chr(124) instead of a | (pipe). For a full list of numbers you can go to http://www.atwebresults.com/ascii-codes.php?type=2. The code for a dot is 46 so $chr(46) will represent a dot.
I don't think there is any 'simple' way to do this. To print identifiers as plain text you have to add a ! after the $. For example '$!time' will return the plain text '$time' as $time will return the actual value of $time.
Yes.

How to print multiple outputs in Smalltalk

|X Y A B C D|
Y:= 7.
X:= 6.
(X = Y)
ifTrue: [X := 0]
ifFalse:[X := 1].
B:=2.
C:=5.
D:=1.
A:= (B squared)*(C-D).
"print both A and X to screen here"
Simple enough little smalltalk example. I'm just curious how I can get this to print X and A as outputs? is there any way to do it w/o having to perform a 'print it' on the top 6 lines and a seperate 'print it' on the bottom 5 lines? if it could print out on just a 'do it' or a single 'print it' please let me know!
You should define what is "printing" and what is X and A.
If "printing" is a result of the "print it" action, then you are talking in general about returning X and A, as "print it" prints the return result of the selected code. This way you have to think about an object which will represent X and A. For this object you can define a printString method or printOn: and get the result printed. Or you can cheat a bit and return a point by doing X#A.
If you are talking about actually printing the thing somewhere then you have to tell more about where do you want to do it. You can print it in Transcript or similar, but there you have to explicitly send a message to the Transcript with what you want to be printed.
Now if you want to use this for "debugging/testing" reasons, it can be easier to go with "inspect it". In your code you can send inspect messages to the objects that you want to look at, and during the execution inspectors will open showing this objects.
Also I encourage you to follow conventions and make your variable names start with lowercase letter.
Smalltalk has no equivalent of print() or println() or the like, since most Smalltalk environments live in a window environment. There are ways to write output to stdout or std error, but this is very dialect specific.
One of the places that somehow replaces stdout in most dialects is a place/stream/window called Transcript, in most dialects this is the window that launches first when your start the IDE.
To write something there you simple do:
Transcript show: 'A=', A asString, ' ; X=', X asString.
(please note that in Smalltalk, Strings and Collections are concatenated with a comma)
You can also write a newLine by sending the message cr to the Transcript like so:
Transcript cr.
Does this answer your question?
A hint for further learning/investigation: Transcript is just a Variable that holds a Stream object. show: is a message that writes some String onto that Stream. asString is a method that returns a String representation of an object.

new line in squeak

i want to do something like this: Transcript show: '\n'. how?
Use the following:
Transcript cr
You can use it after a value via a cascade:
Transcript show: 123; cr
From my (long) experience, missing character escapes are one of the few things that are missing in Smalltalk. For streaming, solutions using cr, tab etc. are ok.
However, if you need a particular control character in a string, this may be ugly and hard to read (using "streamContents:", or "withCRs" to add a newLine). Alternatively, you may want to use one of the (non-standard) string expansion mechanisms. For example, in VisualWorks or Smalltalk/X, you can write (if I remember correctly):
'someString with newline<n>and<t>tabs' expandMacros
or even with printf-like slicing of other object's printStrings:
'anotherString<n><t>with newlines<n>and<t>tabs and<p>' expandMacrosWith:(Float pi)
I guess, there is something similar in Squeak and V'Age as well.
But, be aware: these expansions are done at execution time. So you may encounter a penalty when heavily using them on many strings.
The character itself can be reached as Character cr. So, you could also do this:
Transcript show: 'Bla! , Character cr asString.
But of course,
Transcript show: 'Bla!' ; cr.
is way more elegant.
What I do as a convenience is add a method "line" to the String class:
line
^self, String lf
Then you can just say obj showSomething: 'Hello world!' line.
Or call it newline, endl, lf, etc...

get in Object 'Func with Refinement in Rebol

Let's say I have
o: context [
f: func[message /refine message2][
print [message]
if refine [print message 2]
]
]
I can call it like this
do get in o 'f "hello"
But how can I do for the refinement ? something like this that would work
>> do get in o 'f/refine "hello" "world"
** Script Error: in expected word argument of type: any-word
** Near: do get in o 'f/refine
>>
I don't know if there's a way to directly tell the interpreter to use a refinement in invoking a function value. That would require some parameterization of do when its argument is a function! Nothing like that seems to exist...but maybe it's hidden somewhere else.
The only way I know to use a refinement is with a path. To make it clear, I'll first use a temporary word:
>> fword: get in o 'f
>> do compose [(to-path [fword refine]) "hello" "world"]
hello
world
What that second statement evaluates to after the compose is:
do [fword/refine "hello" "world"]
You can actually put function values into paths too. It gets rid of the need for the intermediary:
>> do compose [(to-path compose [(get in o 'f) refine]) "hello" "world"]
hello
world
P.S. you have an extra space between message and 2 above, where it should just be message2
Do this:
o/('f)/refine "hello" "world"
Parens in a path expression are evaluated if they correspond to object field or series pick/poke index references. That makes the above code equivalent to this:
apply get in o 'f ["hello" true "world"]
Note that apply arguments are positional, so you need to know the order the arguments were declared in. You can't do that trick with the function refinements themselves, so you have to use apply or create path expressions to evaluate if you want to parameterize the refinements of the function call.
Use the simple path o/f/refine