Path: blob/master/src/packages/frontend/editors/editor-button-bar.ts
1678 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/* Definition and control logic behind the various button bars.6//7There is a level of separation between the button bar's and the actual content what they insert/modify.8This is motivated by editing text, where various markups have different realizations ("B"old button -> **abc** or <b>abc</b>)910There are less/none overlaps for programming languages.1112FUTURE:13* think about creating a dedicated dialog for more elaborate examples,14which should also have a client/server communication to avoid bloat15(think of a repository of hundrets of full examples with explanatory text)16* work out how codemirror should react if there is a text selected or multiple17cursors active (just the primary one!?)1819CONSIDERATIONS:20* buttons should insert code which immediately works:21it's easier for users to delete lines than to end up with some partial broken fragments22*/2324import $ from "jquery";2526export const FONT_SIZES = [27"xx-small",28"x-small",29"small",30"medium",31"large",32"x-large",33"xx-large",34] as const;3536export const FONT_FACES = [37"Serif",38"Sans",39"Arial",40"Arial Black",41"Courier",42"Courier New",43"Comic Sans MS",44"Cursive",45"Georgia",46"Helvetica",47"Impact",48"Lucida Grande",49"Lucida Sans",50"Monaco",51"Palatino",52"Tahoma",53"Times New Roman",54"Ubuntu",55"Verdana",56] as const;5758let i, j, k;5960export const commands = {61shell: {62comment: {63wrap: {64left: "#",65right: "",66multi: true,67space: true,68},69},70set_name_and_email: {71insert: `\72git config --global user.name ""73git config --global user.email ""\74`,75},76initalize_git: {77insert: `\78git init\79`,80},81create_gitignore: {82insert: `\83# See examples of .gitignore files at https://github.com/github/gitignore84echo "85# For CoCalc files like .sage-chat etc86*.sage-chat87*.sage-history88*.term89*.py[cod]" >> .gitignore\90`,91},92clone_local_repo: {93insert: `\94git clone ~/local_dir/\95`,96},97clone_remote_repo: {98insert: `\99git clone https://github.com/sagemathinc/cocalc.git\100`,101},102add_file_to_repo: {103insert: `\104git add afile.py\105`,106},107add_all_to_repo: {108insert: `\109git add *\110`,111},112diff: {113insert: `\114git diff\115`,116},117commit: {118insert: `\119git commit -a -m "commit message"\120`,121},122setup_ssh_for_github: {123insert: `\124set -e125mkdir -p ~/.ssh/126SSHFILE=~/.ssh/id_rsa127ssh-keygen -t rsa -b 4096 -N "" -C "[email protected]" -f $SSHFILE128eval $(ssh-agent -s)129ssh-add ~/.ssh/id_rsa130echo "Below this line is your public SSH key"131cat ~/.ssh/id_rsa.pub132# Copy your public key below and follow the instructions at https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/#platform-linux\133`,134},135push_origin_master: {136insert: `\137git push origin master\138`,139},140141status: {142insert: `\143git status\144`,145},146147add_remote_repo: {148insert: `\149git remote add origin <server>\150`,151},152153list_remote_repos: {154insert: `\155git remote -v\156`,157},158159create_new_branch: {160insert: `\161git checkout -b <branchname>\162`,163},164165switch_branches: {166insert: `\167git checkout <branchname>\168`,169},170171list_branches: {172insert: `\173git branch\174`,175},176177delete_the_feature_branch: {178insert: `\179git branch -d <branchname>\180`,181},182183push_branch: {184insert: `\185git push origin <branchname>\186`,187},188189push_all_branches: {190insert: `\191git push --all origin\192`,193},194195delete_remote_branch: {196insert: `\197git push origin --delete <branchName>\198`,199},200201pull: {202insert: `\203git pull\204`,205},206207merge_branch: {208insert: `\209git merge <branchname>210git diff211git diff --base <filename>212git diff <sourcebranch> <targetbranch>213git add <filename>\214`,215},216217show_history: {218insert: `\219git log\220`,221},222223undo_local_changes: {224insert: `\225git checkout -- <filename>\226`,227},228229get_rid_of_local_changes: {230insert: `\231git fetch origin232git reset --hard origin/master\233`,234},235236search_for: {237insert: `\238git grep "foo()"\239`,240},241},242tex: {243integral: {244insert: "$int_{0}^{infty} \frac{1}{1+x^2},mathrm{d}x$",245},246cases: {247insert: `\248$$249f(n) =250\begin{cases}2512 (n+1) & \text{if} n \equiv 0 \\252(3n+1)/2 & \text{if} n \equiv 1.253\end{cases}254$$\255`,256},257bold: {258wrap: {259left: "\\textbf{",260right: "}",261},262},263italic: {264wrap: {265left: "\\textit{",266right: "}",267},268},269underline: {270wrap: {271left: "\\underline{",272right: "}",273},274},275strikethrough: {276// requires the soul package277wrap: {278left: "\\st{",279right: "}",280},281},282equation: {283default: "x^2",284wrap: {285left: "$",286right: "$",287},288},289display_equation: {290default: "x^2",291wrap: {292left: "$$",293right: "$$",294},295},296insertunorderedlist: {297wrap: {298left: "\\begin{itemize}\n \\item\n",299right: "\\end{itemize}",300},301},302insertorderedlist: {303wrap: {304left: "\\begin{enumerate}\n \\item\n",305right: "\\end{enumerate}",306},307},308format_heading_0: {309strip: [310"format_heading_1",311"format_heading_2",312"format_heading_3",313"format_heading_4",314],315wrap: { left: "", right: "" },316},317format_heading_1: {318strip: ["format_heading_2", "format_heading_3", "format_heading_4"],319wrap: {320left: "\\section{",321right: "}",322},323},324format_heading_2: {325strip: ["format_heading_1", "format_heading_3", "format_heading_4"],326wrap: {327left: "\\subsection{",328right: "}",329},330},331format_heading_3: {332strip: ["format_heading_1", "format_heading_2", "format_heading_4"],333wrap: {334left: "\\subsubsection{",335right: "}",336},337},338format_heading_4: {339strip: ["format_heading_1", "format_heading_2", "format_heading_4"],340wrap: {341left: "\\subsubsubsection{",342right: "}",343},344},345format_code: {346wrap: {347left: "\n\\begin{verbatim}\n",348right: "\n\\end{verbatim}\n",349},350},351indent: {352wrap: {353left: "\n\\begin{quote}\n",354right: "\n\\end{quote}\n",355},356},357quote: {358wrap: {359left: "\n\\begin{quote}\n",360right: "\n\\end{quote}\n",361},362},363table: {364wrap: {365left: "\n\\begin{center}\\begin{tabular}{|c|c|}\n\\hline\ncell1 & cell2 \\\\\ncell3 & cell4 \\\\\n\\hline",366right: "\n\\end{tabular}\\end{center}\n",367},368},369subscript: {370wrap: {371left: "_{",372right: "}",373},374},375superscript: {376wrap: {377left: "^{",378right: "}",379},380},381comment: {382wrap: {383left: "%",384right: "",385multi: true,386space: true,387},388},389horizontalRule: {390wrap: {391left: "\\hrulefill",392//left : "\n\\noindent\\makebox[\\linewidth]{\\rule{\\paperwidth}{0.4pt}}\n"393right: "",394},395},396justifyleft: {397wrap: {398left: "\n\\begin{flushleft}\n",399right: "\n\\end{flushleft}\n",400},401},402justifyright: {403wrap: {404left: "\n\\begin{flushright}\n",405right: "\n\\end{flushright}\n",406},407},408justifycenter: {409wrap: {410left: "\n\\begin{center}\n",411right: "\n\\end{center}\n",412},413},414},415416md: {417bold: {418wrap: {419left: "**",420right: "**",421},422},423italic: {424wrap: {425left: "_",426right: "_",427},428},429underline: {430wrap: {431left: "<u>",432right: "</u>",433},434},435strikethrough: {436wrap: {437left: "~~",438right: "~~",439},440},441code: {442wrap: {443left: "`",444right: "`",445},446},447insertunorderedlist: {448wrap: {449left: " - first\n - second\n",450right: "",451multi: true,452space: false,453newline: true,454trim: false,455},456},457insertorderedlist: {458wrap: {459left: "1. first\n2. second\n",460right: "",461multi: true,462space: false,463newline: true,464trim: false,465},466},467format_code: {468wrap: {469left: " ",470right: "",471multi: true,472space: false,473newline: true,474trim: false,475},476},477format_heading_0: {478strip: [479"format_heading_1",480"format_heading_2",481"format_heading_3",482"format_heading_4",483"format_heading_5",484"format_heading_6",485],486wrap: { left: "", right: "" },487},488indent: {489wrap: {490left: "> ",491right: "",492multi: true,493space: false,494newline: true,495trim: false,496},497},498quote: {499wrap: {500left: "> ",501right: "",502multi: true,503space: false,504newline: true,505trim: false,506},507},508horizontalRule: {509wrap: {510left: "\n---\n",511right: "",512},513},514table: {515wrap: {516left: `\517| Left-Aligned | Center Aligned | Right Aligned |518| :------------ |:---------------:| -------------:|519| col 3 is | some wordy text | 1600 |520| col 2 is | centered | 12 |521| zebra stripes | and math | $\\pi^3$ |\522`,523right: "",524},525},526},527528html: {529italic: {530wrap: {531left: "<em>",532right: "</em>",533},534},535bold: {536wrap: {537left: "<strong>",538right: "</strong>",539},540},541underline: {542wrap: {543left: "<u>",544right: "</u>",545},546},547strikethrough: {548wrap: {549left: "<strike>",550right: "</strike>",551},552},553subscript: {554wrap: {555left: "<sub>",556right: "</sub>",557},558},559superscript: {560wrap: {561left: "<sup>",562right: "</sup>",563},564},565comment: {566wrap: {567left: "<!--",568right: " -->",569space: true,570},571},572insertunorderedlist: {573wrap: {574left: "\n<ul>\n <li> ",575right: "</li>\n</ul>\n",576},577},578insertorderedlist: {579wrap: {580left: "\n<ol>\n <li> ",581right: "</li>\n</ol>\n",582},583},584justifyleft: {585// FUTURE -- define via for loop below586strip: ["justifycenter", "justifyright", "justifyfull"],587wrap: {588left: "",589right: "",590},591},592justifycenter: {593strip: ["justifycenter", "justifyright", "justifyleft"],594wrap: {595left: "<div style='text-align:center'>",596right: "</div>",597},598},599justifyright: {600strip: ["justifycenter", "justifyright", "justifyleft"],601wrap: {602left: "<div style='text-align:right'>",603right: "</div>",604},605},606justifyfull: {607strip: ["justifycenter", "justifyright", "justifyleft"],608wrap: {609left: "<div style='text-align:justify'>",610right: "</div>",611},612},613indent: {614wrap: {615left: "<blockquote>",616right: "</blockquote>",617},618},619format_heading_0: {620strip: [621"format_heading_1",622"format_heading_2",623"format_heading_3",624"format_heading_4",625],626wrap: { left: "", right: "" },627},628format_heading_1: {629// FUTURE -- define via for loop below630strip: ["format_heading_2", "format_heading_3", "format_heading_4"],631wrap: {632left: "<h1>",633right: "</h1>",634},635},636format_heading_2: {637strip: ["format_heading_1", "format_heading_3", "format_heading_4"],638wrap: {639left: "<h2>",640right: "</h2>",641},642},643format_heading_3: {644strip: ["format_heading_1", "format_heading_2", "format_heading_4"],645wrap: {646left: "<h3>",647right: "</h3>",648},649},650format_heading_4: {651strip: ["format_heading_1", "format_heading_2", "format_heading_3"],652wrap: {653left: "<h4>",654right: "</h4>",655},656},657format_code: {658wrap: {659left: "<pre>",660right: "</pre>",661},662},663equation: {664default: "x^2",665wrap: {666left: "$",667right: "$",668},669},670display_equation: {671default: "x^2",672wrap: {673left: "$$",674right: "$$",675},676},677table: {678wrap: {679left: `\680<table>681<tr>682<th>Header 1</th>683<th>Header 2</th>684</tr>685<tr>686<td>Cell 1</td>687<td>Cell 2</td>688</tr>689<tr>690<td>Cell 3</td>691<td>Cell 4</td>692</tr>693</table>\694`,695right: "\n",696},697},698horizontalRule: {699wrap: {700left: "\n<hr size='1'/>\n",701right: "",702},703},704},705706rst: {707// there is intentionally no underline or strikethough in rst708italic: {709wrap: {710left: "*",711right: "*",712},713},714bold: {715wrap: {716left: "**",717right: "**",718},719},720subscript: {721wrap: {722left: " :sub:`",723right: "` ",724},725},726superscript: {727wrap: {728left: " :sup:`",729right: "` ",730},731},732comment: {733wrap: {734left: "\n..",735right: "",736multi: true,737space: true,738},739},740insertunorderedlist: {741wrap: {742left: "\n - ",743right: "",744},745},746insertorderedlist: {747wrap: {748left: "\n 1. ",749right: "",750},751},752justifyleft: {753// FUTURE -- define via for loop below754strip: ["justifycenter", "justifyright", "justifyfull"],755wrap: {756left: "",757right: "",758},759},760justifycenter: {761strip: ["justifycenter", "justifyright", "justifyleft"],762wrap: {763left: "\n.. class:: center\n\n",764right: "",765},766},767justifyright: {768strip: ["justifycenter", "justifyright", "justifyleft"],769wrap: {770left: "\n.. class:: right\n\n",771right: "",772},773},774justifyfull: {775strip: ["justifycenter", "justifyright", "justifyleft"],776wrap: {777left: "\n.. class:: justify\n\n",778right: "",779},780},781indent: {782wrap: {783left: "\n ",784right: "",785},786},787format_heading_0: {788strip: [789"format_heading_1",790"format_heading_2",791"format_heading_3",792"format_heading_4",793],794wrap: { left: "", right: "" },795},796format_heading_1: {797// FUTURE -- define via for loop below798strip: ["format_heading_2", "format_heading_3", "format_heading_4"],799wrap: {800left: "\n===============\n",801right: "\n===============\n",802},803},804format_heading_2: {805strip: ["format_heading_1", "format_heading_3", "format_heading_4"],806wrap: {807left: "\n---------------\n",808right: "\n---------------\n",809},810},811format_heading_3: {812strip: ["format_heading_1", "format_heading_2", "format_heading_4"],813wrap: {814left: "\n",815right: "\n=============\n",816},817},818format_heading_4: {819strip: ["format_heading_1", "format_heading_2", "format_heading_3"],820wrap: {821left: "\n",822right: "\n-------------\n",823},824},825format_code: {826wrap: {827left: `\828.. code:: python829830def f(x):831return 2*x\832`,833right: "\n",834},835},836equation: {837default: "x^2",838wrap: {839left: " :math:`",840right: "` ",841},842},843display_equation: {844default: "x^2",845wrap: {846left: "\n.. math::\n\n ",847right: "\n",848},849},850table: {851// the first is the more complex grid table, the second one is a "simple" table852insert: `\853+------------+------------+-----------+854| Header 1 | Header 2 | Header 3 |855+============+============+===========+856| body row 1 | column 2 | column 3 |857+------------+------------+-----------+858| body row 2 | Cells may span columns.|859+------------+------------+-----------+860| body row 3 | Cells may | - Cells |861+------------+ span rows. | - contain |862| body row 4 | | - blocks. |863+------------+------------+-----------+864\865`,866},867/*868insert: """869===== ===== ======870Inputs Output871------------ ------872A B A or B873===== ===== ======874False False False875True False True876False True True877True True True878===== ===== ======879"""880*/881horizontalRule: {882insert: "\n------------------\n",883},884},885886mediawiki: {887// https://www.mediawiki.org/wiki/Help:Formatting888bold: {889wrap: {890left: "'''",891right: "'''",892},893},894italic: {895wrap: {896left: "''",897right: "''",898},899},900underline: {901wrap: {902left: "<u>",903right: "</u>",904},905},906strikethrough: {907wrap: {908left: "<strike>",909right: "</strike>",910},911},912insertunorderedlist: {913wrap: {914left: "\n* item1\n* item2\n* ",915right: "\n",916},917},918insertorderedlist: {919wrap: {920left: "\n# one\n# two\n# ",921right: "\n",922},923},924comment: {925wrap: {926left: "\n<!--",927right: " -->\n",928space: true,929},930},931indent: {932// pre tag is more for code, but makes more sense than a dysfunctional ":"933wrap: {934left: "\n<pre>",935right: "</pre>\n",936},937},938format_heading_0: {939// FUTURE -- define via for loop below940strip: [941"format_heading_1",942"format_heading_2",943"format_heading_3",944"format_heading_4",945],946wrap: { left: "", right: "" },947},948format_heading_1: {949// FUTURE -- define via for loop below950strip: ["format_heading_2", "format_heading_3", "format_heading_4"],951wrap: {952left: "\n== ",953right: " ==\n",954},955},956format_heading_2: {957strip: ["format_heading_1", "format_heading_3", "format_heading_4"],958wrap: {959left: "\n=== ",960right: " ===\n",961},962},963format_heading_3: {964strip: ["format_heading_1", "format_heading_2", "format_heading_4"],965wrap: {966left: "\n==== ",967right: " ====\n",968},969},970format_heading_4: {971strip: ["format_heading_1", "format_heading_2", "format_heading_3"],972wrap: {973left: "\n===== ",974right: " =====\n",975},976},977format_code: {978wrap: {979left: " <code>",980right: "</code> ",981},982},983horizontalRule: {984wrap: {985left: "\n----\n",986right: "",987},988},989table: {990// https://www.mediawiki.org/wiki/Help:Tables991insert: `\n992{| class="table"993|+Table Caption994! Column 1995! Column 2996|-997|Integral998|Derivative999|-1000|Sin1001|Cos1002|-1003|Tan1004|Sec1005|}\1006`,1007},1008},10091010python: {1011comment: {1012wrap: {1013left: "#",1014right: "",1015multi: true,1016space: true,1017},1018},1019len: {1020insert: "len([1, 2, 5, 6, 10])",1021},1022list: {1023insert: "[1, 2, 5, 6, 10]",1024},1025list_comprehension: {1026insert: "[n+1 for n in range(10) if n%2==0]",1027},1028read_csv_file: {1029insert: `\1030import csv1031import sys10321033f = open('example.csv', 'rt')1034try:1035reader = csv.reader(f)1036for row in reader:1037print(row)1038finally:1039f.close()\1040`,1041},1042write_csv_file: {1043insert: `\1044import csv1045import sys10461047f = open('example.csv', 'wt')1048try:1049writer = csv.writer(f)1050writer.writerow( ('Title 1', 'Title 2', 'Title 3') )1051for i in range(10):1052writer.writerow( (i+1, chr(ord('a') + i), '08/%02d/07' % (i+1)) )1053finally:1054f.close()10551056print(open('example.csv', 'rt').read())\1057`,1058},1059dict: {1060insert: "{'sage':'math', 3:7}",1061},1062set: {1063insert: "{7, 3, 2}",1064},1065tuple: {1066insert: "(2, 3, 7)",1067},1068forloop: {1069insert: `\1070for i in range(5):1071print(i)\1072`,1073},1074forlistloop: {1075insert: `\1076l = [1, 2, 5, 8, 10]1077for i in l:1078print(i)\1079`,1080},1081forelseloop: {1082insert: `\1083for k in [1, 2, 5, 10]:1084if k == 3:1085print("found k, returning")1086break1087else:1088print("Haven't found k == 3")\1089`,1090},1091whileloop: {1092insert: `\1093n = 01094while n < 5:1095print(n)1096n += 1\1097`,1098},1099if: {1100insert: `\1101if i == 1:1102print('i equals 1')\1103`,1104},1105ifelse: {1106insert: `\1107if i == 1:1108print('i equals 1')1109else:1110print('i is not 1')\1111`,1112},1113cases: {1114insert: `\1115if i == 0:1116print("i is zero")1117elif i == 1:1118print("i is one")1119else:1120print("i is neither zero or one")\1121`,1122},1123function: {1124insert: `\1125def f(a, b=0):1126\"\"\"1127This function returns the sum of a and b.1128\"\"\"1129return a + b\1130`,1131},1132lambda: {1133insert: "f = lambda a, b: a + b",1134},1135simple_class: {1136insert: `\1137class MyClass(object):1138\"\"\"1139This is a simple class.1140\"\"\"1141def __init__(self, a):1142self.a = a1143def __repr__(self):1144return "Instance of MyClass with a = %s"%self.a11451146print(MyClass(5))\1147`,1148},1149class_inheritance: {1150insert: `\1151class A(object):1152def __repr__(self):1153return "instance of A"1154def foo(self):1155return "foo"11561157class B(object):1158def __repr__(self):1159return "instance of B"1160def bar(self):1161return "bar"11621163class C(A, B):1164\"\"\"1165This is a class that inherits from classes A and B.1166\"\"\"1167def __repr__(self):1168return "instance of C"11691170# Both foo and bar are defined on instances of C.1171c = C()1172print(c.foo(), c.bar())\1173`,1174},1175},1176cython: {1177cython_class: {1178insert: `\1179cdef class MyClass:1180\"\"\"1181This is a Cython class.1182\"\"\"1183cdef int a1184def __init__(self, int a):1185self.a = a1186def __repr__(self):1187return "Instance of MyClass with a = %s"%self.a11881189print(MyClass(5))\1190`,1191},1192},1193sage: {1194sagemathdoc: {1195url: "http://doc.sagemath.org/",1196},1197sagemathtutorial: {1198url: "http://doc.sagemath.org/html/en/tutorial/index.html",1199},1200sagemathreference: {1201url: "http://doc.sagemath.org/html/en/reference/index.html",1202},1203sagemathkeyboardshortcuts: {1204url: "https://github.com/sagemathinc/cocalc/wiki/Keyboard-Shortcuts",1205},1206sagesyntaxerrors: {1207url: "https://github.com/sagemathinc/cocalc/wiki/MathematicalSyntaxErrors",1208},1209cocalcwiki: {1210url: "https://doc.cocalc.com/sagews.html",1211},1212sagequestion: {1213url: "https://github.com/sagemathinc/cocalc/wiki/SageQuestion",1214},1215help: {1216wrap: {1217left: "help(",1218right: ")",1219},1220},1221differentiate: {1222insert: "diff(1 + x + x^2, x)",1223},1224integrate: {1225insert: "integrate(1 + x + x^2, x)",1226},1227nintegrate: {1228insert:1229"numerical_integral(1 + x + x^2, 0, 3)[0] # [1] gives error bound",1230},1231symbolic_function: {1232insert: "f(x,y) = x * sin(y)",1233},1234matrix: {1235insert: "matrix(2, 3, [1,pi,3, e,5,6])",1236},1237vector: {1238insert: "vector([pi, 2, 3, e])",1239},1240plot2d: {1241insert: "plot(x * sin(x), (x, -2, 10))",1242},1243plot_line: {1244insert:1245"line([(0,0), (1,2), (1/2,pi), (1/2,pi/2)], color='darkgreen', thickness=3)",1246},1247plot_polygon: {1248insert: `\1249a = polygon2d([(0,0), (1,2), (1/2,pi), (1/2,pi/2)], color='orange')1250b = polygon2d([(0,0), (1,2), (1/2,pi), (1/2,pi/2)], color='black', fill=False, thickness=3)1251show(a + b)\1252`,1253},1254plot_parametric: {1255insert:1256"parametric_plot([cos(x) + 2*cos(x/4), sin(x) - 2*sin(x/4)], (x,0,8*pi), color='green', thickness=3, fill = True)",1257},1258plot_random_walk: {1259insert: "stats.TimeSeries(1000).randomize('normal').sums().plot()",1260},1261plot_text: {1262insert:1263'text(r"Text and LaTeX: $\\alpha^3 + 1$", (1,1), color="black", fontsize=15, rotation=30)',1264},1265plot_points: {1266insert:1267"show(points([(1,0), (sqrt(2)/2,sqrt(2)/2), (0,1), (1/2,1/2)], color='darkgreen', pointsize=50), aspect_ratio=1)",1268},1269plot3d: {1270insert: `\1271%var x y1272plot3d(x * sin(y), (x, -5, 5), (y, -5, 5))\1273`,1274},1275plot_torus: {1276insert: `\1277from sage.plot.plot3d.shapes import Torus1278inner_radius = .3; outer_radius = 11279show(Torus(outer_radius, inner_radius, color='orange'), aspect_ratio=1, spin=3)\1280`,1281},1282parametric_curve3d: {1283insert: `\1284%var u1285parametric_plot3d( (sin(u), cos(u), u/10), (u, 0, 20), thickness=5, color='green', plot_points=100)\1286`,1287},1288parametric_surface: {1289insert: `\1290%var u, v1291fx = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u))*cos(v)1292fy = (4+2*(1-cos(v)/2)*cos(u))*sin(v)1293fz = -2*(1-cos(v)/2) * sin(u)1294parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), color="green", opacity=.7, mesh=1, spin=5)\1295`,1296},1297implicit_plot3d: {1298insert: `\1299%var x y z1300g = golden_ratio; r = 4.771301p = 2 - (cos(x + g*y) + cos(x - g*y) + cos(y + g*z) +1302cos(y - g*z) + cos(z - g*x) + cos(z + g*x))1303show(implicit_plot3d(p, (x, -r, r), (y, -r, r), (z, -r, r),1304plot_points=30, color='orange', mesh=1, opacity=.7), spin=1)\1305`,1306},13071308random_walk_3d: {1309insert: `\1310v = [(0,0,0)]1311for i in range(1000):1312v.append([a+random()-.5 for a in v[-1]])1313line3d(v, color='red', thickness=3, spin=3)\1314`,1315},1316polytope: {1317insert: `\1318points = [(2,0,0), (0,2,0), (0,0,2), (-1,0,0), (0,-1,0), (0,0,-1)]1319show(LatticePolytope(points).plot3d(), spin=5)\1320`,1321},1322icosahedron: {1323insert: "show(icosahedron(color='green', opacity=.5, mesh=3), spin=1)",1324},1325tetrahedron: {1326insert: "show(tetrahedron(color='lime', opacity=.5, mesh=3), spin=1)",1327},1328cube: {1329insert: `\1330show(cube(color=['red', 'blue', 'green'], frame_thickness=2,1331frame_color='brown', opacity=0.8), frame=False)\1332`,1333},1334plot_text3d: {1335insert: 'text3d("Text in 3D", (1,1, 1), color="darkred", fontsize=20)',1336},1337graphs: {1338insert:1339"# Press the TAB key after 'graphs.' to see a list of predefined graphs.\ngraphs.",1340},1341petersen: {1342insert: "graphs.PetersenGraph()",1343},1344random_graph: {1345insert:1346"g = graphs.RandomGNM(15, 20) # 15 vertices and 20 edges\nshow(g)\ng.incidence_matrix()",1347},1348chromatic_number: {1349insert: "g = graphs.PetersenGraph().chromatic_number()\nshow(g)",1350},1351auto_group_graph: {1352insert: "graphs.PetersenGraph().automorphism_group()",1353},1354graph_2dplot: {1355insert: "show(graphs.PetersenGraph())",1356},1357graph_3dplot: {1358insert: "show(graphs.PetersenGraph().plot3d())",1359},1360factor: {1361insert: "factor(2015)",1362},1363primes: {1364insert: "prime_range(100)",1365},1366prime_pi: {1367insert: "prime_pi(10^6)",1368},1369mod: {1370insert: "Mod(5, 12)",1371},1372contfrac: {1373insert: "continued_fraction(e)",1374},1375binary_quadform: {1376insert: "BinaryQF([1,2,3])",1377},1378ellcurve: {1379insert: "EllipticCurve([1,2,3,4,5])",1380},1381var: {1382insert: "%var x, theta",1383},1384det: {1385insert: "matrix(2, 2, [1,2, 3,4]).det()",1386},1387charpoly: {1388insert: "matrix(2, 2, [1,2, 3,4]).charpoly()",1389},1390eigen: {1391insert: "matrix(3,[1,2,3, 4,5,6, 7,8,9]).right_eigenvectors()",1392},1393svd: {1394insert: "matrix(CDF, 3, [1,2,3, 4,5,6, 7,8,9]).SVD()",1395},1396numpy_array: {1397insert: "import numpy\nnumpy.array([[1,2,3], [4,5,6]], dtype=float)",1398},13991400ring_AA: {1401insert: "AA",1402},1403ring_CC: {1404insert: "CC",1405},1406ring_CDF: {1407insert: "CDF",1408},1409ring_CIF: {1410insert: "CIF",1411},1412ring_CLF: {1413insert: "CLF",1414},1415ring_FF_p: {1416insert: "GF(7)",1417},1418ring_FF_pr: {1419insert: "GF(7^3,'a')",1420},1421ring_QQ: {1422insert: "QQ",1423},1424ring_QQbar: {1425insert: "QQbar",1426},1427ring_QQp: {1428insert: "Qp(7)",1429},1430ring_RR: {1431insert: "RR",1432},1433ring_RDF: {1434insert: "RDF",1435},1436ring_RIF: {1437insert: "RIF",1438},1439ring_RLF: {1440insert: "RLF",1441},1442ring_ZZ: {1443insert: "ZZ",1444},1445ring_ZZp: {1446insert: "Zp(7)",1447},1448ring_QQx: {1449insert: "R.<x> = QQ[]",1450},1451ring_QQxyz: {1452insert: "R.<x,y,z> = QQ[]",1453},1454ring_ZZxp: {1455insert:1456"R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)])\nR.inject_variables()",1457},1458ring_QQ_quo: {1459insert: "R.<x,y> = QQ[]\nR.<xx, yy> = R.quo([y^2 - x^3 - x])",1460},1461interact_fx: {1462insert: `\1463@interact1464def interactive_function(a = slider(0, 10, .05, default=4),1465b = (-3, 3, .1)):1466f(x) = b * x + sin(a * x)1467plot(f, (x, -5, 5)).show()\1468`,1469},1470modes: {1471insert: "print('\\n'.join(modes()))",1472},1473jupyterkernels: {1474insert: "print(jupyter.available_kernels())",1475},1476mode_typeset: {1477insert: "%typeset_mode True\n",1478},1479mode_auto: {1480insert: "%auto",1481},1482mode_cython: {1483insert: "%cython\n",1484},1485mode_default_mode: {1486insert: "%default_mode r # change r to any mode\n",1487},1488mode_exercise: {1489insert: "%exercise\n",1490},1491mode_gap: {1492insert: "%gap\n",1493},1494mode_gp: {1495insert: "%gp\n",1496},1497mode_hide: {1498insert: "%hide\n",1499},1500mode_html: {1501insert: "%html\n",1502},1503mode_julia: {1504insert: "%julia\n",1505},1506mode_javascript: {1507insert: "%javascript\n/* Use print(...) for output */",1508},1509mode_jupyter_bridge: {1510insert: `\1511a5 = jupyter("anaconda5")1512# start new cells with %a51513# or set %default_mode a5\1514`,1515},1516mode_md: {1517insert: "%md\n",1518},1519mode_octave: {1520insert: "%octave\n",1521},1522mode_python: {1523insert: "%python\n",1524},1525mode_python3: {1526insert: "%python3\n",1527},1528mode_anaconda: {1529insert: "%anaconda\n",1530},1531mode_r: {1532insert: "%r\n",1533},1534mode_scilab: {1535insert: "%scilab\n",1536},1537mode_sh: {1538insert: "%sh\n",1539},1540mode_time: {1541wrap: {1542left: "%time ",1543right: "",1544},1545},1546mode_timeit: {1547wrap: {1548left: "%timeit ",1549right: "",1550},1551},1552comment: {1553wrap: {1554left: "# ",1555right: "",1556multi: true,1557space: true,1558},1559},1560assign: {1561insert: "a = 5",1562},1563forloop: {1564insert: `\1565for animal in ["dog", "cat", "mouse"]1566println("$animal is a mammal")1567end\1568`,1569},1570function: {1571insert: `\1572function add(x, y)1573println("x is $x and y is $y")1574# Functions return the value of their last statement1575x + y1576end15771578println(add(2000, 15))\1579`,1580},1581ifelse: {1582insert: `\1583a = 101584if a > 101585println("a is bigger than 10.")1586elseif a < 10 # This elseif clause is optional.1587println("a is smaller than 10.")1588else # The else clause is optional too.1589println("a is indeed 10.")1590end\1591`,1592},1593},15941595r: {1596// http://cran.r-project.org/doc/manuals/r-release/R-intro.html1597comment: {1598wrap: {1599left: "#",1600right: "",1601multi: true,1602space: true,1603},1604},1605vector: {1606insert: "v <- c(1,1,2,3,5,8,13)",1607},1608forloop: {1609insert: `\1610for (i in seq(1, 10, by=2)) {1611print(sprintf("i = %s", i));1612}\1613`,1614},1615ifelse: {1616insert: `\1617k <- 101618if (k > 5) {1619print("k greater than 5")1620} else {1621print("k less or equal than 5")1622}\1623`,1624},1625summary: {1626wrap: {1627left: "summary(",1628right: ")",1629},1630},1631plot: {1632insert: 'plot(c(1,2,4,8,16,32,64), c(1,1,2,3,5,8,13), type="l")',1633},1634seq: {1635insert: "-5:5",1636},1637seq_by: {1638insert: "seq(-5, 5, by=.2)",1639},1640seq_length: {1641insert: "seq(length=51, from=-5, by=.2)",1642},1643rep1: {1644insert: "rep(c(5,1,3), times = 3)",1645},1646rep2: {1647insert: "rep(c(5,1,3), each = 3)",1648},1649charvec: {1650insert: 'paste(c("X","Y"), 1:10, sep="")',1651},1652mean: {1653insert: "mean(c(4,3,4,2,-1,3,2,3,2))",1654},1655matrix: {1656insert: "array(1:20, dim=c(4,5))",1657},1658assign: {1659insert: `\1660x <- "hello"1661print(x)\1662`,1663},1664outer: {1665insert: "c(1,2) %o% c(4,4)",1666},1667matrixmult: {1668insert: `\1669x <- c(1,2,3,4)1670A <- array(seq(1:20), dim=c(5,4))1671A %*% x\1672`,1673},1674function: {1675insert: `\1676f <- function(x, y) {1677y <- 2 * x + y1678return(y + cos(x))1679}1680f(1,2)\1681`,1682},1683inverse: {1684insert: "solve(array(c(2,1,-4,1), dim=c(2,2)))",1685},1686solvelin: {1687insert: "solve(array(c(2,1,-4,1), dim=c(2,2)), c(6,7))",1688},1689svd: {1690insert: "svd(array(-9:6, dim=c(4,4)))",1691},1692list1: {1693insert: `\1694# index into a list via [[idx]]1695l <- list(1,"fred", c(1,2,3))1696print(l[[1]])1697print(l[[2]])1698print(l[[3]])\1699`,1700},1701list2: {1702insert: `\1703# assoziated list of names and objects1704l <- list(a = 1, b = c(1,2,3))1705print(l$a) # access a in l1706print(l$b)\1707`,1708},1709arrayselect: {1710insert: "x <- c(4,7,3,2,9)\nx[x > 4]",1711},1712dataframe: {1713insert: `\1714a <- c(1,2,1)1715b <- c("Fred", "Susan", "Joe")1716c <- seq(1, by=.01, length=3)1717df <- data.frame(sex = a, name = b, result = c)1718df1719# for more information: help(data.frame)\1720`,1721},1722normal: {1723insert: "rnorm(10, mean = 100, sd = 1)",1724},1725stem: {1726insert:1727"# condensed overview of all numbers in the given list\nstem(rnorm(1000, mean = 5, sd = 10))",1728},1729defaultsize: {1730insert: "%sage r.set_plot_options(height=4, width=10)",1731},1732attach: {1733insert:1734"# attach loads internal datasets\nattach(faithful)\nprint(summary(faithful))\nprint(head(faithful))",1735},1736histdensity: {1737insert: `\1738attach(faithful)1739hist(eruptions, seq(1.6, 5.2, 0.2), prob=TRUE)1740lines(density(eruptions, bw=0.1))1741rug(eruptions)\1742`,1743},1744qqplot: {1745insert: `\1746attach(faithful)1747long <- eruptions[eruptions > 3]1748par(pty="s") # square figure1749qqnorm(long)1750qqline(long)\1751`,1752},1753boxplot: {1754insert: `\1755a <- rnorm(10)1756b <- rnorm(10, mean=2)1757boxplot(a, b)\1758`,1759},1760contour: {1761insert: `\1762x <- seq(-pi, pi, len=50)1763y <- x1764f <- outer(x, y, function(x, y) cos(y)/(1 + x^2))1765contour(x, y, f, nlevels=15)\1766`,1767},1768lm: {1769insert: `\1770y <- c(0,3,2,2,4,5,8,9,7,6,2,0)1771x1 <- c(1,2,3,4,3,4,5,7,5,7,8,9)1772x2 <- c(1,1,1,1,2,2,2,3,3,3,4,4)1773df <- data.frame(x1=x1, x2=x2)1774model <-lm(y ~ x1 + x2, data=df)1775model1776summary(model)1777anova(model)\1778`,1779},1780nlm: {1781insert: `\1782x <- c(0.02, 0.02, 0.06, 0.06, 0.11, 0.11, 0.22, 0.22, 0.56, 0.56, 1.10, 1.10)1783y <- c(76, 47, 97, 107, 123, 139, 159, 152, 191, 201, 207, 200)1784# function to be fitted1785fn <- function(p) sum((y - (p[1] * x)/(p[2] + x))^2)1786# supplying nlm with starting varlues1787nlm(fn, p = c(200, 0.1), hessian = TRUE)\1788`,1789},1790},1791} as const;17921793/*1794fricas:1795help:1796wrap:1797insert : ")summary"1798explain:1799wrap:1800left : ")display operation "1801right : ""1802differentiate:1803insert : 'differentiate(1 + x + x^2, x)'1804integrate:1805insert : 'integrate(1 + x + x^2, x)'1806nintegrate:1807insert : 'aromberg(sin, -%pi, %pi, 0.0001, 0.001, 2, 5, 20) -- aromberg(fn, a, b, epsrel, epsabs, nmin, nmax, nint)'1808'one-line function':1809insert : 'f(x,y) == x * sin(y)'1810matrix:1811insert : "matrix [[1,%pi],[3, %e],[5,6]]"1812vector:1813insert : "vector [%pi, 2, 3, %e]"1814factor:1815insert : "factor 2015"1816primes:1817insert : "primes(1,100)"1818mod:1819insert : "12::IntegerMod(5)"1820contfrac:1821insert : "continuedFraction(%e::Expression Float)$NumericContinuedFraction(Float)"1822determinant:1823insert : "determinant matrix [[1,2], [3,4]]"1824charpoly:1825insert : "characteristicPolynomial matrix [[1,2], [3,4]]"1826eigen:1827insert : "eigenvectors matrix [[1,2, 3], [4,5,6], [7,8,9]]"18281829ring_CC:1830insert : "Polynomial Complex Float"1831ring_QQ:1832insert : "Polynomial Fraction Integer"1833ring_RR:1834insert : "Polynomial Float"1835ring_ZZ:1836insert : "Polynomial Integer"1837comment:1838wrap:1839left : "--"1840right: ""1841multi : true1842space : true1843assign:1844insert : "a: = 5"1845forloop:1846insert : """1847for animal in ["dog", "cat", "mouse"] repeat1848output("Mammal: ",animal)1849"""1850function :1851insert : """1852plus(x, y) ==1853output("x is ",x)1854output("and y is ",y)1855-- Functions return the value of their last statement1856return x + y18571858output plus(2000, 15)1859"""1860ifelse:1861insert : """1862a := 101863if a > 10 then1864output("a is bigger than 10.")1865else -- This elseif clause is optional.1866if a < 10 then1867output("a is smaller than 10.")1868else -- The else clause is optional too.1869output("a is indeed 10.")1870"""1871*/18721873/*1874Programmatically adding to above data structure1875*/18761877// 6 markdown heading levels:1878for (k = 1, i = k; k <= 6; k++, i = k) {1879const strip = (() => {1880const result: string[] = [];1881for (j = 1; j <= 6; j++) {1882if (j !== i) {1883result.push(`format_heading_${j}`);1884}1885}1886return result;1887})();1888const left =1889"\n" +1890(() => {1891let asc, end;1892const result1: string[] = [];1893for (1894j = 1, end = i, asc = 1 <= end;1895asc ? j <= end : j >= end;1896asc ? j++ : j--1897) {1898result1.push("#");1899}1900return result1;1901})().join("") +1902" ";1903commands.md[`format_heading_${i}`] = {1904strip,1905wrap: {1906left,1907right: "",1908},1909};1910}19111912/*1913Programmatically creating the menu entries and buttons1914*/19151916//1917// helper functions1918//19191920function make_bar(cls: string = "") {1921return $(`<span class='btn-group ${cls}'></span>`);1922}19231924// this adds the content of a dropdown menu (basically, single or triple entries)1925const add_menu = function (bar, entries) {1926const dropdown = $("<span class='btn-group'></span>");1927dropdown.append(1928$(`\1929<span class="btn btn-default dropdown-toggle" data-toggle="dropdown" title="${entries[1]}">1930${entries[0]} <b class="caret"></b>1931</span>\1932`),1933);19341935const droplist = $("<ul class='dropdown-menu'></ul>");1936const divider = '<li class="divider"></li>';1937let first = true;1938for (let item of entries[2]) {1939var e;1940if (item.length === 1) {1941// new divider1942// don't show dividing line if it is at the very top1943let d = first ? "" : divider;1944d += `<li role="presentation" class="dropdown-header">${item[0]}</li>`;1945e = $(d);1946} else if ([2, 3].includes(item.length)) {1947// item in the menu1948let help = "";1949if (item.length === 3 && item[2].length > 0) {1950help = `data-toggle='tooltip' data-placement='right' title='${item[2]}'`;1951}1952e = $(`<li><a href='${item[1]}' ${help}>${item[0]}</a></li>`);1953}1954first = false;1955droplist.append(e);1956}19571958dropdown.append(droplist);1959return bar.append(dropdown);1960};19611962// this adds a single icon to the bar1963function add_icon(bar, inner: string, href: string, comment: string) {1964let help = "";1965if (comment.length > 0) {1966help = `data-toggle='tooltip' data-placement='bottom' title='${comment}'`;1967}1968const icon = $(`<a href='${href}' class='btn btn-default' ${help}></a>`);1969icon.html(inner);1970return bar.append(icon);1971}19721973//1974// initializing and creating the menus1975// this works in conjunction with editor.html1976//19771978// Initialize fonts for the editor1979const initialize_sagews_editor = function () {1980let item;1981const bar = $(".webapp-editor-codemirror-worksheet-editable-buttons");1982let elt = bar.find(".sagews-output-editor-font").find(".dropdown-menu");1983for (let font of "Serif,Sans,Arial,Arial Black,Courier,Courier New,Comic Sans MS,Georgia,Helvetica,Impact,Lucida Grande,Lucida Sans,Monaco,Palatino,Tahoma,Times New Roman,Verdana".split(1984",",1985)) {1986item = $(`<li><a href='#fontName' data-args='${font}'>${font}</a></li>`);1987item.css("font-family", font);1988elt.append(item);1989}19901991elt = bar.find(".sagews-output-editor-font-size").find(".dropdown-menu");1992for (let size = 1; size <= 7; size++) {1993item = $(1994`<li><a href='#fontSize' data-args='${size}'><font size=${size}>Size ${size}</font></a></li>`,1995);1996elt.append(item);1997}19981999elt = bar.find(".sagews-output-editor-block-type").find(".dropdown-menu");2000for (i = 1; i <= 6; i++) {2001item = $(2002`<li><a href='#formatBlock' data-args='<H${i}>'><H${i} style='margin:0'>Heading</H${i}></a></li>`,2003);2004elt.append(item);2005}20062007elt.prepend('<li role="presentation" class="divider"></li>');20082009// trick so that data is retained even when editor is cloned:2010const args = JSON.stringify([2011null,2012{ normalize: true, elementTagName: "code", applyToEditableOnly: true },2013]);2014item = $(2015`<li><a href='#ClassApplier' data-args='${args}'><i class='fa fa-code'></i> <code>Code</code></a></li>`,2016);2017elt.prepend(item);20182019elt.prepend('<li role="presentation" class="divider"></li>');2020item = $(`<li><a href='#removeFormat'><i class='fa fa-remove'></i> \2021Normal</a></li>`);2022return elt.prepend(item);2023};20242025// Initialize fonts for the editor2026const initialize_md_html_editor = function () {2027let item;2028const bar = $(".webapp-editor-textedit-buttonbar");2029let elt = bar.find(".sagews-output-editor-font-face").find(".dropdown-menu");2030for (let font of FONT_FACES) {2031item = $(`<li><a href='#font_face' data-args='${font}'>${font}</a></li>`);2032item.css("font-family", font);2033elt.append(item);2034}20352036elt = bar.find(".sagews-output-editor-font-size").find(".dropdown-menu");2037const v = [1, 2, 3, 4, 5, 6, 7];2038v.reverse();2039for (let size of v) {2040item = $(2041`<li><a href='#font_size' data-args='${size}'><font size=${size}>Size ${size} ${2042size === 3 ? "default" : ""2043}</font></a></li>`,2044);2045elt.append(item);2046}20472048elt = bar.find(".sagews-output-editor-block-type").find(".dropdown-menu");2049for (i = 1; i <= 4; i++) {2050elt.append(2051$(2052`<li><a href='#format_heading_${i}'><H${i} style='margin:0'>Heading ${i}</H${i}></a></li>`,2053),2054);2055}2056elt.append('<li role="presentation" class="divider"></li>');2057return elt.append(2058$(2059"<li><a href='#format_code'><i class='fa fa-code'></i> <code>Code</code></a></li>",2060),2061);2062};20632064// adding Python & Sage menu entries programmatically (editing HTML directly is too painful)2065// FUTURE: make a general class for menu entries and hence use these functions for all menu entries?2066const initialize_sage_python_r_toolbar = function () {2067// reference example, FUTURE: delete it2068`\2069<span class="btn-group">2070<span class="btn btn-default dropdown-toggle" data-toggle="dropdown" title="Control Structures">2071<i class="fa">Control</i> <b class="caret"></b>2072</span>2073<ul class="dropdown-menu">2074<li role="presentation" class="dropdown-header">Loops</li>2075<li><a href='#forloop' data-toggle="tooltip" data-placement="right" title="Iterate over a range of integers">For-Loop</a></li>2076<li><a href="#forlistloop">For-Loop over a list</a></li>2077<li class="divider"></li>2078<li role="presentation" class="dropdown-header">Decisions</li>2079<li><a href='#if'>If clause</a></li>2080<li><a href='#ifelse'>If-else clause</a></li>2081<li class="divider"></li>2082<li role="presentation" class="dropdown-header">Advanced</li>2083<li><a href="#cases">Cases</a></li>2084<li><a href='#forelseloop'>For-Else Loop</a></li>2085</ul>2086</span>2087<a href='#comment' class='btn btn-default' data-toggle="tooltip" data-placement="bottom" title="Comment selected code"><i class="fa">#</i></a>2088</span>\2089`;20902091const codebar = $(".webapp-editor-codeedit-buttonbar");20922093// -- modes (this isn't really code so weird to put here)2094const system_bar = make_bar("webapp-editor-codeedit-buttonbar-system");20952096const help_list = [2097"<i class='fa fa-question-circle'></i> Help",2098"Sage Worksheet Help",2099[2100["SageMath help"],2101["Overview", "#sagemathdoc"],2102["Tutorial", "#sagemathtutorial"],2103["Reference", "#sagemathreference"],2104["Keyboard shortcuts", "#sagemathkeyboardshortcuts"],2105["Common syntax problems", "#sagesyntaxerrors"],2106["Sage worksheet commands"],2107["Worksheets in CoCalc", "#cocalcwiki"],2108["I have a question about Sage", "#sagequestion"],2109["General help", "#help"],2110["Mode commands", "#modes"],2111["Jupyter kernels", "#jupyterkernels"],2112],2113];2114add_menu(system_bar, help_list);21152116const mode_list = [2117"Modes",2118"Sage Worksheet Modes",2119[2120["General"],2121["Auto execute cell on startup", "#mode_auto"],2122["Hide input", "#mode_hide"],2123["Set default mode", "#mode_default_mode"],2124["Typeset output", "#mode_typeset"],2125["Timing"],2126["Benchmark code repeatedly", "#mode_timeit"],2127["Time code once", "#mode_time"],2128["Language modes"],2129["Anaconda", "#mode_anaconda"],2130["Cython", "#mode_cython"],2131["Gap", "#mode_gap"],2132["PARI/GP", "#mode_gp"],2133["HTML", "#mode_html"],2134["Javascript", "#mode_javascript"],2135["Julia", "#mode_julia"],2136["Jupyter bridge", "#mode_jupyter_bridge"],2137["Markdown", "#mode_md"],2138["Octave", "#mode_octave"],2139["Python", "#mode_python"],2140["Python 3", "#mode_python3"],2141["R", "#mode_r"],2142["Shell", "#mode_sh"],2143],2144];2145add_menu(system_bar, mode_list);21462147//# MAYBE ADD THESE in another menu:2148//axiom2149//capture2150//coffeescript2151//command2152//file2153//fork2154//fortran2155//fricas2156//gap32157//giac2158//go2159//hideall2160//javascript2161//kash2162//lie2163//lisp2164//load2165//macaulay22166//maxima2167//octave2168//pandoc2169//perl2170//prun2171//reset2172//ruby2173//runfile2174//sage02175//script2176//singular2177//typeset_mode2178//var2179//wiki2180//mode_list = ["More", "More Sage Worksheet Modes",2181// [2182// ["Axiom", "#mode_axiom"],2183// ["Scilab", "#mode_scilab"],2184// ["Shell script", "#mode_sh"],2185// []2186// ]]2187//add_menu(system_bar, mode_list)2188codebar.append(system_bar);21892190// -- python specific --2191const pybar = make_bar("webapp-editor-codeedit-buttonbar-python");2192add_icon(pybar, "#", "#comment", "Comment selected text");21932194let py_control = [2195"Data",2196"Basic Data Types",2197[2198["Construction"],2199["Dictionary", "#dict"],2200["List", "#list"],2201["List comprehension", "#list_comprehension"],2202["Set", "#set"],2203["Tuple", "#tuple"],2204["Properties"],2205["Length", "#len"],2206["CSV"],2207["Write CSV file", "#write_csv_file"],2208["Read CSV file", "#read_csv_file"],2209],2210];2211add_menu(pybar, py_control);22122213// structured dropdown menu data: button text, title info, list of ["button, "#id", "title help (optional)"]2214py_control = [2215"Control",2216"Control Structures",2217[2218["Loops"],2219["For-Loop", "#forloop", "Iterate over a range of integers"],2220["For-Loop over a list", "#forlistloop", "Iterate over a list"],2221["While loop", "#whileloop", "Loop while a condition holds"],2222["Decisions"],2223["If", "#if"],2224["If-Else", "#ifelse"],2225["Advanced"],2226["Cases", "#cases", "Deciding between different cases"],2227[2228"For-Else Loop",2229"#forelseloop",2230"Searching for an item with a fallback.",2231],2232],2233];2234add_menu(pybar, py_control);22352236const py_func = [2237"Program",2238"Define Functions and Classes",2239[2240["Functions"],2241["Function", "#function", "Define a Python function"],2242["Lambda", "#lambda", "A Python lambda function"],2243["Classes"],2244["Class", "#simple_class", "Define a simple class"],2245[2246"Class with inheritance",2247"#class_inheritance",2248"A class that inherits from other classes",2249],2250],2251];22522253add_menu(pybar, py_func);22542255codebar.append(pybar);22562257// -- Cython specific2258const cythonbar = make_bar("webapp-editor-codeedit-buttonbar-cython");2259const cython_classes = [2260"Cython Classes",2261"Define cdef'd Classes",2262[["cdef Class", "#cython_class", "Define a Cython class"]],2263];2264add_menu(cythonbar, cython_classes);2265cythonbar.append(cythonbar);22662267// -- sage specific --2268// we hide this bar on smaller screens to avoid the linebreak but still show the assistant2269// https://github.com/sagemathinc/cocalc/issues/40682270// don't worry about xs, because then the whole bar is not visible (and replaced by one for mobile)2271// actually not: https://github.com/sagemathinc/cocalc/issues/64162272const sagebar = make_bar("webapp-editor-codeedit-buttonbar-sage hidden-xs");22732274const sage_calculus = [2275"Calculus",2276"Calculus",2277[2278["∂ Differentiate", "#differentiate", "Differentiate a function"],2279[2280"∫ Numerical integral",2281"#nintegrate",2282"Numerically integrate a function",2283],2284[2285"$f(x,y) = \\cdots $ - Symbolic Function",2286"#symbolic_function",2287"Define a symbolic function",2288],2289["∫ Symbolic integral", "#integrate", "Integrate a function"],2290["Interact plots"],2291["Interactive f(x)", "#interact_fx"],2292],2293];2294const sage_linalg = [2295"Linear",2296"Linear Algebra",2297[2298["Matrix $M$", "#matrix", "Define a matrix"],2299["Vector $\\vec v$", "#vector", "Define a vector"],2300["Functions"],2301["Characteristic polynomial", "#charpoly"],2302["Determinant", "#det"],2303["Eigenvectors", "#eigen", "Eigenvalues and eigenvectors of matrix"],2304["SVD", "#svd", "Singular value decomposition of matrix"],23052306["Numpy"],2307["Array", "#numpy_array"],2308],2309];2310const sage_plotting = [2311"Plots",2312"Plotting Graphics",2313[2314["2D plotting"],2315["Function", "#plot2d", "Plot f(x)"],2316["Line", "#plot_line", "Sequence of line segments"],2317["Parametric", "#plot_parametric", "Parematric plot"],2318["Points", "#plot_points", "Plot many points"],2319["Polygon", "#plot_polygon"],2320["Random walk", "#plot_random_walk", "A random walk"],2321["Text", "#plot_text", "Draw text"],2322["3D plotting"],2323["Cube", "#cube", "Show a colored cube"],2324["Function", "#plot3d", "Plot f(x, y)"],2325["Icosahedron", "#icosahedron"],2326["Implicit plot", "#implicit_plot3d", "Create an implicit 3D plot"],2327["Parametric curve", "#parametric_curve3d"],2328["Parametric surface", "#parametric_surface"],2329["Polytope", "#polytope"],2330["Random walk", "#random_walk_3d", "A 3d Random Walk"],2331["Tetrahedron", "#tetrahedron"],2332["Text", "#plot_text3d", "Draw text"],2333["Torus", "#plot_torus"],2334],2335];2336const sage_graphs = [2337"Graphs",2338"Graph theory",2339[2340["graphs.<tab>", "#graphs"],2341["Petersen graph", "#petersen", "Define the Peterson graph"],2342["Random graph", "#random_graph"],2343["Invariants"],2344[2345"Automorphism group",2346"#auto_group_graph",2347"Automorphism group of a graph",2348],2349["Chromatic number", "#chromatic_number", "Chromatic number of a graph"],2350["Visualization"],2351["2D plot", "#graph_2dplot"],2352["3D plot", "#graph_3dplot"],2353],2354];2355const sage_nt = [2356"Numbers",2357"Number theory",2358[2359[2360"Binary quadratic form",2361"#binary_quadform",2362"Define a binary quadratic form",2363],2364["Continued fraction", "#contfrac", "Compute a continued fraction"],2365["Elliptic curve", "#ellcurve", "Define an elliptic curve"],2366["Factor", "#factor", "Factorization of something"],2367["Mod $n$", "#mod", "Number modulo n"],2368["List prime numbers", "#primes", "Enumerate prime numbers"],2369["Count prime numbers", "#prime_pi", "Count prime numbers"],2370],2371];23722373const sage_rings = [2374"Rings",2375"Rings and fields",2376[2377["$\\CC$ - Complex numbers", "#ring_CC"],2378["$\\QQ$ - Rational numbers", "#ring_QQ"],2379["$\\RR$ - Real numbers", "#ring_RR"],2380["$\\ZZ$ - Integers", "#ring_ZZ"],2381["Polynomial rings"],2382["$\\QQ[x, y, z]$", "#ring_QQxyz"],2383["$\\QQ[x, y]/(y^2-x^3-x)$", "#ring_QQ_quo"],2384["$\\ZZ[x_2, x_3, \\ldots, x_{97}]$", "#ring_ZZxp"],2385["Advanced rings"],2386["$\\mathbb{A}$ - Algebraic reals", "#ring_AA"],2387["$\\CDF$ - Complex double", "#ring_CDF"],2388["$\\CC$ - Complex interval", "#ring_CIF"],2389["$\\CLF$ - Complex lazy", "#ring_CLF"],2390["$\\FF_p$ - Prime finite field", "#ring_FF_p"],2391["$\\FF_{p^r}$ - finite field", "#ring_FF_pr"],2392["$\\overline{\\QQ}$ - Algebraic closure", "#ring_QQbar"],2393["$\\QQ_p$ - $p$-adic numbers", "#ring_QQp"],2394["$\\RDF$ - Real double", "#ring_RDF"],2395["$\\RR$ - Real interval", "#ring_RIF"],2396["$\\RLF$ - Real lazy", "#ring_RLF"],2397["$\\ZZ_p$ - $p$-adic integers", "#ring_ZZp"],2398],2399];24002401add_icon(sagebar, "$x$", "#var", "Define a symbolic variable");2402add_menu(sagebar, sage_plotting);2403add_menu(sagebar, sage_calculus);2404add_menu(sagebar, sage_linalg);2405add_menu(sagebar, sage_graphs);2406add_menu(sagebar, sage_nt);2407add_menu(sagebar, sage_rings);24082409codebar.append(sagebar);24102411// -- r specific --2412const rbar = $(".webapp-editor-redit-buttonbar");24132414const r_basic = make_bar();2415add_icon(r_basic, "#", "#comment", "Comment selected text");2416add_icon(r_basic, "$\\vec v$", "#vector", "Insert a vector");24172418const r_control = make_bar();2419const r_control_entries = [2420"Control",2421"Control structures",2422[2423["Assignment", "#assign", "Give an object a (variable)name"],2424["For-Loop", "#forloop", "Insert a for loop"],2425["Function definition", "#function", "Define a function"],2426["If-Else", "#ifelse"],2427],2428];2429add_menu(r_control, r_control_entries);24302431const r_data = make_bar();2432const r_data_entries = [2433"Data",2434"Data structures",2435[2436["List, indexed", "#list1"],2437["List, associative", "#list2"],2438["Array selection", "#arrayselect"],2439["Data frame", "#dataframe"],2440["Attach", "#attach"],2441],2442];2443add_menu(r_data, r_data_entries);24442445const r_funcs = make_bar();2446const r_funcs_entries = [2447"Functions",2448"Some selected functions",2449[2450["Sequence simple", "#seq"],2451["Sequence stepsize", "#seq_by"],2452["Sequence length", "#seq_length"],2453["Repetitions (times)", "rep1"],2454["Repetitions (each)", "rep2"],2455["Character vector", "#charvec"],2456["Matrix array", "#matrix"],2457["Matrix multipliation", "#matrixmult"],2458["Outer product", "#outer"],2459["Inverse matrix", "#inverse"],2460["Solve A*x=b", "#solvelin"],2461["SVD", "#svd"],2462],2463];2464add_menu(r_funcs, r_funcs_entries);24652466const r_stats = make_bar();2467const r_stats_entries = [2468"Stats",2469"Basic statistical functions",2470[2471["Statistical summary", "#summary"],2472["Mean", "#mean"],2473["Normal distribution", "#normal"],2474["Linear model", "#lm"],2475["Nonlinear model", "#nlm"],2476],2477];2478add_menu(r_stats, r_stats_entries);24792480const r_plot = make_bar();2481const r_plot_entries = [2482"Plots",2483"Basic plots",2484[2485["Plot x/y pairs", "#plot"],2486["Stem plot", "#stem"],2487["Histogram + Density + Rug", "#histdensity"],2488["QQ-Plot", "#qqplot", "Quantile-quantile plot"],2489["Boxplot", "#boxplot"],2490["Contour plot", "#contour"],2491["Change default plot size", "#defaultsize"],2492],2493];2494add_menu(r_plot, r_plot_entries);24952496rbar.append(r_basic);2497rbar.append(r_control);2498rbar.append(r_data);2499rbar.append(r_funcs);2500rbar.append(r_stats);2501rbar.append(r_plot);25022503// -- Julia specific --2504const julia_bar = $(".webapp-editor-julia-edit-buttonbar");25052506const julia_basic = make_bar();2507add_icon(julia_basic, "#", "#comment", "Comment selected text");25082509const julia_control = make_bar();2510const julia_control_entries = [2511"Control",2512"Control structures",2513[2514["Assignment", "#assign", "Give an object a (variable)name"],2515["For-Loop", "#forloop", "Insert a for loop"],2516["Function definition", "#function", "Define a function"],2517["If-Else", "#ifelse"],2518],2519];2520add_menu(julia_control, julia_control_entries);2521julia_bar.append(julia_basic);2522julia_bar.append(julia_control);25232524// -- sh specific --2525const sh_bar = $(".webapp-editor-sh-edit-buttonbar");25262527const sh_git = make_bar();2528const sh_git_entries = [2529"Git",2530"Basic Git commands",2531[2532["Set name and email", "#set_name_and_email", "Set name and email"],2533["Initalize Git", "#initalize_git", "Initalize Git"],2534["Create an ignore file", "#create_gitignore", "Create an ignore file"],2535["Clone a local repo", "#clone_local_repo", "Clone local repo"],2536["Clone a remote repo", "#clone_remote_repo", "Clone remote repo"],2537["Add a file to repo", "#add_file_to_repo", "Add file to the repo"],2538[2539"Add all files to repo",2540"#add_all_to_repo",2541"Add all not ignored files to the repo",2542],2543[2544"See changes before committing",2545"#diff",2546"See changes before committing",2547],2548["Commit your changes", "#commit", "Commit all your changes"],2549["Setup SSH for Github", "#setup_ssh_for_github", "Setup SSH for Github"],2550[2551"Push changes",2552"#push_origin_master",2553"Push changes to the master branch of your remote repository",2554],2555["Status", "#status", "Status"],2556["Add remote repo", "#add_remote_repo", "Connect to a remote repository"],2557[2558"List remote repos",2559"#list_remote_repos",2560"List all currently configured remote repositories",2561],2562[2563"Create a new branch",2564"#create_new_branch",2565"Create a new branch and switch to it",2566],2567[2568"Switch branches",2569"#switch_branches",2570"Switch from one branch to another",2571],2572[2573"List branches",2574"#list_branches",2575"List all the branches in your repo, and also tell you what branch you're currently in",2576],2577[2578"Delete the feature branch",2579"#delete_the_feature_branch",2580"Delete the feature branch",2581],2582[2583"Push branch",2584"#push_branch",2585"Push the branch to your remote repository, so others can use it",2586],2587[2588"Push all branches",2589"#push_all_branches",2590"Push all branches to your remote repository",2591],2592[2593"Delete remote branch",2594"#delete_remote_branch",2595"Delete a branch on your remote repository",2596],2597[2598"Update repo",2599"#pull",2600"Update from the remote repository Fetch and merge changes on the remote server to your working directory",2601],2602[2603"Merge a branch",2604"#merge_branch",2605"To merge a different branch into your active branch",2606],2607["Show history", "#show_history", "Show the history of previous commits"],2608["Undo local changes", "#undo_local_changes", "Undo local changes"],2609[2610"Get rid of local changes",2611"#get_rid_of_local_changes",2612"Drop all your local changes and commits, fetch the latest history from the server and point your local master branch at it",2613],2614[2615"Search the working directory for foo()",2616"#search_for",2617"Search the working directory for foo()",2618],2619],2620];2621add_menu(sh_git, sh_git_entries);2622return sh_bar.append(sh_git);2623};26242625// error since not yet used.2626// @ts-expect-error2627function initialize_latex_buttonbar() {2628const latexbar = make_bar();2629add_icon(2630latexbar,2631"<i class='fa fa-comment'></i>",2632"#comment",2633"Comment selected text",2634);26352636const templates = [2637"Templates",2638"These templates come exclusively on top",2639[2640["Article", "#article"],2641["KOMA Script"],2642["Article", "#scrartcl"],2643["Report", "#scrreprt"],2644],2645];2646add_menu(latexbar, templates);26472648// FUTURE: merge this with the usual text formatting toolbar, such that its list of actions is inserted here2649// IDEA: maybe, clicking on the "Format" dropdown shows the cloned formatting toolbar?2650//text = ["Format", "Text formatting",[]]2651//add_menu(latexbar, text)2652const formatting = $("<span class='btn-group'></span>");2653formatting.append(2654$(`\2655<span class="btn btn-default dropdown-toggle" data-toggle="dropdown" title="Text Formatting">2656<i class="fa">Format</i> <b class="caret"></b>2657</span>\2658`),2659);2660const format_buttons = $(2661".webapp-editor-codemirror-worksheet-editable-buttons",2662).clone();2663format_buttons.addClass("dropdown-menu");2664format_buttons.removeClass("hide");2665format_buttons.css("min-width", 300);2666formatting.append(format_buttons);2667latexbar.append(formatting);2668// end format button idea26692670const formulas = [2671"Formula",2672"These are some standard formuas",2673[2674["$x^2$", "#xsquare"],2675["$\\int$", "#integral"],2676["Environment"],2677["Cases", "#cases"],2678],2679];2680add_menu(latexbar, formulas);26812682const bb = $(".webapp-editor-latex-buttonbar");2683return bb.append(latexbar);2684}26852686// NOT READY YET.2687//initialize_latex_buttonbar()26882689// must get called before using the button bars.2690export function init_buttonbars() {2691initialize_sagews_editor();2692initialize_md_html_editor();2693return initialize_sage_python_r_toolbar();2694}269526962697