标记文本解析器,如 Objective-C 中的 stackoverflow 格式化程序

发布于 2024-09-15 19:47:50 字数 309 浏览 10 评论 0原文

我正在使用 Objective C 创建标记编辑器。我需要以下功能:

  • 识别块的分界,例如 **block**
  • 删除开始和结束“标签”,例如“下一个文本是**粗体**”变为“下一个文本是粗体”
  • 确定新上下文中标记文本的开始和结束位置:“下一个文本是粗体”

编辑: 由于我将来可能会扩展语法(目前会非常有限),因此自顶向下进行解析非常重要,这样文本的开始和结束位置始终与结果文本相对应。因此,正则表达式可能不是最好的解决方案。

最好的方法是什么?

I'm in the process of creating a markup editor in Objective C. I require the following functionality:

  • Recognise the demarcation of a block eg **block**
  • Delete the start and end "tags" eg "The next text is **bold**" becomes "The next text is bold"
  • Determine the start and end positions of the marked-up text in the new context: "The next text is bold"

Edit:
As I may expand the syntax in the future (it will be very limited at the moment), it is important that parsing be top-down such that the start and end positions of the text always correspond with the resulting text. For this reason regex may not be the best solution.

What is the best way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不爱素颜 2024-09-22 19:47:50

最后使用 RegexKitLite 采用正则表达式方法

下面的代码尚未经过充分测试,但确实St3fan 指出的案例。

- (NSArray *) scanContent:(NSMutableString **)content {
    NSMutableArray *tokens = [[NSMutableArray alloc] init];

    NSArray *captureRegex = [[NSArray alloc] initWithObjects:
                             @"\\[\\[(.*?)\\]\\]",@"\\*\\*(.*?)\\*\\*", nil];

    NSArray *tokenID = [[NSArray alloc] initWithObjects:
                        @"Italic",@"Bold", nil];

    int index = 0;

    for (NSString*capture in captureRegex) {

        NSRange captureRange;
        NSRange stringRange;
        stringRange.location = 0;
        stringRange.length = [*content length];

        do {
            captureRange = [*content rangeOfRegex:capture inRange:stringRange];
            if ( captureRange.location != NSNotFound ) {

                NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
                [dictionary setObject:[tokenID objectAtIndex:index] forKey:@"Token"];

                [dictionary setObject:[NSNumber numberWithInt:captureRange.location]
                               forKey:@"Start"];
                [dictionary setObject:[NSNumber numberWithInt:captureRange.length]
                               forKey:@"Length"];

                [tokens addObject:dictionary];

                for (NSMutableDictionary *dict in tokens) {
                    NSNumber *nRange = [dict objectForKey:@"Start"];
                    int start = [nRange intValue];

                    if (start > captureRange.location) {
                        nRange = [NSNumber numberWithInt:start - 4]; // Removing 4 characters 
                        [dict setObject:nRange forKey:@"Start"];
                    }

                    if (start == captureRange.location) {
                        NSString *data = [*content stringByMatching:capture options:RKLMultiline inRange:captureRange capture:1 error:NULL];                
                        NSLog(@"data: %@",data);
                        [*content replaceOccurrencesOfRegex:capture withString:data range:captureRange];
                        NSLog(@"Replaced Content: %@",*content);
                    }
                }

                stringRange.location = captureRange.location + captureRange.length -4;
                stringRange.length = [*content length] - stringRange.location;
            }
        }
        while ( captureRange.location != NSNotFound );

        index++;
    }
    return tokens;
}

In the end went for regex approach using RegexKitLite

The code below is not fully tested but does work with the case St3fan pointed out.

- (NSArray *) scanContent:(NSMutableString **)content {
    NSMutableArray *tokens = [[NSMutableArray alloc] init];

    NSArray *captureRegex = [[NSArray alloc] initWithObjects:
                             @"\\[\\[(.*?)\\]\\]",@"\\*\\*(.*?)\\*\\*", nil];

    NSArray *tokenID = [[NSArray alloc] initWithObjects:
                        @"Italic",@"Bold", nil];

    int index = 0;

    for (NSString*capture in captureRegex) {

        NSRange captureRange;
        NSRange stringRange;
        stringRange.location = 0;
        stringRange.length = [*content length];

        do {
            captureRange = [*content rangeOfRegex:capture inRange:stringRange];
            if ( captureRange.location != NSNotFound ) {

                NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
                [dictionary setObject:[tokenID objectAtIndex:index] forKey:@"Token"];

                [dictionary setObject:[NSNumber numberWithInt:captureRange.location]
                               forKey:@"Start"];
                [dictionary setObject:[NSNumber numberWithInt:captureRange.length]
                               forKey:@"Length"];

                [tokens addObject:dictionary];

                for (NSMutableDictionary *dict in tokens) {
                    NSNumber *nRange = [dict objectForKey:@"Start"];
                    int start = [nRange intValue];

                    if (start > captureRange.location) {
                        nRange = [NSNumber numberWithInt:start - 4]; // Removing 4 characters 
                        [dict setObject:nRange forKey:@"Start"];
                    }

                    if (start == captureRange.location) {
                        NSString *data = [*content stringByMatching:capture options:RKLMultiline inRange:captureRange capture:1 error:NULL];                
                        NSLog(@"data: %@",data);
                        [*content replaceOccurrencesOfRegex:capture withString:data range:captureRange];
                        NSLog(@"Replaced Content: %@",*content);
                    }
                }

                stringRange.location = captureRange.location + captureRange.length -4;
                stringRange.length = [*content length] - stringRange.location;
            }
        }
        while ( captureRange.location != NSNotFound );

        index++;
    }
    return tokens;
}
橘寄 2024-09-22 19:47:50

MarkDown Sharp 是 StackExchange 网站上使用的 Markdown 处理器,它是开源。看看该文件,也许你可以看看他们是如何做到的或者将其移植到 Objective-C 中。

也许更好的是,看看这个问题: “Cocoa 应用程序的 Markdown 最简单实现是什么?”

它链接到一个名为 MarkdownLive 它使用 Markdown 的 C 实现(称为折扣),并且还为其提供了 Objective-C 包装器。

MarkDown Sharp, the markdown processor used on the StackExchange websites, is open source. Take a look at the file, perhaps you can see how they do it or port it to objective-c.

Perhaps better yet, take a look at this question: "What is the simplest implementation of Markdown for a Cocoa application?"

It links to an open source application called MarkdownLive which uses a C implementation of Markdown called discount, and also provides an objective-c wrapper for it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文