blob: a8e7f13fc42a770e39541960c9a4e835db23d918 [file] [log] [blame]
Shawn Pearce12c8fab2016-05-15 16:55:21 -07001// Copyright (C) 2016 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles.doc;
16
Shawn Pearcec77a18b2016-07-26 10:18:37 -070017import static com.google.gitiles.doc.SmartQuoted.Type.DOUBLE;
18import static com.google.gitiles.doc.SmartQuoted.Type.SINGLE;
Shawn Pearce12c8fab2016-05-15 16:55:21 -070019
Shawn Pearce12c8fab2016-05-15 16:55:21 -070020import org.commonmark.Extension;
21import org.commonmark.node.Node;
22import org.commonmark.node.Text;
Shawn Pearce12c8fab2016-05-15 16:55:21 -070023import org.commonmark.parser.Parser;
24import org.commonmark.parser.Parser.ParserExtension;
Shawn Pearcec77a18b2016-07-26 10:18:37 -070025import org.commonmark.parser.delimiter.DelimiterProcessor;
26import org.commonmark.parser.delimiter.DelimiterRun;
Shawn Pearce12c8fab2016-05-15 16:55:21 -070027
28/** Uses smart quotes for ' and ". */
29public class SmartQuotedExtension implements ParserExtension {
30 public static Extension create() {
31 return new SmartQuotedExtension();
32 }
33
34 private SmartQuotedExtension() {}
35
36 @Override
37 public void extend(Parser.Builder builder) {
38 builder.customDelimiterProcessor(new QuotedProcessor(SINGLE, '\''));
39 builder.customDelimiterProcessor(new QuotedProcessor(DOUBLE, '"'));
40 }
41
Matthias Sohne2e3c6a2023-10-01 00:11:52 +020042 private static void quote(SmartQuoted.Type type, Text opener, Text closer) {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070043 SmartQuoted quote = new SmartQuoted();
44 quote.setType(type);
45 for (Node t = opener.getNext(); t != null && t != closer; ) {
46 Node next = t.getNext();
47 quote.appendChild(t);
48 t = next;
49 }
50 opener.insertAfter(quote);
51 }
52
53 /** Parses single and double quoted strings for smart quotes. */
54 private static class QuotedProcessor implements DelimiterProcessor {
55 private final SmartQuoted.Type type;
56 private final char delim;
57
58 QuotedProcessor(SmartQuoted.Type type, char open) {
59 this.type = type;
60 this.delim = open;
61 }
62
63 @Override
Shawn Pearcec77a18b2016-07-26 10:18:37 -070064 public char getOpeningCharacter() {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070065 return delim;
66 }
67
68 @Override
Shawn Pearcec77a18b2016-07-26 10:18:37 -070069 public char getClosingCharacter() {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070070 return delim;
71 }
72
73 @Override
Shawn Pearcec77a18b2016-07-26 10:18:37 -070074 public int getMinLength() {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070075 return 1;
76 }
77
78 @Override
Ivan Frade21831b92022-12-01 21:54:21 -080079 public int process(DelimiterRun openingRun, DelimiterRun closingRun) {
80 quote(type, openingRun.getOpener(), closingRun.getCloser());
Shawn Pearce12c8fab2016-05-15 16:55:21 -070081 return 1;
82 }
Shawn Pearce12c8fab2016-05-15 16:55:21 -070083 }
84}