[Question]
  [
Space indentation users, *unite*! We must fight against all the [lowly tab users](https://codegolf.stackexchange.com/questions/56001/my-god-its-full-of-spaces)!
Your mission (should you choose to accept it) is to write a program or function that takes in two arguments:
* A string: This is the input.
* A positive integer: This the number of spaces per tab.
You must go through every line of the string and replace every tab *used for indentation* with the given number of spaces, and every tab not used for indentation (e.g. in the middle of a line) with one space.
Note that lines such as `\t \tabc` are undefined behavior; they were inserted by the evil tab users to complicate your programs.
According to the Tabs Must Die Society, your program must be as short as possible to avoid detection by the evil tab users.
## Example
`\t` is used to represent tabs here.
Input string:
```
a
\t\tb\tc
d
```
Input number:
```
4
```
Output:
```
a
        b c
d
```
The middle line was indented by 8 spaces, 4 per tab (since the given number was 4).
Input string:
```
\ta\t\tb
```
Input number:
```
4
```
Output:
```
    a  b
```
**NOTE:** This is *not* a duplicate of the [tab expansion challenge](https://codegolf.stackexchange.com/questions/18960/expand-tabs-implement-expand1); it requires a very different input format and slightly different requirements.
  
[Answer]
# K5, ~~53~~ 45 bytes
```
{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}
```
In action:
```
  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")
```
I just want the record to show that this question is morally reprehensible.
[Answer]
# Perl, 23 bytes
22 bytes code + 1 bytes command line
Hopefully not too cheeky to assume the numeric input can be given via the -i parameter! Ensure to replace \t in the below code with the actual tab character.
```
s/\G\t/$"x$^I/ge;y/\t/ /
```
Usage example:
```
printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4
```
Or for convenience:
```
printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4
```
### Explanation:
Using the `-p` argument will execute the program for every line in the input, then print the result at the end.
In the above example, the regex substitution replaces `\G\t` with `" "x4` (a space repeated four times). `\G` is a little-known regex construct which matches either the position of first match if the first iteration, or from the position of the previous match if not the first iteration, meaning it will only replace all tabs at the start of the string, and will do so one-by-one. The `y/\t/ /` simply replaces all remaining tabs with spaces.
[Answer]
# CJam, ~~30~~ ~~24~~ 23 bytes
```
q{_9=NA=Seasi*' ?@?:N}/
```
I usually refuse to post malicious code on the internet…
This is a full program that reads the string from STDIN and the number as a command-line argument.
Try it online in the [CJam interpreter](http://cjam.aditsu.net/#code=l%3AE%3B%20e%23%20Implement%20%60ea'%20(command-line%20arguments)%20as%20%60Ea'.%0A%0Aq%7B_9%3DNA%3DSEasi*'%20%3F%40%3F%3AN%7D%2F&input=4%0Aa%0A%09%09b%09c%0Ad).
### How it works
```
q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.
```
What `NA=` does:
* For the first character, `N` will contain its default value, i.e., the string `"\n"`.
For all subsequent characters, `N` will contain the result of the last iteration, i.e., the last character from input, a space character or a string of one or more spaces.
* If `N` is a string, `NA=` selects the element at index 10 of N (wrapping around). The result will be a space or a linefeed character. Both are truthy.
If N is a character, `NA=` pushes 1 for a linefeed and 0 otherwise.
* Because of the above, `NA=` will push a truthy value for the first character, a character preceded by a linefeed or a character preceded by a string of spaces (indentation that has already been replaced).
In all other cases (including a tabulator that has been replace by a space *character*), `NA=` will push a falsy value.
[Answer]
# Julia, ~~69~~ 59 bytes
```
f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")
```
Ungolfed:
```
function f(s::String, n::Int)
    # Replace the leading indentation tabs
    r1 = replace(s, r"^\t*"m, i -> " "^endof(i)n)
    # Replace any remaining tabs between words
    r2 = replace(r1, r"\t", " ")
    # Return
    r2
end
```
Saved 10 bytes and fixed an issue thanks to Glen O!
[Answer]
# Haskell, 82 bytes
```
n!('\t':x)=([1..n]>>" ")++n!x
n!x=f<$>x
f '\t'=' '
f x=x
g n=unlines.map(n!).lines
```
Then `g 3 "a\n\t\tb\tc\nd"` does the thing.
[Answer]
# Mathematica, ~~42~~ 37 bytes
Thanks to @LegionMammal978 for multiple code-saving suggestions.
The first parameter, `#` is for the input text, the second parameter, `#2`, for the number of spaces per tab.
```
StringReplace[#,"\t"->" "~Table~{#2}]&
```
[Answer]
# Ruby 49 bytes
```
def r s,t;s.gsub! /^\t/,' '*t;s.gsub!"\t",' ';end
```
[Answer]
# JavaScript (ES6), 70
Using template strings, the newline is significant and counted
```
(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``
```
Test running the snippet below in Firefox.
```
F=(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``
// TEST
out=x=>O.innerHTML+=x+'\n\n'
out('Input: "A\\n\\t\\tB\\tC\\nD" 4\nOutput:\n'+F('A\n\t\tB\tC\nD',4))
out('Input: "\\tA\\t\\tB" 4\nOutput:\n'+F('\tA\t\tB', 4))
```
```
<pre id=O></pre>
```
[Answer]
# CoffeeScript, 72 bytes
```
(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
```
(Trying to golf it at least 2 more bites, so it will beat the ES6 solution... Help appreciated :D)
Usage:
```
f=(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
str="""
My nice\tString
\tIndent <--
\t\tDouble
""" #\t is recognized as tab by CS
alert(f(str,4))
```
[Answer]
# Retina, 42 bytes
All occurrences of `.` are spaces, all `\t` are literal tabs (1 byte), and `<empty>` represents a blank file. It's just for readability. I'm also not entirely sure that I'm doing the loop correctly, but I think so. Each line should be placed in its own file. I've added 1 byte for each additional file.
Input is assumed to be in Unary on its own line at the end of the input.
```
(1*)$
_$1
m+`(?<!^|\t)\t
.
(`1$
<empty>
)`\t
\t.
\t|_
<empty>
```
### Explanation
I add a `_` before the Unary input to delimit it during replacement, so that I don't remove any trailing ones from the input string. Then, I replace all tabs not at the beginning of a line with a single space. Then, I loop, removing a single `1` and adding a single space after each tab, until I run out of input. Finally, I clean up by removing the tabs and underscore.
[Answer]
# Python, ~~72~~ 68 bytes
Tabs are literal tabs (1 byte), so `r'...'` is not needed. Unfortunately, Python requires "fixed-width" look-behinds / look-aheads, so I can't use `(?<!^|\t)`. Uses pretty much the same method as my Retina solution.
```
import re
lambda s,n:re.sub('\t',' '*n,re.sub('(?<!^)(?<!\t)\t',' ',s))
```
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 20 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
ÜR╧█╧╫≡eX,)~σOÜ¢G╩N‼
```
[Run and debug it](https://staxlang.xyz/#p=9a52cfdbcfd7f065582c297ee54f9a9b47ca4e13&i=4+%0Aa%0A%09%09b%09c%0Ad%0A%0A4%0A%09a%09%09b&a=1&m=1)
This program reads the first line as the indent width, and the rest of the input as the program.
[Answer]
# Japt v2.0a0, 17 bytes
```
r/^\t+/m_çVçÃr\tS
```
[Try it](https://ethproductions.github.io/japt/?v=2.0a0&code=ci9eXHQrL21f51bnw3JcdFM=&input=ImEKCQliCWMKZCIKNA==)
[Answer]
# [Haskell](https://www.haskell.org/), 75 bytes
```
s#m|let('\t':r)#n=(' '<$[1..n])++r#n;(x:r)#n=x:r#(m^sum[1|x<' ']);e#_=e=s#m
```
[Try it online!](https://tio.run/##y0gszk7Nyfn/v1g5tyYntURDPaZE3apIUznPVkNdQd1GJdpQTy8vVlNbu0g5z1qjAiIFpJQ1cuOKS3OjDWsqbIAKYzWtU5XjbVNtgeb8z03MzFOwVcjMK0ktSkwuUdBQNtH8n8jFyZnEmcyVwsWZCGQBAA "Haskell – Try It Online") This assumes the input contains only printable chars as well as tabs and newlines, as allowed by OP in the comments.
**Explanation:**
The outer `#` function takes a string `s` and a number `m` and calls the inner locally defined `#` function with the same arguments. This is done to keep track of the original `m` value, as the inner `#` function changes the number:
* `('\t':r)#n=(' '<$[1..n])++r#n` If you encounter a tab, replace it by `n` spaces and leave `n` unchanged.
* `(x:r)#n=x:r#(m^sum[1|x<' '])` If some `x` which is not a tab is encountered, keep it as is but set `n` to the original number `m` if `x` is a newline and to `1` otherwise. This is done by `m^sum[1|x<' ']`: `m` is taken to the power of `sum[1|x<' ']` which evaluates to `1` when `x` is smaller than a space (i.e. a newline), so we get `m^1 = m`. Otherwise it's `0` and we have `m^0 = 1`.
[Answer]
# Java 11, 134 bytes
```
n->s->{var r="";for(var p:s.split("\n")){for(;p.charAt(0)==9;p=p.substring(1))r+=" ".repeat(n);r+=p+"\n";}return r.replace('\t',' ');}
```
[Try it online.](https://tio.run/##fVCxbsMgEN3zFScWg@qgVOrSUlvqUqlDp4whA7FxSupgBOdUUeRvd6FG7daJe9zde/feSV3U@tR@zk2vQoB3ZextBRBQoWngFLt8RNPzbrQNmsHy11w8v1nUR@3Lf4e26I09lrC8dQ0dVLNd12Fd3y7Kg68IEd3gaQLuKfDgeoOUSEsYu6WGcLz5UP4F6YZV1aNwleNhPIQfQnrPmL@rvHZaxS0gpWUifri7xCAmr3H0FjyPE71qNC0kFmUBBRPTLFbRqBsPfTSa/V4G08I5ZkCXg3d7UCzlAbC9BtRnPozIXWwh7bhyrr/SB5YLIlFJK1HiQWIjbZuASriNZkRkmVZ/0S4CkE/PKLoqIZKDOg@jxSydXVj9lbdoKlMqu2Vuz34NErkhZaTJetP8DQ)  
NOTE: Java 11 isn't on TIO yet, so `" ".repeat(n)` has been emulated as `repeat(" ",n)` instead (with the same byte-count).
**Explanation:**
```
n->s->{                 // Method with integer & String parameters and String return-type
  var r="";             //  Result-String, starting empty
  for(var p:s.split("\n")){
                        //  Loop over the rows (split by new-lines)
    for(;p.charAt(0)==9;//   Inner loop as long as the current row starts with a tab
       p=p.substring(1))//     After every iteration: remove the first character (tab)
      r+=" ".repeat(n); //    Append `n` amount of spaces to the result-String
    r+=p+"\n";}         //   Append the rest of the row with a newline to the result
  return r.replace('\t',' ');} 
                        //   Replace any remaining tabs with a space, and return the result
```
]