5

This question is extension of this question about listing questions of directories. I get a problem that I need to understand the original section of the text.

Current output

enter image description here

where you see the second question does not make sense. It was included in the subsection Takayasu arteritis in the directory Rheumatology:

\subsection{Takayasu arteritis}

\begin{question}
{You get a patient. 
What do you notice first in this patient?}
Absence of peripheral pulse.
\end{question}

Lorem ipsum.    

\begin{question}
{What was the first Takayasu case?}
Young woman in Asia with red vessels in the eye. 
So special eye diagnosis done. 
Affects eye.
\end{question}

where the current output is by this excellent code

\section{Rheumatology}  

\begin{question}
{You get a patient. 
What do you notice first in this patient?}
Absence of peripheral pulse.
\end{question}

\begin{question}
{What was the first Takayasu case?}
Young woman in Asia with red vessels in the eye. 
So special eye diagnosis done. 
Affects eye.
\end{question}

but I would like it to be

\section{Rheumatology}  

\subsection{Takayasu arteritis}

\begin{question}
{You get a patient. 
What do you notice first in this patient?}
Absence of peripheral pulse.
\end{question}

\begin{question}
{What was the first Takayasu case?}
Young woman in Asia with red vessels in the eye. 
So special eye diagnosis done. 
Affects eye.
\end{question}

My proposal is to include subsections if there are questions within the subsection.

My pseudocode

Look for the environment \begin{question}...\end{question}.
See the subsection of the question (it locates above the question). 
   If there is no subsection, leave blank. 
   If there are many questions within one subsection, put only one subsection. 

Terdon's code

#!/usr/bin/env bash

## avoid errors if a directory has no *tex files
shopt -s nullglob

directories=("Cardiology" "Rheumatology" "Surgery");

## Change this to set whichever options you want.
printf "%s\n%s\n" "\documentclass{YOURCLASS}" "\begin{document}"

for directory in ${directories[@]}
do
    ## Reset the counter, avoid empty sections.
    c=0;
    for file in "$directory"/*tex
    do
        let c++
        [ "$c" -eq 1 ] && printf "\n%s\n" "\section{$directory}"
        ## Extract the wanted lines
        perl -lne '$a=1 && print "" if /\\begin{question}/; 
                  print if $a==1;
                  $a=0 if /\\end{question}/;' "$file" 
        echo ""
    done
done
echo "\end{document}"

where I think the logic of these lines should be changed

        ## Extract the wanted lines
        perl -lne '$a=1 && print "" if /\\begin{question}/; 
                  print if $a==1;
                  $a=0 if /\\end{question}/;' "$file" 
        echo ""

which uses a regex to find all questions in a file, AND ignores the subsections of the questions.

Example of data (little different from the last case!)

\subsection{Takayasu arteritis}

\begin{question}
{You get a patient. 
What do you notice first in this patient?}
Absence of peripheral pulse.
\end{question}

\begin{question}
{What was the first Takayasu case?}
Young woman in Asia with red vessels in the eye. 
So special eye diagnosis done. 
Affects eye.
\end{question}


Fever of unknown origin can be used when you do not know what is causing the disease. 

% Show cases in MedScape and ask class. 

Aneurysms. 


\subsubsection{Treatment}

\begin{question}
{What you should always include in Takayasu treatment? 
What are the symptoms?}
Blood pressure.
Aneurysms which will burst without treatment. 
So blood pressure decreasing drugs like beta blockers along in combination with other drugs.
\end{question}

\begin{question}
{When is the checkup of the Takayasu arteritis?} 
Only once per year. 
You could expect every month like normally in this kind of diseases.
But only once per year.
\end{question}

where you can ignore subsubsections in the application.

How can you write the pseudocode?


Bug in Terdon's code 14.10.2014 found

Example of data which causes the bug

\subsection{3}
A 55 y.o male says that for the last year ... 

\begin{question}
{What is the pathogenetic mechanism of his complains?} 
\end{question}

which parsed by Terdon's code gives exactly the same result which is wrong, since the sentence A 55 y.o... should not be there anymore in the final result. If there is a enter between the subsection and the body text, then correct output. However, this cannot be assumed.

The cause of this bug is the Windows symbols, moved here.

4
  • "Pseudocode" makes this a general programming question. →SO?
    – Anko
    Oct 5, 2014 at 22:28
  • 1
    @Anko no, this is basically a text parsing question and those are on topic here.
    – terdon
    Oct 5, 2014 at 22:32
  • It should be in shell script?
    – Braiam
    Oct 6, 2014 at 1:02
  • 'Extract and merge sections from Q&As in all .tex files for specific directories: the case of "subsubsections"?'. Not certain if this is an accurate title as the "section" aspect of the 2 questions and the interplay is hard to grasp, in my opinion. It is about the hierarchy of the question components in the .tex files.
    – user44370
    Oct 6, 2014 at 5:46

2 Answers 2

3

I was going to extend my original code but it is getting to a point where it's much easier to just reimplement everything in Perl directly:

#!/usr/bin/env perl

## This is the path to the target  directories
my $path="/Users/Masi/Dropbox/";

## The target directories
my @directories=("Cardiology","Rheumatology","Surgery");

## Iterate over the directories
foreach my $dir (@directories) {
    my $dd=0;
    ## Read the current directory
    opendir (my $DIR, "$path/$dir");
    ## Find all files in this directory
    while (my $file = readdir($DIR)) {
        ## Reset the counter
        my $c=0;
        ## Skip any files that aren't .tex
        next unless $file =~ /\.tex$/;

        ## Open the file
        open(my $fh,"$path/$dir/$file");

        while (<$fh>) {
            ## Get the subsection. $_ is the current line.
            $sub="$_" and $n=0 if /\\subsection{/;
            ## If this line is a question
            if (/\\begin{question}/) {
                ## If this counter is 0, this is the first file
                ## of this directory, so print the section
                ## Print the section name
                if ($dd==0) {
                    print "\\section{$dir}\n\n";
                    $dd++;
                } 
                ## If this counter is 0, this is the first question
                ## of this subsection, so print the subsection line
                print "$sub\n" if $n==0;

                $n++;
                ## Increment the counter, we want these lines
                $c++;
                ## And print
                print;
            }
            else {
                ## Print lines if the counter is 1
                print if $c==1;
                ## reset the counter to 0
                print "\n" and $c=0 if /\\end{question}/;
            }
        }
        print "\n";
    }

}

Note that this ignores subsubsections but it would be easy to modify it to include them.

12
  • Thank you for your answer! I run this like this perl /Users/Masi/Dropbox/makeSummary.pl. I get no output. What is the expected output? I changed the parameter path to /Users/Masi/Dropbox/. Some subtle bug somewhere. Oct 6, 2014 at 7:40
  • Is there something wrong here if (/\\begin{question}/) { ... print; }. In the subsection and matching question environment, it says print. Is that enough for printing the content of the of the question? Oct 6, 2014 at 7:45
  • @Masi not sure what you mean. Doesn't it produce the output you wanted? In perl, print with no arguments will print the current value of the special variable $_. In this context, that is the current line of the input file. So, if block will print the \begin{question} line and also increment $c. The else block will print the current line if $c==1. The result is that the entire question should be printed.
    – terdon
    Oct 6, 2014 at 13:10
  • It returns nothing as the output. What do you get as an output? Oct 6, 2014 at 14:46
  • @Masi I get precisely what you show in your question. Are you sure the directories are under /Users/Masi/Dropbox/? The script expects to find, for example,/Users/Masi/Dropbox/Rheumatology/file.tex.
    – terdon
    Oct 6, 2014 at 15:55
1

Extension or improvement of terdon's code based on the some logic in this answer

#!/usr/bin/env perl

## This is the path to the target  directories
my $path="/Users/Masi/Dropbox/";
chdir $path or die "cannot chdir '$path'";

## Iterate over the directories
foreach my $dir (
    "Cardiology", "Pathophysiology", "Patology and Biopsy", "Physiology",
    "Propedeutics", "Radiology", "Rheumatology", "Surgery"
)
{
    my $dd=0;
    ## Read the current directory
    opendir my $DIR, $dir or die "cannot opendir '$dir'";

    ## Find all files in this directory
    while (my $file = readdir($DIR)) {
        ## Reset the counter
        my $c=0;
        ## Skip any files that aren't .tex
        next unless $file =~ /\.tex$/;

        ## Open the file
        open(my $fh,"$path/$dir/$file");

        while (<$fh>) {
            ## Get the subsection. $_ is the current line.
            $sub="$_" and $n=0 if /\\subsection{/;
            ## If this line is a question
            if (/\\begin{question}/) {
                ## If this counter is 0, this is the first file
                ## of this directory, so print the section
                ## Print the section name
                if ($dd==0) {
                    print "\\section{$dir}\n\n";
                    $dd++;
                }
                ## If this counter is 0, this is the first question
                ## of this subsection, so print the subsection line
                print "$sub\n" if $n==0;

                $n++;
                ## Increment the counter, we want these lines
                $c++;
                ## And print
                print;
            }
            else {
                ## Print lines if the counter is 1
                print if $c==1;
                ## reset the counter to 0
                print "\n" and $c=0 if /\\end{question}/;
            }
        }
        print "\n";
    }
    closedir $DIR  or die "cannot closedir '$dir'";
}

where I added some error management.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .