|
11 | 11 | */ |
12 | 12 | public class MagicParser { |
13 | 13 |
|
| 14 | + private final Pattern lineMagicPattern; |
| 15 | + private final Pattern cellMagicPattern; |
| 16 | + private final MagicTranspiler transpiler; |
| 17 | + |
| 18 | + public MagicParser(String lineMagicStart, String cellMagicStart, MagicTranspiler transpiler) { |
| 19 | + this.lineMagicPattern = Pattern.compile(lineMagicStart + "(?<args>\\w.*?)$", Pattern.MULTILINE); |
| 20 | + this.cellMagicPattern = Pattern.compile("^(?<argsLine>" + cellMagicStart + "(?<args>\\w.*?))\\R(?<body>(?sU).+?)$"); |
| 21 | + this.transpiler = transpiler; |
| 22 | + } |
| 23 | + |
| 24 | + /** |
| 25 | + * Replaces cell and line magics in the source with native kernel code. |
| 26 | + */ |
| 27 | + public String resolveMagics(String cellSource) { |
| 28 | + return transpileCellMagic(cellSource).orElse(transpileLineMagics(cellSource)); |
| 29 | + } |
| 30 | + |
| 31 | + private Optional<String> transpileCellMagic(String cellSource) { |
| 32 | + ParsedCellMagic parsedCell = parseCellMagic(cellSource); |
| 33 | + return Optional.ofNullable(parsedCell).map(transpiler::transpileCell); |
| 34 | + } |
| 35 | + |
| 36 | + String transpileLineMagics(String cellSource) { |
| 37 | + |
| 38 | + StringBuffer out = new StringBuffer(); |
| 39 | + Matcher m = lineMagicPattern.matcher(cellSource); |
| 40 | + |
| 41 | + while (m.find()) { |
| 42 | + ParsedLineMagic parsed = parseLineMagic(cellSource, m); |
| 43 | + String transformed = transpiler.transpileLine(parsed); |
| 44 | + m.appendReplacement(out, Matcher.quoteReplacement(transformed)); |
| 45 | + } |
| 46 | + |
| 47 | + m.appendTail(out); |
| 48 | + return out.toString(); |
| 49 | + } |
| 50 | + |
| 51 | + ParsedCellMagic parseCellMagic(String cellSource) { |
| 52 | + Matcher m = cellMagicPattern.matcher(cellSource); |
| 53 | + |
| 54 | + if (!m.matches()) { |
| 55 | + return null; |
| 56 | + } |
| 57 | + |
| 58 | + List<String> split = split(m.group("args")); |
| 59 | + String body = m.group("body"); |
| 60 | + |
| 61 | + return new ParsedCellMagic( |
| 62 | + split.get(0), |
| 63 | + split.subList(1, split.size()), |
| 64 | + body); |
| 65 | + } |
| 66 | + |
| 67 | + private ParsedLineMagic parseLineMagic(String cellSource, Matcher matchedLine) { |
| 68 | + List<String> split = split(matchedLine.group("args")); |
| 69 | + |
| 70 | + String rawLinePrefix = cellSource.substring(0, matchedLine.start()); |
| 71 | + String linePrefix = rawLinePrefix.substring(rawLinePrefix.lastIndexOf('\n') + 1); |
| 72 | + |
| 73 | + return new ParsedLineMagic( |
| 74 | + split.get(0), |
| 75 | + split.subList(1, split.size()), |
| 76 | + linePrefix, |
| 77 | + matchedLine.group() |
| 78 | + ); |
| 79 | + } |
| 80 | + |
14 | 81 | static List<String> split(String args) { |
15 | 82 | args = args.trim(); |
16 | 83 |
|
@@ -64,69 +131,4 @@ static List<String> split(String args) { |
64 | 131 |
|
65 | 132 | return split; |
66 | 133 | } |
67 | | - |
68 | | - private final Pattern lineMagicPattern; |
69 | | - private final Pattern cellMagicPattern; |
70 | | - private final MagicTranspiler transpiler; |
71 | | - |
72 | | - public MagicParser(String lineMagicStart, String cellMagicStart, MagicTranspiler transpiler) { |
73 | | - this.lineMagicPattern = Pattern.compile(lineMagicStart + "(?<args>\\w.*?)$", Pattern.MULTILINE); |
74 | | - this.cellMagicPattern = Pattern.compile("^(?<argsLine>" + cellMagicStart + "(?<args>\\w.*?))\\R(?<body>(?sU).+?)$"); |
75 | | - this.transpiler = transpiler; |
76 | | - } |
77 | | - |
78 | | - /** |
79 | | - * Replaces cell and line magics in the source with native kernel code. |
80 | | - */ |
81 | | - public String resolveMagics(String cellSource) { |
82 | | - return transpileCellMagic(cellSource).orElse(transpileLineMagics(cellSource)); |
83 | | - } |
84 | | - |
85 | | - private Optional<String> transpileCellMagic(String cellSource) { |
86 | | - ParsedCellMagic parsedCell = parseCellMagic(cellSource); |
87 | | - return Optional.ofNullable(parsedCell).map(transpiler::transpileCell); |
88 | | - } |
89 | | - |
90 | | - String transpileLineMagics(String cellSource) { |
91 | | - |
92 | | - StringBuffer out = new StringBuffer(); |
93 | | - Matcher m = lineMagicPattern.matcher(cellSource); |
94 | | - |
95 | | - while (m.find()) { |
96 | | - ParsedLineMagic parsed = parseLineMagic(cellSource, m); |
97 | | - String transformed = transpiler.transpileLine(parsed); |
98 | | - m.appendReplacement(out, Matcher.quoteReplacement(transformed)); |
99 | | - } |
100 | | - |
101 | | - m.appendTail(out); |
102 | | - return out.toString(); |
103 | | - } |
104 | | - |
105 | | - ParsedCellMagic parseCellMagic(String cellSource) { |
106 | | - Matcher m = this.cellMagicPattern.matcher(cellSource); |
107 | | - |
108 | | - if (!m.matches()) { |
109 | | - return null; |
110 | | - } |
111 | | - |
112 | | - String rawArgsLine = m.group("argsLine"); |
113 | | - String rawArgs = m.group("args"); |
114 | | - String body = m.group("body"); |
115 | | - List<String> split = split(rawArgs); |
116 | | - |
117 | | - CellMagicArgs args = new CellMagicArgs(split.get(0), split.subList(1, split.size()), body); |
118 | | - return new ParsedCellMagic(args, rawArgsLine, cellSource); |
119 | | - } |
120 | | - |
121 | | - private ParsedLineMagic parseLineMagic(String cellSource, Matcher matchedLine) { |
122 | | - String raw = matchedLine.group(); |
123 | | - String rawArgs = matchedLine.group("args"); |
124 | | - List<String> split = split(rawArgs); |
125 | | - |
126 | | - LineMagicArgs args = new LineMagicArgs(split.get(0), split.subList(1, split.size())); |
127 | | - |
128 | | - String rawLinePrefix = cellSource.substring(0, matchedLine.start()); |
129 | | - String linePrefix = rawLinePrefix.substring(rawLinePrefix.lastIndexOf('\n') + 1); |
130 | | - return new ParsedLineMagic(args, raw, cellSource, linePrefix); |
131 | | - } |
132 | 134 | } |
0 commit comments