Search code examples
matlabpostscriptcarriage-returnepslinefeed

Print to eps on Win produces Unix line endings (Bug?)


On Win7 64b with R2014b, printing a figure to .eps produces Unix line endings (LF or \n). Is this expected or a bug?

Also, does it depend on Matlab version?

You can test with:

% Plot and export to .eps
plot(1:10)
print(gcf,'test','-depsc')
fid = fopen('test.eps');

% Check if Unix LF only
line = fgets(fid);
if all(line(end-1:end) == sprintf('\r\n'))
    disp('CRLF')
elseif line(end) == sprintf('\n')
    disp('LF only!')
end

% Clean up
fclose(fid);
delete('test.eps')

Edit

Why it matters to me? I am exporting figures to .eps and compiling them with a Miktex 2.9 distribution through epstopdf. However, I get a blank figure and the problem is explained here https://tex.stackexchange.com/questions/208179/epstopdf-error-undefined-in-uagelevel

Now, I was wondering why I never had this issue before. It seems from Louis's answer, it was introduced with the new release and Unix like line endings in the .eps


Solution

  • First off: according to the EPS format specification (large file obtained from here):

    • Page 26:

      The characters carriage return (CR) and line feed (LF) are also called newline characters. The combination of a carriage return followed immediately by a line feed is treated as one newline.

    • Page 74:

      The PostScript language scanner and the readline operator recognize all three external forms of end-of-line (EOL)—CR alone, LF alone, and the CR-LF pair— and treat them uniformly, translating them as described below.

    So both forms could actually be used.


    I think your test is wrong. You separate lines with textscan according to '\n'; but that doesn't exclude '\r\n' (you will split lines according to '\n', and '\r' will remain as the last character of each line).

    I suggest you test this way:

    fid = fopen('test.eps');
    s = fread(fid); %// read whole file as a vector of ASCII codes
    LF = find(a==10); %// find locations of LF
    CR = find(a==13); %// find locations of CR
    if all(ismember(LF-1,CR)) %// test if every LF is preceded by a CR
        disp('Every LF is preceded by a CR')
    end
    

    On my Windows system (Matlab 2010b, Windows Vista 32 bits) it turns out that indeed every LF is preceded by a CR, so Windows-like line endings are used.