0

So I have some data for a rock climbing guide I'm writing. In the last page I want to list all the routes, sorted by grade. The thing is that the conventional sorting doesn't apply here.

Quick explanation of climbing grades (YDS system):

A grade is a one-dimensional quantity to indicate the difficulty of a rock climb. The grades are indicated by numbers, and from grade 10 onwards, are subdivided in four grades, indicated by letters a, b, c, and d.

Examples: 8, 9, 10a, 10c, 11b

Sometimes grades are divided in two, not in four, indicated by - and + signs. This way, a route graded 10+ could be a 10c or 10d, and in the table it should be displayed between those grades.

So I want to be able to sort this somehow.

MWE:

\documentclass[12pt,a4paper]{article}

\usepackage{datatool}
\usepackage{filecontents}

\usepackage{longtable}

\begin{filecontents*}{datos.csv}
Route,Grade
Cempasúchil,9
La Gripe, 8
Dopamina infinita, 10b
Casiopea, 11c
El Hombre Avispa, 11b
Tiranosaurio Tex, 11-
Euro Dance, 11a
El Primer Contacto, 12d
\end{filecontents*}

\pagestyle{empty}

\DTLloaddb[keys={Route,Grade}]{datos}{datos.csv}
\DTLsort{Grade=ascending}{datos}

\begin{document}

{\tiny
\noindent
\begin{longtable}{ll}

  \bfseries Route & \bfseries Grade \\

  \DTLforeach{datos}{%
    \pname=Route,\pGrade=Grade}{%
    \pname & \pGrade \\
  }

\end{longtable}
}
\end{document}

Output:

enter image description here

Correct order:

8, 9, 10b, 11a, 11-, 11b, 11c, 12d

Solution ideas:

-Split the number and the letter, and sort by two columns. I like this solution, however, it would probably put + and - grades at the end of that number (I could live with his). Also I would like to do this splitting in datatool, not from the source.

-Maybe there is some way to specify custom order. I would not mind having to type all the possible grades by hand, there aren´t that many (hardest route in the world is 15d, but for the guide they range from 8 to 14a) To solve this maybe modifying or creating a custom handler (like \dtlicompare)?

0

Ok so I managed to solve the problem. Perhaps this is not the most elegant way, but it works for me.

I adapted the answer for this question: Custom Alphabetic CSV Sorting (Turkish Characters)

So the main idea is: yoo can change the code of a character to whatever you would like, so that they sort in a different way than the UTF8 codes.

I changed the codes of these characters:

Char  ----> New Code
8     ----> 1     (8 always goes first)
9     ----> 2     (9 always goes second)
a     ----> 96    (move the a back one code, to put - between a and b)
-     ----> 97    (right between a and b)
+     ----> 100   (Right after the c)
d     ----> 101   (d is displaced by the d)

As you can see, this solution is very specific to my situation, and doesn't generalize well. The changes I made to characters 8 and 9 would be problematic if a route graded 18 existed, as they would be placed before the 10's. But since this difficulty doesn't exist (and probably never will) it is no problem.

Maybe this approach is suitable to someone reading this question/answer.

Code (add to preamble):

\renewcommand*{\dtlsetcharcode}[2]{%
  \ifstrequal{#1}{8}%
  {%
    #2=1\relax
  }%
  {%
    \ifstrequal{#1}{9}%
    {%
      #2=2\relax
    }%
    {%
      \ifstrequal{#1}{a}%
      {%
        #2=96\relax
      }%
      {%
        \ifstrequal{#1}{-}%
        {%
          #2=97\relax
        }%
        {%
          \ifstrequal{#1}{+}%
          {%
            #2=100\relax
          }%
          {%
            \ifstrequal{#1}{d}%
            {%
              #2=101\relax
            }%
            {%
              #2=`#1\relax
            }%
          }%
        }%
      }%
    }%
  }%
}

Output:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.