/// <summary>
        /// Performs transformation for a single file.
        /// </summary>
        /// <param name="file">The file to transform</param>
        /// <param name="outputType">The type of the transformation to perform</param>
        /// <param name="targetFilename">The output file into which to write the result.</param>
        /// <param name="solutionsUpToTask">Use solutions up to a given task number. Student versions are used otherwise. If <paramref name="outputType"/> is <see cref="TMLOutputType.Solution"/> and <paramref name="onlyTransformedFiles"/> is <c>true</c>, the output will only contain files that have snippets with the provided task number.</param>
        /// <param name="useSpecialSolution">Determines if the processor uses the <c>specialsolution</c> subtags instead of the <c>solution</c> subtags if available.</param>
        /// <returns>Returns true if the file has been transformed. Returns false if the file did not contain any relevant snippets.</returns>
        bool TransformFile(FileInfo file, TMLOutputType outputType, string targetFilename, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution)
        {
            //Parse the input file
            var doc = new TMLDocument(File.ReadAllText(file.FullName));

            //If the file does not contain any snippets, do not do anything
            if (doc.GetSnippetCount() == 0)
            {
                return(false);
            }

            //Check if there are relevant snippets.
            if (outputType == TMLOutputType.Solution && doc.GetSnippetCountForTask(solutionsUpToTask) == 0)
            {
                return(false);
            }

            using (var ms = new MemoryStream())
            {
                //Construct the new file first. Then, if no errors occured, write the file.
                doc.TransformDocument(ms, outputType, solutionsUpToTask, useSpecialSolution);
                ms.Seek(0, SeekOrigin.Begin);
                System.IO.File.WriteAllText(targetFilename, string.Empty);
                using (var fs = new FileStream(targetFilename, FileMode.OpenOrCreate))
                    ms.CopyTo(fs);
            }

            return(true);
        }
Пример #2
0
 /// <summary>
 /// Transforms this document and writes the result into <paramref name="output"/>.
 /// </summary>
 /// <param name="output">Output stream of the result</param>
 /// <param name="type">The type of the transformation to perform</param>
 /// <param name="solutionsUpToTask">Use solutions up to a given task number. Student versions are used otherwise.</param>
 /// <param name="useSpecialSolution">Determines if the processor uses the <c>specialsolution</c> subtags instead of the <c>solution</c> subtags if available.</param>
 public void TransformDocument(StreamWriter output, TMLOutputType type, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution = false)
 {
     //Simply print the active representation of every semantic node to the output.
     foreach (var node in nodes)
     {
         node.Print(output, text, type, solutionsUpToTask, useSpecialSolution);
     }
 }
Пример #3
0
            public override void Print(StreamWriter output, string originalDocument, TMLOutputType type, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution)
            {
                //specifies if the output should complete the entire TML markup.
                var printAll = type == TMLOutputType.TMLWithActiveSolution || type == TMLOutputType.TMLWithActiveStudentVersion;

                var subtagsActive = new Dictionary <string, bool>();

                //determine if the solution is active
                subtagsActive["solution"] = (type == TMLOutputType.TMLWithActiveSolution || type == TMLOutputType.Solution) && IsInOrBeforeTask(solutionsUpToTask);
                //determine if the specialsolution is active
                subtagsActive["specialsolution"] = SpecialSolutionContent != null && useSpecialSolution && subtagsActive["solution"];
                if (subtagsActive["specialsolution"])
                {
                    subtagsActive["solution"] = false;
                }
                subtagsActive["student"] = !subtagsActive["solution"] && !subtagsActive["specialsolution"];

                if (printAll)
                {
                    //Print the initial //<snippet> tag.
                    output.Write("//<snippet");
                    if (TaskNumber.HasValue)
                    {
                        output.Write($" task=\"{TaskNumber.ToString()}\"");
                    }
                    output.WriteLine(">");
                }

                //Print all subtags if applicable
                foreach (var subtag in subsnippets)
                {
                    var content = (SubSnippet)subtag.Key.GetValue(this);
                    if (content == null)
                    {
                        continue;
                    }

                    if (printAll)
                    {
                        //print the opening tag
                        output.Write(Indentation);
                        output.WriteLine($"//<{subtag.Value.TagName}>");
                        output.Write(Indentation);
                    }

                    //print the actual content
                    if (subtagsActive[subtag.Value.TagName] || printAll)
                    {
                        content.Print(output, subtagsActive[subtag.Value.TagName], Indentation);
                    }

                    if (printAll)
                    {
                        //print the closing tag
                        output.WriteLine();
                        output.Write(Indentation);
                        output.WriteLine($"//</{subtag.Value.TagName}>");
                    }
                }

                if (printAll)
                {
                    //print the closing snippet tag
                    output.Write(Indentation);
                    output.Write("//</snippet>");
                }
            }
Пример #4
0
 public override void Print(StreamWriter output, string originalDocument, TMLOutputType type, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution)
 {
     //Does not depend on the transformation type, simply print the text.
     output.Write(originalDocument.Substring(Content.BeginIndex, Content.Length));
 }
Пример #5
0
 /// <summary>
 /// Prints the correct representation according to the transformation type to <paramref name="output"/>.
 /// </summary>
 /// <param name="output">Output stream</param>
 /// <param name="originalDocument">Original content of the document</param>
 /// <param name="type">The transformation type to use</param>
 /// <param name="solutionsUpToTask">Use solutions up to a given task number. Student versions are used otherwise.</param>
 /// <param name="useSpecialSolution">Determines if the processor uses the <c>specialsolution</c> subtags instead of the <c>solution</c> subtags if available.</param>
 public abstract void Print(StreamWriter output, string originalDocument, TMLOutputType type, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution = false);
Пример #6
0
 /// <summary>
 /// Transforms this document and writes the result into <paramref name="output"/>.
 /// </summary>
 /// <param name="output">Output stream of the result</param>
 /// <param name="type">The type of the transformation to perform</param>
 /// <param name="solutionsUpToTask">Use solutions up to a given task number. Student versions are used otherwise.</param>
 /// <param name="useSpecialSolution">Determines if the processor uses the <c>specialsolution</c> subtags instead of the <c>solution</c> subtags if available.</param>
 public void TransformDocument(Stream output, TMLOutputType type, HierarchicalNumber?solutionsUpToTask, bool useSpecialSolution = false)
 {
     using (var str = new StreamWriter(output, Encoding.UTF8, 0x8000, true))
         TransformDocument(str, type, solutionsUpToTask, useSpecialSolution);
 }
        /// <summary>
        /// Starts the transformation of all files in the given source folder.
        /// </summary>
        /// <param name="folder">Source folder to process</param>
        /// <param name="outputType">The type of the transformation to perform</param>
        /// <param name="filter">The filter string for file extensions (file extensions separated by <c>' '</c>; extensions must start with <c>'.'</c>)</param>
        /// <param name="externalFolder">The output folder. Only used if <paramref name="outputType"/> is <see cref="TMLOutputType.Solution"/> or <see cref="TMLOutputType.StudentVersion"/>.</param>
        /// <param name="solutionsUpToTask">Use solutions up to a given task number. Student versions are used otherwise. If <paramref name="outputType"/> is <see cref="TMLOutputType.Solution"/> and <paramref name="onlyTransformedFiles"/> is <c>true</c>, the output will only contain files that have snippets with the provided task number.</param>
        /// <param name="onlyTransformedFiles">Determines if only files with any snippets in them are copied to the output directly. Only used if <paramref name="outputType"/> is <see cref="TMLOutputType.Solution"/> or <see cref="TMLOutputType.StudentVersion"/>.</param>
        /// <param name="useSpecialSolution">Determines if the processor uses the <c>specialsolution</c> subtags instead of the <c>solution</c> subtags if available.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="folder"/> is <c>null</c> or if <paramref name="externalFolder"/> is null but required for the current operation.</exception>
        /// <exception cref="ArgumentException">Thrown if the directory defined by <paramref name="folder"/> does not exist or if <paramref name="externalFolder"/> is required for the current operation and points to the same directory as <paramref name="folder"/>.</exception>
        /// <exception cref="FileTransformationException">Thrown if one of the files cannot be transformed.</exception>
        public void TransformFolder(string folder, TMLOutputType outputType, string filter, string externalFolder, HierarchicalNumber?solutionsUpToTask, bool onlyTransformedFiles, bool useSpecialSolution)
        {
            if (folder == null)
            {
                throw new ArgumentNullException("No input folder is provided for transformation.");
            }
            var dir = new DirectoryInfo(folder);

            if (!dir.Exists)
            {
                throw new ArgumentException($"The directory {folder} does not exist.");
            }

            //Backup
            if (folder != lastFolder)
            {
                CopyDirectories(dir, new DirectoryInfo(BackupFolder + "\\" + dir.Name));
            }

            DirectoryInfo externalDir = null;

            if (outputType == TMLOutputType.Solution || outputType == TMLOutputType.StudentVersion)
            {
                if (externalFolder == null)
                {
                    throw new ArgumentNullException("No output folder is provided for transformation.");
                }
                externalDir = new DirectoryInfo(externalFolder);
                if (externalDir.FullName == dir.FullName)
                {
                    throw new ArgumentException("The source and target directories cannot be the same.");
                }
                externalDir.Create();
            }

            //put all filters into a hash set for efficient queries
            var filters = new HashSet <string>(filter.Split(' '));

            //determines if we want to copy files that have no transformed snippets.
            bool copyUntransformedFiles = (outputType == TMLOutputType.StudentVersion || outputType == TMLOutputType.Solution) && !onlyTransformedFiles;

            //process each file in the directory
            foreach (string newPath in Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories))
            {
                //stores if the current file has been transformed
                bool transformed = false;
                var  inputFile   = new FileInfo(newPath);

                string targetFilename;
                if (outputType == TMLOutputType.Solution || outputType == TMLOutputType.StudentVersion)
                {
                    targetFilename = newPath.Replace(dir.FullName, externalDir.FullName);
                    var targetFile = new FileInfo(targetFilename);
                    Directory.CreateDirectory(Path.GetDirectoryName(targetFile.FullName));
                    if (targetFile.Exists)
                    {
                        targetFile.Delete();
                    }
                }
                else
                {
                    targetFilename = inputFile.FullName;
                }

                //only process files with the provided extensions
                if (filters.Contains(inputFile.Extension))
                {
                    try
                    {
                        //try to perform the transformation
                        transformed = TransformFile(inputFile, outputType, targetFilename, solutionsUpToTask, useSpecialSolution);
                    }
                    catch (Exception x)
                    {
                        throw new FileTransformationException(inputFile.FullName, x);
                    }
                }

                //Copy untransformed files to the output directory if applicable
                if (!transformed && copyUntransformedFiles)
                {
                    inputFile.CopyTo(targetFilename);
                }
            }
        }