|
3 | 3 | % change without any prior notice. Usage of these undocumented APIs outside of |
4 | 4 | % these files is not supported. |
5 | 5 |
|
6 | | -function result = execute(code) |
| 6 | +function result = execute(code, kernelId) |
7 | 7 | % EXECUTE A helper function for handling execution of MATLAB code and post-processing |
8 | 8 | % the outputs to conform to Jupyter API. We use the Live Editor API for majority |
9 | 9 | % of the work. |
|
17 | 17 | % Embed user MATLAB code in a try-catch block for MATLAB versions less than R2022b. |
18 | 18 | % This is will disable inbuilt ErrorRecovery mechanism. Any exceptions created in |
19 | 19 | % user code would be handled by +jupyter/getOrStashExceptions.m |
20 | | -if verLessThan('matlab', '9.13') |
| 20 | +if isMATLABReleaseOlderThan("R2022b") |
21 | 21 | code = sprintf(['try\n'... |
22 | | - '%s\n'... |
23 | | - 'catch JupyterKernelME\n'... |
24 | | - 'jupyter.getOrStashExceptions(JupyterKernelME)\n'... |
25 | | - 'clear JupyterKernelME\n'... |
26 | | - 'end'], code); |
| 22 | + '%s\n'... |
| 23 | + 'catch JupyterKernelME\n'... |
| 24 | + 'jupyter.getOrStashExceptions(JupyterKernelME)\n'... |
| 25 | + 'clear JupyterKernelME\n'... |
| 26 | + 'end'], code); |
27 | 27 | end |
28 | 28 |
|
29 | 29 | % Value that needs to be shown in the error message when a particular error |
|
32 | 32 | fileToShowErrors = 'Notebook'; |
33 | 33 |
|
34 | 34 | % Prepare the input for the Live Editor API. |
35 | | -jsonedRegionList = jsonencode(struct(... |
36 | | - 'regionLineNumber',1,... |
37 | | - 'regionString',code,... |
38 | | - 'regionNumber',0,... |
39 | | - 'endOfSection',true,... |
40 | | - 'sectionNumber',1)); |
| 35 | +% 'requestId' - char array - UUID |
| 36 | +% 'editorId' - char array - unique identifier usually corresponding to a file. |
41 | 37 | request = struct('requestId', 'jupyter_matlab_kernel',... |
42 | | - 'regionArray', jsonedRegionList,... |
| 38 | + 'editorId', kernelId,... |
43 | 39 | 'fullText', code,... |
44 | 40 | 'fullFilePath', fileToShowErrors); |
45 | 41 |
|
| 42 | +% Update additional fields in the request based on MATLAB and LiveEditor API version. |
| 43 | +request = updateRequest(request, code); |
| 44 | + |
46 | 45 | % Disable Hotlinks in the output captured. The hotlinks do not have a purpose |
47 | 46 | % in Jupyter notebooks. |
48 | 47 | hotlinksPreviousState = feature('hotlinks','off'); |
|
54 | 53 | % Post-process the outputs to conform to Jupyter API. |
55 | 54 | result = processOutputs(resp.outputs); |
56 | 55 |
|
| 56 | +% Helper function to update fields in the request based on MATLAB and LiveEditor |
| 57 | +% API version. |
| 58 | +function request = updateRequest(request, code) |
| 59 | +% Support for MATLAB version <= R2023a. |
| 60 | +if isMATLABReleaseOlderThan("R2023b") |
| 61 | + request = updateRequestFromBefore23b(request, code); |
| 62 | +else |
| 63 | + % Support for MATLAB version >= R2023b. |
| 64 | + |
| 65 | + % To maintain backwards compatibility, each case in the switch |
| 66 | + % encodes conversion from the version number in the case |
| 67 | + % to the current version. |
| 68 | + switch matlab.internal.editor.getApiVersion('synchronous') |
| 69 | + case 1 |
| 70 | + request = updateRequestFromVersion1(request, code); |
| 71 | + otherwise |
| 72 | + error("Invalid API version. Create an issue at https://github.com/mathworks/jupyter-matlab-proxy for further support."); |
| 73 | + end |
| 74 | +end |
| 75 | + |
| 76 | +% Helper function to update fields in the request for MATLAB versions less than |
| 77 | +% R2023b |
| 78 | +function request = updateRequestFromBefore23b(request, code) |
| 79 | +jsonedRegionList = jsonencode(struct(... |
| 80 | + 'regionLineNumber',1,... |
| 81 | + 'regionString',code,... |
| 82 | + 'regionNumber',0,... |
| 83 | + 'endOfSection',true,... |
| 84 | + 'sectionNumber',1)); |
| 85 | +request.regionArray = jsonedRegionList; |
| 86 | + |
| 87 | +% Helper function to update fields in the request when LiveEditor API version is 1. |
| 88 | +function request = updateRequestFromVersion1(request, code) |
| 89 | +request.sectionBoundaries = []; |
| 90 | +request.startLine = 1; |
| 91 | +request.endLine = numel(splitlines(code)); |
| 92 | + |
| 93 | +% Allow figures to be used across Notebook cells. Cleanup needs to be |
| 94 | +% done explicitly when the kernel shutsdown. |
| 95 | +request.shouldResetState = false; |
| 96 | +request.shouldDoFullCleanup = false; |
| 97 | + |
| 98 | +% Helper function to process different types of outputs given by LiveEditor API. |
57 | 99 | function result = processOutputs(outputs) |
58 | 100 | result =cell(1,length(outputs)); |
59 | 101 | figureTrackingMap = containers.Map; |
|
137 | 179 |
|
138 | 180 | if isempty(webwindow) |
139 | 181 | url = 'toolbox/matlab/codetools/liveeditor/index.html'; |
140 | | - |
| 182 | + |
141 | 183 | % MATLAB versions R2020b and R2021a requires specifying the base url. |
142 | 184 | % Not doing so results in the URL not being loaded with the error |
143 | 185 | %"Not found. Request outside of context root". |
144 | | - if verLessThan('matlab','9.11') |
| 186 | + if isMATLABReleaseOlderThan("R2021b") |
145 | 187 | url = strcat(getenv("MWI_BASE_URL"), '/', url); |
146 | 188 | end |
147 | 189 | webwindow = matlab.internal.cef.webwindow(connector.getUrl(url)); |
|
0 commit comments