Saturday, October 11, 2008

Bibliography sorting (Matlab Code)

Those who write papers, especially longer one, they know how difficult and irritating it is to sort the bibliography every time you change the text. I made this little code to sort the bibliography as they appear in the text using '\cite{}'. Some journal does not allow to sort the bibliography as it appear in the figure caption. I have not given any special care to it for simplicity. The code appears below in a very misaligned fashion. It should work pretty well.

function bibsort(fname,bibfile,outfile)
%
% 'bibsort' sorts the bibliography of the main latex file
% as the references appear in the text.
%
% bibsort('paper.tex','bibliography.tex',''outputfile.tex')
% will find the citation from file 'paper.tex' and find the
% bibliography from file 'bibliography.tex' and the sorted bibliograpy
% will be written in 'outputfile.tex'. Default biblography file is the
% main file and the default outputfile is 'bib.tex'.
%
% This program will identify a reference as written in '\cite{reference}'
% in the main file and then search for that reference in the bibliograpy
% as written in '\bibitem{refererence}'. More reference as seperated
% by , inside one '\cite{}' is incorporated. Again, one '\cite{}' as
% splitted into two lines are also taken care of.
%
% Tanmoy Das.
% Feb 12 2008.
%
if nargin<1;error('Specify your input latex file');end;
if nargin ==1;bibfile=fname;outfile = 'bib.tex';end;
if nargin ==2;outfile = 'bib.tex';end;
%
fid = fopen(fname,'rt');
if fid<0;error(sprintf('%s%s%s','Input file [',fname,'] NOT found'));end
bfid = fopen(bibfile,'rt');
if bfid<0;error(sprintf('%s%s%s','Bibliography file [',bibname,'] NOT found'));end
ofid = fopen(outfile,'w');
%
% Identify all the references and save in variable 'd'
b = 'cite{';
ii = 1; % No of references as identified
while feof(fid) == 0;
tline = fgetl(fid); %read one line
len = length(tline);
if len>=1&tline(1)=='%';continue;end
% find the indices where refereces are located
indi = findstr(tline, b);
%num = length(indi);
if length(indi) > 0
len1= length(indi);
ik = 1; % index for the length of a reference
ij = 1; % index for the no of reference in one line
while (ij<=len1)
%tline(indi(ij)-1)
if (indi(ij)>2)&(tline(indi(ij)-2)=='%');ij=ij+1;continue;end;
il = indi(ij)+5;
while(il<=len)
c = tline(il); % store one character of the line
%} is found then the ref(s) in \cite{} is identified
if c=='}' ;ii= ii+1; ik=1; break; end;
% if , in \cite{} is found then one ref if identified
if c==','; ik=1; ii=ii+1; il = il+1; end;
d(ii,ik)=tline(il); % Store one character of a ref.
ik = ik+1; % increases the character length of a ref
% check if the line is finished before identifying one full
% ref.
if il==len;
tlinen = fgetl(fid); % go to net line
while length(tlinen)>=1&tlinen(1)=='%';
tlinen = fgetl(fid); % go to net line
end
tline = [tline tlinen]; % add the new line to old one
len = length(tline); % modify the new line length
% look for aditional '\cite{' in the new line
indi = findstr(tline, b);
% modify the new no of '\cite{' in the total line
len1=length(indi);
end
il = il+1; % go to the next character in the line
end %while: all ref found under one '\cite'
ij = ij+1; % go to the next '\cite'
end %while
end % if
end % while
%%%%%%%%%%%%%%%%%%%%%
% Now remove the same reference and store all independent references in
% 'f', as they are in order
%%%%%%%%%%%%%%%%%%%%%
ii = 1;
f(ii,:) = d(ii,:);
for ij = 2:size(d,1)
flag = 0;
for ik = ij-1:-1:1
if d(ij,:)==d(ik,:);flag = 1;break;end;
end
if (flag==0)
ii = ii+1;
f(ii,:) = d(ij,:);
else
continue
end
end
fclose(fid);
%
% Now look for the references fron 'The bibliograpy'
%
bfid = fopen(bibfile,'rt');
while feof(bfid) == 0;
tline = fgetl(bfid);
%if length(tline)>=1&tline(1)=='%';continue;end
indi = findstr(tline, sprintf('%s%s%s','\begin{thebibliography'));
num = length(indi);
if num > 0
fprintf(ofid,'%s\n',tline);
break;
end
end
fclose(bfid);
%
for ii = 1:size(f,1)
bfid = fopen(bibfile,'rt');
while feof(bfid) == 0;
tline = fgetl(bfid);
%if length(tline)>=1&tline(1)=='%';continue;end
indi = findstr(tline, sprintf('%s%s%s','\bibitem{',f(ii,:),'}'));
num = length(indi);
if num > 0
if (indi(1)>1)&(tline(indi(1)-1)=='%');continue;end;
fprintf(ofid,'%s\n',tline);
num2 = 0;
while (num2==0)
tline1 = fgetl(bfid);
%while length(tline1)>=1;%&tline1(1)=='%';
% tline1 = fgetl(fid);
%end
ind1 = findstr(tline1, '\end{thebibliography');
num1 = length(ind1);
if num1 >0;break;end;
ind2 = findstr(tline1, '\bibitem{');
num2 = length(ind2);
if num2==0;
%tline = [tline; tline1];
fprintf(ofid,'%s\n',tline1);
end;
end
% fprintf(ofid,'%s\n',tline);
break
end
end
fclose(bfid);
if(num<=0)error(sprintf('%s%s%s','Reference[',f(ii,:),']not found'));end;
end
%
bfid = fopen(bibfile,'rt');
while feof(bfid) == 0;
tline = fgetl(bfid);
%if length(tline)>=1&tline(1)=='%';continue;end
indi = findstr(tline, sprintf('%s%s%s','\end{thebibliography'));
num = length(indi);
if num > 0
fprintf(ofid,'%s\n',tline);
end
end
fclose(bfid);
fclose(ofid);

return

1 comment:

Baris Altunkaynak said...

This is a very useful program, thank you very much for sharing it with us.