Given a Diagram, Find X
Python 3, 428 408 385 378 bytes
Working, but has a ton of potential to be golfed. I'm a bit rusty.
Assumes input is padded with spaces to make a rectangle.
EDIT: Thanks to @Artyer for 23 byte savings!
EDIT2: Wow I completely missed a 6 byte savings. Saved 1 more by swapping sides of an equals check.
*i,=map(list,input().split('\n'))
r=c=s=q=e=w=0
o=lambda y,x:len(i[0])>x>=0<=y<len(i)
d='\/_|'
for l in i:
if'x'in l:r=i.index(l);c=l.index('x')
for a,b in(1,0),(0,1),(-1,0),(0,-1):
y,x=r+a,c+b;f=o(y,x)and i[y][x]
if f in d:s=f;w=d.index(f);q,e=y,x
k=lambda y,x,g=[1,1,0,1][w],v=[1,-1,1,0][w]:o(y,x)and s==i[y][x]and(exec('i[y][x]=0')or 1+k(y+g,x+v)+k(y-g,x-v))
print(k(q,e))
Expanded version with explanation:
inputtt=''' ______________.
/ ____________ \
|/ __________ \|
||/ ________ \||
|||/ ______ \|||
||||/ \||||
|||||/ x |||||
|||||\_____/||||
||||\_______/|||
|||\_________/||
||\___________/|
\_____________/'''
# First, we get the input from STDIN and make it
# into a doubly-nested array
*input_text,=map(list,inputtt.split('\n'))
# A pretty cool Python trick to assign 0 to
# mulitple variables at once.
row=col=line_letter=line_row=line_col=line_char_index=0
# A function to check if a certian row and col is
# in bounds or not. Uses python's comparator chaining
in_bounds=lambda y,x:len(input_text[0])>x>=0<=y<len(input_text)
# A string to store all the line characters.
chars='\/_|'
# Search for the x
for line in input_text:
# If this line contains the x...
if'x'in line:
# Mark the row and column
row=input_text.index(line);col=line.index('x')
# For each direction...
for down,right in(1,0),(0,1),(-1,0),(0,-1):
# Move in that direction
y,x=row+down,col+right
# If the position is in bounds, mark the char at that position
line_found=in_bounds(y,x)and input_text[y][x]
# If the char is a line char, set all the variables saying we found it
if line_found in chars:
line_letter=line_found
line_char_index=chars.index(line_found)
line_row,line_col=y,x
recur=lambda y,x,\
# Find which directions we are supposed to recur in based on the line char
g=[1,1,0,1][line_char_index],v=[1,-1,1,0][line_char_index]:\
# If the char is in bounds and we are still on the line...
in_bounds(y,x)and input_text[y][x]==line_letter and\
# Set the spot to a 0, so we won't go back, increment,
# and recur in both directions
(exec('i[y][x]=0')or 1+recur(y+g,x+v)+recur(y-g,x-v))
# Finally, print the answer
print(recur(line_row,line_col))
JavaScript (ES6), 165, 155 bytes
EDIT: Inlined x and w, to save some more bytes.
Golfed (assumes input is padded with spaces to make a rectangle)
t=>([k=e=o=1,v=t.search`\n`+2,-1,-v].some(h=>i=({"|":v-1,"_":1,"/":v,"\\":v})[d=t[r=l=t.search`x`+h]]),[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d)),o)
Expanded
/*
G(<input string,space padded>) => line length
*/
G=t=> {
/*
! Note that these two are inlined, in the "golfed" version !
"w" - line "width"
"x" - index of "x"
*/
x=t.search`x`;
w=t.search`\n`+1;
/*
Locate the "line"
l,r - left cursor, right cursor (for navigating along the line)
k - left stop flag, e - right stop flag
i - increment
d - direction (char)
*/
[k=e=o=1,v=w+1,-1,-w-1].some(h=>i=({"|":w,"_":1,"/":v,"\\":v})[d=t[r=l=x+h]]);
/*
Travel along the line axis in both directions
Note, the stop condition should rather be: while(k|e),
but we iterate over all the chars with map instead (as o is guaranteed to be < # chars),
to save some space
*/
[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d));
/*
Resulting line length
*/
return o;
};
Test
G=
t=>([k=e=o=1,v=t.search`\n`+2,-1,-v].some(h=>i=({"|":v-1,"_":1,"/":v,"\\":v})[d=t[r=l=t.search`x`+h]]),[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d)),o);
[
G(
"| \n" +
"| \n" +
"|x\n" +
"| \n" +
"| \n"
),
G(
"|\\ \n" +
"| \\x \n" +
"| \\ \n" +
"|___\\\n"
),
G(
"Diagram of a Wobbly Line:\n" +
"IRRELEVANTTEXT____ \n" +
"____ ____\/ \n" +
" \___\/ X ;) \n" +
" x \n"
),
G(
" ______________ \n" +
"/ ____________ \\\n" +
"|/ __________ \\|\n" +
"||/ ________ \\||\n" +
"|||/ ______ \\|||\n" +
"||||/ \\||||\n" +
"|||||/ x |||||\n" +
"|||||\_____\/||||\n" +
"||||\_______\/|||\n" +
"|||\_________\/||\n" +
"||\___________\/|\n" +
" \_____________\/\n"
)
]
Sample output (if you run this in Google Chrome Developer Tools console)
[5, 4, 3, 5]