<commit_before>/******************************************************************
 *  LexMarkdown.cxx
 *
 *  A simple Markdown lexer for scintilla.
 *   
 *  Includes highlighting for some extra features from the
 *  Pandoc implementation; strikeout, using '#.' as a default 
 *  ordered list item marker, and delimited code blocks.
 * 
 *  Limitations:
 * 
 *  Standard indented code blocks are not highlighted at all,
 *  as it would conflict with other indentation schemes. Use 
 *  delimited code blocks for blanket highlighting of an
 *  entire code block.  Embedded HTML is not highlighted either.
 *  Blanket HTML highlighting has issues, because some Markdown
 *  implementations allow Markdown markup inside of the HTML. Also,
 *  there is a following blank line issue that can't be ignored, 
 *  explained in the next paragraph. Embedded HTML and code 
 *  blocks would be better supported with language specific 
 *  highlighting.
 * 
 *  The highlighting aims to accurately reflect correct syntax,
 *  but a few restrictions are relaxed. Delimited code blocks are
 *  highlighted, even if the line following the code block is not blank.  
 *  Requiring a blank line after a block, breaks the highlighting
 *  in certain cases, because of the way Scintilla ends up calling
 *  the lexer.
 * 
 *  Written by <NAME> - <EMAIL>
 *
 *  The License.txt file describes the conditions under which this
 *  software may be distributed.
 *
 *****************************************************************/

#include <stdlib.h>         
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsNewline(const int ch) {
    return (ch == '\n' || ch == '\r');
}

// True if can follow ch down to the end with possibly trailing whitespace
static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
    unsigned int i = 0;
    while (sc.GetRelative(++i) == ch)
        ;
    // Skip over whitespace
    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
        ++i;
    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
        sc.Forward(i);
        sc.ChangeState(state);
        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
        return true;
    }
    else return false;
}

// Set the state on text section from current to length characters, 
// then set the rest until the newline to default, except for any characters matching token
static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
    sc.SetState(state);
    sc.Forward(length);
    sc.SetState(SCE_MARKDOWN_DEFAULT);
    sc.Forward();
    bool started = false;
    while (sc.More() && !IsNewline(sc.ch)) {
        if (sc.ch == token && !started) {
            sc.SetState(state);
            started = true;
        }
        else if (sc.ch != token) {
            sc.SetState(SCE_MARKDOWN_DEFAULT);
            started = false;
        }
        sc.Forward();
    }
    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}

// Does the previous line have more than spaces and tabs?
static bool HasPrevLineContent(StyleContext &sc) {
    int i = 0;
    // Go back to the previous newline
    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) 
        ;
    while (--i + sc.currentPos) {
        if (IsNewline(sc.GetRelative(i)))
            break;
        if (!IsASpaceOrTab(sc.GetRelative(i)))
            return true;
    }
    return false;
}

static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
    int c, count = 1;
    unsigned int i = 0;
    while (++i) {
        c = sc.GetRelative(i);
        if (c == sc.ch) 
            ++count;
        // hit a terminating character
        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
            // Are we a valid HRULE<commit_msg>See bug 91001.  Neil would only accept my patch for bug91001 if it would apply cleanly to current HEAD LexMarkdown.cxx.  So I updated ours to be the same as his, and we can drop the old patch, and revise the current one.<commit_after>/******************************************************************
 *  LexMarkdown.cxx
 *
 *  A simple Markdown lexer for scintilla.
 *   
 *  Includes highlighting for some extra features from the
 *  Pandoc implementation; strikeout, using '#.' as a default 
 *  ordered list item marker, and delimited code blocks.
 * 
 *  Limitations:
 * 
 *  Standard indented code blocks are not highlighted at all,
 *  as it would conflict with other indentation schemes. Use 
 *  delimited code blocks for blanket highlighting of an
 *  entire code block.  Embedded HTML is not highlighted either.
 *  Blanket HTML highlighting has issues, because some Markdown
 *  implementations allow Markdown markup inside of the HTML. Also,
 *  there is a following blank line issue that can't be ignored, 
 *  explained in the next paragraph. Embedded HTML and code 
 *  blocks would be better supported with language specific 
 *  highlighting.
 * 
 *  The highlighting aims to accurately reflect correct syntax,
 *  but a few restrictions are relaxed. Delimited code blocks are
 *  highlighted, even if the line following the code block is not blank.  
 *  Requiring a blank line after a block, breaks the highlighting
 *  in certain cases, because of the way Scintilla ends up calling
 *  the lexer.
 * 
 *  Written by <NAME> - <EMAIL>
 *
 *  The License.txt file describes the conditions under which this
 *  software may be distributed.
 *
 *****************************************************************/

#include <stdlib.h>         
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsNewline(const int ch) {
    return (ch == '\n' || ch == '\r');
}

// True if can follow ch down to the end with possibly trailing whitespace
static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
    unsigned int i = 0;
    while (sc.GetRelative(++i) == ch)
        ;
    // Skip over whitespace
    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
        ++i;
    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
        sc.Forward(i);
        sc.ChangeState(state);
        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
        return true;
    }
    else return false;
}

// Set the state on text section from current to length characters, 
// then set the rest until the newline to default, except for any characters matching token
static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
    sc.SetState(state);
    sc.Forward(length);
    sc.SetState(SCE_MARKDOWN_DEFAULT);
    sc.Forward();
    bool started = false;
    while (sc.More() && !IsNewline(sc.ch)) {
        if (sc.ch == token && !started) {
            sc.SetState(state);
            started = true;
        }
        else if (sc.ch != token) {
            sc.SetState(SCE_MARKDOWN_DEFAULT);
            started = false;
        }
        sc.Forward();
    }
    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}

// Does the previous line have more than spaces and tabs?
static bool HasPrevLineContent(StyleContext &sc) {
    int i = 0;
    // Go back to the previous newline
    while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
        ;
    while ((--i + (int)sc.currentPos) >= 0) {
        if (IsNewline(sc.GetRelative(i)))
            break;
        if (!IsASpaceOrTab(sc.GetRelative(i)))
            return true;
    }
    return false;
}

static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
    int c, count = 1;
    unsigned int i = 0;
    while (++i) {
        c = sc.GetRelative(i);
        if (c == sc.ch) 
            ++count;
        // hit a terminating character
        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
            // Are we a valid HRULE
{'fraction_non_alphanumeric': 0.1274251497005988, 'fraction_numerical': 0.0023952095808383233, 'mean_word_length': 2.944733112895607, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6395376', 'n_tokens_mistral': 2518, 'n_tokens_neox': 2429, 'n_words': 888}