REQIF->TEX->PDF implemented
This commit is contained in:
parent
ab366754df
commit
368b42c1ae
23
__init__.py
23
__init__.py
@ -1,5 +1,8 @@
|
||||
import optparse
|
||||
import os
|
||||
from reqif import xml_parser
|
||||
|
||||
import xml_parser
|
||||
import reqif_conv
|
||||
|
||||
|
||||
class reqif_dict(dict):
|
||||
@ -17,7 +20,7 @@ class reqif_dict(dict):
|
||||
for specification in self.rd.get_specifications():
|
||||
if specification.get(specification_key) == specification_identifier:
|
||||
sw_spec = specification
|
||||
break
|
||||
break
|
||||
#
|
||||
self[self.KEY_ITEM_DICT] = {}
|
||||
for obj_id in sw_spec.children:
|
||||
@ -65,3 +68,19 @@ class reqif(object):
|
||||
|
||||
def get_title(self):
|
||||
return self._data._title
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser("usage: %%prog reqif_file [options]")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
#
|
||||
# Check options and args
|
||||
if len(args) != 1 or not os.path.isfile(args[0]):
|
||||
parser.print_help()
|
||||
else:
|
||||
reqif_path = args[0]
|
||||
tex_path = os.path.abspath(os.path.splitext(reqif_path)[0] + '.tex')
|
||||
reqif_data = reqif_dict(reqif_path, 'Heading', 'Software Specification')
|
||||
reqif_conv.tex_gen(reqif_data, tex_path)
|
||||
reqif_conv.pdf_gen(tex_path)
|
||||
|
35
reqif_conv.py
Normal file
35
reqif_conv.py
Normal file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import jinja2
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
"""fn_tex = 'requirements_specification.tex'
|
||||
fn_pdf = 'requirements_specification.pdf'
|
||||
tmp_path = 'tmp'"""
|
||||
|
||||
|
||||
def tex_gen(reqif_data, tex_path):
|
||||
print('Creating LaTeX-File %s' % tex_path)
|
||||
with open(tex_path, 'w') as fh:
|
||||
#
|
||||
template_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates', 'tex'))
|
||||
template_filename = 'requirement_specification.tex'
|
||||
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path))
|
||||
template = jenv.get_template(template_filename)
|
||||
fh.write(template.render(data=reqif_data))
|
||||
|
||||
|
||||
def pdf_gen(tex_path):
|
||||
pdf_path = os.path.splitext(tex_path)[0] + '.pdf'
|
||||
print('Creating PDF %s' % pdf_path)
|
||||
for i in range(3):
|
||||
sys.stdout.write(' Starting run %d/3 of pdflatex... ' % (i + 1))
|
||||
sys.stdout.flush()
|
||||
exit_value = os.system("pdflatex -interaction nonstopmode %s 1> /dev/null" % tex_path)
|
||||
if exit_value != 0:
|
||||
print('FAILED')
|
||||
break
|
||||
else:
|
||||
print('SUCCESS')
|
17
templates/Makefile
Normal file
17
templates/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
SPEC_FILENAME=requirements
|
||||
|
||||
.PHONY: specification
|
||||
|
||||
specification:
|
||||
venv/bin/python reqif/__init__.py $(SPEC_FILENAME).reqif
|
||||
@$(MAKE) --no-print-directory clean
|
||||
xdg-open $(SPEC_FILENAME).pdf
|
||||
|
||||
clean:
|
||||
@echo Removing generated files for target
|
||||
@rm -f $(SPEC_FILENAME).tex $(SPEC_FILENAME).aux $(SPEC_FILENAME).log $(SPEC_FILENAME).out $(SPEC_FILENAME).toc *~
|
||||
|
||||
|
||||
cleanall: clean
|
||||
@echo Removing target
|
||||
@rm -f $(SPEC_FILENAME).pdf
|
1
templates/tex/foot.tex
Normal file
1
templates/tex/foot.tex
Normal file
@ -0,0 +1 @@
|
||||
\end{document}
|
96
templates/tex/head.tex
Normal file
96
templates/tex/head.tex
Normal file
@ -0,0 +1,96 @@
|
||||
{%- import 'macros.tex' as macros %}
|
||||
\documentclass[a4paper]{article}
|
||||
%\documentclass[a4paper,landscape]{article}
|
||||
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
\usepackage[table]{xcolor}
|
||||
\definecolor{orange}{rgb}{1, 0.7, 0}
|
||||
\definecolor{lightgrey}{rgb}{0.925, 0.925, 0.925}
|
||||
|
||||
\setlength{\topmargin}{-3cm}
|
||||
\setlength{\oddsidemargin}{-0.5cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\textwidth}{17.5cm}
|
||||
\setlength{\textheight}{24.5cm}
|
||||
%\setlength{\textwidth}{25cm}
|
||||
%\setlength{\textheight}{15cm}
|
||||
\setlength{\headheight}{84pt}
|
||||
|
||||
\usepackage{fancyvrb}
|
||||
\usepackage{fvextra}
|
||||
%\usepackage{framed,color}
|
||||
%\newenvironment{modulelog}{\snugshade\Verbatim}{\endVerbatim\endsnugshade}
|
||||
\usepackage{adjustbox}
|
||||
\newenvironment{modulelog}%
|
||||
{\par\noindent\adjustbox{margin=0ex,bgcolor=shadecolor,margin=0ex}\bgroup\varwidth\linewidth\Verbatim}%
|
||||
{\endVerbatim\endvarwidth\egroup}
|
||||
%\usepackage{xcolor}
|
||||
|
||||
\renewcommand{\baselinestretch}{1,2}
|
||||
\setlength{\parindent}{0pt}
|
||||
\setlength{\parskip}{9pt plus3pt minus3pt}
|
||||
|
||||
\usepackage{listings}
|
||||
\usepackage{color}
|
||||
\definecolor{bg-partially-covered}{rgb}{1,1,0.6} % light-yellow
|
||||
\definecolor{bg-uncovered}{rgb}{1,0.8,0.8} % light-red
|
||||
\definecolor{bg-covered}{rgb}{0.95,1,0.95} % very light-green
|
||||
\definecolor{bg-clean}{rgb}{1,1,1} % white
|
||||
\definecolor{mygreen}{rgb}{0,0.6,0}
|
||||
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
|
||||
\definecolor{mymauve}{rgb}{0.58,0,0.82}
|
||||
\lstset{ %
|
||||
backgroundcolor=\color{white}, % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}; should come as last argument
|
||||
basicstyle=\footnotesize, % the size of the fonts that are used for the code
|
||||
breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace
|
||||
breaklines=true, % sets automatic line breaking
|
||||
captionpos=b, % sets the caption-position to bottom
|
||||
commentstyle=\color{mygreen}, % comment style
|
||||
deletekeywords={...}, % if you want to delete keywords from the given language
|
||||
escapeinside={\%*}{*)}, % if you want to add LaTeX within your code
|
||||
extendedchars=true, % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8
|
||||
frame=none, % adds a frame around the code
|
||||
keepspaces=true, % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible)
|
||||
keywordstyle=\color{blue}, % keyword style
|
||||
language=Octave, % the language of the code
|
||||
morekeywords={*,...}, % if you want to add more keywords to the set
|
||||
numbers=left, % where to put the line-numbers; possible values are (none, left, right)
|
||||
numbersep=5pt, % how far the line-numbers are from the code
|
||||
numberstyle=\tiny\color{mygray}, % the style that is used for the line-numbers
|
||||
rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
|
||||
showlines=true,
|
||||
showspaces=false, % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
|
||||
showstringspaces=false, % underline spaces within strings only
|
||||
showtabs=false, % show tabs within strings adding particular underscores
|
||||
stepnumber=1, % the step between two line-numbers. If it's 1, each line will be numbered
|
||||
stringstyle=\color{mymauve}, % string literal style
|
||||
tabsize=2, % sets default tabsize to 2 spaces
|
||||
}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{longtable}
|
||||
\usepackage{tabu}
|
||||
\usepackage{multicol}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{lastpage} % for the number of the last page in the document
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{xspace}
|
||||
|
||||
|
||||
% define commands for easy access
|
||||
\newcommand{\req}[2]{\begin{infoBox} \textbf{ #1:} #2 \end{infoBox}}
|
||||
\newcommand{\rfori}[1]{\textbf{Reason for Implementation:} #1 \\}
|
||||
\newcommand{\fitcrit}[1]{\textbf{Fitcriterion:} #1 \\}
|
||||
|
||||
\fancyhf{}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\renewcommand{\footrulewidth}{0pt}
|
||||
\lhead{\textcolor{gray}{}}
|
||||
\chead{\textcolor{gray}{ Requirement Specification for {\tt {{ macros.latex_filter(data.titel) }} }}}
|
||||
\rhead{\textcolor{gray}{}}
|
||||
\lfoot{\textcolor{gray}{}}
|
||||
\cfoot{\textcolor{gray}{}}
|
||||
\rfoot{\textcolor{gray}{\thepage\,/ \pageref{LastPage}}}
|
||||
|
||||
\begin{document}
|
||||
|
13
templates/tex/macros.tex
Normal file
13
templates/tex/macros.tex
Normal file
@ -0,0 +1,13 @@
|
||||
{%- macro requirement_filter(text) -%}{{ text.replace('<', '$<$').replace('>', '$>$').replace('_', '\\_') }}
|
||||
{%- endmacro -%}
|
||||
{%- macro latex_filter(text) -%}{{ requirement_filter(text.replace('"', '\'')).replace('/xc2/xb0', '$^\circ$').replace('/', '/\\allowbreak ').replace('&', '\\allowbreak \\&').replace('->', '$\\rightarrow$').replace('<-', '$\\leftarrow$').replace('=>', '$\\Rightarrow$').replace('<=', '$\\leq$').replace('>=', '$\\geq$').replace('{', '\{').replace('}', '\}').replace('#', '\\#')}}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro color_by_level(level) -%}{% if level <= 10 %}black{% else %}{% if level <= 20 %}green{% else %}{% if level <= 30 %}orange{% else %}red{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro bg_by_levelno(level) -%}{% if level <= 10 %}0.8 0.8 0.8{% else %}{% if level <= 20 %}0.8 0.95 0.8{% else %}{% if level <= 30 %}1 0.75 0.45{% else %}0.95 0.8 0.8{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro result(level) -%}{% if level <= 10 %}Info{% else %}{% if level <= 20 %}\textcolor{green}{Success}{% else %}{% if level <= 30 %}\textcolor{orange}{Warning}{% else %}\textcolor{red}{Failed}{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
13
templates/tex/macros.tex~
Normal file
13
templates/tex/macros.tex~
Normal file
@ -0,0 +1,13 @@
|
||||
{%- macro requirement_filter(text) -%}{{ text.replace('<', '$<$').replace('>', '$>$') }}
|
||||
{%- endmacro -%}
|
||||
{%- macro latex_filter(text) -%}{{ requirement_filter(text).replace('\\', '/').replace('/xc2/xb0', '$^\circ$').replace('"', '\'').replace('/', '/\\allowbreak ').replace('&', '\\allowbreak \\&').replace('_', '\\_').replace('->', '$\\rightarrow$').replace('<-', '$\\leftarrow$').replace('=>', '$\\Rightarrow$').replace('<=', '$\\leq$').replace('>=', '$\\geq$').replace('{', '\{').replace('}', '\}').replace('#', '\\#')}}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro color_by_level(level) -%}{% if level <= 10 %}black{% else %}{% if level <= 20 %}green{% else %}{% if level <= 30 %}orange{% else %}red{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro bg_by_levelno(level) -%}{% if level <= 10 %}0.8 0.8 0.8{% else %}{% if level <= 20 %}0.8 0.95 0.8{% else %}{% if level <= 30 %}1 0.75 0.45{% else %}0.95 0.8 0.8{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro result(level) -%}{% if level <= 10 %}Info{% else %}{% if level <= 20 %}\textcolor{green}{Success}{% else %}{% if level <= 30 %}\textcolor{orange}{Warning}{% else %}\textcolor{red}{Failed}{% endif %}{% endif %}{% endif %}
|
||||
{%- endmacro -%}
|
15
templates/tex/requirement.tex
Normal file
15
templates/tex/requirement.tex
Normal file
@ -0,0 +1,15 @@
|
||||
{%- import 'macros.tex' as macros %}
|
||||
{%- if 'Description' in item and item.Description != '' %}
|
||||
\paragraph{\xspace{}{{ macros.latex_filter(item.ID) }} ({{macros.latex_filter(item.Heading)}}):}
|
||||
|
||||
{{ macros.requirement_filter(item.Description) }}
|
||||
|
||||
{%- endif %}
|
||||
{%- if 'ReasonForImplementation' in item and item.ReasonForImplementation != '' %}
|
||||
|
||||
Reason for Implementation: {{ macros.requirement_filter(item.ReasonForImplementation) }}
|
||||
{%- endif %}
|
||||
{%- if 'Fitcriterion' in item and item.Fitcriterion != '' %}
|
||||
|
||||
Fitcriterion: {{ macros.requirement_filter(item.Fitcriterion) }}
|
||||
{%- endif %}
|
32
templates/tex/requirement_specification.tex
Normal file
32
templates/tex/requirement_specification.tex
Normal file
@ -0,0 +1,32 @@
|
||||
{%- import 'macros.tex' as macros %}
|
||||
{%- include 'head.tex' %}
|
||||
{%- include 'titlepage.tex' %}
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
{%- for uid in data.uid_list_sorted %}
|
||||
{% with item=data.item_dict[uid] %}
|
||||
{%- if item.system_type_uid == '_4-K5EHYYEem_kd-7nxt1sg' %}
|
||||
\section{ {{macros.latex_filter(item.Heading)}} }
|
||||
{%- elif item.system_type_uid == '_MR7eNHYYEem_kd-7nxt1sg' %}
|
||||
\subsection{\xspace{}{{ macros.latex_filter(item.ID) }}: {{macros.latex_filter(item.Heading)}} }
|
||||
{%- if 'Description' in item and item.Description != '' %}
|
||||
{{ macros.requirement_filter(item.Description) }}
|
||||
{%- if 'ReasonForImplementation' in item and item.ReasonForImplementation != '' or 'Fitcriterion' in item and item.Fitcriterion != ''%}
|
||||
|
||||
\begin{tabu}{lX}
|
||||
\toprule
|
||||
{%- if 'ReasonForImplementation' in item and item.ReasonForImplementation != '' %}
|
||||
\emph{Reason} & {{ macros.requirement_filter(item.ReasonForImplementation) }}\\
|
||||
{%- endif %}
|
||||
{%- if 'Fitcriterion' in item and item.Fitcriterion != '' %}
|
||||
\emph{Fitcriterion} & {{ macros.requirement_filter(item.Fitcriterion) }}\\
|
||||
{%- endif %}
|
||||
\bottomrule
|
||||
\end{tabu}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{% endwith %}
|
||||
{%- endfor %}
|
||||
{% include 'foot.tex' %}
|
15
templates/tex/titlepage.tex
Normal file
15
templates/tex/titlepage.tex
Normal file
@ -0,0 +1,15 @@
|
||||
{%- import 'macros.tex' as macros %}
|
||||
\begin{titlepage}
|
||||
\date{\today}
|
||||
\title{
|
||||
Requirement Specification for\\{\tt {{ macros.latex_filter(data.titel) }} }
|
||||
}
|
||||
\date{\today}
|
||||
\maketitle
|
||||
\thispagestyle{empty}
|
||||
\newpage
|
||||
\end{titlepage}
|
||||
|
||||
\setcounter{page}{1}
|
||||
\pagestyle{fancy}
|
||||
|
Loading…
x
Reference in New Issue
Block a user