wikitextparser/_template.py
def set_arg(
        self, name: str,
        value: str,
        positional: bool = None,
        before: str = None,
        after: str = None,
        preserve_spacing: bool = True
    ) -> None:
        """Set the value for `name` argument. Add it if it doesn't exist.

        - Use `positional`, `before` and `after` keyword arguments only when
          adding a new argument.
        - If `before` is given, ignore `after`.
        - If neither `before` nor `after` are given and it's needed to add a
          new argument, then append the new argument to the end.
        - If `positional` is True, try to add the given value as a positional
          argument. Ignore `preserve_spacing` if positional is True.
          If it's None, do what seems more appropriate.
        """
        args = list(reversed(self.arguments))
        arg = get_arg(name, args)
        # Updating an existing argument.
        if arg:
            if positional:
                arg.positional = positional
            if preserve_spacing:
                val = arg.value
                arg.value = val.replace(val.strip(WS), value)
            else:
                arg.value = value
            return
        # Adding a new argument
        if not name and positional is None:
            positional = True
        # Calculate the whitespace needed before arg-name and after arg-value.
        if not positional and preserve_spacing and args:
            before_names = []
            name_lengths = []
            before_values = []
            after_values = []
            for arg in args:
                aname = arg.name
                name_len = len(aname)
                name_lengths.append(name_len)
                before_names.append(STARTING_WS_MATCH(aname)[0])
                arg_value = arg.value
                before_values.append(STARTING_WS_MATCH(arg_value)[0])
                after_values.append(ENDING_WS_MATCH(arg_value)[0])
            pre_name_ws_mode = mode(before_names)
            name_length_mode = mode(name_lengths)
            post_value_ws_mode = mode(
                [SPACE_AFTER_SEARCH(self.string)[0]] + after_values[1:]
            )
            pre_value_ws_mode = mode(before_values)
        else:
            preserve_spacing = False
        # Calculate the string that needs to be added to the Template.
        if positional:
            # Ignore preserve_spacing for positional args.
            addstring = '|' + value
        else:
            if preserve_spacing:
                # noinspection PyUnboundLocalVariable
                addstring = (
                    '|' + (pre_name_ws_mode + name.strip(WS)).
                    ljust(name_length_mode) +
                    '=' + pre_value_ws_mode + value + post_value_ws_mode
                )
            else:
                addstring = '|' + name + '=' + value
        # Place the addstring in the right position.
        if before:
            arg = get_arg(before, args)
            arg.insert(0, addstring)
        elif after:
            arg = get_arg(after, args)
            arg.insert(len(arg.string), addstring)
        else:
            if args and not positional:
                arg = args[0]
                arg_string = arg.string
                if preserve_spacing:
                    # Insert after the last argument.
                    # The addstring needs to be recalculated because we don't
                    # want to change the the whitespace before final braces.
                    # noinspection PyUnboundLocalVariable
                    arg[0:len(arg_string)] = (
                        arg.string.rstrip(WS) + post_value_ws_mode +
                        addstring.rstrip(WS) + after_values[0]
                    )
                else:
                    arg.insert(len(arg_string), addstring)
            else:
                # The template has no arguments or the new arg is
                # positional AND is to be added at the end of the template.
                self.insert(-2, addstring)
def set_arg(
        self, name: str,
        value: str,
        positional: bool = None,
        before: str = None,
        after: str = None,
        preserve_spacing: bool = True
    ) -> None:
        """Set the value for `name` argument. Add it if it doesn't exist.

        - Use `positional`, `before` and `after` keyword arguments only when
          adding a new argument.
        - If `before` is given, ignore `after`.
        - If neither `before` nor `after` are given and it's needed to add a
          new argument, then append the new argument to the end.
        - If `positional` is True, try to add the given value as a positional
          argument. Ignore `preserve_spacing` if positional is True.
          If it's None, do what seems more appropriate.
        """
        args = list(reversed(self.arguments))
        arg = get_arg(name, args)
        # Updating an existing argument.
        if arg:
            if positional:
                arg.positional = positional
            if preserve_spacing:
                val = arg.value
                arg.value = val.replace(val.strip(WS), value)
            else:
                arg.value = value
            return
        # Adding a new argument
        if not name and positional is None:
            positional = True
        # Calculate the whitespace needed before arg-name and after arg-value.
        if not positional and preserve_spacing and args:
            before_names = []
            name_lengths = []
            before_values = []
            after_values = []
            for arg in args:
                aname = arg.name
                name_len = len(aname)
                name_lengths.append(name_len)
                before_names.append(STARTING_WS_MATCH(aname)[0])
                arg_value = arg.value
                before_values.append(STARTING_WS_MATCH(arg_value)[0])
                after_values.append(ENDING_WS_MATCH(arg_value)[0])
            pre_name_ws_mode = mode(before_names)
            name_length_mode = mode(name_lengths)
            post_value_ws_mode = mode(
                [SPACE_AFTER_SEARCH(self.string)[0]] + after_values[1:]
            )
            pre_value_ws_mode = mode(before_values)
        else:
            preserve_spacing = False
        # Calculate the string that needs to be added to the Template.
        if positional:
            # Ignore preserve_spacing for positional args.
            addstring = '|' + value
        else:
            if preserve_spacing:
                # noinspection PyUnboundLocalVariable
                addstring = (
                    '|' + (pre_name_ws_mode + name.strip(WS)).
                    ljust(name_length_mode) +
                    '=' + pre_value_ws_mode + value + post_value_ws_mode
                )
            else:
                addstring = '|' + name + '=' + value
        # Place the addstring in the right position.
        if before:
            arg = get_arg(before, args)
            arg.insert(0, addstring)
        elif after:
            arg = get_arg(after, args)
            arg.insert(len(arg.string), addstring)
        else:
            if args and not positional:
                arg = args[0]
                arg_string = arg.string
                if preserve_spacing:
                    # Insert after the last argument.
                    # The addstring needs to be recalculated because we don't
                    # want to change the the whitespace before final braces.
                    # noinspection PyUnboundLocalVariable
                    arg[0:len(arg_string)] = (
                        arg.string.rstrip(WS) + post_value_ws_mode +
                        addstring.rstrip(WS) + after_values[0]
                    )
                else:
                    arg.insert(len(arg_string), addstring)
            else:
                # The template has no arguments or the new arg is
                # positional AND is to be added at the end of the template.
                self.insert(-2, addstring)
Set the value for `name` argument. Add it if it doesn't exist.

        - Use `positional`, `before` and `after` keyword arguments only when
          adding a new argument.
        - If `before` is given, ignore `after`.
        - If neither `before` nor `after` are given and it's needed to add a
          new argument, then append the new argument to the end.
        - If `positional` is True, try to add the given value as a positional
          argument. Ignore `preserve_spacing` if positional is True.
          If it's None, do what seems more appropriate.