All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.markdown.HtmlListChannel Maven / Gradle / Ivy

/*
 * SonarQube
 * Copyright (C) 2009-2024 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.sonar.markdown;

import org.sonar.channel.Channel;
import org.sonar.channel.CodeReader;
import org.sonar.channel.RegexChannel;

/**
 * Lists come in two flavors:
 * 
    *
  • Unordered lists, triggered by lines that start with a *
  • *
  • Ordered lists (added in 4.4), triggered by lines that start with a digit followed by a .
  • *
* E.g., the input: *
 * * One
 * * Two
 * * Three
 * 
* will produce: * {@literal
    }{@literal
  • }One{@literal
  • } * {@literal
  • }Two{@literal
  • } * {@literal
  • }Three{@literal
  • }{@literal
} * * Whereas the input: *
 * 1. One
 * 1. Two
 * 1. Three
 * 
* will produce: * {@literal
    }{@literal
  1. }One{@literal
  2. } * {@literal
  3. }Two{@literal
  4. } * {@literal
  5. }Three{@literal
  6. }{@literal
} * * @since 2.10.1 */ class HtmlListChannel extends Channel { private OrderedListElementChannel orderedListElement = new OrderedListElementChannel(); private UnorderedListElementChannel unorderedListElement = new UnorderedListElementChannel(); private EndOfLine endOfLine = new EndOfLine(); private boolean pendingListConstruction; @Override public boolean consume(CodeReader code, MarkdownOutput output) { try { ListElementChannel currentChannel = null; if (code.getColumnPosition() == 0) { if (orderedListElement.consume(code, output)) { currentChannel = orderedListElement; } else if (unorderedListElement.consume(code, output)) { currentChannel = unorderedListElement; } if (currentChannel != null) { while (endOfLine.consume(code, output) && currentChannel.consume(code, output)) { // consume input } output.append(""); return true; } } return false; } finally { pendingListConstruction = false; } } private class OrderedListElementChannel extends ListElementChannel { public OrderedListElementChannel() { super("\\d\\.", "ol"); } } private class UnorderedListElementChannel extends ListElementChannel { public UnorderedListElementChannel() { super("\\*", "ul"); } } private abstract class ListElementChannel extends RegexChannel { private String listElement; protected ListElementChannel(String markerRegexp, String listElement) { super("\\s*+" + markerRegexp + "\\s[^\r\n]*+"); this.listElement = listElement; } @Override protected void consume(CharSequence token, MarkdownOutput output) { if (!pendingListConstruction) { output.append("<" + listElement + ">"); pendingListConstruction = true; } output.append("
  • "); output.append(token.subSequence(searchIndexOfFirstCharacter(token), token.length())); output.append("
  • "); } private int searchIndexOfFirstCharacter(CharSequence token) { for (int index = 0; index < token.length(); index++) { if (token.charAt(index) == '*' || Character.isDigit(token.charAt(index))) { if (token.charAt(index + 1) == '.') { index ++; } while (++ index < token.length()) { if (token.charAt(index) != ' ') { return index; } } } } return token.length() - 1; } } private static final class EndOfLine extends RegexChannel { public EndOfLine() { super("(\r?\n)|(\r)"); } @Override protected void consume(CharSequence token, MarkdownOutput output) { output.append(token); } } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy