-
Notifications
You must be signed in to change notification settings - Fork 217
sagews custom modes
By default, running a cell in a Sage worksheet causes the input to be run as Sage commands, with output from Sage written to the output of the cell. Mode commands in a Sage worksheet cause the input to be run through some other process to create cell output. For example,
- Typing
%md
at the start of a cell causes cell input to be rendered as markdown in the cell output. - Typing
%r
causes cell input to be treated as statements in the R language, with corresponding output. - Typing
%HTML
causes cell input to be treated as HTML, rendered as the output.
There are many built-in modes (e.g. Cython, GAP, Pari, R, Python, Markdown, HTML, etc...)
Note: If it is not the default mode of your *.sagews
worksheet, a mode command must be the first line of a cell. In other words, make sure the command %md
, %r
, or %HTML
is the first line of a cell.
Alternatively, you can make any mode the default for all cells in the worksheet using %default_mode <some_mode>
. Then all cells will be using that chosen mode. If you choose this approach, you may still explicitly use %sage
for cells you want processed by the Sage interpreter (or %foo
to explicitly switch to any non-default mode).
There is an entire section of the FAQ page CoCalc Worksheet (and User Interface) Help dedicated to questions about the built-in modes. It had 10 questions-and-answers in it as of July 28, 2016.
You can view available built-in modes by selecting Help > Mode commands in the Sage toolbar while cursor is in a sage cell. That will
insert the line print('\n'.join(modes()))
into the current cell.
Custom mode commands are modes defined by the user. Like any mode command, a custom mode command processes the input section of a cell and writes the output. As stated in the help for modes,
Create your own mode command by defining a function that takes a string as input and outputs a string. (Yes, it is that simple.)
Custom mode commands can be used to
- render or compile cell input into cell output
- send commands to other processes and show the results
Here are some examples:
Define the mode in a sage cell, as follows:
import pandas as pd
from io import StringIO
def csv_table(str):
print(pd.read_csv(StringIO((str)),index_col = 0))
Input:
%csv_table
Sample,start,middle,end
A,2,5,51
B,6,8,11
C,7,22,41
Output:
start middle end
Sample
A 2 5 51
B 6 8 11
C 7 22 41
NOTE: Sage's show
command is also aware of Pandas tables,
so if you instead define
def csv_table(str):
show(pd.read_csv(StringIO((str)),index_col = 0))
then %csv_table
will produce nice HTML output.
Define the mode:
import json
import yaml
def j2y(str):
print(yaml.safe_dump(json.loads(str)))
Input:
%j2y
{
"foo": "bar",
"baz": [
"xyzzy",
"plugh"
]
}
Output:
baz: [xyzzy, plugh]
foo: bar
In this example, each input line is a number with units, possibly followed by target units. If target units are not specified, SI units are the target. This example uses the Sage Units of Measurement package.
Define the mode:
def convert_units(str):
for line in str.split('\n'):
if 'units' in line:
lval = eval(line)
if isinstance(lval, tuple):
print(lval[0].convert(lval[1]))
else:
print(lval.convert())
Input:
%convert_units
# pounds to kilograms
175.0 * units.mass.pound
# miles to kilometers
3.0 * units.length.mile, units.length.kilometer
# an adult doing moderate exercise might burn 200 kcal per hour
# convert to watts
200.0 * units.energy.calorie * units.si_prefixes.kilo/units.time.hour, units.power.watt
Output:
79.37866475*kilogram
4.828032*kilometer
232.6*watt
This example uses Biopython, which is already installed on CoCalc.
Define the mode:
from Bio.Seq import Seq
def revcomp(str):
s = Seq(str)
print(s.reverse_complement())
Input:
%revcomp
ATGC
GCTCCGACACTTT
Output:
AAAGTGTCGGAGC
GCAT
Suppose you want several bash processes with different working directories or environment variables controlled from the same worksheet. You can use the built-in jupyter
command to create several custom modes.
More information on "the sage-jupyter bridge" is available at Sage Jupyter. Code creating a mode for anaconda3 is available by selecting Modes > Jupyter bridge. You can view available Jupyter kernels by selecting Help > Jupyter kernels in the Sage toolbar while cursor is in a sage cell. That will
insert the line print(jupyter.available_kernels())
into the current cell.
Define the modes:
sh1 = jupyter("bash")
sh2 = jupyter("bash")
Cell 1:
%sh1
# show PID of current sh process
echo $BASHPID
-- output --
23723
Cell 2:
%sh2
echo $BASHPID
-- output --
23727
Cell 3:
%sh1
echo $BASHPID
-- output --
23723
In this example, any cell in the custom mode consists of shell commands to be run on a remote server. The same session is used for all cells in the given mode.
Notes:
- The CoCalc project must have Internet access. This is an upgrade, only available to users with a paid subscription. (See also "Why Should I Purchase a Subscription?".)
- Configure ssh public and private keys with empty passphrase.
- Set host and user for the remote connection.
- You may want to set IdentityFile in your ~/.ssh/config file.
Define the mode:
%sage
from pexpect import pxssh
from ansi2html import Ansi2HTMLConverter
conv = Ansi2HTMLConverter(inline=True, linkify=True)
s = pxssh.pxssh(echo = False)
host = 'myhost.mydomain.org'
user = 'joe'
if s.login(host, user):
def sshexec(code):
for line in code.split('\n'):
s.sendline(line)
s.prompt()
h = s.before
h = conv.convert(h, full = False)
h = '<pre style="font-family:monospace;">'+h+'\n</pre>'
salvus.html(h)
print 'sshexec defined; logout with s.logout()'
else:
print 'sshexec setup failed'
Input:
%sshexec
ls
cd /tmp
Output:
... ls listing, showing color-ls output if available ...
Input in second cell, showing that working directory is retained
%sshexec
pwd
The following function takes whatever the cell input is, executes the code in FriCAS
, performs some simple substitutions on the FriCAS
output and then displays it using Markdown
:
Define the mode:
%sage
def fricas_tex(s):
import re
t = fricas.eval(s)
t=re.compile(r'\r').sub('',t)
# mathml overbar
t=re.compile(r'¯').sub('‾',t,count=0)
# cleanup FriCAS LaTeX
t=re.compile(r'\\leqno\(.*\)\n').sub('',t)
t=re.compile(r'\\sb ').sub('_',t,count=0)
t=re.compile(r'\\sp ').sub('^',t,count=0)
md(t, hide=False)
With this mode, FriCAS
can generate output that is (almost) compatible with Markdown
format.
For example you can use this new mode in a cell with the following input:
%fricas_tex
)set output algebra off
)set output mathml off
)set output tex on
sqrt(2)/2+1
Output:
If you don't find what you need, or if you'd like to ask a question, then please email [email protected] at any time. We'd love to hear from you! Please include a link (the URL address in your browser) to any relevant project or document, as part of your email.
This Wiki is for CoCalc.com.
A more structured documentation is the CoCalc User Manual.
For further questions, please contact us.