diff --git a/DOCS/interface-changes/sub-sdh-enclosures.txt b/DOCS/interface-changes/sub-sdh-enclosures.txt new file mode 100644 index 0000000000..5cd06c3f15 --- /dev/null +++ b/DOCS/interface-changes/sub-sdh-enclosures.txt @@ -0,0 +1 @@ +the `--sub-sdh-enclosures` option is now a string list option diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index c01ca29543..ca4f59bc40 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -3162,13 +3162,13 @@ Subtitles Default: ``no``. ``--sub-filter-sdh-enclosures=`` - Specify a string of characters that ``--sub-filter-sdh`` will use to potentially - remove text. Text that is enclosed within characters specified by this string will - be removed. Note that bracket characters with known pairs (such as ``(`` or ``[``) - will be mapped internally to their matching right hand character, so you only need - to specify left hand characters. + Specify pairs of characters that ``--sub-filter-sdh`` will use to + potentially remove text. This is a string list option. See `List Options`_ + for details. Text that is enclosed within each specified pair will be + removed. Note that parenthesis pairs (normal and full width) are treated as + a special case and require ``--sub-fitler-sdh-harder`` to be removed. - Default: ``([(``. + Default: ``(),[],()`` ``--sub-filter-regex-...=...`` Set a list of regular expressions to match on text subtitles, and remove any diff --git a/sub/filter_sdh.c b/sub/filter_sdh.c index b71c193299..0178124e1d 100644 --- a/sub/filter_sdh.c +++ b/sub/filter_sdh.c @@ -33,13 +33,6 @@ // all SDH parts. // It is for filtering ASS encoded subtitles -static const char *const enclosure_pair[][2] = { - {"(", ")"}, - {"[", "]"}, - {"\uFF08", "\uFF09"}, - {0}, -}; - struct buffer { char *string; int length; @@ -84,26 +77,26 @@ static int get_char_bytes(char *str) return 0; } -static const char *get_right_enclosure(char *left) +static bool is_parenthesis_pair(const char *left, const char *right) { - // See if the right hand character is mapped. If not, just return the same thing. - for (int i = 0; enclosure_pair[i][0]; i++) { - if (strcmp(left, enclosure_pair[i][0]) == 0) - return enclosure_pair[i][1]; - } - return left; + if (!strcmp(left, "(") && !strcmp(right, ")")) + return true; + if (!strcmp(left, "\uFF08") && !strcmp(right, "\uFF09")) + return true; + return false; } -static bool valid_left_enclosure(struct sd_filter *sd, char *str) +static int matching_enclosure(char **enclosures, char *str) { - // All characters in this string are valid left hand enclosure characters. - char *enclosures = sd->opts->sub_filter_SDH_enclosures; - int len = strlen(enclosures); - for (int i = 0; i < len; i++) { - if (str && str[0] && str[0] == enclosures[i]) - return true; + int len = get_char_bytes(str); + for (int i = 0; len && enclosures && enclosures[i]; ++i) { + if (!strncmp(str, enclosures[i], len) && + len == get_char_bytes(enclosures[i])) // str doesn't end early + { + return i; + } } - return false; + return -1; } @@ -246,7 +239,7 @@ static bool skip_enclosed(struct sd_filter *sd, char **rpp, struct buffer *buf, bool filter_harder = sd->opts->sub_filter_SDH_harder; char *rp = *rpp; int old_pos = buf->pos; - bool parenthesis = strcmp(left, "(") == 0 || strcmp(left, "\uFF08") == 0; + bool parenthesis = is_parenthesis_pair(left, right); // skip past the left character rp += get_char_bytes(rp); @@ -380,15 +373,16 @@ static char *filter_SDH(struct sd_filter *sd, char *data, int length, ptrdiff_t while (*rp && !(rp[0] == '\\' && rp[1] == 'N')) { copy_ass(sd, &rp, buf); char left[5] = {0}; - const char *right = NULL; - if (valid_left_enclosure(sd, rp)) { + char **enclosures = sd->opts->sub_filter_SDH_enclosures; + int index = matching_enclosure(enclosures, rp); + if (index > -1) { int bytes = get_char_bytes(rp); for (int i = 0; i < bytes; i++) left[i] = rp[i]; - left[bytes] = '\0'; - right = get_right_enclosure(left); } - if (left[0] && right && right[0]) { + if (left[0]) { + // Skip left character + char *right = enclosures[index] + get_char_bytes(enclosures[index]); if (!skip_enclosed(sd, &rp, buf, left, right)) { append(sd, buf, rp[0]); rp++; diff --git a/sub/sd.h b/sub/sd.h index 406cbb8506..5acbbb1ff7 100644 --- a/sub/sd.h +++ b/sub/sd.h @@ -70,7 +70,7 @@ void lavc_conv_uninit(struct lavc_conv *priv); struct mp_sub_filter_opts { bool sub_filter_SDH; bool sub_filter_SDH_harder; - char *sub_filter_SDH_enclosures; + char **sub_filter_SDH_enclosures; bool rf_enable; bool rf_plain; char **rf_items; diff --git a/sub/sd_ass.c b/sub/sd_ass.c index d56facdbde..a3d948adde 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -75,7 +75,7 @@ const struct m_sub_options mp_sub_filter_opts = { .opts = (const struct m_option[]){ {"sdh", OPT_BOOL(sub_filter_SDH)}, {"sdh-harder", OPT_BOOL(sub_filter_SDH_harder)}, - {"sdh-enclosures", OPT_STRING(sub_filter_SDH_enclosures)}, + {"sdh-enclosures", OPT_STRINGLIST(sub_filter_SDH_enclosures)}, {"regex-enable", OPT_BOOL(rf_enable)}, {"regex-plain", OPT_BOOL(rf_plain)}, {"regex", OPT_STRINGLIST(rf_items)}, @@ -85,7 +85,12 @@ const struct m_sub_options mp_sub_filter_opts = { }, .size = sizeof(OPT_BASE_STRUCT), .defaults = &(OPT_BASE_STRUCT){ - .sub_filter_SDH_enclosures = "([\uFF08", + .sub_filter_SDH_enclosures = (char *[]) { + "()", + "[]", + "\uFF08\uFF09", + NULL + }, .rf_enable = true, }, .change_flags = UPDATE_SUB_FILT,