def substitute_variables(cls, configuration, value, ref):
        """
        Substitute variables in `value` from `configuration` where any path reference is relative to
        `ref`.

        Parameters
        ----------
        configuration : dict
            configuration (required to resolve intra-document references)
        value :
            value to resolve substitutions for
        ref : str
            path to `value` in the `configuration`

        Returns
        -------
        value :
            value after substitution
        """
        if isinstance(value, str):
            # Substitute all intra-document references
            while True:
                match = cls.REF_PATTERN.search(value)
                if match is None:
                    break
                path = os.path.join(os.path.dirname(ref), match.group('path'))
                try:
                    value = value.replace(
                        match.group(0), str(util.get_value(configuration, path)))
                except KeyError:
                    raise KeyError(path)

            # Substitute all variable references
            while True:
                match = cls.VAR_PATTERN.search(value)
                if match is None:
                    break
                value = value.replace(
                    match.group(0),
                    str(util.get_value(cls.VARIABLES, match.group('path'), '/')))
        return value
Substitute variables in `value` from `configuration` where any path reference is relative to
        `ref`.

        Parameters
        ----------
        configuration : dict
            configuration (required to resolve intra-document references)
        value :
            value to resolve substitutions for
        ref : str
            path to `value` in the `configuration`

        Returns
        -------
        value :
            value after substitution