示例#1
0
文件: inlines.c 项目: lowks/cmark.ex
static void process_emphasis(subject *subj, delimiter *start_delim)
{
	delimiter *closer = subj->last_delim;
	delimiter *opener;

	// move back to first relevant delim.
	while (closer != NULL && closer->previous != start_delim) {
		closer = closer->previous;
	}

	// now move forward, looking for closers, and handling each
	while (closer != NULL) {
		if (closer->can_close &&
		    (closer->delim_char == '*' || closer->delim_char == '_' ||
		     closer->delim_char == '"' || closer->delim_char == '\'')) {
			// Now look backwards for first matching opener:
			opener = closer->previous;
			while (opener != NULL && opener != start_delim) {
				if (opener->delim_char == closer->delim_char &&
				    opener->can_open) {
					break;
				}
				opener = opener->previous;
			}
			if (closer->delim_char == '*' || closer->delim_char == '_') {
				if (opener != NULL && opener != start_delim) {
					closer = S_insert_emph(subj, opener, closer);
				} else {
					closer = closer->next;
				}
			} else if (closer->delim_char == '\'') {
				cmark_chunk_free(&closer->inl_text->as.literal);
				closer->inl_text->as.literal =
					cmark_chunk_literal(RIGHTSINGLEQUOTE);
				if (opener != NULL && opener != start_delim) {
					cmark_chunk_free(&opener->inl_text->as.literal);
					opener->inl_text->as.literal =
						cmark_chunk_literal(LEFTSINGLEQUOTE);
				}
				closer = closer->next;
			} else if (closer->delim_char == '"') {
				cmark_chunk_free(&closer->inl_text->as.literal);
				closer->inl_text->as.literal =
					cmark_chunk_literal(RIGHTDOUBLEQUOTE);
				if (opener != NULL && opener != start_delim) {
					cmark_chunk_free(&opener->inl_text->as.literal);
					opener->inl_text->as.literal =
						cmark_chunk_literal(LEFTDOUBLEQUOTE);
				}
				closer = closer->next;
			}
		} else {
			closer = closer->next;
		}
	}
	// free all delimiters in list until start_delim:
	while (subj->last_delim != start_delim) {
		remove_delimiter(subj, subj->last_delim);
	}
}
示例#2
0
static void process_emphasis(subject *subj, delimiter *start_delim)
{
	delimiter *closer = subj->last_delim;
	delimiter *opener;

	// move back to first relevant delim.
	while (closer != NULL && closer->previous != start_delim) {
		closer = closer->previous;
	}

	// now move forward, looking for closers, and handling each
	while (closer != NULL) {
		if (closer->can_close &&
		    (closer->delim_char == '*' || closer->delim_char == '_')) {
			// Now look backwards for first matching opener:
			opener = closer->previous;
			while (opener != NULL && opener != start_delim) {
				if (opener->delim_char == closer->delim_char &&
				    opener->can_open) {
					break;
				}
				opener = opener->previous;
			}
			if (opener != NULL && opener != start_delim) {
				closer = S_insert_emph(subj, opener, closer);
			} else {
				closer = closer->next;
			}
		} else {
			closer = closer->next;
		}
	}
	// free all delimiters in list until start_delim:
	while (subj->last_delim != start_delim) {
		remove_delimiter(subj, subj->last_delim);
	}
}
示例#3
0
static void process_emphasis(subject *subj, delimiter *stack_bottom) {
  delimiter *closer = subj->last_delim;
  delimiter *opener;
  delimiter *old_closer;
  bool opener_found;
  int openers_bottom_index;
  delimiter *openers_bottom[6] = {stack_bottom, stack_bottom, stack_bottom,
                                  stack_bottom, stack_bottom, stack_bottom};

  // move back to first relevant delim.
  while (closer != NULL && closer->previous != stack_bottom) {
    closer = closer->previous;
  }

  // now move forward, looking for closers, and handling each
  while (closer != NULL) {
    if (closer->can_close) {
      switch (closer->delim_char) {
      case '"':
        openers_bottom_index = 0;
        break;
      case '\'':
        openers_bottom_index = 1;
        break;
      case '_':
        openers_bottom_index = 2;
        break;
      case '*':
        openers_bottom_index = 3 + (closer->length % 3);
        break;
      default:
        assert(false);
      }

      // Now look backwards for first matching opener:
      opener = closer->previous;
      opener_found = false;
      while (opener != NULL && opener != openers_bottom[openers_bottom_index]) {
        if (opener->can_open && opener->delim_char == closer->delim_char) {
          // interior closer of size 2 can't match opener of size 1
          // or of size 1 can't match 2
          if (!(closer->can_open || opener->can_close) ||
              ((opener->length + closer->length) % 3) != 0) {
            opener_found = true;
            break;
          }
        }
        opener = opener->previous;
      }
      old_closer = closer;
      if (closer->delim_char == '*' || closer->delim_char == '_') {
        if (opener_found) {
          closer = S_insert_emph(subj, opener, closer);
        } else {
          closer = closer->next;
        }
      } else if (closer->delim_char == '\'') {
        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
        if (opener_found) {
          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
          opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
        }
        closer = closer->next;
      } else if (closer->delim_char == '"') {
        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
        if (opener_found) {
          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
          opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
        }
        closer = closer->next;
      }
      if (!opener_found) {
        // set lower bound for future searches for openers
        openers_bottom[openers_bottom_index] = old_closer->previous;
        if (!old_closer->can_open) {
          // we can remove a closer that can't be an
          // opener, once we've seen there's no
          // matching opener:
          remove_delimiter(subj, old_closer);
        }
      }
    } else {
      closer = closer->next;
    }
  }
  // free all delimiters in list until stack_bottom:
  while (subj->last_delim != NULL && subj->last_delim != stack_bottom) {
    remove_delimiter(subj, subj->last_delim);
  }
}
示例#4
0
文件: inlines.c 项目: tin-pot/cmark
static void process_emphasis(subject *subj, delimiter *stack_bottom) {
  delimiter *closer = subj->last_delim;
  delimiter *opener;
  delimiter *old_closer;
  bool opener_found;
  bool odd_match;
  delimiter *openers_bottom[128];

  // initialize openers_bottom:
  openers_bottom['*'] = stack_bottom;
  openers_bottom['_'] = stack_bottom;
  openers_bottom['\''] = stack_bottom;
  openers_bottom['"'] = stack_bottom;

  // move back to first relevant delim.
  while (closer != NULL && closer->previous != stack_bottom) {
    closer = closer->previous;
  }

  // now move forward, looking for closers, and handling each
  while (closer != NULL) {
    if (closer->can_close) {
      // Now look backwards for first matching opener:
      opener = closer->previous;
      opener_found = false;
      odd_match = false;
      while (opener != NULL && opener != stack_bottom &&
             opener != openers_bottom[closer->delim_char]) {
        // interior closer of size 2 can't match opener of size 1
        // or of size 1 can't match 2
        odd_match = (closer->can_open || opener->can_close) &&
                    ((opener->inl_text->as.literal.len +
                      closer->inl_text->as.literal.len) %
                         3 ==
                     0);
        if (opener->delim_char == closer->delim_char && opener->can_open &&
            !odd_match) {
          opener_found = true;
          break;
        }
        opener = opener->previous;
      }
      old_closer = closer;
      if (closer->delim_char == '*' || closer->delim_char == '_') {
        if (opener_found) {
          closer = S_insert_emph(subj, opener, closer);
        } else {
          closer = closer->next;
        }
      } else if (closer->delim_char == '\'') {
        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
        if (opener_found) {
          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
          opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
        }
        closer = closer->next;
      } else if (closer->delim_char == '"') {
        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
        if (opener_found) {
          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
          opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
        }
        closer = closer->next;
      }
      if (!opener_found && !odd_match) {
        // set lower bound for future searches for openers
        // (we don't do this with 'odd_match' set because
        // a ** that didn't match an earlier * might turn into
        // an opener, and the * might be matched by something
        // else.
        openers_bottom[old_closer->delim_char] = old_closer->previous;
        if (!old_closer->can_open) {
          // we can remove a closer that can't be an
          // opener, once we've seen there's no
          // matching opener:
          remove_delimiter(subj, old_closer);
        }
      }
    } else {
      closer = closer->next;
    }
  }
  // free all delimiters in list until stack_bottom:
  while (subj->last_delim != stack_bottom) {
    remove_delimiter(subj, subj->last_delim);
  }
}
示例#5
0
文件: inlines.c 项目: omasanori/cmark
static void process_emphasis(subject *subj, delimiter *stack_bottom)
{
	delimiter *closer = subj->last_delim;
	delimiter *opener;
	delimiter *old_closer;
	bool opener_found;
	delimiter *openers_bottom[128];

	// initialize openers_bottom:
	openers_bottom['*'] = stack_bottom;
	openers_bottom['_'] = stack_bottom;
	openers_bottom['\''] = stack_bottom;
	openers_bottom['"'] = stack_bottom;

	// move back to first relevant delim.
	while (closer != NULL && closer->previous != stack_bottom) {
		closer = closer->previous;
	}

	// now move forward, looking for closers, and handling each
	while (closer != NULL) {
		if (closer->can_close &&
		    (closer->delim_char == '*' || closer->delim_char == '_' ||
		     closer->delim_char == '"' || closer->delim_char == '\'')) {
			// Now look backwards for first matching opener:
			opener = closer->previous;
			opener_found = false;
			while (opener != NULL && opener != stack_bottom &&
			       opener != openers_bottom[closer->delim_char]) {
				if (opener->delim_char == closer->delim_char &&
				    opener->can_open) {
					opener_found = true;
					break;
				}
				opener = opener->previous;
			}
			old_closer = closer;
			if (closer->delim_char == '*' || closer->delim_char == '_') {
				if (opener_found) {
					closer = S_insert_emph(subj, opener, closer);
				} else {
					closer = closer->next;
				}
			} else if (closer->delim_char == '\'') {
				cmark_chunk_free(&closer->inl_text->as.literal);
				closer->inl_text->as.literal =
				    cmark_chunk_literal(RIGHTSINGLEQUOTE);
				if (opener_found) {
					cmark_chunk_free(&opener->inl_text->as.literal);
					opener->inl_text->as.literal =
					    cmark_chunk_literal(LEFTSINGLEQUOTE);
				}
				closer = closer->next;
			} else if (closer->delim_char == '"') {
				cmark_chunk_free(&closer->inl_text->as.literal);
				closer->inl_text->as.literal =
				    cmark_chunk_literal(RIGHTDOUBLEQUOTE);
				if (opener_found) {
					cmark_chunk_free(&opener->inl_text->as.literal);
					opener->inl_text->as.literal =
					    cmark_chunk_literal(LEFTDOUBLEQUOTE);
				}
				closer = closer->next;
			}
			if (!opener_found) {
				// set lower bound for future searches for openers:
				openers_bottom[old_closer->delim_char] = old_closer->previous;
				if (!old_closer->can_open) {
					// we can remove a closer that can't be an
					// opener, once we've seen there's no
					// matching opener:
					remove_delimiter(subj, old_closer);
				}
			}
		} else {
			closer = closer->next;
		}
	}
	// free all delimiters in list until stack_bottom:
	while (subj->last_delim != stack_bottom) {
		remove_delimiter(subj, subj->last_delim);
	}
}