/*
I used ENT_COMPAT because escaping single quotes is only relevant, if attribute are written with single quotes.
Since NoTeePHP does not use single quotes, using ENT_COMPAT is enough.
485103
public function escapeHtml(string $value) : string
    {
        return htmlspecialchars($value, ENT_COMPAT, $this->encoding, false);
    }
58053
String unescapeEntities(boolean inAttribute) {
        StringBuilder builder = StringUtil.borrowBuilder();
        while (!reader.isEmpty()) {
            builder.append(reader.consumeTo('&'));
            if (reader.matches('&')) {
                reader.consume();
                int[] c = consumeCharacterReference(null, inAttribute);
                if (c == null || c.length==0)
                    builder.append('&');
                else {
                    builder.appendCodePoint(c[0]);
                    if (c.length == 2)
                        builder.appendCodePoint(c[1]);
                }

            }
        }
        return StringUtil.releaseBuilder(builder);
    }
895523
protected void writeAttributeValue(String value, Writer out) throws IOException {
		// .[apostrophe and <, & escaped],
		final char quot = attributeUseApostrophe ? '\'' : '"';
		final String quotEntity = attributeUseApostrophe ? "&apos;" : "&quot;";

		int pos = 0;
		for (int i = 0; i < value.length(); i++) {
			char ch = value.charAt(i);
			if (ch == '&') {
				if (i > pos)
					out.write(value.substring(pos, i));
				out.write("&amp;");
				pos = i + 1;
			}
			if (ch == '<') {
				if (i > pos)
					out.write(value.substring(pos, i));
				out.write("&lt;");
				pos = i + 1;
			} else if (ch == quot) {
				if (i > pos)
					out.write(value.substring(pos, i));
				out.write(quotEntity);
				pos = i + 1;
			} else if (ch < 32) {
				// in XML 1.0 only legal character are #x9 | #xA | #xD
				// and they must be escaped otherwise in attribute value they
				// are normalized to spaces
				if (ch == 13 || ch == 10 || ch == 9) {
					if (i > pos)
						out.write(value.substring(pos, i));
					out.write("&#");
					out.write(Integer.toString(ch));
					out.write(';');
					pos = i + 1;
				} else {
					if (TRACE_ESCAPING)
						System.err.println(getClass().getName() + " DEBUG ATTR value.len=" + value.length() + " " + printable(value));

					throw new IllegalStateException(
							// "character "+Integer.toString(ch)+" is not
							// allowed in output"+getLocation());
							"character " + printable(ch) + " (" + Integer.toString(ch) + ") is not allowed in output" + getLocation() + " (attr value=" + printable(value) + ")");
					// in XML 1.1 legal are [#x1-#xD7FF]
					// if(ch > 0) {
					// if(i > pos) out.write(text.substring(pos, i));
					// out.write("&#");
					// out.write(Integer.toString(ch));
					// out.write(';');
					// pos = i + 1;
					// } else {
					// throw new IllegalStateException(
					// "character zero is not allowed in XML 1.1
					// output"+getLocation());
					// }
				}
			}
		}
		if (pos > 0) {
			out.write(value.substring(pos));
		} else {
			out.write(value); // this is shortcut to the most common case
		}

	}
970448
@Override
    public String toReplacerPattern(boolean escapeUnprintable) {
        StringBuffer rule = new StringBuffer();
        StringBuffer quoteBuf = new StringBuffer();

        int cursor = cursorPos;

        // Handle a cursor preceding the output
        if (hasCursor && cursor < 0) {
            while (cursor++ < 0) {
                Utility.appendToRule(rule, '@', true, escapeUnprintable, quoteBuf);
            }
            // Fall through and append '|' below
        }

        for (int i=0; i<output.length(); ++i) {
            if (hasCursor && i == cursor) {
                Utility.appendToRule(rule, '|', true, escapeUnprintable, quoteBuf);
            }
            char c = output.charAt(i); // Ok to use 16-bits here

            UnicodeReplacer r = data.lookupReplacer(c);
            if (r == null) {
                Utility.appendToRule(rule, c, false, escapeUnprintable, quoteBuf);
            } else {
                StringBuffer buf = new StringBuffer(" ");
                buf.append(r.toReplacerPattern(escapeUnprintable));
                buf.append(' ');
                Utility.appendToRule(rule, buf.toString(),
                                     true, escapeUnprintable, quoteBuf);
            }
        }

        // Handle a cursor after the output.  Use > rather than >= because
        // if cursor == output.length() it is at the end of the output,
        // which is the default position, so we need not emit it.
        if (hasCursor && cursor > output.length()) {
            cursor -= output.length();
            while (cursor-- > 0) {
                Utility.appendToRule(rule, '@', true, escapeUnprintable, quoteBuf);
            }
            Utility.appendToRule(rule, '|', true, escapeUnprintable, quoteBuf);
        }
        // Flush quoteBuf out to result
        Utility.appendToRule(rule, -1,
                             true, escapeUnprintable, quoteBuf);

        return rule.toString();
    }
101417
function applyQuotes( $text, &$parameter, $onlyQuote = false )
    {
        $quote = "\"";
        if ( $parameter != null )
        {
            $val = eZTemplateNodeTool::elementConstantValue( $parameter );
            if ( $val == 'single' )
                $quote = "'";
            else if ( $val == 'no' )
                $quote = false;
        }

        if ( $onlyQuote )
        {
            return $quote;
        }

        $http = eZHTTPTool::instance();

        if ( isset( $http->UseFullUrl ) and $http->UseFullUrl
                                        and strncasecmp( $text, '/' , 1 ) === 0 ) // do not prepend the site path if it's not a http url
        {
            $text = $http->createRedirectUrl( $text, array( 'pre_url' => false ) );
        }
        if ( $quote !== false )
            return $quote . $text . $quote;

        return $text;
    }
1144461
static String unescapeCommandAttributeValue(String s, QuoteStyle quoteStyle) {
    // NOTE: we don't just use String.replace since it internally allocates/compiles a regular
    // expression.  Instead we have a handrolled loop.
    int index = s.indexOf(quoteStyle == QuoteStyle.DOUBLE ? "\\\"" : "\\\'");
    if (index == -1) {
      return s;
    }
    StringBuilder buf = new StringBuilder(s.length());
    buf.append(s);
    boolean nextIsQ = buf.charAt(s.length() - 1) == quoteStyle.getQuoteChar();
    for (int i = s.length() - 2; i >= index; i--) {
      char c = buf.charAt(i);
      if (c == '\\' && nextIsQ) {
        buf.deleteCharAt(i);
      }
      nextIsQ = c == quoteStyle.getQuoteChar();
    }
    return buf.toString();
  }
358592
function parse_NoteSh(blob, length, opts) {
	if(opts.biff < 8) return;
	var row = blob.read_shift(2), col = blob.read_shift(2);
	var flags = blob.read_shift(2), idObj = blob.read_shift(2);
	var stAuthor = parse_XLUnicodeString2(blob, 0, opts);
	if(opts.biff < 8) blob.read_shift(1);
	return [{r:row,c:col}, stAuthor, idObj, flags];
}
429553
def format_value(self, attr, attr_props, value):
        
        if isinstance(value, bool):
            return str(value).upper()

        if any(i in ["enum"] for i in attr_props):
            if not isinstance(value, numbers.Number):
                return value.upper()  # value is from a set list, no need for quote
            else:
                return value

        if "type" in attr_props and attr_props["type"] == "string":  # and "enum" not in attr_props
            # check schemas for expressions and handle accordingly
            if self.is_expression(attr_props) and self.quoter.in_slashes(value):
                return value
            elif self.is_expression(attr_props) and (value.endswith("'i") or value.endswith('"i')):
                # for case insensitive regex
                return value
            else:
                return self.quoter.add_quotes(value)

        # expressions can be one of a string or an expression in brackets
        if any(i in ["oneOf", "anyOf"] for i in attr_props):  # and check that type string is in list
            if "oneOf" in attr_props:
                options_list = attr_props["oneOf"]
            else:
                options_list = attr_props["anyOf"]
            if self.quoter.is_string(value):
                if self.quoter.in_parenthesis(value):
                    pass
                elif attr == "expression" and self.quoter.in_braces(value):
                    # don't add quotes to list expressions such as {val1, val2}
                    pass
                elif attr != "text" and self.quoter.in_brackets(value):
                    # TEXT expressions are often "[field1]-[field2]" so need to leave quotes for these
                    pass
                elif value.startswith("NOT ") and self.quoter.in_parenthesis(value[4:]):
                    value = "NOT {}".format(value[4:])
                else:
                    value = self.check_options_list(options_list, value)

        if isinstance(value, list):
            new_values = []

            for v in value:
                if not isinstance(v, numbers.Number):
                    v = self.quoter.add_quotes(v)
                new_values.append(v)

            value = " ".join(list(map(str, new_values)))
        else:
            value = self.quoter.escape_quotes(value)

        return value
81204
function(name, title, attrs){
			if (!name) return (title || "");
			name = name.replace('::', '.prototype.');
			if (docMap[name]) {
				var attrsArr = [];
				for(var prop in attrs){
					attrsArr.push(prop+"=\""+attrs[prop]+"\"")
				}
				return '<a href="' + docsFilename(name, config) + '" '+attrsArr.join(" ")+'>' + (title || name ) + '</a>';
			} else {
				return title || name || "";
			}
		}
1372840
protected function escapeAttribute(): string
    {
        $value = $this->validateEncoding();
        $value = strip_tags($value);

        return htmlspecialchars($value, ENT_QUOTES);
    }
1179552
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
        if (str == null) {
            return null;
        }
        try {
            Writer writer = new StringBuilderWriter(str.length() * 2);
            escapeJavaStyleString(writer, str, escapeSingleQuotes, escapeForwardSlash);
            return writer.toString();
        } catch (IOException ioe) {
            // this should never ever happen while writing to a StringBuilderWriter
            throw new RuntimeException(ioe);
        }
    }
683002
@Override
  public final String xmlEscape(final char pChar) throws Exception {
    if (pChar == '<') {
      return "&lt;";
    } else if (pChar == '>') {
      return "&gt;";
    } else if (pChar == '"') {
      return "&quot;";
    } else if (pChar == '\'') {
      return "&apos;";
    } else if (pChar == '&') {
      return "&amp;";
    }
    return String.valueOf(pChar);
  }
160879
function createMarkupForCustomAttribute(name, value) {
    if (!isAttributeNameSafe(name) || value == null) {
      return '';
    }
    return name + '=' + quoteAttributeValueForBrowser(value);
  }
301477
function (text, attr) {
    if (attr === void 0) { attr = '1'; }
    var do_quotes;
    var do_backticks;
    var do_dashes;
    var do_ellipses;
    var do_stupefy;
    if (typeof attr === 'number') {
      attr = attr.toString();
    }
    else {
      attr = attr.replace(/\s/g, '');
    }
    if (attr === '0') {
      // Do nothing
      return text;
    }
    else if (attr === '1') {
      // Do everything, turn all options on.
      do_quotes = 1;
      do_backticks = 1;
      do_dashes = 1;
      do_ellipses = 1;
    }
    else if (attr === '2') {
      // Do everything, turn all options on, use old school dash shorthand.
      do_quotes = 1;
      do_backticks = 1;
      do_dashes = 3;
      do_ellipses = 1;
    }
    else if (attr === '3') {
      // Do everything, turn all options on, use inverted old school dash shorthand.
      do_quotes = 1;
      do_backticks = 1;
      do_dashes = 3;
      do_ellipses = 1;
    }
    else if (attr === '-1') {
      // Special "stupefy" mode.
      do_stupefy = 1;
    }
    else {
      for (var i = 0; i < attr.length; i++) {
        var c = attr[i];
        if (c === 'q') {
          do_quotes = 1;
        }
        if (c === 'b') {
          do_backticks = 1;
        }
        if (c === 'B') {
          do_backticks = 2;
        }
        if (c === 'd') {
          do_dashes = 1;
        }
        if (c === 'D') {
          do_dashes = 2;
        }
        if (c === 'i') {
          do_dashes = 3;
        }
        if (c === 'e') {
          do_ellipses = 1;
        }
      }
    }
    if (do_dashes) {
      text = text.replace(/&#8211;/g, '\u2013'); // en-dash
      text = text.replace(/&#8212;/g, '\u2014'); // em-dash
    }
    if (do_quotes || do_backticks) {
      text = text.replace(/&#8216;/g, '\u2018'); // open single quote
      text = text.replace(/&#8217;/g, '\u2019'); // close single quote
      text = text.replace(/&#8220;/g, '\u201c'); // open double quote
      text = text.replace(/&#8221;/g, '\u201d'); // close double quote
    }
    if (do_ellipses) {
      text = text.replace(/&#8230;/g, '\u2026'); // ellipsis
    }
    return text;
  }
1326339
function formatAttributes(outNode, profile) {
	const node = outNode.node;

	return node.attributes.map(attr => {
		if (attr.options.implied && attr.value == null) {
			return null;
		}

		const attrName = profile.attribute(attr.name);
		let attrValue = null;

		// handle boolean attributes
		if (attr.options.boolean || profile.get('booleanAttributes').indexOf(attrName.toLowerCase()) !== -1) {
			if (profile.get('compactBooleanAttributes') && attr.value == null) {
				return ` ${attrName}`;
			} else if (attr.value == null) {
				attrValue = attrName;
			}
		}

		if (attrValue == null) {
			attrValue = outNode.renderFields(attr.value);
		}

		return attr.options.before && attr.options.after
			? ` ${attrName}=${attr.options.before+attrValue+attr.options.after}`
			: ` ${attrName}=${profile.quote(attrValue)}`;
	}).join('');
}
140726
function compatMaxage(opts) {
  if (opts) {
    opts.maxage = opts.maxage === undefined
      ? opts.maxAge
      : opts.maxage;
    delete opts.maxAge;
  }
}
1055519
function escapeJsonQuotes(json) {
      return JSON.stringify(json)
        .replace(/'/g, "&amp;apos;")
        .replace(/"/g, "&amp;quot;")
        /**
         * Codepen was unescaping &lt; (<) and &gt; (>) which caused, on some demos,
         * an unclosed elements (like <md-select>).
         * Used different unicode lookalike characters so it won't be considered as an element
         */
        .replace(/&amp;lt;/g, "&#x02C2;") // http://graphemica.com/%CB%82
        .replace(/&amp;gt;/g, "&#x02C3;"); // http://graphemica.com/%CB%83
    }